diff --git a/.github/workflows/check-updates.yml b/.github/workflows/check-updates.yml index 40b4b6adb..ebc8d4294 100644 --- a/.github/workflows/check-updates.yml +++ b/.github/workflows/check-updates.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.6.0 + - uses: actions/checkout@v4.1.1 with: token: ${{ secrets.WORKFLOW_SECRET }} diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml index bb139aacb..0665a8289 100644 --- a/.github/workflows/dev.yml +++ b/.github/workflows/dev.yml @@ -16,19 +16,19 @@ jobs: runs-on: ubuntu-latest steps: - name: Prepare - Checkout - uses: actions/checkout@v3.6.0 + uses: actions/checkout@v4.1.1 - name: Prepare - Inject short Variables uses: rlespinasse/github-slug-action@v4.4.1 - name: Prepare - Set up QEMU - uses: docker/setup-qemu-action@v2.2.0 + uses: docker/setup-qemu-action@v3.0.0 - name: Prepare - Set up Docker Buildx - uses: docker/setup-buildx-action@v2.9.1 + uses: docker/setup-buildx-action@v3.0.0 - name: Build - BUILD - uses: docker/build-push-action@v4.1.1 + uses: docker/build-push-action@v5.0.0 with: load: true build-args: "SQUIDEX__RUNTIME__VERSION=7.0.0-dev-${{ env.BUILD_NUMBER }}" @@ -103,7 +103,7 @@ jobs: - name: Publish - Login to Docker Hub if: github.event_name != 'pull_request' - uses: docker/login-action@v2.2.0 + uses: docker/login-action@v3.0.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 88f0f3872..ffbc6cb51 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,19 +11,19 @@ jobs: runs-on: ubuntu-latest steps: - name: Prepare - Checkout - uses: actions/checkout@v3.6.0 + uses: actions/checkout@v4.1.1 - name: Prepare - Inject short Variables uses: rlespinasse/github-slug-action@v4.4.1 - name: Prepare - Set up QEMU - uses: docker/setup-qemu-action@v2.2.0 + uses: docker/setup-qemu-action@v3.0.0 - name: Prepare - Set up Docker Buildx - uses: docker/setup-buildx-action@v2.9.1 + uses: docker/setup-buildx-action@v3.0.0 - name: Build - BUILD - uses: docker/build-push-action@v4.1.1 + uses: docker/build-push-action@v5.0.0 with: load: true build-args: "SQUIDEX__BUILD__VERSION=${{ env.GITHUB_REF_SLUG }},SQUIDEX__RUNTIME__VERSION=${{ env.GITHUB_REF_SLUG }}" @@ -104,7 +104,7 @@ jobs: fi - name: Publish - Login to Docker Hub - uses: docker/login-action@v2.2.0 + uses: docker/login-action@v3.0.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} diff --git a/CHANGELOG.md b/CHANGELOG.md index d1a11b277..b83f28758 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,26 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [7.8.2] - 2023-09-19 + +### Fixed + +* **Assets**: Fixed S3 configuration. +* **Contents**: Fixed a query that was causing exceptions when using pagination. +* **UI**: Generate unique IDs for radio groups to fix a problem when multiple groups exist per page. + +### Changed + +* **UI**: Migration to angular 16. +* **UI**: Better chat dialog. + +### Added + +* **Contents**: Default values for array fields. +* **Contents**: Default values for components fields. +* **Rules**: Support for deep detect to annotate images with AI models. +* **UI**: Widget plugins for teams and app dashboard. + ## [7.8.1] - 2023-08-04 ### Fixed diff --git a/backend/extensions/Squidex.Extensions/Actions/Algolia/AlgoliaActionHandler.cs b/backend/extensions/Squidex.Extensions/Actions/Algolia/AlgoliaActionHandler.cs index bffac761a..d3c60f317 100644 --- a/backend/extensions/Squidex.Extensions/Actions/Algolia/AlgoliaActionHandler.cs +++ b/backend/extensions/Squidex.Extensions/Actions/Algolia/AlgoliaActionHandler.cs @@ -40,65 +40,65 @@ public sealed class AlgoliaActionHandler : RuleActionHandler CreateJobAsync(EnrichedEvent @event, AlgoliaAction action) { - if (@event is IEnrichedEntityEvent entityEvent) + if (@event is not IEnrichedEntityEvent entityEvent) { - var delete = @event.ShouldDelete(scriptEngine, action.Delete); + return ("Ignore", new AlgoliaJob()); + } - var ruleDescription = string.Empty; - var contentId = entityEvent.Id.ToString(); - var content = (AlgoliaContent?)null; + var delete = @event.ShouldDelete(scriptEngine, action.Delete); - if (delete) - { - ruleDescription = $"Delete entry from Algolia index: {action.IndexName}"; - } - else - { - ruleDescription = $"Add entry to Algolia index: {action.IndexName}"; + var ruleDescription = string.Empty; + var contentId = entityEvent.Id.ToString(); + var content = (AlgoliaContent?)null; - try - { - string? jsonString; + if (delete) + { + ruleDescription = $"Delete entry from Algolia index: {action.IndexName}"; + } + else + { + ruleDescription = $"Add entry to Algolia index: {action.IndexName}"; - if (!string.IsNullOrEmpty(action.Document)) - { - jsonString = await FormatAsync(action.Document, @event); - jsonString = jsonString?.Trim(); - } - else - { - jsonString = ToJson(@event); - } + try + { + string? jsonString; - content = serializer.Deserialize(jsonString!); + if (!string.IsNullOrEmpty(action.Document)) + { + jsonString = await FormatAsync(action.Document, @event); + jsonString = jsonString?.Trim(); } - catch (Exception ex) + else { - content = new AlgoliaContent - { - More = new Dictionary - { - ["error"] = $"Invalid JSON: {ex.Message}" - } - }; + jsonString = ToJson(@event); } - content.ObjectID = contentId; + content = serializer.Deserialize(jsonString!); } - - var ruleJob = new AlgoliaJob + catch (Exception ex) { - AppId = action.AppId, - ApiKey = action.ApiKey, - Content = serializer.Serialize(content, true), - ContentId = contentId, - IndexName = (await FormatAsync(action.IndexName, @event))! - }; - - return (ruleDescription, ruleJob); + content = new AlgoliaContent + { + More = new Dictionary + { + ["error"] = $"Invalid JSON: {ex.Message}" + } + }; + } + + content.ObjectID = contentId; } - return ("Ignore", new AlgoliaJob()); + var ruleJob = new AlgoliaJob + { + AppId = action.AppId, + ApiKey = action.ApiKey, + Content = serializer.Serialize(content, true), + ContentId = contentId, + IndexName = (await FormatAsync(action.IndexName, @event))! + }; + + return (ruleDescription, ruleJob); } protected override async Task ExecuteJobAsync(AlgoliaJob job, diff --git a/backend/extensions/Squidex.Extensions/Actions/Comment/CommentActionHandler.cs b/backend/extensions/Squidex.Extensions/Actions/Comment/CommentActionHandler.cs index 1865f7c38..8e785b134 100644 --- a/backend/extensions/Squidex.Extensions/Actions/Comment/CommentActionHandler.cs +++ b/backend/extensions/Squidex.Extensions/Actions/Comment/CommentActionHandler.cs @@ -7,65 +7,68 @@ using Squidex.Domain.Apps.Core.HandleRules; using Squidex.Domain.Apps.Core.Rules.EnrichedEvents; -using Squidex.Domain.Apps.Entities.Comments.Commands; +using Squidex.Domain.Apps.Entities.Collaboration; +using Squidex.Domain.Apps.Events.Comments; using Squidex.Infrastructure; -using Squidex.Infrastructure.Commands; namespace Squidex.Extensions.Actions.Comment; -public sealed class CommentActionHandler : RuleActionHandler +public sealed class CommentActionHandler : RuleActionHandler { private const string Description = "Send a Comment"; - private readonly ICommandBus commandBus; + private readonly ICollaborationService collaboration; - public CommentActionHandler(RuleEventFormatter formatter, ICommandBus commandBus) + public CommentActionHandler(RuleEventFormatter formatter, ICollaborationService collaboration) : base(formatter) { - this.commandBus = commandBus; + this.collaboration = collaboration; } - protected override async Task<(string Description, CreateComment Data)> CreateJobAsync(EnrichedEvent @event, CommentAction action) + protected override async Task<(string Description, CommentCreated Data)> CreateJobAsync(EnrichedEvent @event, CommentAction action) { - if (@event is EnrichedContentEvent contentEvent) + if (@event is not EnrichedContentEvent contentEvent) { - var ruleJob = new CreateComment - { - AppId = contentEvent.AppId - }; + return ("Ignore", new CommentCreated()); + } + + var ruleJob = new CommentCreated + { + AppId = contentEvent.AppId + }; - ruleJob.Text = (await FormatAsync(action.Text, @event))!; + var text = await FormatAsync(action.Text, @event); - if (!string.IsNullOrEmpty(action.Client)) - { - ruleJob.Actor = RefToken.Client(action.Client); - } - else - { - ruleJob.Actor = contentEvent.Actor; - } + if (string.IsNullOrWhiteSpace(text)) + { + return ("NoText", new CommentCreated()); + } - ruleJob.CommentsId = contentEvent.Id; + ruleJob.Text = text; - return (Description, ruleJob); + if (!string.IsNullOrEmpty(action.Client)) + { + ruleJob.Actor = RefToken.Client(action.Client); } + else + { + ruleJob.Actor = contentEvent.Actor; + } + + ruleJob.CommentsId = contentEvent.Id; - return ("Ignore", new CreateComment()); + return (Description, ruleJob); } - protected override async Task ExecuteJobAsync(CreateComment job, + protected override async Task ExecuteJobAsync(CommentCreated job, CancellationToken ct = default) { - var command = job; - - if (command.CommentsId == default) + if (job.CommentsId == default) { return Result.Ignored(); } - command.FromRule = true; - - await commandBus.PublishAsync(command, ct); + await collaboration.CommentAsync(job.AppId, job.CommentsId, job.Text, job.Actor, job.Url, true, ct); - return Result.Success($"Commented: {command.Text}"); + return Result.Success($"Commented: {job.Text}"); } } diff --git a/backend/extensions/Squidex.Extensions/Actions/CreateContent/CreateContentActionHandler.cs b/backend/extensions/Squidex.Extensions/Actions/CreateContent/CreateContentActionHandler.cs index b97e08857..657db7908 100644 --- a/backend/extensions/Squidex.Extensions/Actions/CreateContent/CreateContentActionHandler.cs +++ b/backend/extensions/Squidex.Extensions/Actions/CreateContent/CreateContentActionHandler.cs @@ -47,6 +47,7 @@ public sealed class CreateContentActionHandler : RuleActionHandler +{ + private const string Description = "Analyze Image"; + private readonly IHttpClientFactory httpClientFactory; + private readonly IJsonSerializer jsonSerializer; + private readonly IAppProvider appProvider; + private readonly IAssetQueryService assetQuery; + private readonly ICommandBus commandBus; + private readonly IUrlGenerator urlGenerator; + + public DeepDetectActionHandler(RuleEventFormatter formatter, IHttpClientFactory httpClientFactory, + IJsonSerializer jsonSerializer, + IAppProvider appProvider, + IAssetQueryService assetQuery, + ICommandBus commandBus, + IUrlGenerator urlGenerator) + : base(formatter) + { + this.httpClientFactory = httpClientFactory; + this.jsonSerializer = jsonSerializer; + this.appProvider = appProvider; + this.assetQuery = assetQuery; + this.commandBus = commandBus; + this.urlGenerator = urlGenerator; + } + + protected override Task<(string Description, DeepDetectJob Data)> CreateJobAsync(EnrichedEvent @event, DeepDetectAction action) + { + if (@event is not EnrichedAssetEvent assetEvent) + { + return Task.FromResult(("Ignore", new DeepDetectJob())); + } + + if (assetEvent.AssetType != AssetType.Image) + { + return Task.FromResult(("Ignore", new DeepDetectJob())); + } + + var ruleJob = new DeepDetectJob + { + Actor = assetEvent.Actor, + AppId = assetEvent.AppId.Id, + AssetId = assetEvent.Id, + MaximumTags = action.MaximumTags, + MinimumPropability = action.MinimumProbability, + Url = urlGenerator.AssetContent(assetEvent.AppId, assetEvent.Id.ToString(), assetEvent.FileVersion) + }; + + return Task.FromResult((Description, ruleJob)); + } + + protected override async Task ExecuteJobAsync(DeepDetectJob job, + CancellationToken ct = default) + { + if (string.IsNullOrWhiteSpace(job.Url)) + { + return Result.Ignored(); + } + + var httpClient = httpClientFactory.CreateClient("DeepDetect"); + + var response = await httpClient.PostAsJsonAsync("predict", new + { + service = "squidexdetector", + output = new + { + best = job.MaximumTags, + confidence_threshold = job.MinimumPropability / 100d, + }, + data = new[] + { + job.Url, + } + }, ct); + + var body = await response.Content.ReadAsStringAsync(ct); + + if (!response.IsSuccessStatusCode) + { + return Result.Failed(new InvalidOperationException($"Failed with status code {response.StatusCode}\n\n{body}")); + } + + var responseJson = jsonSerializer.Deserialize(body); + + var tags = responseJson!.Body.Predictions.SelectMany(x => x.Classes); + + if (!tags.Any()) + { + return Result.Success(body); + } + + var app = await appProvider.GetAppAsync(job.AppId, true, ct); + if (app == null) + { + return Result.Failed(new InvalidOperationException("App not found.")); + } + + var context = Context.Admin(app); + + var asset = await assetQuery.FindAsync(context, job.AssetId, ct: ct); + if (asset == null) + { + return Result.Failed(new InvalidOperationException("Asset not found.")); + } + + var command = new AnnotateAsset + { + Tags = asset.TagNames, + AssetId = asset.AssetId, + AppId = asset.AppId, + Actor = job.Actor, + FromRule = true + }; + + foreach (var tag in tags) + { + var tagParts = tag.Cat.Split(',')[0].Split(' ', StringSplitOptions.RemoveEmptyEntries); + + if (IdRegex().IsMatch(tagParts[0])) + { + tagParts = tagParts.Skip(1).ToArray(); + } + + var tagName = string.Join('_', tagParts.Select(x => x.Slugify())); + + command.Tags.Add($"ai/{tagName}"); + } + + await commandBus.PublishAsync(command, ct); + return Result.Success(body); + } + + private sealed class DetectResponse + { + public DetectBody Body { get; set; } + } + + private sealed class DetectBody + { + public DetectPredications[] Predictions { get; set; } + } + + private sealed class DetectPredications + { + public DetectClass[] Classes { get; set; } + } + + private sealed class DetectClass + { + public double Prob { get; set; } + + public string Cat { get; set; } + } + + [GeneratedRegex("^n[0-9]+$")] + private static partial Regex IdRegex(); +} + +public sealed class DeepDetectJob +{ + public DomainId AppId { get; set; } + + public DomainId AssetId { get; set; } + + public RefToken Actor { get; set; } + + public long MaximumTags { get; set; } + + public long MinimumPropability { get; set; } + + public string? Url { get; set; } +} diff --git a/backend/extensions/Squidex.Extensions/Actions/DeepDetect/DeepDetectPlugin.cs b/backend/extensions/Squidex.Extensions/Actions/DeepDetect/DeepDetectPlugin.cs new file mode 100644 index 000000000..c614fc7a1 --- /dev/null +++ b/backend/extensions/Squidex.Extensions/Actions/DeepDetect/DeepDetectPlugin.cs @@ -0,0 +1,32 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Squidex.Infrastructure.Plugins; + +namespace Squidex.Extensions.Actions.DeepDetect; + +internal class DeepDetectPlugin : IPlugin +{ + public void ConfigureServices(IServiceCollection services, IConfiguration config) + { + var url = config.GetValue("deepdetect:url"); + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + { + return; + } + + services.AddHttpClient("DeepDetect", client => + { + client.BaseAddress = uri; + }); + + services.AddRuleAction(); + } +} diff --git a/backend/extensions/Squidex.Extensions/Actions/Email/EmailActionHandler.cs b/backend/extensions/Squidex.Extensions/Actions/Email/EmailActionHandler.cs index 888fb19f7..1252a8dc6 100644 --- a/backend/extensions/Squidex.Extensions/Actions/Email/EmailActionHandler.cs +++ b/backend/extensions/Squidex.Extensions/Actions/Email/EmailActionHandler.cs @@ -47,7 +47,6 @@ public sealed class EmailActionHandler : RuleActionHandler +public sealed class NotificationActionHandler : RuleActionHandler { private const string Description = "Send a Notification"; - private readonly ICommandBus commandBus; + private readonly ICollaborationService collaboration; private readonly IUserResolver userResolver; - public NotificationActionHandler(RuleEventFormatter formatter, ICommandBus commandBus, IUserResolver userResolver) + public NotificationActionHandler(RuleEventFormatter formatter, ICollaborationService collaboration, IUserResolver userResolver) : base(formatter) { - this.commandBus = commandBus; - + this.collaboration = collaboration; this.userResolver = userResolver; } - protected override async Task<(string Description, CreateComment Data)> CreateJobAsync(EnrichedEvent @event, NotificationAction action) + protected override async Task<(string Description, CommentCreated Data)> CreateJobAsync(EnrichedEvent @event, NotificationAction action) { - if (@event is EnrichedUserEventBase userEvent) + if (@event is not EnrichedUserEventBase userEvent) { - var user = await userResolver.FindByIdOrEmailAsync(action.User); + return ("Ignore", new CommentCreated()); + } - if (user == null) - { - throw new InvalidOperationException($"Cannot find user by '{action.User}'"); - } + var user = await userResolver.FindByIdOrEmailAsync(action.User); - var actor = userEvent.Actor; + if (user == null) + { + throw new InvalidOperationException($"Cannot find user by '{action.User}'"); + } - if (!string.IsNullOrEmpty(action.Client)) - { - actor = RefToken.Client(action.Client); - } + var actor = userEvent.Actor; - var ruleJob = new CreateComment - { - AppId = CommentsCommand.NoApp, - Actor = actor, - CommentId = DomainId.NewGuid(), - CommentsId = DomainId.Create(user.Id), - FromRule = true, - Text = (await FormatAsync(action.Text, @event))! - }; - - if (!string.IsNullOrWhiteSpace(action.Url)) - { - var url = await FormatAsync(action.Url, @event); + if (!string.IsNullOrEmpty(action.Client)) + { + actor = RefToken.Client(action.Client); + } - if (Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out var uri)) - { - ruleJob.Url = uri; - } - } + var ruleJob = new CommentCreated + { + Actor = actor, + CommentId = DomainId.NewGuid(), + CommentsId = DomainId.Create(user.Id), + FromRule = true, + Text = (await FormatAsync(action.Text, @event))! + }; + + if (!string.IsNullOrWhiteSpace(action.Url)) + { + var url = await FormatAsync(action.Url, @event); - return (Description, ruleJob); + if (Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out var uri)) + { + ruleJob.Url = uri; + } } - return ("Ignore", new CreateComment()); + return (Description, ruleJob); } - protected override async Task ExecuteJobAsync(CreateComment job, + protected override async Task ExecuteJobAsync(CommentCreated job, CancellationToken ct = default) { - var command = job; - - if (command.CommentsId == default) + if (job.CommentsId == default) { return Result.Ignored(); } - await commandBus.PublishAsync(command, ct); + await collaboration.NotifyAsync(job.CommentsId.ToString(), job.Text, job.Actor, job.Url, true, ct); - return Result.Success($"Notified: {command.Text}"); + return Result.Success($"Notified: {job.Text}"); } } diff --git a/backend/extensions/Squidex.Extensions/Actions/Prerender/PrerenderActionHandler.cs b/backend/extensions/Squidex.Extensions/Actions/Prerender/PrerenderActionHandler.cs index 98686646d..5ac0c3357 100644 --- a/backend/extensions/Squidex.Extensions/Actions/Prerender/PrerenderActionHandler.cs +++ b/backend/extensions/Squidex.Extensions/Actions/Prerender/PrerenderActionHandler.cs @@ -27,8 +27,8 @@ public sealed class PrerenderActionHandler : RuleActionHandler(); } + + // Version 27: New rule statistics using normal usage collection. + if (version < 26) + { + yield return serviceProvider.GetRequiredService(); + } } } diff --git a/backend/src/Migrations/Migrations/MongoDb/CopyRuleStatistics.cs b/backend/src/Migrations/Migrations/MongoDb/CopyRuleStatistics.cs new file mode 100644 index 000000000..d97b51ca2 --- /dev/null +++ b/backend/src/Migrations/Migrations/MongoDb/CopyRuleStatistics.cs @@ -0,0 +1,66 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; +using MongoDB.Driver; +using Squidex.Domain.Apps.Entities.Rules; +using Squidex.Infrastructure; +using Squidex.Infrastructure.Migrations; +using Squidex.Infrastructure.MongoDb; + +namespace Migrations.Migrations.MongoDb; + +public sealed class CopyRuleStatistics : IMigration +{ + private readonly IMongoDatabase database; + private readonly IRuleUsageTracker ruleUsageTracker; + + [BsonIgnoreExtraElements] + public class Document + { + public DomainId AppId { get; private set; } + + public DomainId RuleId { get; private set; } + + public int NumFailed { get; private set; } + + public int NumSucceeded { get; private set; } + } + + public CopyRuleStatistics(IMongoDatabase database, IRuleUsageTracker ruleUsageTracker) + { + this.database = database; + this.ruleUsageTracker = ruleUsageTracker; + } + + public async Task UpdateAsync( + CancellationToken ct) + { + var collectionName = "RuleStatistics"; + + // Do not create the collection if not needed. + if (!await database.CollectionExistsAsync(collectionName, ct)) + { + return; + } + + var collection = database.GetCollection(collectionName); + + await foreach (var document in collection.Find(new BsonDocument()).ToAsyncEnumerable(ct)) + { + await ruleUsageTracker.TrackAsync( + document.AppId, + document.RuleId, + default, + 0, + document.NumSucceeded, + document.NumFailed, + ct); + } + } +} diff --git a/backend/src/Squidex.Domain.Apps.Events/Comments/CommentDeleted.cs b/backend/src/Migrations/OldEvents/CommentDeleted.cs similarity index 82% rename from backend/src/Squidex.Domain.Apps.Events/Comments/CommentDeleted.cs rename to backend/src/Migrations/OldEvents/CommentDeleted.cs index f6282e2e0..efd794251 100644 --- a/backend/src/Squidex.Domain.Apps.Events/Comments/CommentDeleted.cs +++ b/backend/src/Migrations/OldEvents/CommentDeleted.cs @@ -7,9 +7,9 @@ using Squidex.Infrastructure.EventSourcing; -namespace Squidex.Domain.Apps.Events.Comments; +namespace Migrations.OldEvents; [EventType(nameof(CommentDeleted))] -public sealed class CommentDeleted : CommentsEvent +public sealed class CommentDeleted : IEvent { } diff --git a/backend/src/Squidex.Domain.Apps.Events/Comments/CommentUpdated.cs b/backend/src/Migrations/OldEvents/CommentUpdated.cs similarity index 83% rename from backend/src/Squidex.Domain.Apps.Events/Comments/CommentUpdated.cs rename to backend/src/Migrations/OldEvents/CommentUpdated.cs index dc314d772..7a490f196 100644 --- a/backend/src/Squidex.Domain.Apps.Events/Comments/CommentUpdated.cs +++ b/backend/src/Migrations/OldEvents/CommentUpdated.cs @@ -7,10 +7,10 @@ using Squidex.Infrastructure.EventSourcing; -namespace Squidex.Domain.Apps.Events.Comments; +namespace Migrations.OldEvents; [EventType(nameof(CommentUpdated))] -public sealed class CommentUpdated : CommentsEvent +public sealed class CommentUpdated : IEvent { public string Text { get; set; } } diff --git a/backend/src/Migrations/RebuilderExtensions.cs b/backend/src/Migrations/RebuilderExtensions.cs index 1dc8462bd..73aea3227 100644 --- a/backend/src/Migrations/RebuilderExtensions.cs +++ b/backend/src/Migrations/RebuilderExtensions.cs @@ -11,6 +11,7 @@ using Squidex.Domain.Apps.Entities.Contents.DomainObject; using Squidex.Domain.Apps.Entities.Rules.DomainObject; using Squidex.Domain.Apps.Entities.Schemas.DomainObject; using Squidex.Infrastructure.Commands; +using Squidex.Infrastructure.EventSourcing; namespace Migrations; @@ -21,36 +22,48 @@ public static class RebuilderExtensions public static Task RebuildAppsAsync(this Rebuilder rebuilder, int batchSize, CancellationToken ct = default) { - return rebuilder.RebuildAsync("^app\\-", batchSize, AllowedErrorRate, ct); + var streamFilter = StreamFilter.Prefix("app-"); + + return rebuilder.RebuildAsync(streamFilter, batchSize, AllowedErrorRate, ct); } public static Task RebuildSchemasAsync(this Rebuilder rebuilder, int batchSize, CancellationToken ct = default) { - return rebuilder.RebuildAsync("^schema\\-", batchSize, AllowedErrorRate, ct); + var streamFilter = StreamFilter.Prefix("schema-"); + + return rebuilder.RebuildAsync(streamFilter, batchSize, AllowedErrorRate, ct); } public static Task RebuildRulesAsync(this Rebuilder rebuilder, int batchSize, CancellationToken ct = default) { - return rebuilder.RebuildAsync("^rule\\-", batchSize, AllowedErrorRate, ct); + var streamFilter = StreamFilter.Prefix("rule-"); + + return rebuilder.RebuildAsync(streamFilter, batchSize, AllowedErrorRate, ct); } public static Task RebuildAssetsAsync(this Rebuilder rebuilder, int batchSize, CancellationToken ct = default) { - return rebuilder.RebuildAsync("^asset\\-", batchSize, AllowedErrorRate, ct); + var streamFilter = StreamFilter.Prefix("asset-"); + + return rebuilder.RebuildAsync(streamFilter, batchSize, AllowedErrorRate, ct); } public static Task RebuildAssetFoldersAsync(this Rebuilder rebuilder, int batchSize, CancellationToken ct = default) { - return rebuilder.RebuildAsync("^assetFolder\\-", batchSize, AllowedErrorRate, ct); + var streamFilter = StreamFilter.Prefix("assetFolder-"); + + return rebuilder.RebuildAsync(streamFilter, batchSize, AllowedErrorRate, ct); } public static Task RebuildContentAsync(this Rebuilder rebuilder, int batchSize, CancellationToken ct = default) { - return rebuilder.RebuildAsync("^content\\-", batchSize, AllowedErrorRate, ct); + var streamFilter = StreamFilter.Prefix("content-"); + + return rebuilder.RebuildAsync(streamFilter, batchSize, AllowedErrorRate, ct); } } diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Comments/Comment.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Comments/Comment.cs index 8c3a5224d..eb47a2d3d 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Model/Comments/Comment.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Comments/Comment.cs @@ -12,7 +12,7 @@ using Squidex.Infrastructure; namespace Squidex.Domain.Apps.Core.Comments; -public sealed record Comment(DomainId Id, Instant Time, RefToken User, string Text, Uri? Url = null) +public sealed record Comment(Instant Time, RefToken User, string Text, Uri? Url = null, bool SkipHandlers = false) { public RefToken User { get; } = Guard.NotNull(User); diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/FieldDescriptions.Designer.cs b/backend/src/Squidex.Domain.Apps.Core.Model/FieldDescriptions.Designer.cs index abb9aa2f3..7f4b90c45 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Model/FieldDescriptions.Designer.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Model/FieldDescriptions.Designer.cs @@ -762,6 +762,15 @@ namespace Squidex.Domain.Apps.Core { } } + /// + /// Looks up a localized string similar to The graphql request.. + /// + public static string GraphqlRequest { + get { + return ResourceManager.GetString("GraphqlRequest", resourceCulture); + } + } + /// /// Looks up a localized string similar to The current item, if the field is part of an array.. /// diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/FieldDescriptions.resx b/backend/src/Squidex.Domain.Apps.Core.Model/FieldDescriptions.resx index fb2bdafa3..ed8b9d303 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Model/FieldDescriptions.resx +++ b/backend/src/Squidex.Domain.Apps.Core.Model/FieldDescriptions.resx @@ -351,6 +351,9 @@ The type of the event. + + The graphql request. + The current item, if the field is part of an array. diff --git a/backend/src/Squidex.Domain.Apps.Entities/Comments/Commands/DeleteComment.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ArrayCalculatedDefaultValue.cs similarity index 77% rename from backend/src/Squidex.Domain.Apps.Entities/Comments/Commands/DeleteComment.cs rename to backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ArrayCalculatedDefaultValue.cs index 8281697a7..c74a7a6b8 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Comments/Commands/DeleteComment.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ArrayCalculatedDefaultValue.cs @@ -5,8 +5,10 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -namespace Squidex.Domain.Apps.Entities.Comments.Commands; +namespace Squidex.Domain.Apps.Core.Schemas; -public sealed class DeleteComment : CommentCommand +public enum ArrayCalculatedDefaultValue { + EmptyArray, + Null } diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ArrayFieldProperties.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ArrayFieldProperties.cs index d5be61a81..3a6e74c40 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ArrayFieldProperties.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ArrayFieldProperties.cs @@ -15,6 +15,8 @@ public sealed record ArrayFieldProperties : FieldProperties public int? MaxItems { get; init; } + public ArrayCalculatedDefaultValue CalculatedDefaultValue { get; init; } + public ReadonlyList? UniqueFields { get; init; } public override T Accept(IFieldPropertiesVisitor visitor, TArgs args) diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ComponentsFieldProperties.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ComponentsFieldProperties.cs index 4cbff3585..09a7bf436 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ComponentsFieldProperties.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ComponentsFieldProperties.cs @@ -18,6 +18,8 @@ public sealed record ComponentsFieldProperties : FieldProperties public ReadonlyList? UniqueFields { get; init; } + public ArrayCalculatedDefaultValue CalculatedDefaultValue { get; init; } + public DomainId SchemaId { init diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ReferencesFieldProperties.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ReferencesFieldProperties.cs index d0f72af6a..a35b58cd5 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ReferencesFieldProperties.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ReferencesFieldProperties.cs @@ -26,6 +26,8 @@ public sealed record ReferencesFieldProperties : FieldProperties public bool MustBePublished { get; init; } + public string? Query { get; init; } + public ReferencesFieldEditor Editor { get; init; } public DomainId SchemaId diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/StringFieldProperties.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/StringFieldProperties.cs index 11448b254..817af70ba 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/StringFieldProperties.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/StringFieldProperties.cs @@ -14,6 +14,8 @@ public sealed record StringFieldProperties : FieldProperties { public ReadonlyList? AllowedValues { get; init; } + public ReadonlyList? ClassNames { get; set; } + public LocalizedValue DefaultValues { get; init; } public string? DefaultValue { get; init; } diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/DefaultValueFactory.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/DefaultValueFactory.cs index e5e3be6bd..3a4c50dce 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/DefaultValueFactory.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/ConvertContent/DefaultValueFactory.cs @@ -33,6 +33,21 @@ public sealed class DefaultValueFactory : IFieldPropertiesVisitor appId, string idOrSlug); + string AssetContent(NamedId appId, string idOrSlug, long version); + string AssetContentBase(); string AssetContentBase(string appName); diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj b/backend/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj index 4a6dc3952..0ecc9f021 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/Squidex.Domain.Apps.Core.Operations.csproj @@ -28,7 +28,7 @@ - + diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/Subscriptions/SubscriptionPublisher.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/Subscriptions/SubscriptionPublisher.cs index fa2db26d5..4bd054ed7 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/Subscriptions/SubscriptionPublisher.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/Subscriptions/SubscriptionPublisher.cs @@ -16,25 +16,13 @@ public sealed class SubscriptionPublisher : IEventConsumer private readonly ISubscriptionService subscriptionService; private readonly IEnumerable subscriptionEventCreators; - public string Name - { - get => "Subscriptions"; - } + public string Name => "Subscriptions"; - public string EventsFilter - { - get => "^(content-|asset-)"; - } + public StreamFilter EventsFilter { get; } = StreamFilter.Prefix("content-", "asset-"); - public bool StartLatest - { - get => true; - } + public bool StartLatest => true; - public bool CanClear - { - get => false; - } + public bool CanClear => false; public SubscriptionPublisher(ISubscriptionService subscriptionService, IEnumerable subscriptionEventCreators) { diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/Extensions.cs b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/Extensions.cs index da077c338..5a1cc11ca 100644 --- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/Extensions.cs +++ b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Contents/Operations/Extensions.cs @@ -5,6 +5,7 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using MongoDB.Bson; using MongoDB.Bson.Serialization; using MongoDB.Bson.Serialization.Attributes; using MongoDB.Driver; @@ -18,6 +19,15 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Contents.Operations; public static class Extensions { + private static readonly BsonDocument LookupLet = + new BsonDocument() + .Add("id", "$_id"); + + private static readonly BsonDocument LookupMatch = + new BsonDocument() + .Add("$expr", new BsonDocument() + .Add("$eq", new BsonArray { "$_id", "$$id" })); + private static Dictionary propertyMap; public static IReadOnlyDictionary PropertyMap @@ -113,8 +123,15 @@ public static class Extensions .QuerySort(query) .QuerySkip(query) .QueryLimit(query) - .Lookup(collection, x => x.Id, x => x.DocumentId, x => x.Joined) - .SelectFields(q.Fields) + .Lookup(collection, + LookupLet, + PipelineDefinitionBuilder.For() + .Match(LookupMatch) + .Project( + BuildProjection2(q.Fields)), + x => x.Joined) + .Project( + Builders.Projection.Include(x => x.Joined)) .ToListAsync(ct); return joined.Select(x => x.Joined[0]).ToList(); @@ -147,15 +164,15 @@ public static class Extensions public static IFindFluent SelectFields(this IFindFluent find, IEnumerable? fields) { - return find.Project(BuildProjection(fields)); + return find.Project(BuildProjection2(fields)); } public static IAggregateFluent SelectFields(this IAggregateFluent find, IEnumerable? fields) { - return find.Project(BuildProjection(fields)); + return find.Project(BuildProjection2(fields)); } - private static ProjectionDefinition BuildProjection(IEnumerable? fields) + private static ProjectionDefinition BuildProjection2(IEnumerable? fields) { var projector = Builders.Projection; var projections = new List>(); diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemasHash.cs b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemasHash.cs index 85fe766d8..e1bc24fbb 100644 --- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemasHash.cs +++ b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Schemas/MongoSchemasHash.cs @@ -19,25 +19,11 @@ namespace Squidex.Domain.Apps.Entities.MongoDb.Schemas; public sealed class MongoSchemasHash : MongoRepositoryBase, ISchemasHash, IEventConsumer, IDeleter { - public int BatchSize - { - get => 1000; - } + public int BatchSize => 1000; - public int BatchDelay - { - get => 500; - } + public int BatchDelay => 500; - public string Name - { - get => GetType().Name; - } - - public string EventsFilter - { - get => "^schema-"; - } + public StreamFilter EventsFilter { get; } = StreamFilter.Prefix("schema-"); public MongoSchemasHash(IMongoDatabase database) : base(database) diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Squidex.Domain.Apps.Entities.MongoDb.csproj b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Squidex.Domain.Apps.Entities.MongoDb.csproj index c030c99e5..f247b82a5 100644 --- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Squidex.Domain.Apps.Entities.MongoDb.csproj +++ b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Squidex.Domain.Apps.Entities.MongoDb.csproj @@ -23,7 +23,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/backend/src/Squidex.Domain.Apps.Entities/Apps/AppEventDeleter.cs b/backend/src/Squidex.Domain.Apps.Entities/Apps/AppEventDeleter.cs index 4574191b5..08ac26e25 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Apps/AppEventDeleter.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Apps/AppEventDeleter.cs @@ -23,6 +23,8 @@ public sealed class AppEventDeleter : IDeleter public Task DeleteAppAsync(IAppEntity app, CancellationToken ct) { - return eventStore.DeleteAsync($"^([a-zA-Z0-9]+)\\-{app.Id}", ct); + var streamFilter = StreamFilter.Prefix($"([a-zA-Z0-9]+)-{app.Id}"); + + return eventStore.DeleteAsync(streamFilter, ct); } } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Apps/AppPermanentDeleter.cs b/backend/src/Squidex.Domain.Apps.Entities/Apps/AppPermanentDeleter.cs index 8c1857763..d339b83fb 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Apps/AppPermanentDeleter.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Apps/AppPermanentDeleter.cs @@ -20,15 +20,7 @@ public sealed class AppPermanentDeleter : IEventConsumer private readonly IDomainObjectFactory factory; private readonly HashSet consumingTypes; - public string Name - { - get => GetType().Name; - } - - public string EventsFilter - { - get => "^app-"; - } + public StreamFilter EventsFilter { get; } = StreamFilter.Prefix("app-"); public AppPermanentDeleter(IEnumerable deleters, IDomainObjectFactory factory, TypeRegistry typeRegistry) { diff --git a/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetPermanentDeleter.cs b/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetPermanentDeleter.cs index 0ca13dc5b..85e299c82 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetPermanentDeleter.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetPermanentDeleter.cs @@ -17,15 +17,7 @@ public sealed class AssetPermanentDeleter : IEventConsumer private readonly IAssetFileStore assetFileStore; private readonly HashSet consumingTypes; - public string Name - { - get => GetType().Name; - } - - public string EventsFilter - { - get => "^asset-"; - } + public StreamFilter EventsFilter { get; } = StreamFilter.Prefix("asset-"); public AssetPermanentDeleter(IAssetFileStore assetFileStore, TypeRegistry typeRegistry) { diff --git a/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetUsageTracker_EventHandling.cs b/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetUsageTracker_EventHandling.cs index b7251970d..dd9af405b 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetUsageTracker_EventHandling.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetUsageTracker_EventHandling.cs @@ -21,25 +21,11 @@ public partial class AssetUsageTracker : IEventConsumer { private IMemoryCache memoryCache; - public int BatchSize - { - get => 1000; - } + public int BatchSize => 1000; - public int BatchDelay - { - get => 1000; - } + public int BatchDelay => 1000; - public string Name - { - get => GetType().Name; - } - - public string EventsFilter - { - get => "^asset-"; - } + public StreamFilter EventsFilter { get; } = StreamFilter.Prefix("asset-"); private void ClearCache() { diff --git a/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetsFluidExtension.cs b/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetsFluidExtension.cs index 4bdbb74f5..07f964a1a 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetsFluidExtension.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Assets/AssetsFluidExtension.cs @@ -39,19 +39,21 @@ public sealed class AssetsFluidExtension : IFluidExtension private async ValueTask ResolveAsset(ValueTuple arguments, TextWriter writer, TextEncoder encoder, TemplateContext context) { - if (context.GetValue("event")?.ToObjectValue() is EnrichedEvent enrichedEvent) + if (context.GetValue("event")?.ToObjectValue() is not EnrichedEvent enrichedEvent) { - var (nameArg, idArg) = arguments; + return Completion.Normal; + } - var assetId = await idArg.EvaluateAsync(context); - var asset = await ResolveAssetAsync(serviceProvider, enrichedEvent.AppId.Id, assetId); + var (nameArg, idArg) = arguments; - if (asset != null) - { - var name = (await nameArg.EvaluateAsync(context)).ToStringValue(); + var assetId = await idArg.EvaluateAsync(context); + var asset = await ResolveAssetAsync(serviceProvider, enrichedEvent.AppId.Id, assetId); - context.SetValue(name, asset); - } + if (asset != null) + { + var name = (await nameArg.EvaluateAsync(context)).ToStringValue(); + + context.SetValue(name, asset); } return Completion.Normal; diff --git a/backend/src/Squidex.Domain.Apps.Entities/Assets/RebuildFiles.cs b/backend/src/Squidex.Domain.Apps.Entities/Assets/RebuildFiles.cs index 91a8c128c..b9c248abc 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Assets/RebuildFiles.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Assets/RebuildFiles.cs @@ -33,7 +33,9 @@ public sealed class RebuildFiles public async Task RepairAsync( CancellationToken ct = default) { - await foreach (var storedEvent in eventStore.QueryAllAsync("^asset\\-", ct: ct)) + var streamFilter = StreamFilter.Prefix("asset-"); + + await foreach (var storedEvent in eventStore.QueryAllAsync(streamFilter, ct: ct)) { var @event = eventFormatter.ParseIfKnown(storedEvent); diff --git a/backend/src/Squidex.Domain.Apps.Entities/Assets/RecursiveDeleter.cs b/backend/src/Squidex.Domain.Apps.Entities/Assets/RecursiveDeleter.cs index 1ec6fa155..9d198968f 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Assets/RecursiveDeleter.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Assets/RecursiveDeleter.cs @@ -23,15 +23,7 @@ public sealed class RecursiveDeleter : IEventConsumer private readonly ILogger log; private readonly HashSet consumingTypes; - public string Name - { - get => GetType().Name; - } - - public string EventsFilter - { - get => "^assetFolder-"; - } + public StreamFilter EventsFilter { get; } = StreamFilter.Prefix("assetFolder-"); public RecursiveDeleter( ICommandBus commandBus, diff --git a/backend/src/Squidex.Domain.Apps.Entities/Backup/BackupProcessor.cs b/backend/src/Squidex.Domain.Apps.Entities/Backup/BackupProcessor.cs index 64b9e66a3..b61844a62 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Backup/BackupProcessor.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Backup/BackupProcessor.cs @@ -5,7 +5,6 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using System.Text.RegularExpressions; using Microsoft.Extensions.Logging; using NodaTime; using Squidex.Domain.Apps.Entities.Backup.State; @@ -147,7 +146,9 @@ public sealed partial class BackupProcessor var backupUsers = new UserMapping(run.Actor); var backupContext = new BackupContext(appId, backupUsers, writer); - await foreach (var storedEvent in eventStore.QueryAllAsync(GetFilter(), ct: ct)) + var streamFilter = StreamFilter.Prefix($"[^\\-]*-{appId}"); + + await foreach (var storedEvent in eventStore.QueryAllAsync(streamFilter, ct: ct)) { var @event = eventFormatter.Parse(storedEvent); @@ -200,11 +201,6 @@ public sealed partial class BackupProcessor } } - private string GetFilter() - { - return $"^[^\\-]*-{Regex.Escape(appId.ToString())}"; - } - public Task DeleteAsync(DomainId id) { return scheduler.ScheduleAsync(async _ => diff --git a/backend/src/Squidex.Domain.Apps.Entities/Billing/UsageGate.Rules.cs b/backend/src/Squidex.Domain.Apps.Entities/Billing/UsageGate.Rules.cs index 79cfba15e..5e04d5be9 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Billing/UsageGate.Rules.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Billing/UsageGate.Rules.cs @@ -103,18 +103,26 @@ public sealed partial class UsageGate : IRuleUsageTracker var tasks = new List { - usageTracker.TrackAsync(date, appKey, ruleId.ToString(), counters, ct), usageTracker.TrackAsync(SummaryDate, appKey, ruleId.ToString(), counters, ct) }; + if (date != default) + { + tasks.Add(usageTracker.TrackAsync(date, appKey, ruleId.ToString(), counters, ct)); + } + var (_, _, teamId) = await GetPlanForAppAsync(appId, true, ct); if (teamId != null) { var teamKey = TeamRulesKey(teamId.Value); - tasks.Add(usageTracker.TrackAsync(date, teamKey, appId.ToString(), counters, ct)); tasks.Add(usageTracker.TrackAsync(SummaryDate, teamKey, appId.ToString(), counters, ct)); + + if (date != default) + { + tasks.Add(usageTracker.TrackAsync(date, teamKey, appId.ToString(), counters, ct)); + } } await Task.WhenAll(tasks); diff --git a/backend/src/Squidex.Domain.Apps.Entities/Billing/UsageNotifierWorker.cs b/backend/src/Squidex.Domain.Apps.Entities/Billing/UsageNotifierWorker.cs index 36b14bcb5..b16fdbaa3 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Billing/UsageNotifierWorker.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Billing/UsageNotifierWorker.cs @@ -6,7 +6,7 @@ // ========================================================================== using NodaTime; -using Squidex.Domain.Apps.Entities.Notifications; +using Squidex.Domain.Apps.Entities.Collaboration; using Squidex.Hosting; using Squidex.Infrastructure; using Squidex.Infrastructure.States; diff --git a/backend/src/Squidex.Domain.Apps.Entities/Collaboration/CommentCollaborationHandler.cs b/backend/src/Squidex.Domain.Apps.Entities/Collaboration/CommentCollaborationHandler.cs new file mode 100644 index 000000000..dc8659ff0 --- /dev/null +++ b/backend/src/Squidex.Domain.Apps.Entities/Collaboration/CommentCollaborationHandler.cs @@ -0,0 +1,266 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System.Text.RegularExpressions; +using Microsoft.Extensions.Logging; +using NodaTime; +using Squidex.Domain.Apps.Core.Comments; +using Squidex.Domain.Apps.Events.Comments; +using Squidex.Infrastructure; +using Squidex.Infrastructure.EventSourcing; +using Squidex.Infrastructure.Json; +using Squidex.Infrastructure.Reflection; +using Squidex.Shared.Users; +using YDotNet.Document.Cells; +using YDotNet.Document.Types.Events; +using YDotNet.Extensions; +using YDotNet.Server; + +namespace Squidex.Domain.Apps.Entities.Collaboration; + +public sealed partial class CommentCollaborationHandler : IDocumentCallback, ICollaborationService +{ + private static readonly Regex MentionRegex = BuildMentionRegex(); + private readonly IJsonSerializer jsonSerializer; + private readonly IEventStore eventStore; + private readonly IEventFormatter eventFormatter; + private readonly IUserResolver userResolver; + private readonly IClock clock; + private readonly ILogger log; + private IDocumentManager? currentManager; + + public Task LastTask { get; private set; } + + public CommentCollaborationHandler( + IJsonSerializer jsonSerializer, + IEventStore eventStore, + IEventFormatter eventFormatter, + IUserResolver userResolver, + IClock clock, + ILogger log) + { + this.jsonSerializer = jsonSerializer; + this.eventStore = eventStore; + this.eventFormatter = eventFormatter; + this.userResolver = userResolver; + this.clock = clock; + this.log = log; + } + + public ValueTask OnInitializedAsync(IDocumentManager manager) + { + currentManager = manager; + return default; + } + + public Task NotifyAsync(string userId, string text, RefToken actor, Uri? url, bool skipHandlers, + CancellationToken ct = default) + { + return CommentAsync(UserDocument(userId), text, actor, url, skipHandlers, ct); + } + + public Task CommentAsync(NamedId appId, DomainId resourceId, string text, RefToken actor, Uri? url, bool skipHandlers, + CancellationToken ct = default) + { + return CommentAsync(ResourceDocument(appId, resourceId), text, actor, url, skipHandlers, ct); + } + + private async Task CommentAsync(string documentName, string text, RefToken actor, Uri? url, bool skipHandlers, + CancellationToken ct) + { + if (currentManager == null) + { + return; + } + + var notificationsContext = new DocumentContext(documentName, 0); + + // Use the update method to ensure that only one thread has access to the doc. + await currentManager.UpdateDocAsync(notificationsContext, doc => + { + var stream = doc.Array("stream"); + + using (var transaction = doc.WriteTransaction()) + { + var commentValue = new Comment(clock.GetCurrentInstant(), actor, text, url, skipHandlers); + var commentJson = jsonSerializer.Serialize(commentValue); + + stream.InsertRange(transaction, stream.Length, InputFactory.FromJson(commentJson)); + } + }, ct); + } + + public ValueTask OnDocumentLoadedAsync(DocumentLoadEvent @event) + { + if (!IsResourceDocument(@event.Context.DocumentName, out var appId, out var resourceId)) + { + return default; + } + + var stream = @event.Document.Array("stream"); + + stream.ObserveDeep(changes => + { + var newComments = + changes + .Where(x => x.Tag == EventBranchTag.Array) + .Select(x => x.ArrayEvent) + .SelectMany(x => x.Delta).Where(x => x.Tag == EventChangeTag.Add) + .SelectMany(x => x.Values).Where(x => x.Tag == OutputTag.JsonObject) + .ToArray(); + + if (newComments.Length == 0) + { + // Just store the last task for tests. + LastTask = Task.CompletedTask; + return; + } + + LastTask = Task.Run(async () => + { + try + { + // Run in an extra task to prevent deadlocks with the outer transaction. + await HandleAsync(@event, appId, resourceId, newComments); + } + catch (Exception ex) + { + // We are in an extra task, so the exception would be probably swallowed. + log.LogError(ex, "Failed to handle yjs event."); + throw; + } + }); + }); + + return default; + } + + private async Task HandleAsync(DocumentLoadEvent @event, NamedId appId, DomainId resourceId, Output[] newComments) + { + var comments = new List(); + + // Use the update method to ensure that only one thread has access to the doc. + await @event.Source.UpdateDocAsync(@event.Context, (doc) => + { + using (var transaction = @event.Document.ReadTransaction()) + { + foreach (var output in newComments) + { + // Just use the json string for debuggability. + var json = output.ToJson(transaction); + + var comment = jsonSerializer.Deserialize(json); + + if (!comment.SkipHandlers) + { + comments.Add(comment); + } + } + } + }); + + var streamName = $"comments-{DomainId.Combine(appId, resourceId)}"; + + foreach (var comment in comments) + { + var commentEvent = await CreateEventAsync(comment, appId, resourceId); + + var eventBody = Envelope.Create(commentEvent); + var eventData = eventFormatter.ToEventData(eventBody, Guid.NewGuid()); + + await eventStore.AppendAsync(Guid.NewGuid(), streamName, EtagVersion.Any, new List { eventData }); + + foreach (var mentionedUser in commentEvent.Mentions.OrEmpty()) + { + await NotifyAsync(mentionedUser, comment.Text, RefToken.User(mentionedUser), comment.Url, true); + } + } + } + + private async Task CreateEventAsync(Comment comment, NamedId appId, DomainId commentsId) + { + var @event = new CommentCreated + { + Actor = comment.User, + CommentId = DomainId.NewGuid(), + CommentsId = commentsId, + AppId = appId, + }; + + SimpleMapper.Map(comment, @event); + + await MentionUsersAsync(@event); + return @event; + } + + private async Task MentionUsersAsync(CommentCreated comment) + { + if (string.IsNullOrWhiteSpace(comment.Text)) + { + return; + } + + var emails = MentionRegex.Matches(comment.Text).Select(x => x.Value[1..]).ToArray(); + + if (emails.Length == 0) + { + return; + } + + var mentions = new List(); + + foreach (var email in emails) + { + var user = await userResolver.FindByIdOrEmailAsync(email); + + if (user != null) + { + mentions.Add(user.Id); + } + } + + if (mentions.Count > 0) + { + comment.Mentions = mentions.ToArray(); + } + } + + public string UserDocument(string userId) + { + return $"users/{userId}"; + } + + public string ResourceDocument(NamedId appId, DomainId resourceId) + { + return $"apps/{appId}/{resourceId}"; + } + + private static bool IsResourceDocument(string name, out NamedId appId, out DomainId resourceId) + { + resourceId = default; + + if (!name.StartsWith("apps", StringComparison.Ordinal)) + { + appId = default!; + return false; + } + + var parts = name.Split('/'); + + if (parts.Length < 3 || !NamedId.TryParse(parts[1], DomainId.TryParse, out appId!)) + { + appId = default!; + return false; + } + + resourceId = DomainId.Create(string.Join('/', parts.Skip(2))); + return true; + } + + [GeneratedRegex(@"@(?=.{1,64}@)[-!#$%&'*+\/0-9=?A-Z^_`a-z{|}~]+(\.[-!#$%&'*+\/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*", RegexOptions.Compiled | RegexOptions.ExplicitCapture, matchTimeoutMilliseconds: 100)] + private static partial Regex BuildMentionRegex(); +} diff --git a/backend/src/Squidex.Domain.Apps.Entities/Comments/CommentTriggerHandler.cs b/backend/src/Squidex.Domain.Apps.Entities/Collaboration/CommentTriggerHandler.cs similarity index 98% rename from backend/src/Squidex.Domain.Apps.Entities/Comments/CommentTriggerHandler.cs rename to backend/src/Squidex.Domain.Apps.Entities/Collaboration/CommentTriggerHandler.cs index 48638d957..bc893b434 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Comments/CommentTriggerHandler.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Collaboration/CommentTriggerHandler.cs @@ -17,7 +17,7 @@ using Squidex.Infrastructure.EventSourcing; using Squidex.Infrastructure.Reflection; using Squidex.Shared.Users; -namespace Squidex.Domain.Apps.Entities.Comments; +namespace Squidex.Domain.Apps.Entities.Collaboration; public sealed class CommentTriggerHandler : IRuleTriggerHandler { @@ -29,7 +29,6 @@ public sealed class CommentTriggerHandler : IRuleTriggerHandler public CommentTriggerHandler(IScriptEngine scriptEngine, IUserResolver userResolver) { this.scriptEngine = scriptEngine; - this.userResolver = userResolver; } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Notifications/EmailUserNotificationOptions.cs b/backend/src/Squidex.Domain.Apps.Entities/Collaboration/EmailUserNotificationOptions.cs similarity index 94% rename from backend/src/Squidex.Domain.Apps.Entities/Notifications/EmailUserNotificationOptions.cs rename to backend/src/Squidex.Domain.Apps.Entities/Collaboration/EmailUserNotificationOptions.cs index 084779b28..1936a2b9f 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Notifications/EmailUserNotificationOptions.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Collaboration/EmailUserNotificationOptions.cs @@ -5,7 +5,7 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -namespace Squidex.Domain.Apps.Entities.Notifications; +namespace Squidex.Domain.Apps.Entities.Collaboration; public sealed class EmailUserNotificationOptions { diff --git a/backend/src/Squidex.Domain.Apps.Entities/Notifications/EmailUserNotifications.cs b/backend/src/Squidex.Domain.Apps.Entities/Collaboration/EmailUserNotifications.cs similarity index 99% rename from backend/src/Squidex.Domain.Apps.Entities/Notifications/EmailUserNotifications.cs rename to backend/src/Squidex.Domain.Apps.Entities/Collaboration/EmailUserNotifications.cs index 932625dd0..bf7721e00 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Notifications/EmailUserNotifications.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Collaboration/EmailUserNotifications.cs @@ -16,7 +16,7 @@ using Squidex.Infrastructure.Email; using Squidex.Shared.Identity; using Squidex.Shared.Users; -namespace Squidex.Domain.Apps.Entities.Notifications; +namespace Squidex.Domain.Apps.Entities.Collaboration; public sealed class EmailUserNotifications : IUserNotifications { diff --git a/backend/src/Squidex.Domain.Apps.Entities/Collaboration/ICollaborationService.cs b/backend/src/Squidex.Domain.Apps.Entities/Collaboration/ICollaborationService.cs new file mode 100644 index 000000000..8b8bf67c2 --- /dev/null +++ b/backend/src/Squidex.Domain.Apps.Entities/Collaboration/ICollaborationService.cs @@ -0,0 +1,23 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Squidex.Infrastructure; + +namespace Squidex.Domain.Apps.Entities.Collaboration; + +public interface ICollaborationService +{ + Task NotifyAsync(string userId, string text, RefToken actor, Uri? url, bool skipHandlers, + CancellationToken ct = default); + + Task CommentAsync(NamedId appId, DomainId resourceId, string text, RefToken actor, Uri? url, bool skipHandlers, + CancellationToken ct = default); + + string UserDocument(string userId); + + string ResourceDocument(NamedId appId, DomainId resourceId); +} diff --git a/backend/src/Squidex.Domain.Apps.Entities/Notifications/IUserNotifications.cs b/backend/src/Squidex.Domain.Apps.Entities/Collaboration/IUserNotifications.cs similarity index 94% rename from backend/src/Squidex.Domain.Apps.Entities/Notifications/IUserNotifications.cs rename to backend/src/Squidex.Domain.Apps.Entities/Collaboration/IUserNotifications.cs index c66ddf8a4..a7fbf5b35 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Notifications/IUserNotifications.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Collaboration/IUserNotifications.cs @@ -9,7 +9,7 @@ using Squidex.Domain.Apps.Entities.Apps; using Squidex.Domain.Apps.Entities.Teams; using Squidex.Shared.Users; -namespace Squidex.Domain.Apps.Entities.Notifications; +namespace Squidex.Domain.Apps.Entities.Collaboration; public interface IUserNotifications { diff --git a/backend/src/Squidex.Domain.Apps.Entities/Notifications/NoopUserNotifications.cs b/backend/src/Squidex.Domain.Apps.Entities/Collaboration/NoopUserNotifications.cs similarity index 95% rename from backend/src/Squidex.Domain.Apps.Entities/Notifications/NoopUserNotifications.cs rename to backend/src/Squidex.Domain.Apps.Entities/Collaboration/NoopUserNotifications.cs index 19d61f210..ca80e1dc9 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Notifications/NoopUserNotifications.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Collaboration/NoopUserNotifications.cs @@ -9,7 +9,7 @@ using Squidex.Domain.Apps.Entities.Apps; using Squidex.Domain.Apps.Entities.Teams; using Squidex.Shared.Users; -namespace Squidex.Domain.Apps.Entities.Notifications; +namespace Squidex.Domain.Apps.Entities.Collaboration; public sealed class NoopUserNotifications : IUserNotifications { diff --git a/backend/src/Squidex.Domain.Apps.Entities/Comments/Commands/CommentTextCommand.cs b/backend/src/Squidex.Domain.Apps.Entities/Comments/Commands/CommentTextCommand.cs deleted file mode 100644 index 7367eb270..000000000 --- a/backend/src/Squidex.Domain.Apps.Entities/Comments/Commands/CommentTextCommand.cs +++ /dev/null @@ -1,15 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -namespace Squidex.Domain.Apps.Entities.Comments.Commands; - -public abstract class CommentTextCommand : CommentCommand -{ - public string Text { get; set; } - - public string[]? Mentions { get; set; } -} diff --git a/backend/src/Squidex.Domain.Apps.Entities/Comments/Commands/CreateComment.cs b/backend/src/Squidex.Domain.Apps.Entities/Comments/Commands/CreateComment.cs deleted file mode 100644 index 6934c166b..000000000 --- a/backend/src/Squidex.Domain.Apps.Entities/Comments/Commands/CreateComment.cs +++ /dev/null @@ -1,22 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using Squidex.Infrastructure; - -namespace Squidex.Domain.Apps.Entities.Comments.Commands; - -public sealed class CreateComment : CommentTextCommand -{ - public bool IsMention { get; set; } - - public Uri? Url { get; set; } - - public CreateComment() - { - CommentId = DomainId.NewGuid(); - } -} diff --git a/backend/src/Squidex.Domain.Apps.Entities/Comments/Commands/_CommentsCommand.cs b/backend/src/Squidex.Domain.Apps.Entities/Comments/Commands/_CommentsCommand.cs deleted file mode 100644 index 8a811b85e..000000000 --- a/backend/src/Squidex.Domain.Apps.Entities/Comments/Commands/_CommentsCommand.cs +++ /dev/null @@ -1,48 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using Squidex.Infrastructure; -using Squidex.Infrastructure.Commands; - -#pragma warning disable MA0048 // File name must match type name - -namespace Squidex.Domain.Apps.Entities.Comments.Commands; - -public abstract class CommentCommand : CommentsCommand -{ - public DomainId CommentId { get; set; } -} - -public abstract class CommentsCommand : CommentsCommandBase -{ - public static readonly NamedId NoApp = NamedId.Of(DomainId.Empty, "none"); - - public DomainId CommentsId { get; set; } - - public override DomainId AggregateId - { - get - { - if (AppId.Id == default) - { - return CommentsId; - } - else - { - return DomainId.Combine(AppId, CommentsId); - } - } - } -} - -// This command is needed as marker for middlewares. -public abstract class CommentsCommandBase : SquidexCommand, IAppCommand, IAggregateCommand -{ - public NamedId AppId { get; set; } - - public abstract DomainId AggregateId { get; } -} diff --git a/backend/src/Squidex.Domain.Apps.Entities/Comments/CommentsLoader.cs b/backend/src/Squidex.Domain.Apps.Entities/Comments/CommentsLoader.cs deleted file mode 100644 index c3c02bdd8..000000000 --- a/backend/src/Squidex.Domain.Apps.Entities/Comments/CommentsLoader.cs +++ /dev/null @@ -1,32 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using Squidex.Domain.Apps.Entities.Comments.DomainObject; -using Squidex.Infrastructure; -using Squidex.Infrastructure.Commands; - -namespace Squidex.Domain.Apps.Entities.Comments; - -public sealed class CommentsLoader : ICommentsLoader -{ - private readonly IDomainObjectFactory domainObjectFactory; - - public CommentsLoader(IDomainObjectFactory domainObjectFactory) - { - this.domainObjectFactory = domainObjectFactory; - } - - public async Task GetCommentsAsync(DomainId id, long version = EtagVersion.Any, - CancellationToken ct = default) - { - var stream = domainObjectFactory.Create(id); - - await stream.LoadAsync(ct); - - return stream.GetComments(version); - } -} diff --git a/backend/src/Squidex.Domain.Apps.Entities/Comments/CommentsResult.cs b/backend/src/Squidex.Domain.Apps.Entities/Comments/CommentsResult.cs deleted file mode 100644 index dd591e04d..000000000 --- a/backend/src/Squidex.Domain.Apps.Entities/Comments/CommentsResult.cs +++ /dev/null @@ -1,95 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using Squidex.Domain.Apps.Core.Comments; -using Squidex.Domain.Apps.Events.Comments; -using Squidex.Infrastructure; -using Squidex.Infrastructure.EventSourcing; - -namespace Squidex.Domain.Apps.Entities.Comments; - -public sealed class CommentsResult -{ - public List CreatedComments { get; set; } = new List(); - - public List UpdatedComments { get; set; } = new List(); - - public List DeletedComments { get; set; } = new List(); - - public long Version { get; set; } - - public static CommentsResult FromEvents(IEnumerable> events, long currentVersion, int lastVersion) - { - var result = new CommentsResult { Version = currentVersion }; - - foreach (var @event in events.Skip(lastVersion < 0 ? 0 : lastVersion + 1)) - { - switch (@event.Payload) - { - case CommentDeleted deleted: - { - var id = deleted.CommentId; - - if (result.CreatedComments.Exists(x => x.Id == id)) - { - result.CreatedComments.RemoveAll(x => x.Id == id); - } - else if (result.UpdatedComments.Exists(x => x.Id == id)) - { - result.UpdatedComments.RemoveAll(x => x.Id == id); - result.DeletedComments.Add(id); - } - else - { - result.DeletedComments.Add(id); - } - - break; - } - - case CommentCreated created: - { - var comment = new Comment( - created.CommentId, - @event.Headers.Timestamp(), - @event.Payload.Actor, - created.Text, - created.Url); - - result.CreatedComments.Add(comment); - break; - } - - case CommentUpdated updated: - { - var id = updated.CommentId; - - var comment = new Comment( - id, - @event.Headers.Timestamp(), - @event.Payload.Actor, - updated.Text, - null); - - if (result.CreatedComments.Exists(x => x.Id == id)) - { - result.CreatedComments.RemoveAll(x => x.Id == id); - result.CreatedComments.Add(comment); - } - else - { - result.UpdatedComments.Add(comment); - } - - break; - } - } - } - - return result; - } -} diff --git a/backend/src/Squidex.Domain.Apps.Entities/Comments/DomainObject/CommentsCommandMiddleware.cs b/backend/src/Squidex.Domain.Apps.Entities/Comments/DomainObject/CommentsCommandMiddleware.cs deleted file mode 100644 index 3b2239dab..000000000 --- a/backend/src/Squidex.Domain.Apps.Entities/Comments/DomainObject/CommentsCommandMiddleware.cs +++ /dev/null @@ -1,76 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using System.Text.RegularExpressions; -using Squidex.Domain.Apps.Entities.Comments.Commands; -using Squidex.Infrastructure.Commands; -using Squidex.Shared.Users; - -namespace Squidex.Domain.Apps.Entities.Comments.DomainObject; - -public sealed class CommentsCommandMiddleware : AggregateCommandMiddleware -{ - private static readonly Regex MentionRegex = new Regex(@"@(?=.{1,64}@)[-!#$%&'*+\/0-9=?A-Z^_`a-z{|}~]+(\.[-!#$%&'*+\/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*", RegexOptions.Compiled | RegexOptions.ExplicitCapture, TimeSpan.FromMilliseconds(100)); - private readonly IUserResolver userResolver; - - public CommentsCommandMiddleware(IDomainObjectFactory domainObjectFactory, IUserResolver userResolver) - : base(domainObjectFactory) - { - this.userResolver = userResolver; - } - - public override async Task HandleAsync(CommandContext context, NextDelegate next, - CancellationToken ct) - { - if (context.Command is CommentsCommand commentsCommand) - { - if (commentsCommand is CreateComment createComment && !IsMention(createComment)) - { - await MentionUsersAsync(createComment); - } - } - - await base.HandleAsync(context, next, ct); - } - - private static bool IsMention(CreateComment createComment) - { - return createComment.IsMention; - } - - private async Task MentionUsersAsync(CommentTextCommand command) - { - if (string.IsNullOrWhiteSpace(command.Text)) - { - return; - } - - var emails = MentionRegex.Matches(command.Text).Select(x => x.Value[1..]).ToArray(); - - if (emails.Length == 0) - { - return; - } - - var mentions = new List(); - - foreach (var email in emails) - { - var user = await userResolver.FindByIdOrEmailAsync(email); - - if (user != null) - { - mentions.Add(user.Id); - } - } - - if (mentions.Count > 0) - { - command.Mentions = mentions.ToArray(); - } - } -} diff --git a/backend/src/Squidex.Domain.Apps.Entities/Comments/DomainObject/CommentsStream.cs b/backend/src/Squidex.Domain.Apps.Entities/Comments/DomainObject/CommentsStream.cs deleted file mode 100644 index a40721ac2..000000000 --- a/backend/src/Squidex.Domain.Apps.Entities/Comments/DomainObject/CommentsStream.cs +++ /dev/null @@ -1,167 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using Squidex.Domain.Apps.Entities.Comments.Commands; -using Squidex.Domain.Apps.Entities.Comments.DomainObject.Guards; -using Squidex.Domain.Apps.Events.Comments; -using Squidex.Infrastructure; -using Squidex.Infrastructure.Commands; -using Squidex.Infrastructure.EventSourcing; -using Squidex.Infrastructure.Reflection; - -namespace Squidex.Domain.Apps.Entities.Comments.DomainObject; - -public class CommentsStream : IAggregate -{ - private readonly List> uncommittedEvents = new List>(); - private readonly List> events = new List>(); - private readonly DomainId key; - private readonly IEventFormatter eventFormatter; - private readonly IEventStore eventStore; - private readonly string streamName; - private long version = EtagVersion.Empty; - - private long Version => version; - - public CommentsStream( - DomainId key, - IEventFormatter eventFormatter, - IEventStore eventStore) - { - this.key = key; - this.eventFormatter = eventFormatter; - this.eventStore = eventStore; - - streamName = $"comments-{key}"; - } - - public virtual async Task LoadAsync( - CancellationToken ct) - { - var storedEvents = await eventStore.QueryReverseAsync(streamName, 100, ct); - - foreach (var @event in storedEvents) - { - var parsedEvent = eventFormatter.Parse(@event); - - version = @event.EventStreamNumber; - - events.Add(parsedEvent.To()); - } - } - - public virtual async Task ExecuteAsync(IAggregateCommand command, - CancellationToken ct) - { - await LoadAsync(ct); - - switch (command) - { - case CreateComment createComment: - return await Upsert(createComment, c => - { - GuardComments.CanCreate(c); - - Create(c); - }, ct); - - case UpdateComment updateComment: - return await Upsert(updateComment, c => - { - GuardComments.CanUpdate(c, key.ToString(), events); - - Update(c); - }, ct); - - case DeleteComment deleteComment: - return await Upsert(deleteComment, c => - { - GuardComments.CanDelete(c, key.ToString(), events); - - Delete(c); - }, ct); - - default: - ThrowHelper.NotSupportedException(); - return null!; - } - } - - private async Task Upsert(TCommand command, Action handler, - CancellationToken ct) where TCommand : CommentsCommand - { - Guard.NotNull(command); - Guard.NotNull(handler); - - if (command.ExpectedVersion > EtagVersion.Any && command.ExpectedVersion != Version) - { - throw new DomainObjectVersionException(key.ToString(), Version, command.ExpectedVersion); - } - - var previousVersion = version; - - try - { - handler(command); - - if (uncommittedEvents.Count > 0) - { - var commitId = Guid.NewGuid(); - - var eventData = uncommittedEvents.Select(x => eventFormatter.ToEventData(x, commitId)).ToList(); - - await eventStore.AppendAsync(commitId, streamName, previousVersion, eventData, ct); - } - - events.AddRange(uncommittedEvents); - - return CommandResult.Empty(key, Version, previousVersion); - } - catch - { - version = previousVersion; - - throw; - } - finally - { - uncommittedEvents.Clear(); - } - } - - public void Create(CreateComment command) - { - RaiseEvent(SimpleMapper.Map(command, new CommentCreated())); - } - - public void Update(UpdateComment command) - { - RaiseEvent(SimpleMapper.Map(command, new CommentUpdated())); - } - - public void Delete(DeleteComment command) - { - RaiseEvent(SimpleMapper.Map(command, new CommentDeleted())); - } - - private void RaiseEvent(CommentsEvent @event) - { - uncommittedEvents.Add(Envelope.Create(@event)); - - version++; - } - - public virtual List> GetUncommittedEvents() - { - return uncommittedEvents; - } - - public virtual CommentsResult GetComments(long sinceVersion = EtagVersion.Any) - { - return CommentsResult.FromEvents(events, Version, (int)sinceVersion); - } -} diff --git a/backend/src/Squidex.Domain.Apps.Entities/Comments/DomainObject/Guards/GuardComments.cs b/backend/src/Squidex.Domain.Apps.Entities/Comments/DomainObject/Guards/GuardComments.cs deleted file mode 100644 index 68f7c406a..000000000 --- a/backend/src/Squidex.Domain.Apps.Entities/Comments/DomainObject/Guards/GuardComments.cs +++ /dev/null @@ -1,87 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using Squidex.Domain.Apps.Entities.Comments.Commands; -using Squidex.Domain.Apps.Events.Comments; -using Squidex.Infrastructure; -using Squidex.Infrastructure.EventSourcing; -using Squidex.Infrastructure.Translations; -using Squidex.Infrastructure.Validation; - -namespace Squidex.Domain.Apps.Entities.Comments.DomainObject.Guards; - -public static class GuardComments -{ - public static void CanCreate(CreateComment command) - { - Guard.NotNull(command); - - Validate.It(e => - { - if (string.IsNullOrWhiteSpace(command.Text)) - { - e(Not.Defined(nameof(command.Text)), nameof(command.Text)); - } - }); - } - - public static void CanUpdate(UpdateComment command, string commentsId, List> events) - { - Guard.NotNull(command); - - var comment = FindComment(events, command.CommentId); - - if (!string.Equals(commentsId, command.Actor.Identifier, StringComparison.Ordinal) && !comment.Payload.Actor.Equals(command.Actor)) - { - throw new DomainException(T.Get("comments.notUserComment")); - } - - Validate.It(e => - { - if (string.IsNullOrWhiteSpace(command.Text)) - { - e(Not.Defined(nameof(command.Text)), nameof(command.Text)); - } - }); - } - - public static void CanDelete(DeleteComment command, string commentsId, List> events) - { - Guard.NotNull(command); - - var comment = FindComment(events, command.CommentId); - - if (!string.Equals(commentsId, command.Actor.Identifier, StringComparison.Ordinal) && !comment.Payload.Actor.Equals(command.Actor)) - { - throw new DomainException(T.Get("comments.notUserComment")); - } - } - - private static Envelope FindComment(List> events, DomainId commentId) - { - Envelope? result = null; - - foreach (var @event in events) - { - if (@event.Payload is CommentCreated created && created.CommentId == commentId) - { - result = @event.To(); - } - else if (@event.Payload is CommentDeleted deleted && deleted.CommentId == commentId) - { - result = null; - } - } - - if (result == null) - { - throw new DomainObjectNotFoundException(commentId.ToString()); - } - - return result; - } -} diff --git a/backend/src/Squidex.Domain.Apps.Entities/Comments/ICommentsLoader.cs b/backend/src/Squidex.Domain.Apps.Entities/Comments/ICommentsLoader.cs deleted file mode 100644 index 69a30c652..000000000 --- a/backend/src/Squidex.Domain.Apps.Entities/Comments/ICommentsLoader.cs +++ /dev/null @@ -1,16 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using Squidex.Infrastructure; - -namespace Squidex.Domain.Apps.Entities.Comments; - -public interface ICommentsLoader -{ - Task GetCommentsAsync(DomainId id, long version = EtagVersion.Any, - CancellationToken ct = default); -} diff --git a/backend/src/Squidex.Domain.Apps.Entities/Comments/IWatchingService.cs b/backend/src/Squidex.Domain.Apps.Entities/Comments/IWatchingService.cs deleted file mode 100644 index 85df75ec7..000000000 --- a/backend/src/Squidex.Domain.Apps.Entities/Comments/IWatchingService.cs +++ /dev/null @@ -1,16 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using Squidex.Infrastructure; - -namespace Squidex.Domain.Apps.Entities.Comments; - -public interface IWatchingService -{ - Task GetWatchingUsersAsync(DomainId appId, string? resource, string userId, - CancellationToken ct = default); -} diff --git a/backend/src/Squidex.Domain.Apps.Entities/Comments/WatchingService.cs b/backend/src/Squidex.Domain.Apps.Entities/Comments/WatchingService.cs deleted file mode 100644 index 4ed8372db..000000000 --- a/backend/src/Squidex.Domain.Apps.Entities/Comments/WatchingService.cs +++ /dev/null @@ -1,61 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using NodaTime; -using Squidex.Infrastructure; -using Squidex.Infrastructure.States; - -namespace Squidex.Domain.Apps.Entities.Comments; - -public sealed class WatchingService : IWatchingService -{ - private readonly IPersistenceFactory persistenceFactory; - - [CollectionName("Watches")] - public sealed class State - { - private static readonly Duration Timeout = Duration.FromMinutes(1); - - public Dictionary Users { get; set; } = new Dictionary(); - - public (bool, string[]) Add(string watcherId, IClock clock) - { - var now = clock.GetCurrentInstant(); - - foreach (var (userId, lastSeen) in Users.ToList()) - { - var timeSinceLastSeen = now - lastSeen; - - if (timeSinceLastSeen > Timeout) - { - Users.Remove(userId); - } - } - - Users[watcherId] = now; - - return (true, Users.Keys.ToArray()); - } - } - - public IClock Clock { get; set; } = SystemClock.Instance; - - public WatchingService(IPersistenceFactory persistenceFactory) - { - this.persistenceFactory = persistenceFactory; - } - - public async Task GetWatchingUsersAsync(DomainId appId, string? resource, string userId, - CancellationToken ct = default) - { - var state = new SimpleState(persistenceFactory, GetType(), $"{appId}_{resource}"); - - await state.LoadAsync(ct); - - return await state.UpdateAsync(x => x.Add(userId, Clock), ct: ct); - } -} diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/ContentChangedTriggerHandler.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/ContentChangedTriggerHandler.cs index d8b2eb3c3..f8df30776 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/ContentChangedTriggerHandler.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/ContentChangedTriggerHandler.cs @@ -97,8 +97,10 @@ public sealed class ContentChangedTriggerHandler : IRuleTriggerHandler, ISubscri yield break; } + var allTriggers = context.Rules.Select(x => x.Value.Trigger).OfType(); + // This method is only called once per event, therefore we check all rules. - if (!context.Rules.Select(x => x.Value.Trigger).OfType().Any(t => MatchesAnySchema(t.ReferencedSchemas, enrichedEvent))) + if (!allTriggers.Any(t => MatchesAnySchema(t.ReferencedSchemas, enrichedEvent))) { yield break; } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/ContentHeaders.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/ContentHeaders.cs index bae1f0394..8330ca44f 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/ContentHeaders.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/ContentHeaders.cs @@ -23,6 +23,7 @@ public static class ContentHeaders public const string KeyNoResolveLanguages = "X-NoResolveLanguages"; public const string KeyResolveFlow = "X-ResolveFlow"; public const string KeyResolveUrls = "X-ResolveUrls"; + public const string KeyResolveSchemaNames = "X-ResolveSchemaName"; public const string KeyUnpublished = "X-Unpublished"; public static void AddCacheHeaders(this Context context, IRequestCache cache) @@ -98,6 +99,16 @@ public static class ContentHeaders return builder.WithBoolean(KeyResolveFlow, value); } + public static bool ResolveSchemaNames(this Context context) + { + return context.AsBoolean(KeyResolveSchemaNames); + } + + public static ICloneBuilder WithResolveSchemaNames(this ICloneBuilder builder, bool value = true) + { + return builder.WithBoolean(KeyResolveSchemaNames, value); + } + public static bool NoResolveLanguages(this Context context) { return context.AsBoolean(KeyNoResolveLanguages); diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Cache/CachingBatchLoader.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Cache/CachingBatchLoader.cs index fe90dee19..6e52f5ef3 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Cache/CachingBatchLoader.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Cache/CachingBatchLoader.cs @@ -21,11 +21,11 @@ internal class CachingBatchDataLoader : DataLoaderBase queryCache; private readonly Func, CancellationToken, Task>> queryDelegate; - public CachingBatchDataLoader(IQueryCache queryStore, + public CachingBatchDataLoader(IQueryCache queryCache, Func, CancellationToken, Task>> queryDelegate, bool canCache = true, int maxBatchSize = int.MaxValue) : base(canCache, maxBatchSize) { - this.queryCache = queryStore; + this.queryCache = queryCache; this.queryDelegate = queryDelegate; } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLExecutionContext.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLExecutionContext.cs index faf3609b2..08bd14652 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLExecutionContext.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLExecutionContext.cs @@ -41,6 +41,7 @@ public sealed class GraphQLExecutionContext : QueryExecutionContext this.dataLoaders = dataLoaders; Context = context.Clone(b => b + .WithResolveSchemaNames() .WithNoCleanup() .WithNoEnrichment() .WithNoAssetEnrichment()); @@ -76,7 +77,9 @@ public sealed class GraphQLExecutionContext : QueryExecutionContext public IDataLoaderResult GetContent(DomainId schemaId, DomainId id, long version) { - return dataLoaders.Context!.GetOrAddLoader(nameof(GetContent), ct => + var cacheKey = $"{nameof(GetContent)}_{schemaId}_{id}_{version}"; + + return dataLoaders.Context!.GetOrAddLoader(cacheKey, ct => { return FindContentAsync(schemaId.ToString(), id, version, ct); }).LoadAsync(); diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ApplicationQueries.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ApplicationQueries.cs index 190cb3dac..200b1a6c2 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ApplicationQueries.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ApplicationQueries.cs @@ -6,7 +6,9 @@ // ========================================================================== using GraphQL.Types; +using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents; +using static Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Contents.ContentActions; namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types; @@ -28,34 +30,62 @@ internal sealed class ApplicationQueries : ObjectGraphType continue; } - AddContentFind(schemaInfo, contentType); - AddContentQueries(builder, schemaInfo, contentType); + if (schemaInfo.Schema.SchemaDef.Type == SchemaType.Singleton) + { + // Mark the normal queries as deprecated to motivate using the new endpoint. + var deprecation = $"Use 'find{schemaInfo.TypeName}Singleton' instead."; + + AddContentFind(schemaInfo, contentType, deprecation); + AddContentFindSingleton(schemaInfo, contentType); + AddContentQueries(builder, schemaInfo, contentType, deprecation); + } + else + { + AddContentFind(schemaInfo, contentType, null); + AddContentQueries(builder, schemaInfo, contentType, null); + } } Description = "The app queries."; } - private void AddContentFind(SchemaInfo schemaInfo, IGraphType contentType) + private void AddContentFind(SchemaInfo schemaInfo, IGraphType contentType, string? deprecatedReason) { AddField(new FieldTypeWithSchemaId { Name = $"find{schemaInfo.TypeName}Content", - Arguments = ContentActions.Find.Arguments, + Arguments = Find.Arguments, ResolvedType = contentType, - Resolver = ContentActions.Find.Resolver, + Resolver = Find.Resolver, + DeprecationReason = deprecatedReason, Description = $"Find an {schemaInfo.DisplayName} content by id.", SchemaId = schemaInfo.Schema.Id }); } - private void AddContentQueries(Builder builder, SchemaInfo schemaInfo, IGraphType contentType) + private void AddContentFindSingleton(SchemaInfo schemaInfo, IGraphType contentType) + { + AddField(new FieldTypeWithSchemaId + { + Name = $"find{schemaInfo.TypeName}Singleton", + Arguments = FindSingleton.Arguments, + ResolvedType = contentType, + Resolver = FindSingleton.Resolver, + DeprecationReason = null, + Description = $"Find an {schemaInfo.DisplayName} singleton.", + SchemaId = schemaInfo.Schema.Id + }); + } + + private void AddContentQueries(Builder builder, SchemaInfo schemaInfo, IGraphType contentType, string? deprecatedReason) { AddField(new FieldTypeWithSchemaId { Name = $"query{schemaInfo.TypeName}Contents", - Arguments = ContentActions.QueryOrReferencing.Arguments, + Arguments = QueryOrReferencing.Arguments, ResolvedType = new ListGraphType(new NonNullGraphType(contentType)), - Resolver = ContentActions.QueryOrReferencing.Query, + Resolver = QueryOrReferencing.Query, + DeprecationReason = deprecatedReason, Description = $"Query {schemaInfo.DisplayName} content items.", SchemaId = schemaInfo.Schema.Id }); @@ -70,9 +100,10 @@ internal sealed class ApplicationQueries : ObjectGraphType AddField(new FieldTypeWithSchemaId { Name = $"query{schemaInfo.TypeName}ContentsWithTotal", - Arguments = ContentActions.QueryOrReferencing.Arguments, + Arguments = QueryOrReferencing.Arguments, ResolvedType = contentResultTyp, - Resolver = ContentActions.QueryOrReferencing.QueryWithTotal, + Resolver = QueryOrReferencing.QueryWithTotal, + DeprecationReason = deprecatedReason, Description = $"Query {schemaInfo.DisplayName} content items with total count.", SchemaId = schemaInfo.Schema.Id }); @@ -90,9 +121,9 @@ internal sealed class ApplicationQueries : ObjectGraphType AddField(new FieldType { Name = "queryContentsByIds", - Arguments = ContentActions.QueryByIds.Arguments, + Arguments = QueryByIds.Arguments, ResolvedType = new NonNullGraphType(new ListGraphType(new NonNullGraphType(unionType))), - Resolver = ContentActions.QueryByIds.Resolver, + Resolver = QueryByIds.Resolver, Description = "Query content items by IDs across schemeas." }); } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/ContentActions.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/ContentActions.cs index bda4e47f0..949aacf55 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/ContentActions.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/ContentActions.cs @@ -96,6 +96,36 @@ internal static class ContentActions }); } + public static class FindSingleton + { + public static readonly QueryArguments Arguments = new QueryArguments + { + new QueryArgument(Scalars.Int) + { + Name = "version", + Description = FieldDescriptions.QueryVersion, + DefaultValue = null + } + }; + + public static readonly IFieldResolver Resolver = Resolvers.Sync((_, fieldContext, context) => + { + var contentSchemaId = fieldContext.FieldDefinition.SchemaId(); + var contentVersion = fieldContext.GetArgument("version"); + + if (contentVersion >= 0) + { + return context.GetContent(contentSchemaId, contentSchemaId, contentVersion.Value); + } + else + { + return context.GetContent(contentSchemaId, contentSchemaId, + fieldContext.FieldNames(), + fieldContext.CacheDuration()); + } + }); + } + public static class QueryByIds { public static readonly QueryArguments Arguments = new QueryArguments diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/Steps/ConvertData.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/Steps/ConvertData.cs index 7327fcafe..82a6685a8 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/Steps/ConvertData.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/Queries/Steps/ConvertData.cs @@ -149,7 +149,10 @@ public sealed class ConvertData : IContentEnricherStep { converter.Add(new ResolveAssetUrls(context.App.NamedId(), urlGenerator, assetUrls)); } + } + if (!context.IsFrontendClient || context.ResolveSchemaNames()) + { converter.Add(new AddSchemaNames(components)); } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/ReferencesFluidExtension.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/ReferencesFluidExtension.cs index fcd5d3b6d..8695544ab 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/ReferencesFluidExtension.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/ReferencesFluidExtension.cs @@ -39,19 +39,21 @@ public sealed class ReferencesFluidExtension : IFluidExtension private async ValueTask ResolveReference(ValueTuple arguments, TextWriter writer, TextEncoder encoder, TemplateContext context) { - if (context.GetValue("event")?.ToObjectValue() is EnrichedEvent enrichedEvent) + if (context.GetValue("event")?.ToObjectValue() is not EnrichedEvent enrichedEvent) { - var (nameArg, idArg) = arguments; + return Completion.Normal; + } - var contentId = await idArg.EvaluateAsync(context); - var content = await ResolveContentAsync(serviceProvider, enrichedEvent.AppId.Id, contentId); + var (nameArg, idArg) = arguments; - if (content != null) - { - var name = (await nameArg.EvaluateAsync(context)).ToStringValue(); + var contentId = await idArg.EvaluateAsync(context); + var content = await ResolveContentAsync(serviceProvider, enrichedEvent.AppId.Id, contentId); - context.SetValue(name, content); - } + if (content != null) + { + var name = (await nameArg.EvaluateAsync(context)).ToStringValue(); + + context.SetValue(name, content); } return Completion.Normal; diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexingProcess.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexingProcess.cs index 754f68d34..adf5aaf19 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexingProcess.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/Text/TextIndexingProcess.cs @@ -21,25 +21,13 @@ public sealed class TextIndexingProcess : IEventConsumer private readonly ITextIndex textIndex; private readonly ITextIndexerState textIndexerState; - public int BatchSize - { - get => 1000; - } + public int BatchSize => 1000; - public int BatchDelay - { - get => 1000; - } + public int BatchDelay => 1000; - public string Name - { - get => "TextIndexer5"; - } + public string Name => "TextIndexer5"; - public string EventsFilter - { - get => "^content-"; - } + public StreamFilter EventsFilter { get; } = StreamFilter.Prefix("content-"); public ITextIndex TextIndex { diff --git a/backend/src/Squidex.Domain.Apps.Entities/Invitation/InvitationEventConsumer.cs b/backend/src/Squidex.Domain.Apps.Entities/Invitation/InvitationEventConsumer.cs index faaa7b406..6b381570c 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Invitation/InvitationEventConsumer.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Invitation/InvitationEventConsumer.cs @@ -7,7 +7,7 @@ using Microsoft.Extensions.Logging; using NodaTime; -using Squidex.Domain.Apps.Entities.Notifications; +using Squidex.Domain.Apps.Entities.Collaboration; using Squidex.Domain.Apps.Events.Apps; using Squidex.Domain.Apps.Events.Teams; using Squidex.Infrastructure; @@ -24,15 +24,9 @@ public sealed class InvitationEventConsumer : IEventConsumer private readonly IAppProvider appProvider; private readonly ILogger log; - public string Name - { - get => "NotificationEmailSender"; - } + public string Name => "NotificationEmailSender"; - public string EventsFilter - { - get { return "^app-|^app-"; } - } + public StreamFilter EventsFilter { get; } = StreamFilter.Prefix("app-"); public InvitationEventConsumer( IAppProvider appProvider, diff --git a/backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/DefaultRuleRunnerService.cs b/backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/DefaultRuleRunnerService.cs index efd5edefd..4c8e8dbb4 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/DefaultRuleRunnerService.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/DefaultRuleRunnerService.cs @@ -65,9 +65,10 @@ public sealed class DefaultRuleRunnerService : IRuleRunnerService var simulatedEvents = new List(MaxSimulatedEvents); - var fromNow = SystemClock.Instance.GetCurrentInstant().Minus(Duration.FromDays(7)); + var streamStart = SystemClock.Instance.GetCurrentInstant().Minus(Duration.FromDays(7)); + var streamFilter = StreamFilter.Prefix($"([a-zA-Z0-9]+)-{appId.Id}"); - await foreach (var storedEvent in eventStore.QueryAllReverseAsync($"^([a-zA-Z0-9]+)\\-{appId.Id}", fromNow, MaxSimulatedEvents, ct)) + await foreach (var storedEvent in eventStore.QueryAllReverseAsync(streamFilter, streamStart, MaxSimulatedEvents, ct)) { var @event = eventFormatter.ParseIfKnown(storedEvent); diff --git a/backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/RuleRunnerProcessor.cs b/backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/RuleRunnerProcessor.cs index 7947b4d1e..a9d2e5745 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/RuleRunnerProcessor.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Rules/Runner/RuleRunnerProcessor.cs @@ -254,9 +254,9 @@ public sealed class RuleRunnerProcessor await using var batch = new RuleQueueWriter(ruleEventRepository, ruleUsageTracker, null); // Use a prefix query so that the storage can use an index for the query. - var filter = $"^([a-z]+)\\-{appId}"; + var streamFilter = StreamFilter.Prefix($"([a-zA-Z0-9]+)\\-{appId}"); - await foreach (var storedEvent in eventStore.QueryAllAsync(filter, run.Job.Position, ct: ct)) + await foreach (var storedEvent in eventStore.QueryAllAsync(streamFilter, run.Job.Position, ct: ct)) { var @event = eventFormatter.ParseIfKnown(storedEvent); diff --git a/backend/src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj b/backend/src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj index 3219d7b43..abb308e63 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj +++ b/backend/src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj @@ -29,7 +29,9 @@ - + + + @@ -52,4 +54,7 @@ Resources.Designer.cs + + + diff --git a/backend/src/Squidex.Domain.Apps.Events/Comments/CommentCreated.cs b/backend/src/Squidex.Domain.Apps.Events/Comments/CommentCreated.cs index 79b202ded..c44590112 100644 --- a/backend/src/Squidex.Domain.Apps.Events/Comments/CommentCreated.cs +++ b/backend/src/Squidex.Domain.Apps.Events/Comments/CommentCreated.cs @@ -5,13 +5,18 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using Squidex.Infrastructure; using Squidex.Infrastructure.EventSourcing; namespace Squidex.Domain.Apps.Events.Comments; [EventType(nameof(CommentCreated))] -public sealed class CommentCreated : CommentsEvent +public sealed class CommentCreated : AppEvent { + public DomainId CommentsId { get; set; } + + public DomainId CommentId { get; set; } + public string Text { get; set; } public string[]? Mentions { get; set; } diff --git a/backend/src/Squidex.Domain.Apps.Events/Comments/CommentsEvent.cs b/backend/src/Squidex.Domain.Apps.Events/Comments/CommentsEvent.cs deleted file mode 100644 index 652358c85..000000000 --- a/backend/src/Squidex.Domain.Apps.Events/Comments/CommentsEvent.cs +++ /dev/null @@ -1,17 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using Squidex.Infrastructure; - -namespace Squidex.Domain.Apps.Events.Comments; - -public abstract class CommentsEvent : AppEvent -{ - public DomainId CommentsId { get; set; } - - public DomainId CommentId { get; set; } -} diff --git a/backend/src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj b/backend/src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj index 90c9fa556..6946662d9 100644 --- a/backend/src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj +++ b/backend/src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj @@ -24,7 +24,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/backend/src/Squidex.Infrastructure.GetEventStore/EventSourcing/EventStoreProjectionClient.cs b/backend/src/Squidex.Infrastructure.GetEventStore/EventSourcing/EventStoreProjectionClient.cs index f40798b0e..7dd723949 100644 --- a/backend/src/Squidex.Infrastructure.GetEventStore/EventSourcing/EventStoreProjectionClient.cs +++ b/backend/src/Squidex.Infrastructure.GetEventStore/EventSourcing/EventStoreProjectionClient.cs @@ -29,22 +29,22 @@ public sealed class EventStoreProjectionClient return $"by-{projectionPrefix.Slugify()}-{filter.Slugify()}"; } - public async Task CreateProjectionAsync(string? streamFilter = null) + public async Task CreateProjectionAsync(StreamFilter filter) { - if (!string.IsNullOrWhiteSpace(streamFilter) && streamFilter[0] != '^') + if (filter.Kind == StreamFilterKind.MatchFull && filter.Prefixes?.Count == 1) { - return $"{projectionPrefix}-{streamFilter}"; + return $"{projectionPrefix}-{filter.Prefixes[0]}"; } - streamFilter ??= ".*"; + var regex = filter.ToRegex(); - var name = CreateFilterProjectionName(streamFilter); + var name = CreateFilterProjectionName(regex); var query = $@"fromAll() .when({{ $any: function (s, e) {{ - if (e.streamId.indexOf('{projectionPrefix}') === 0 && /{streamFilter}/.test(e.streamId.substring({projectionPrefix.Length + 1}))) {{ + if (e.streamId.indexOf('{projectionPrefix}') === 0 && /{regex}/.test(e.streamId.substring({projectionPrefix.Length + 1}))) {{ linkTo('{name}', e); }} }} diff --git a/backend/src/Squidex.Infrastructure.GetEventStore/EventSourcing/GetEventStore.cs b/backend/src/Squidex.Infrastructure.GetEventStore/EventSourcing/GetEventStore.cs index 5e90f56a3..7519d9eab 100644 --- a/backend/src/Squidex.Infrastructure.GetEventStore/EventSourcing/GetEventStore.cs +++ b/backend/src/Squidex.Infrastructure.GetEventStore/EventSourcing/GetEventStore.cs @@ -46,14 +46,14 @@ public sealed class GetEventStore : IEventStore, IInitializable } } - public IEventSubscription CreateSubscription(IEventSubscriber subscriber, string? streamFilter = null, string? position = null) + public IEventSubscription CreateSubscription(IEventSubscriber subscriber, StreamFilter filter, string? position = null) { - Guard.NotNull(streamFilter); + Guard.NotNull(filter); - return new GetEventStoreSubscription(subscriber, client, projectionClient, serializer, position, StreamPrefix, streamFilter); + return new GetEventStoreSubscription(subscriber, client, projectionClient, serializer, position, StreamPrefix, filter); } - public async IAsyncEnumerable QueryAllAsync(string? streamFilter = null, string? position = null, int take = int.MaxValue, + public async IAsyncEnumerable QueryAllAsync(StreamFilter filter, string? position = null, int take = int.MaxValue, [EnumeratorCancellation] CancellationToken ct = default) { if (take <= 0) @@ -61,7 +61,7 @@ public sealed class GetEventStore : IEventStore, IInitializable yield break; } - var streamName = await projectionClient.CreateProjectionAsync(streamFilter); + var streamName = await projectionClient.CreateProjectionAsync(filter); var stream = QueryAsync(streamName, position.ToPosition(false), take, ct); @@ -71,7 +71,7 @@ public sealed class GetEventStore : IEventStore, IInitializable } } - public async IAsyncEnumerable QueryAllReverseAsync(string? streamFilter = null, Instant timestamp = default, int take = int.MaxValue, + public async IAsyncEnumerable QueryAllReverseAsync(StreamFilter filter, Instant timestamp = default, int take = int.MaxValue, [EnumeratorCancellation] CancellationToken ct = default) { if (take <= 0) @@ -79,7 +79,7 @@ public sealed class GetEventStore : IEventStore, IInitializable yield break; } - var streamName = await projectionClient.CreateProjectionAsync(streamFilter); + var streamName = await projectionClient.CreateProjectionAsync(filter); var stream = QueryReverseAsync(streamName, StreamPosition.End, take, ct); @@ -89,41 +89,14 @@ public sealed class GetEventStore : IEventStore, IInitializable } } - public async Task> QueryReverseAsync(string streamName, int count = int.MaxValue, + public async Task> QueryStreamAsync(string streamName, long afterStreamPosition = EtagVersion.Empty, CancellationToken ct = default) { - Guard.NotNullOrEmpty(streamName); - - if (count <= 0) - { - return EmptyEvents; - } - - using (Telemetry.Activities.StartActivity("GetEventStore/GetEventStore")) - { - var result = new List(); - - var stream = QueryReverseAsync(GetStreamName(streamName), StreamPosition.End, count, ct); - - await foreach (var storedEvent in stream.IgnoreNotFound(ct)) - { - result.Add(storedEvent); - } - - return result.ToList(); - } - } - - public async Task> QueryAsync(string streamName, long afterStreamPosition = EtagVersion.Empty, - CancellationToken ct = default) - { - Guard.NotNullOrEmpty(streamName); - using (Telemetry.Activities.StartActivity("GetEventStore/QueryAsync")) { var result = new List(); - var stream = QueryAsync(GetStreamName(streamName), afterStreamPosition.ToPositionBefore(), int.MaxValue, ct); + var stream = QueryAsync(streamName, afterStreamPosition.ToPositionBefore(), int.MaxValue, ct); await foreach (var storedEvent in stream.IgnoreNotFound(ct)) { @@ -156,7 +129,7 @@ public sealed class GetEventStore : IEventStore, IInitializable streamName, start, count, - resolveLinkTos: true, + true, cancellationToken: ct); return result.Select(x => Formatter.Read(x, StreamPrefix, serializer)); @@ -210,10 +183,10 @@ public sealed class GetEventStore : IEventStore, IInitializable } } - public async Task DeleteAsync(string streamFilter, + public async Task DeleteAsync(StreamFilter filter, CancellationToken ct = default) { - var streamName = await projectionClient.CreateProjectionAsync(streamFilter); + var streamName = await projectionClient.CreateProjectionAsync(filter); var events = client.ReadStreamAsync(Direction.Forwards, streamName, StreamPosition.Start, resolveLinkTos: true, cancellationToken: ct); diff --git a/backend/src/Squidex.Infrastructure.GetEventStore/EventSourcing/GetEventStoreSubscription.cs b/backend/src/Squidex.Infrastructure.GetEventStore/EventSourcing/GetEventStoreSubscription.cs index e5d511f58..432abadff 100644 --- a/backend/src/Squidex.Infrastructure.GetEventStore/EventSourcing/GetEventStoreSubscription.cs +++ b/backend/src/Squidex.Infrastructure.GetEventStore/EventSourcing/GetEventStoreSubscription.cs @@ -23,14 +23,14 @@ internal sealed class GetEventStoreSubscription : IEventSubscription IJsonSerializer serializer, string? position, string? prefix, - string? streamFilter) + StreamFilter filter) { #pragma warning disable MA0134 // Observe result of async calls Task.Run(async () => { var ct = cts.Token; - var streamName = await projectionClient.CreateProjectionAsync(streamFilter); + var streamName = await projectionClient.CreateProjectionAsync(filter); async Task OnEvent(StreamSubscription subscription, ResolvedEvent @event, CancellationToken ct) diff --git a/backend/src/Squidex.Infrastructure.GetEventStore/EventSourcing/Utils.cs b/backend/src/Squidex.Infrastructure.GetEventStore/EventSourcing/Utils.cs index f2e233b28..9284cf20b 100644 --- a/backend/src/Squidex.Infrastructure.GetEventStore/EventSourcing/Utils.cs +++ b/backend/src/Squidex.Infrastructure.GetEventStore/EventSourcing/Utils.cs @@ -77,4 +77,21 @@ public static class Utils yield return enumerator.Current; } } + + public static string ToRegex(this StreamFilter filter) + { + if (filter.Prefixes == null) + { + return ".*"; + } + + if (filter.Kind == StreamFilterKind.MatchStart) + { + return $"^{string.Join('|', filter.Prefixes.Select(p => $"({p})"))}"; + } + else + { + return $"^{string.Join('|', filter.Prefixes.Select(p => $"({p})"))}$"; + } + } } diff --git a/backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/FilterExtensions.cs b/backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/FilterExtensions.cs index 3e9ec4f83..fe75f1ff7 100644 --- a/backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/FilterExtensions.cs +++ b/backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/FilterExtensions.cs @@ -5,6 +5,7 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using System.Text.RegularExpressions; using MongoDB.Driver; namespace Squidex.Infrastructure.EventSourcing; @@ -13,53 +14,57 @@ internal static class FilterExtensions { public static FilterDefinition ByOffset(long streamPosition) { - return Builders.Filter.Gte(x => x.EventStreamOffset, streamPosition); + var builder = Builders.Filter; + + return builder.Gte(x => x.EventStreamOffset, streamPosition); } public static FilterDefinition ByPosition(StreamPosition streamPosition) { + var builder = Builders.Filter; + if (streamPosition.IsEndOfCommit) { - return Builders.Filter.Gt(x => x.Timestamp, streamPosition.Timestamp); + return builder.Gt(x => x.Timestamp, streamPosition.Timestamp); } else { - return Builders.Filter.Gte(x => x.Timestamp, streamPosition.Timestamp); + return builder.Gte(x => x.Timestamp, streamPosition.Timestamp); } } - public static FilterDefinition? ByStream(string? streamFilter) + public static FilterDefinition ByStream(StreamFilter filter) { - if (StreamFilter.IsAll(streamFilter)) - { - return Builders.Filter.Exists(x => x.EventStream, true); - } + var builder = Builders.Filter; - if (streamFilter.Contains('^', StringComparison.Ordinal)) + if (filter.Prefixes == null) { - return Builders.Filter.Regex(x => x.EventStream, streamFilter); + return builder.Exists(x => x.EventStream, true); } - else + + if (filter.Kind == StreamFilterKind.MatchStart) { - return Builders.Filter.Eq(x => x.EventStream, streamFilter); + return builder.Or(filter.Prefixes.Select(p => builder.Regex(x => x.EventStream, $"^{p}"))); } + + return builder.In(x => x.EventStream, filter.Prefixes); } - public static FilterDefinition>? ByChangeInStream(string? streamFilter) + public static FilterDefinition>? ByChangeInStream(StreamFilter filter) { - if (StreamFilter.IsAll(streamFilter)) + var builder = Builders>.Filter; + + if (filter.Prefixes == null) { return null; } - if (streamFilter.Contains('^', StringComparison.Ordinal)) - { - return Builders>.Filter.Regex(x => x.FullDocument.EventStream, streamFilter); - } - else + if (filter.Kind == StreamFilterKind.MatchStart) { - return Builders>.Filter.Eq(x => x.FullDocument.EventStream, streamFilter); + return builder.Or(filter.Prefixes.Select(p => builder.Regex(x => x.FullDocument.EventStream, $"^{Regex.Escape(p)}"))); } + + return builder.In(x => x.FullDocument.EventStream, filter.Prefixes); } public static IEnumerable Filtered(this MongoEventCommit commit, StreamPosition position) diff --git a/backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStoreSubscription.cs b/backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStoreSubscription.cs index 7239513c7..2e6177045 100644 --- a/backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStoreSubscription.cs +++ b/backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStoreSubscription.cs @@ -18,7 +18,7 @@ public sealed class MongoEventStoreSubscription : IEventSubscription private readonly IEventSubscriber eventSubscriber; private readonly CancellationTokenSource stopToken = new CancellationTokenSource(); - public MongoEventStoreSubscription(MongoEventStore eventStore, IEventSubscriber eventSubscriber, string? streamFilter, string? position) + public MongoEventStoreSubscription(MongoEventStore eventStore, IEventSubscriber eventSubscriber, StreamFilter streamFilter, string? position) { this.eventStore = eventStore; this.eventSubscriber = eventSubscriber; @@ -26,7 +26,7 @@ public sealed class MongoEventStoreSubscription : IEventSubscription QueryAsync(streamFilter, position).Forget(); } - private async Task QueryAsync(string? streamFilter, string? position) + private async Task QueryAsync(StreamFilter streamFilter, string? position) { try { @@ -51,7 +51,7 @@ public sealed class MongoEventStoreSubscription : IEventSubscription } } - private async Task QueryCurrentAsync(string? streamFilter, StreamPosition lastPosition) + private async Task QueryCurrentAsync(StreamFilter streamFilter, StreamPosition lastPosition) { BsonDocument? resumeToken = null; @@ -103,7 +103,7 @@ public sealed class MongoEventStoreSubscription : IEventSubscription } } - private async Task QueryOldAsync(string? streamFilter, string? position) + private async Task QueryOldAsync(StreamFilter streamFilter, string? position) { string? lastRawPosition = null; @@ -134,7 +134,7 @@ public sealed class MongoEventStoreSubscription : IEventSubscription return lastRawPosition; } - private static PipelineDefinition, ChangeStreamDocument>? Match(string? streamFilter) + private static PipelineDefinition, ChangeStreamDocument>? Match(StreamFilter streamFilter) { var result = new EmptyPipelineDefinition>(); diff --git a/backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStore_Reader.cs b/backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStore_Reader.cs index adaa68d6e..d86fc0183 100644 --- a/backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStore_Reader.cs +++ b/backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStore_Reader.cs @@ -20,71 +20,40 @@ public partial class MongoEventStore : MongoRepositoryBase, IE { private static readonly List EmptyEvents = new List(); - public IEventSubscription CreateSubscription(IEventSubscriber subscriber, string? streamFilter = null, string? position = null) + public IEventSubscription CreateSubscription(IEventSubscriber subscriber, StreamFilter filter, string? position = null) { Guard.NotNull(subscriber); if (CanUseChangeStreams) { - return new MongoEventStoreSubscription(this, subscriber, streamFilter, position); + return new MongoEventStoreSubscription(this, subscriber, filter, position); } else { - return new PollingSubscription(this, subscriber, streamFilter, position); + return new PollingSubscription(this, subscriber, filter, position); } } - public async Task> QueryReverseAsync(string streamName, int count = int.MaxValue, + public async Task> QueryStreamAsync(string streamName, long afterStreamPosition = EtagVersion.Empty, CancellationToken ct = default) { - Guard.NotNullOrEmpty(streamName); - - if (count <= 0) - { - return EmptyEvents; - } - - using (Telemetry.Activities.StartActivity("MongoEventStore/QueryLatestAsync")) - { - var filter = Filter.Eq(x => x.EventStream, streamName); - - var commits = - await Collection.Find(filter).Sort(Sort.Descending(x => x.Timestamp)).Limit(count) - .ToListAsync(ct); - - var result = commits.Select(x => x.Filtered()).Reverse().SelectMany(x => x).TakeLast(count).ToList(); - - return result; - } - } - - public async Task> QueryAsync(string streamName, long afterStreamPosition = EtagVersion.Empty, - CancellationToken ct = default) - { - Guard.NotNullOrEmpty(streamName); - using (Telemetry.Activities.StartActivity("MongoEventStore/QueryAsync")) { - var filter = - Filter.And( - Filter.Eq(x => x.EventStream, streamName), - Filter.Gte(x => x.EventStreamOffset, afterStreamPosition)); - var commits = - await Collection.Find(filter) + await Collection.Find(CreateFilter(StreamFilter.Name(streamName), afterStreamPosition)) .ToListAsync(ct); var result = Convert(commits, afterStreamPosition); if ((commits.Count == 0 || commits[0].EventStreamOffset != afterStreamPosition) && afterStreamPosition > EtagVersion.Empty) { - filter = + var filterBefore = Filter.And( - Filter.Eq(x => x.EventStream, streamName), + FilterExtensions.ByStream(StreamFilter.Name(streamName)), Filter.Lt(x => x.EventStreamOffset, afterStreamPosition)); commits = - await Collection.Find(filter).SortByDescending(x => x.EventStreamOffset).Limit(1) + await Collection.Find(filterBefore).SortByDescending(x => x.EventStreamOffset).Limit(1) .ToListAsync(ct); result = Convert(commits, afterStreamPosition).Concat(result).ToList(); @@ -94,26 +63,7 @@ public partial class MongoEventStore : MongoRepositoryBase, IE } } - public async Task>> QueryManyAsync(IEnumerable streamNames, - CancellationToken ct = default) - { - Guard.NotNull(streamNames); - - using (Telemetry.Activities.StartActivity("MongoEventStore/QueryManyAsync")) - { - var filter = Filter.In(x => x.EventStream, streamNames); - - var commits = - await Collection.Find(filter) - .ToListAsync(ct); - - var result = commits.GroupBy(x => x.EventStream).ToDictionary(x => x.Key, Convert); - - return result; - } - } - - public async IAsyncEnumerable QueryAllReverseAsync(string? streamFilter = null, Instant timestamp = default, int take = int.MaxValue, + public async IAsyncEnumerable QueryAllReverseAsync(StreamFilter filter, Instant timestamp = default, int take = int.MaxValue, [EnumeratorCancellation] CancellationToken ct = default) { if (take <= 0) @@ -123,10 +73,8 @@ public partial class MongoEventStore : MongoRepositoryBase, IE StreamPosition lastPosition = timestamp; - var filterDefinition = CreateFilter(streamFilter, lastPosition); - var find = - Collection.Find(filterDefinition, Batching.Options) + Collection.Find(CreateFilter(filter, lastPosition), Batching.Options) .Limit(take).Sort(Sort.Descending(x => x.Timestamp).Ascending(x => x.EventStream)); var taken = 0; @@ -158,12 +106,12 @@ public partial class MongoEventStore : MongoRepositoryBase, IE } } - public async IAsyncEnumerable QueryAllAsync(string? streamFilter = null, string? position = null, int take = int.MaxValue, + public async IAsyncEnumerable QueryAllAsync(StreamFilter filter, string? position = null, int take = int.MaxValue, [EnumeratorCancellation] CancellationToken ct = default) { StreamPosition lastPosition = position; - var filterDefinition = CreateFilter(streamFilter, lastPosition); + var filterDefinition = CreateFilter(filter, lastPosition); var find = Collection.Find(filterDefinition).SortBy(x => x.Timestamp).ThenByDescending(x => x.EventStream) @@ -197,15 +145,13 @@ public partial class MongoEventStore : MongoRepositoryBase, IE return commits.OrderBy(x => x.EventStreamOffset).ThenBy(x => x.Timestamp).SelectMany(x => x.Filtered(streamPosition)).ToList(); } - private static FilterDefinition CreateFilter(string? streamFilter, StreamPosition streamPosition) + private static FilterDefinition CreateFilter(StreamFilter filter, StreamPosition streamPosition) { - var filter = FilterExtensions.ByPosition(streamPosition); - - if (streamFilter != null) - { - return Filter.And(filter, FilterExtensions.ByStream(streamFilter)); - } + return Filter.And(FilterExtensions.ByPosition(streamPosition), FilterExtensions.ByStream(filter)); + } - return filter; + private static FilterDefinition CreateFilter(StreamFilter filter, long streamPosition) + { + return Filter.And(FilterExtensions.ByStream(filter), FilterExtensions.ByOffset(streamPosition)); } } diff --git a/backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStore_Writer.cs b/backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStore_Writer.cs index f9a490114..cfc17fe19 100644 --- a/backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStore_Writer.cs +++ b/backend/src/Squidex.Infrastructure.MongoDb/EventSourcing/MongoEventStore_Writer.cs @@ -17,20 +17,12 @@ public partial class MongoEventStore private const int MaxWriteAttempts = 20; private static readonly BsonTimestamp EmptyTimestamp = new BsonTimestamp(0); - public Task DeleteStreamAsync(string streamName, + public Task DeleteAsync(StreamFilter filter, CancellationToken ct = default) { - Guard.NotNullOrEmpty(streamName); - - return Collection.DeleteManyAsync(x => x.EventStream == streamName, ct); - } - - public Task DeleteAsync(string streamFilter, - CancellationToken ct = default) - { - Guard.NotNullOrEmpty(streamFilter); + Guard.NotDefault(filter); - return Collection.DeleteManyAsync(FilterExtensions.ByStream(streamFilter), ct); + return Collection.DeleteManyAsync(FilterExtensions.ByStream(filter), ct); } public async Task AppendAsync(Guid commitId, string streamName, long expectedVersion, ICollection events, diff --git a/backend/src/Squidex.Infrastructure.MongoDb/Squidex.Infrastructure.MongoDb.csproj b/backend/src/Squidex.Infrastructure.MongoDb/Squidex.Infrastructure.MongoDb.csproj index 47516ece4..6da25bf78 100644 --- a/backend/src/Squidex.Infrastructure.MongoDb/Squidex.Infrastructure.MongoDb.csproj +++ b/backend/src/Squidex.Infrastructure.MongoDb/Squidex.Infrastructure.MongoDb.csproj @@ -18,8 +18,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/backend/src/Squidex.Infrastructure/Commands/Rebuilder.cs b/backend/src/Squidex.Infrastructure/Commands/Rebuilder.cs index efb001f67..c5fa61ad1 100644 --- a/backend/src/Squidex.Infrastructure/Commands/Rebuilder.cs +++ b/backend/src/Squidex.Infrastructure/Commands/Rebuilder.cs @@ -49,14 +49,14 @@ public class Rebuilder return domainObject; } - public virtual Task RebuildAsync(string filter, int batchSize, + public virtual Task RebuildAsync(StreamFilter filter, int batchSize, CancellationToken ct = default) where T : DomainObject where TState : class, IDomainState, new() { return RebuildAsync(filter, batchSize, 0, ct); } - public virtual async Task RebuildAsync(string filter, int batchSize, double errorThreshold, + public virtual async Task RebuildAsync(StreamFilter filter, int batchSize, double errorThreshold, CancellationToken ct = default) where T : DomainObject where TState : class, IDomainState, new() { diff --git a/backend/src/Squidex.Infrastructure/DomainId.cs b/backend/src/Squidex.Infrastructure/DomainId.cs index 9cf9f3dfa..4c04eea93 100644 --- a/backend/src/Squidex.Infrastructure/DomainId.cs +++ b/backend/src/Squidex.Infrastructure/DomainId.cs @@ -102,4 +102,10 @@ public readonly struct DomainId : IEquatable, IComparable { return new DomainId($"{id1}{IdSeparator}{id2}"); } + + public static bool TryParse(ReadOnlySpan input, out DomainId result) + { + result = new DomainId(input.ToString()); + return true; + } } diff --git a/backend/src/Squidex.Infrastructure/EventSourcing/IEventConsumer.cs b/backend/src/Squidex.Infrastructure/EventSourcing/IEventConsumer.cs index cc664b1f3..78331f763 100644 --- a/backend/src/Squidex.Infrastructure/EventSourcing/IEventConsumer.cs +++ b/backend/src/Squidex.Infrastructure/EventSourcing/IEventConsumer.cs @@ -13,9 +13,9 @@ public interface IEventConsumer int BatchSize => 1; - string Name { get; } + string Name => GetType().Name; - string EventsFilter => ".*"; + StreamFilter EventsFilter => default; bool StartLatest => false; diff --git a/backend/src/Squidex.Infrastructure/EventSourcing/IEventStore.cs b/backend/src/Squidex.Infrastructure/EventSourcing/IEventStore.cs index b957ec631..8f63ee016 100644 --- a/backend/src/Squidex.Infrastructure/EventSourcing/IEventStore.cs +++ b/backend/src/Squidex.Infrastructure/EventSourcing/IEventStore.cs @@ -11,28 +11,22 @@ namespace Squidex.Infrastructure.EventSourcing; public interface IEventStore { - Task> QueryReverseAsync(string streamName, int take = int.MaxValue, + Task> QueryStreamAsync(string streamName, long afterStreamPosition = EtagVersion.Empty, CancellationToken ct = default); - Task> QueryAsync(string streamName, long afterStreamPosition = EtagVersion.Empty, + IAsyncEnumerable QueryAllReverseAsync(StreamFilter filter, Instant timestamp = default, int take = int.MaxValue, CancellationToken ct = default); - IAsyncEnumerable QueryAllReverseAsync(string? streamFilter = null, Instant timestamp = default, int take = int.MaxValue, - CancellationToken ct = default); - - IAsyncEnumerable QueryAllAsync(string? streamFilter = null, string? position = null, int take = int.MaxValue, + IAsyncEnumerable QueryAllAsync(StreamFilter filter, string? position = null, int take = int.MaxValue, CancellationToken ct = default); Task AppendAsync(Guid commitId, string streamName, long expectedVersion, ICollection events, CancellationToken ct = default); - Task DeleteAsync(string streamFilter, - CancellationToken ct = default); - - Task DeleteStreamAsync(string streamName, + Task DeleteAsync(StreamFilter filter, CancellationToken ct = default); - IEventSubscription CreateSubscription(IEventSubscriber eventSubscriber, string? streamFilter = null, string? position = null); + IEventSubscription CreateSubscription(IEventSubscriber eventSubscriber, StreamFilter filter, string? position = null); async Task AppendUnsafeAsync(IEnumerable commits, CancellationToken ct = default) @@ -42,17 +36,4 @@ public interface IEventStore await AppendAsync(commit.Id, commit.StreamName, commit.Offset, commit.Events, ct); } } - - async Task>> QueryManyAsync(IEnumerable streamNames, - CancellationToken ct = default) - { - var result = new Dictionary>(); - - foreach (var streamName in streamNames) - { - result[streamName] = await QueryAsync(streamName, EtagVersion.Empty, ct); - } - - return result; - } } diff --git a/backend/src/Squidex.Infrastructure/EventSourcing/PollingSubscription.cs b/backend/src/Squidex.Infrastructure/EventSourcing/PollingSubscription.cs index acc12d042..e6129c5f5 100644 --- a/backend/src/Squidex.Infrastructure/EventSourcing/PollingSubscription.cs +++ b/backend/src/Squidex.Infrastructure/EventSourcing/PollingSubscription.cs @@ -17,7 +17,7 @@ public sealed class PollingSubscription : IEventSubscription public PollingSubscription( IEventStore eventStore, IEventSubscriber eventSubscriber, - string? streamFilter, + StreamFilter streamFilter, string? position) { timer = new CompletionTimer(5000, async ct => diff --git a/backend/src/Squidex.Infrastructure/EventSourcing/StreamFilter.cs b/backend/src/Squidex.Infrastructure/EventSourcing/StreamFilter.cs index 89605f3dc..4b907bc96 100644 --- a/backend/src/Squidex.Infrastructure/EventSourcing/StreamFilter.cs +++ b/backend/src/Squidex.Infrastructure/EventSourcing/StreamFilter.cs @@ -5,17 +5,38 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using System.Diagnostics.CodeAnalysis; +using Squidex.Infrastructure.Collections; namespace Squidex.Infrastructure.EventSourcing; -public static class StreamFilter +public readonly record struct StreamFilter { - public static bool IsAll([NotNullWhen(false)] string? filter) + public ReadonlyList? Prefixes { get; } + + public StreamFilterKind Kind { get; } + + public StreamFilter(StreamFilterKind kind, params string[] prefixes) + { + Kind = kind; + + if (prefixes.Length > 0) + { + Prefixes = prefixes.ToReadonlyList(); + } + } + + public static StreamFilter Prefix(params string[] prefixes) + { + return new StreamFilter(StreamFilterKind.MatchStart, prefixes); + } + + public static StreamFilter Name(params string[] prefixes) + { + return new StreamFilter(StreamFilterKind.MatchFull, prefixes); + } + + public static StreamFilter All() { - return string.IsNullOrWhiteSpace(filter) - || string.Equals(filter, ".*", StringComparison.OrdinalIgnoreCase) - || string.Equals(filter, "(.*)", StringComparison.OrdinalIgnoreCase) - || string.Equals(filter, "(.*?)", StringComparison.OrdinalIgnoreCase); + return default; } } diff --git a/backend/src/Squidex.Domain.Apps.Entities/Comments/Commands/UpdateComment.cs b/backend/src/Squidex.Infrastructure/EventSourcing/StreamFilterKind.cs similarity index 76% rename from backend/src/Squidex.Domain.Apps.Entities/Comments/Commands/UpdateComment.cs rename to backend/src/Squidex.Infrastructure/EventSourcing/StreamFilterKind.cs index 46307f83e..f52fda22c 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Comments/Commands/UpdateComment.cs +++ b/backend/src/Squidex.Infrastructure/EventSourcing/StreamFilterKind.cs @@ -5,8 +5,10 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -namespace Squidex.Domain.Apps.Entities.Comments.Commands; +namespace Squidex.Infrastructure.EventSourcing; -public sealed class UpdateComment : CommentTextCommand +public enum StreamFilterKind { + MatchFull, + MatchStart } diff --git a/backend/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj b/backend/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj index badc75a90..029014e54 100644 --- a/backend/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj +++ b/backend/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj @@ -24,12 +24,12 @@ - - - - - - + + + + + + diff --git a/backend/src/Squidex.Infrastructure/States/BatchContext.cs b/backend/src/Squidex.Infrastructure/States/BatchContext.cs index 325123302..a56671dea 100644 --- a/backend/src/Squidex.Infrastructure/States/BatchContext.cs +++ b/backend/src/Squidex.Infrastructure/States/BatchContext.cs @@ -50,22 +50,27 @@ public sealed class BatchContext : IBatchContext public async Task LoadAsync(IEnumerable ids) { - var streamNames = ids.ToDictionary(x => x, x => eventStreamNames.GetStreamName(owner, x.ToString())); + var streamNames = ids.ToDictionary( + x => x, + x => eventStreamNames.GetStreamName(owner, x.ToString())); if (streamNames.Count == 0) { return; } - var streams = await eventStore.QueryManyAsync(streamNames.Values); + var eventsResults = await eventStore.QueryAllAsync(StreamFilter.Name(streamNames.Values.ToArray())).ToListAsync(); + var eventsByStream = eventsResults.ToLookup(x => x.StreamName); foreach (var (id, streamName) in streamNames) { - if (streams.TryGetValue(streamName, out var data)) + var byStream = eventsByStream[streamName].ToList(); + + if (byStream.Count > 0) { - var stream = data.Select(eventFormatter.ParseIfKnown).NotNull().ToList(); + var parsed = byStream.Select(eventFormatter.ParseIfKnown).NotNull().ToList(); - events[id] = (data.Count - 1, stream); + events[id] = (byStream.Count - 1, parsed); } else { diff --git a/backend/src/Squidex.Infrastructure/States/Persistence.cs b/backend/src/Squidex.Infrastructure/States/Persistence.cs index 8e2fcc798..6592c48e0 100644 --- a/backend/src/Squidex.Infrastructure/States/Persistence.cs +++ b/backend/src/Squidex.Infrastructure/States/Persistence.cs @@ -82,7 +82,7 @@ internal sealed class Persistence : IPersistence { using (Telemetry.Activities.StartActivity("Persistence/ReadEvents")) { - await eventStore.DeleteStreamAsync(streamName.Value, ct); + await eventStore.DeleteAsync(StreamFilter.Name(streamName.Value), ct); } versionEvents = EtagVersion.Empty; @@ -144,7 +144,7 @@ internal sealed class Persistence : IPersistence private async Task ReadEventsAsync( CancellationToken ct) { - var events = await eventStore.QueryAsync(streamName.Value, versionEvents, ct); + var events = await eventStore.QueryStreamAsync(streamName.Value, versionEvents, ct); var isStopped = false; diff --git a/backend/src/Squidex.Infrastructure/UsageTracking/BackgroundUsageTracker.cs b/backend/src/Squidex.Infrastructure/UsageTracking/BackgroundUsageTracker.cs index 535f3dbcd..3867f1a79 100644 --- a/backend/src/Squidex.Infrastructure/UsageTracking/BackgroundUsageTracker.cs +++ b/backend/src/Squidex.Infrastructure/UsageTracking/BackgroundUsageTracker.cs @@ -116,9 +116,8 @@ public sealed class BackgroundUsageTracker : DisposableObjectBase, IUsageTracker category = GetCategory(category); -#pragma warning disable MA0105 // Use the lambda parameters instead of using a closure - jobs.AddOrUpdate((key, category, date), counters, (k, p) => p.SumpUpCloned(counters)); -#pragma warning restore MA0105 // Use the lambda parameters instead of using a closure + // Create a copy of the counters on add, so that we do not share it. + jobs.AddOrUpdate((key, category, date), (_, args) => new Counters(args), (_, v, args) => v.Merge(args), counters); return Task.CompletedTask; } @@ -191,7 +190,7 @@ public sealed class BackgroundUsageTracker : DisposableObjectBase, IUsageTracker foreach (var usage in queried) { - result.SumpUp(usage.Counters); + result.Merge(usage.Counters); } return result; diff --git a/backend/src/Squidex.Infrastructure/UsageTracking/Counters.cs b/backend/src/Squidex.Infrastructure/UsageTracking/Counters.cs index c13e34696..2a9927166 100644 --- a/backend/src/Squidex.Infrastructure/UsageTracking/Counters.cs +++ b/backend/src/Squidex.Infrastructure/UsageTracking/Counters.cs @@ -42,14 +42,7 @@ public sealed class Counters : Dictionary return (long)value; } - public Counters SumpUpCloned(Counters counters) - { - var result = new Counters(this); - - return result.SumpUp(counters); - } - - public Counters SumpUp(Counters source) + public Counters Merge(Counters source) { foreach (var (key, value) in source) { diff --git a/backend/src/Squidex.Web/Services/UrlGenerator.cs b/backend/src/Squidex.Web/Services/UrlGenerator.cs index 3b1ae6265..acdaeb28d 100644 --- a/backend/src/Squidex.Web/Services/UrlGenerator.cs +++ b/backend/src/Squidex.Web/Services/UrlGenerator.cs @@ -67,6 +67,11 @@ public sealed class UrlGenerator : IUrlGenerator return urlGenerator.BuildUrl($"api/assets/{appId.Name}/{idOrSlug}"); } + public string AssetContent(NamedId appId, string idOrSlug, long version) + { + return urlGenerator.BuildUrl($"api/assets/{appId.Name}/{idOrSlug}?version={version}"); + } + public string? AssetSource(NamedId appId, DomainId assetId, long fileVersion) { return assetFileStore.GeneratePublicUrl(appId.Id, assetId, fileVersion, null); diff --git a/backend/src/Squidex/Areas/Api/Config/OpenApi/AcceptAnyBodyAttribute.cs b/backend/src/Squidex/Areas/Api/Config/OpenApi/AcceptAnyBodyAttribute.cs new file mode 100644 index 000000000..0fb316492 --- /dev/null +++ b/backend/src/Squidex/Areas/Api/Config/OpenApi/AcceptAnyBodyAttribute.cs @@ -0,0 +1,42 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using NJsonSchema; +using NSwag; +using NSwag.Annotations; +using NSwag.Generation.Processors; +using NSwag.Generation.Processors.Contexts; +using Squidex.Domain.Apps.Core; + +namespace Squidex.Areas.Api.Config.OpenApi; + +public sealed class AcceptAnyBodyAttribute : OpenApiOperationProcessorAttribute +{ + public AcceptAnyBodyAttribute() + : base(typeof(Processor)) + { + } + + public sealed class Processor : IOperationProcessor + { + public bool Process(OperationProcessorContext context) + { + context.OperationDescription.Operation.Parameters.Add( + new OpenApiParameter + { + Name = "request", + Kind = OpenApiParameterKind.Body, + Schema = new JsonSchema + { + }, + Description = FieldDescriptions.GraphqlRequest + }); + + return true; + } + } +} diff --git a/backend/src/Squidex/Areas/Api/Config/OpenApi/AcceptQueryAttribute.cs b/backend/src/Squidex/Areas/Api/Config/OpenApi/AcceptQueryAttribute.cs index 8fc630000..adb8b66bc 100644 --- a/backend/src/Squidex/Areas/Api/Config/OpenApi/AcceptQueryAttribute.cs +++ b/backend/src/Squidex/Areas/Api/Config/OpenApi/AcceptQueryAttribute.cs @@ -18,18 +18,13 @@ public sealed class AcceptQueryAttribute : OpenApiOperationProcessorAttribute { } - public sealed class Processor : IOperationProcessor +#pragma warning disable SA1313 // Parameter names should begin with lower-case letter + public sealed record Processor(bool SupportsSearch) : IOperationProcessor +#pragma warning restore SA1313 // Parameter names should begin with lower-case letter { - private readonly bool supportsSearch; - - public Processor(bool supportsSearch) - { - this.supportsSearch = supportsSearch; - } - public bool Process(OperationProcessorContext context) { - context.OperationDescription.Operation.AddQuery(supportsSearch); + context.OperationDescription.Operation.AddQuery(SupportsSearch); return true; } } diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/AppAssetsController.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/AppAssetsController.cs index 71f924b53..f3e8cf647 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/AppAssetsController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/AppAssetsController.cs @@ -29,8 +29,8 @@ public sealed class AppAssetsController : ApiController /// Get the app asset scripts. /// /// The name of the app to get the asset scripts for. - /// Asset scripts returned.. - /// App not found.. + /// Asset scripts returned. + /// App not found. [HttpGet] [Route("apps/{app}/assets/scripts")] [ProducesResponseType(typeof(AssetScriptsDto), StatusCodes.Status200OK)] @@ -51,9 +51,9 @@ public sealed class AppAssetsController : ApiController /// /// The name of the app to update. /// The values to update. - /// Asset scripts updated.. - /// Asset request not valid.. - /// App not found.. + /// Asset scripts updated. + /// Asset request not valid. + /// App not found. [HttpPut] [Route("apps/{app}/assets/scripts")] [ProducesResponseType(typeof(AssetScriptsDto), StatusCodes.Status200OK)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/AppClientsController.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/AppClientsController.cs index 42a06c553..6ccda9323 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/AppClientsController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/AppClientsController.cs @@ -31,8 +31,8 @@ public sealed class AppClientsController : ApiController /// Get app clients. /// /// The name of the app. - /// Clients returned.. - /// App not found.. + /// Clients returned. + /// App not found. /// /// Gets all configured clients for the app with the specified name. /// @@ -58,9 +58,9 @@ public sealed class AppClientsController : ApiController /// /// The name of the app. /// Client object that needs to be added to the app. - /// Client created.. - /// Client request not valid.. - /// App not found.. + /// Client created. + /// Client request not valid. + /// App not found. /// /// Create a new client for the app with the specified name. /// The client secret is auto generated on the server and returned. The client does not expire, the access token is valid for 30 days. @@ -85,9 +85,9 @@ public sealed class AppClientsController : ApiController /// The name of the app. /// The ID of the client that must be updated. /// Client object that needs to be updated. - /// Client updated.. - /// Client request not valid.. - /// Client or app not found.. + /// Client updated. + /// Client request not valid. + /// Client or app not found. /// /// Only the display name can be changed, create a new client if necessary. /// @@ -110,8 +110,8 @@ public sealed class AppClientsController : ApiController /// /// The name of the app. /// The ID of the client that must be deleted. - /// Client deleted.. - /// Client or app not found.. + /// Client deleted. + /// Client or app not found. /// /// The application that uses this client credentials cannot access the API after it has been revoked. /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/AppContributorsController.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/AppContributorsController.cs index 17fd0c5ae..0a88d8d2d 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/AppContributorsController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/AppContributorsController.cs @@ -38,8 +38,8 @@ public sealed class AppContributorsController : ApiController /// Get app contributors. /// /// The name of the app. - /// Contributors returned.. - /// App not found.. + /// Contributors returned. + /// App not found. [HttpGet] [Route("apps/{app}/contributors/")] [ProducesResponseType(typeof(ContributorsDto), StatusCodes.Status200OK)] @@ -57,9 +57,9 @@ public sealed class AppContributorsController : ApiController /// /// The name of the app. /// Contributor object that needs to be added to the app. - /// Contributor assigned to app.. - /// Contributor request not valid.. - /// App not found.. + /// Contributor assigned to app. + /// Contributor request not valid. + /// App not found. [HttpPost] [Route("apps/{app}/contributors/")] [ProducesResponseType(typeof(ContributorsDto), StatusCodes.Status201Created)] @@ -78,8 +78,8 @@ public sealed class AppContributorsController : ApiController /// Remove yourself. /// /// The name of the app. - /// Contributor removed.. - /// Contributor or app not found.. + /// Contributor removed. + /// Contributor or app not found. [HttpDelete] [Route("apps/{app}/contributors/me/")] [ProducesResponseType(typeof(ContributorsDto), StatusCodes.Status200OK)] @@ -99,8 +99,8 @@ public sealed class AppContributorsController : ApiController /// /// The name of the app. /// The ID of the contributor. - /// Contributor removed.. - /// Contributor or app not found.. + /// Contributor removed. + /// Contributor or app not found. [HttpDelete] [Route("apps/{app}/contributors/{id}/")] [ProducesResponseType(typeof(ContributorsDto), StatusCodes.Status200OK)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/AppImageController.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/AppImageController.cs index 82f4b7ab9..1e67c827b 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/AppImageController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/AppImageController.cs @@ -41,8 +41,8 @@ public sealed class AppImageController : ApiController /// Get the app image. /// /// The name of the app. - /// App image found and content or (resized) image returned.. - /// App not found.. + /// App image found and content or (resized) image returned. + /// App not found. [HttpGet] [Route("apps/{app}/image")] [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/AppLanguagesController.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/AppLanguagesController.cs index b68e2c0d0..8da4b7039 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/AppLanguagesController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/AppLanguagesController.cs @@ -32,8 +32,8 @@ public sealed class AppLanguagesController : ApiController /// Get app languages. /// /// The name of the app. - /// Languages returned.. - /// App not found.. + /// Languages returned. + /// App not found. [HttpGet] [Route("apps/{app}/languages/")] [ProducesResponseType(typeof(AppLanguagesDto), StatusCodes.Status200OK)] @@ -56,9 +56,9 @@ public sealed class AppLanguagesController : ApiController /// /// The name of the app. /// The language to add to the app. - /// Language created.. - /// Language request not valid.. - /// App not found.. + /// Language created. + /// Language request not valid. + /// App not found. [HttpPost] [Route("apps/{app}/languages/")] [ProducesResponseType(typeof(AppLanguagesDto), 201)] @@ -79,9 +79,9 @@ public sealed class AppLanguagesController : ApiController /// The name of the app. /// The language to update. /// The language object. - /// Language updated.. - /// Language request not valid.. - /// Language or app not found.. + /// Language updated. + /// Language request not valid. + /// Language or app not found. [HttpPut] [Route("apps/{app}/languages/{language}/")] [ProducesResponseType(typeof(AppLanguagesDto), StatusCodes.Status200OK)] @@ -101,9 +101,9 @@ public sealed class AppLanguagesController : ApiController /// /// The name of the app. /// The language to delete from the app. - /// Language deleted.. - /// Language is master language.. - /// Language or app not found.. + /// Language deleted. + /// Language is master language. + /// Language or app not found. [HttpDelete] [Route("apps/{app}/languages/{language}/")] [ProducesResponseType(typeof(AppLanguagesDto), StatusCodes.Status200OK)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/AppRolesController.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/AppRolesController.cs index 7e48adad0..8ffb5351d 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/AppRolesController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/AppRolesController.cs @@ -35,8 +35,8 @@ public sealed class AppRolesController : ApiController /// Get app roles. /// /// The name of the app. - /// Roles returned.. - /// App not found.. + /// Roles returned. + /// App not found. [HttpGet] [Route("apps/{app}/roles/")] [ProducesResponseType(typeof(RolesDto), StatusCodes.Status200OK)] @@ -58,8 +58,8 @@ public sealed class AppRolesController : ApiController /// Get app permissions. /// /// The name of the app. - /// App permissions returned.. - /// App not found.. + /// App permissions returned. + /// App not found. [HttpGet] [Route("apps/{app}/roles/permissions")] [ProducesResponseType(typeof(string[]), StatusCodes.Status200OK)] @@ -82,9 +82,9 @@ public sealed class AppRolesController : ApiController /// /// The name of the app. /// Role object that needs to be added to the app. - /// Role created.. - /// Role request not valid.. - /// App not found.. + /// Role created. + /// Role request not valid. + /// App not found. [HttpPost] [Route("apps/{app}/roles/")] [ProducesResponseType(typeof(RolesDto), 201)] @@ -105,9 +105,9 @@ public sealed class AppRolesController : ApiController /// The name of the app. /// The name of the role to be updated. /// Role to be updated for the app. - /// Role updated.. - /// Role request not valid.. - /// Role or app not found.. + /// Role updated. + /// Role request not valid. + /// Role or app not found. [HttpPut] [Route("apps/{app}/roles/{roleName}/")] [ProducesResponseType(typeof(RolesDto), StatusCodes.Status200OK)] @@ -128,9 +128,9 @@ public sealed class AppRolesController : ApiController /// /// The name of the app. /// The name of the role. - /// Role deleted.. - /// Role is in use by contributor or client or a default role.. - /// Role or app not found.. + /// Role deleted. + /// Role is in use by contributor or client or a default role. + /// Role or app not found. [HttpDelete] [Route("apps/{app}/roles/{roleName}/")] [ProducesResponseType(typeof(RolesDto), StatusCodes.Status200OK)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/AppSettingsController.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/AppSettingsController.cs index 50a504bcd..25b8081c7 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/AppSettingsController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/AppSettingsController.cs @@ -29,8 +29,8 @@ public sealed class AppSettingsController : ApiController /// Get the app settings. /// /// The name of the app to get the settings for. - /// App settings returned.. - /// App not found.. + /// App settings returned. + /// App not found. [HttpGet] [Route("apps/{app}/settings")] [ProducesResponseType(typeof(AppSettingsDto), StatusCodes.Status200OK)] @@ -51,9 +51,9 @@ public sealed class AppSettingsController : ApiController /// /// The name of the app to update. /// The values to update. - /// App updated.. - /// App request not valid.. - /// App not found.. + /// App updated. + /// App request not valid. + /// App not found. [HttpPut] [Route("apps/{app}/settings")] [ProducesResponseType(typeof(AppSettingsDto), StatusCodes.Status200OK)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/AppWorkflowsController.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/AppWorkflowsController.cs index 8e3714bd4..2117c3c30 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/AppWorkflowsController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/AppWorkflowsController.cs @@ -36,8 +36,8 @@ public sealed class AppWorkflowsController : ApiController /// Get app workflow. /// /// The name of the app. - /// Workflows returned.. - /// App not found.. + /// Workflows returned. + /// App not found. [HttpGet] [Route("apps/{app}/workflows/")] [ProducesResponseType(typeof(WorkflowsDto), StatusCodes.Status200OK)] @@ -60,9 +60,9 @@ public sealed class AppWorkflowsController : ApiController /// /// The name of the app. /// The new workflow. - /// Workflow created.. - /// Workflow request not valid.. - /// Workflow or app not found.. + /// Workflow created. + /// Workflow request not valid. + /// Workflow or app not found. [HttpPost] [Route("apps/{app}/workflows/")] [ProducesResponseType(typeof(WorkflowsDto), StatusCodes.Status200OK)] @@ -83,9 +83,9 @@ public sealed class AppWorkflowsController : ApiController /// The name of the app. /// The ID of the workflow to update. /// The new workflow. - /// Workflow updated.. - /// Workflow request not valid.. - /// Workflow or app not found.. + /// Workflow updated. + /// Workflow request not valid. + /// Workflow or app not found. [HttpPut] [Route("apps/{app}/workflows/{id}")] [ProducesResponseType(typeof(WorkflowsDto), StatusCodes.Status200OK)] @@ -105,8 +105,8 @@ public sealed class AppWorkflowsController : ApiController /// /// The name of the app. /// The ID of the workflow to update. - /// Workflow deleted.. - /// Workflow or app not found.. + /// Workflow deleted. + /// Workflow or app not found. [HttpDelete] [Route("apps/{app}/workflows/{id}")] [ProducesResponseType(typeof(WorkflowsDto), StatusCodes.Status200OK)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Apps/AppsController.cs b/backend/src/Squidex/Areas/Api/Controllers/Apps/AppsController.cs index f6a66b6cc..b6ea9ae8c 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Apps/AppsController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Apps/AppsController.cs @@ -37,7 +37,7 @@ public sealed class AppsController : ApiController /// /// Get your apps. /// - /// Apps returned.. + /// Apps returned. /// /// You can only retrieve the list of apps when you are authenticated as a user (OpenID implicit flow). /// You will retrieve all apps, where you are assigned as a contributor. @@ -68,7 +68,7 @@ public sealed class AppsController : ApiController /// Get team apps. /// /// The ID of the team. - /// Apps returned.. + /// Apps returned. /// /// You can only retrieve the list of apps when you are authenticated as a user (OpenID implicit flow). /// You will retrieve all apps, where you are assigned as a contributor. @@ -96,8 +96,8 @@ public sealed class AppsController : ApiController /// Get an app by name. /// /// The name of the app. - /// Apps returned.. - /// App not found.. + /// Apps returned. + /// App not found. [HttpGet] [Route("apps/{app}")] [ProducesResponseType(typeof(AppDto), StatusCodes.Status200OK)] @@ -121,9 +121,9 @@ public sealed class AppsController : ApiController /// Create a new app. /// /// The app object that needs to be added to Squidex. - /// App created.. - /// App request not valid.. - /// App name is already in use.. + /// App created. + /// App request not valid. + /// App name is already in use. /// /// You can only create an app when you are authenticated as a user (OpenID implicit flow). /// You will be assigned as owner of the new app automatically. @@ -145,9 +145,9 @@ public sealed class AppsController : ApiController /// /// The name of the app to update. /// The values to update. - /// App updated.. - /// App request not valid.. - /// App not found.. + /// App updated. + /// App request not valid. + /// App not found. [HttpPut] [Route("apps/{app}/")] [ProducesResponseType(typeof(AppDto), StatusCodes.Status200OK)] @@ -165,9 +165,9 @@ public sealed class AppsController : ApiController /// /// The name of the app to update. /// The team information. - /// App transferred.. - /// App request not valid.. - /// App not found.. + /// App transferred. + /// App request not valid. + /// App not found. [HttpPut] [Route("apps/{app}/team")] [ProducesResponseType(typeof(AppDto), StatusCodes.Status200OK)] @@ -185,9 +185,9 @@ public sealed class AppsController : ApiController /// /// The name of the app to update. /// The file to upload. - /// App image uploaded.. - /// App request not valid.. - /// App not found.. + /// App image uploaded. + /// App request not valid. + /// App not found. [HttpPost] [Route("apps/{app}/image")] [ProducesResponseType(typeof(AppDto), StatusCodes.Status200OK)] @@ -204,8 +204,8 @@ public sealed class AppsController : ApiController /// Remove the app image. /// /// The name of the app to update. - /// App image removed.. - /// App not found.. + /// App image removed. + /// App not found. [HttpDelete] [Route("apps/{app}/image")] [ProducesResponseType(typeof(AppDto), StatusCodes.Status200OK)] @@ -222,8 +222,8 @@ public sealed class AppsController : ApiController /// Delete the app. /// /// The name of the app to delete. - /// App deleted.. - /// App not found.. + /// App deleted. + /// App not found. [HttpDelete] [Route("apps/{app}/")] [ProducesResponseType(StatusCodes.Status204NoContent)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetContentController.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetContentController.cs index 2867cb83b..aab2d0948 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetContentController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetContentController.cs @@ -52,8 +52,8 @@ public sealed class AssetContentController : ApiController /// The id or slug of the asset. /// The request parameters. /// Optional suffix that can be used to seo-optimize the link to the image Has not effect. - /// Asset found and content or (resized) image returned.. - /// Asset or app not found.. + /// Asset found and content or (resized) image returned. + /// Asset or app not found. [HttpGet] [Route("assets/{app}/{idOrSlug}/{*more}")] [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK)] @@ -79,8 +79,8 @@ public sealed class AssetContentController : ApiController /// /// The ID of the asset. /// The request parameters. - /// Asset found and content or (resized) image returned.. - /// Asset or app not found.. + /// Asset found and content or (resized) image returned. + /// Asset or app not found. [HttpGet] [Route("assets/{id}/")] [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetFoldersController.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetFoldersController.cs index 27fe42245..cc6db161c 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetFoldersController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetFoldersController.cs @@ -39,8 +39,8 @@ public sealed class AssetFoldersController : ApiController /// The name of the app. /// The optional parent folder id. /// The scope of the query. - /// Asset folders returned.. - /// App not found.. + /// Asset folders returned. + /// App not found. /// /// Get all asset folders for the app. /// @@ -90,9 +90,9 @@ public sealed class AssetFoldersController : ApiController /// /// The name of the app. /// The asset folder object that needs to be added to the App. - /// Asset folder created.. - /// Asset folder request not valid.. - /// App not found.. + /// Asset folder created. + /// Asset folder request not valid. + /// App not found. [HttpPost] [Route("apps/{app}/assets/folders", Order = -1)] [ProducesResponseType(typeof(AssetFolderDto), StatusCodes.Status201Created)] @@ -114,9 +114,9 @@ public sealed class AssetFoldersController : ApiController /// The name of the app. /// The ID of the asset folder. /// The asset folder object that needs to updated. - /// Asset folder updated.. - /// Asset folder request not valid.. - /// Asset folder or app not found.. + /// Asset folder updated. + /// Asset folder request not valid. + /// Asset folder or app not found. [HttpPut] [Route("apps/{app}/assets/folders/{id}/", Order = -1)] [ProducesResponseType(typeof(AssetFolderDto), StatusCodes.Status200OK)] @@ -138,9 +138,9 @@ public sealed class AssetFoldersController : ApiController /// The name of the app. /// The ID of the asset folder. /// The asset folder object that needs to updated. - /// Asset folder moved.. - /// Asset folder request not valid.. - /// Asset folder or app not found.. + /// Asset folder moved. + /// Asset folder request not valid. + /// Asset folder or app not found. [HttpPut] [Route("apps/{app}/assets/folders/{id}/parent", Order = -1)] [ProducesResponseType(typeof(AssetFolderDto), StatusCodes.Status200OK)] @@ -161,8 +161,8 @@ public sealed class AssetFoldersController : ApiController /// /// The name of the app. /// The ID of the asset folder to delete. - /// Asset folder deleted.. - /// Asset folder or app not found.. + /// Asset folder deleted. + /// Asset folder or app not found. [HttpDelete] [Route("apps/{app}/assets/folders/{id}/", Order = -1)] [ProducesResponseType(StatusCodes.Status204NoContent)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetsController.cs b/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetsController.cs index a5879b0db..d262bdbff 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetsController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Assets/AssetsController.cs @@ -58,8 +58,8 @@ public sealed class AssetsController : ApiController /// Get assets tags. /// /// The name of the app. - /// Assets tags returned.. - /// App not found.. + /// Assets tags returned. + /// App not found. /// /// Get all tags for assets. /// @@ -83,8 +83,8 @@ public sealed class AssetsController : ApiController /// The name of the app. /// The tag to return. /// The required request object. - /// Asset tag renamed and new tags returned.. - /// App not found.. + /// Asset tag renamed and new tags returned. + /// App not found. [HttpPut] [Route("apps/{app}/assets/tags/{name}")] [ProducesResponseType(typeof(Dictionary), StatusCodes.Status200OK)] @@ -104,8 +104,8 @@ public sealed class AssetsController : ApiController /// The optional parent folder id. /// The optional asset ids. /// The optional json query. - /// Assets returned.. - /// App not found.. + /// Assets returned. + /// App not found. /// /// Get all assets for the app. /// @@ -134,8 +134,8 @@ public sealed class AssetsController : ApiController /// /// The name of the app. /// The required query object. - /// Assets returned.. - /// App not found.. + /// Assets returned. + /// App not found. /// /// Get all assets for the app. /// @@ -163,8 +163,8 @@ public sealed class AssetsController : ApiController /// /// The name of the app. /// The ID of the asset to retrieve. - /// Asset found.. - /// Asset or app not found.. + /// Asset found. + /// Asset or app not found. [HttpGet] [Route("apps/{app}/assets/{id}/")] [ProducesResponseType(typeof(AssetDto), StatusCodes.Status200OK)] @@ -192,10 +192,10 @@ public sealed class AssetsController : ApiController /// /// The name of the app. /// The request parameters. - /// Asset created.. - /// Asset request not valid.. - /// Asset exceeds the maximum upload size.. - /// App not found.. + /// Asset created. + /// Asset request not valid. + /// Asset exceeds the maximum upload size. + /// App not found. /// /// You can only upload one file at a time. The mime type of the file is not calculated by Squidex and is required correctly. /// @@ -218,10 +218,10 @@ public sealed class AssetsController : ApiController /// Upload a new asset using tus.io. /// /// The name of the app. - /// Asset created.. - /// Asset request not valid.. - /// Asset exceeds the maximum upload size.. - /// App not found.. + /// Asset created. + /// Asset request not valid. + /// Asset exceeds the maximum upload size. + /// App not found. /// /// Use the tus protocol to upload an asset. /// @@ -254,9 +254,9 @@ public sealed class AssetsController : ApiController /// /// The name of the app. /// The bulk update request. - /// Assets created, update or delete.. - /// Assets request not valid.. - /// App not found.. + /// Assets created, update or delete. + /// Assets request not valid. + /// App not found. [HttpPost] [Route("apps/{app}/assets/bulk")] [ProducesResponseType(typeof(BulkResultDto[]), StatusCodes.Status200OK)] @@ -280,10 +280,10 @@ public sealed class AssetsController : ApiController /// The name of the app. /// The optional custom asset id. /// The request parameters. - /// Asset created or updated.. - /// Asset request not valid.. - /// Asset exceeds the maximum upload size.. - /// App not found.. + /// Asset created or updated. + /// Asset request not valid. + /// Asset exceeds the maximum upload size. + /// App not found. /// /// You can only upload one file at a time. The mime type of the file is not calculated by Squidex and is required correctly. /// @@ -308,10 +308,10 @@ public sealed class AssetsController : ApiController /// The name of the app. /// The ID of the asset. /// The file to upload. - /// Asset updated.. - /// Asset request not valid.. - /// Asset exceeds the maximum upload size.. - /// Asset or app not found.. + /// Asset updated. + /// Asset request not valid. + /// Asset exceeds the maximum upload size. + /// Asset or app not found. /// /// Use multipart request to upload an asset. /// @@ -336,9 +336,9 @@ public sealed class AssetsController : ApiController /// The name of the app. /// The ID of the asset. /// The asset object that needs to updated. - /// Asset updated.. - /// Asset request not valid.. - /// Asset or app not found.. + /// Asset updated. + /// Asset request not valid. + /// Asset or app not found. [HttpPut] [Route("apps/{app}/assets/{id}/")] [ProducesResponseType(typeof(AssetDto), StatusCodes.Status200OK)] @@ -360,9 +360,9 @@ public sealed class AssetsController : ApiController /// The name of the app. /// The ID of the asset. /// The asset object that needs to updated. - /// Asset moved.. - /// Asset request not valid.. - /// Asset or app not found.. + /// Asset moved. + /// Asset request not valid. + /// Asset or app not found. [HttpPut] [Route("apps/{app}/assets/{id}/parent")] [ProducesResponseType(typeof(AssetDto), StatusCodes.Status200OK)] @@ -384,8 +384,8 @@ public sealed class AssetsController : ApiController /// The name of the app. /// The ID of the asset to delete. /// The request parameters. - /// Asset deleted.. - /// Asset or app not found.. + /// Asset deleted. + /// Asset or app not found. [HttpDelete] [Route("apps/{app}/assets/{id}/")] [ProducesResponseType(StatusCodes.Status204NoContent)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Backups/BackupContentController.cs b/backend/src/Squidex/Areas/Api/Controllers/Backups/BackupContentController.cs index 77cb1644f..15199d298 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Backups/BackupContentController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Backups/BackupContentController.cs @@ -37,8 +37,8 @@ public class BackupContentController : ApiController /// /// The name of the app. /// The ID of the backup. - /// Backup found and content returned.. - /// Backup or app not found.. + /// Backup found and content returned. + /// Backup or app not found. [HttpGet] [Route("apps/{app}/backups/{id}")] [ResponseCache(Duration = 3600 * 24 * 30)] @@ -56,8 +56,8 @@ public class BackupContentController : ApiController /// The ID of the backup. /// The ID of the app. /// The name of the app. - /// Backup found and content returned.. - /// Backup or app not found.. + /// Backup found and content returned. + /// Backup or app not found. [HttpGet] [Route("apps/backups/{id}")] [ResponseCache(Duration = 3600 * 24 * 30)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Backups/BackupsController.cs b/backend/src/Squidex/Areas/Api/Controllers/Backups/BackupsController.cs index 080611e0e..75b7d9eb6 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Backups/BackupsController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Backups/BackupsController.cs @@ -34,8 +34,8 @@ public class BackupsController : ApiController /// Get all backup jobs. /// /// The name of the app. - /// Backups returned.. - /// App not found.. + /// Backups returned. + /// App not found. [HttpGet] [Route("apps/{app}/backups/")] [ProducesResponseType(typeof(BackupJobsDto), StatusCodes.Status200OK)] @@ -54,9 +54,9 @@ public class BackupsController : ApiController /// Start a new backup. /// /// The name of the app. - /// Backup started.. - /// Backup contingent reached.. - /// App not found.. + /// Backup started. + /// Backup contingent reached. + /// App not found. [HttpPost] [Route("apps/{app}/backups/")] [ProducesResponseType(StatusCodes.Status204NoContent)] @@ -74,8 +74,8 @@ public class BackupsController : ApiController /// /// The name of the app. /// The ID of the backup to delete. - /// Backup deleted.. - /// Backup or app not found.. + /// Backup deleted. + /// Backup or app not found. [HttpDelete] [Route("apps/{app}/backups/{id}")] [ProducesResponseType(StatusCodes.Status204NoContent)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Backups/RestoreController.cs b/backend/src/Squidex/Areas/Api/Controllers/Backups/RestoreController.cs index 09bf5ad81..dd93f220e 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Backups/RestoreController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Backups/RestoreController.cs @@ -33,7 +33,7 @@ public class RestoreController : ApiController /// /// Get current restore status. /// - /// Status returned.. + /// Status returned. [HttpGet] [Route("apps/restore/")] [ProducesResponseType(typeof(RestoreJobDto), StatusCodes.Status200OK)] @@ -56,7 +56,7 @@ public class RestoreController : ApiController /// Restore a backup. /// /// The backup to restore. - /// Restore operation started.. + /// Restore operation started. [HttpPost] [Route("apps/restore/")] [ProducesResponseType(StatusCodes.Status204NoContent)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Comments/CommentsController.cs b/backend/src/Squidex/Areas/Api/Controllers/Comments/CommentsController.cs index 4e3be2eff..e61b61d0d 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Comments/CommentsController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Comments/CommentsController.cs @@ -5,162 +5,40 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== -using System.Globalization; using Microsoft.AspNetCore.Mvc; -using Microsoft.Net.Http.Headers; -using Squidex.Areas.Api.Controllers.Comments.Models; -using Squidex.Domain.Apps.Entities.Comments; -using Squidex.Domain.Apps.Entities.Comments.Commands; +using Squidex.Domain.Apps.Entities.Apps; +using Squidex.Domain.Apps.Entities.Collaboration; using Squidex.Infrastructure; using Squidex.Infrastructure.Commands; +using Squidex.Infrastructure.Security; using Squidex.Shared; using Squidex.Web; +using YDotNet.Server.WebSockets; namespace Squidex.Areas.Api.Controllers.Comments; -/// -/// Update and query comments for any kind of app resource. -/// -[ApiExplorerSettings(GroupName = nameof(Comments))] public sealed class CommentsController : ApiController { - private readonly ICommentsLoader commentsLoader; - private readonly IWatchingService watchingService; + private readonly ICollaborationService collaboration; - public CommentsController(ICommandBus commandBus, ICommentsLoader commentsLoader, - IWatchingService watchingService) + public CommentsController(ICommandBus commandBus, ICollaborationService collaboration) : base(commandBus) { - this.commentsLoader = commentsLoader; - this.watchingService = watchingService; + this.collaboration = collaboration; } - /// - /// Get all watching users.. - /// - /// The name of the app. - /// The path to the resource. - /// Watching users returned.. - /// App not found.. - [HttpGet] - [Route("apps/{app}/watching/{*resource}")] - [ProducesResponseType(typeof(string[]), StatusCodes.Status200OK)] - [ApiPermissionOrAnonymous] - [ApiCosts(0)] - public async Task GetWatchingUsers(string app, string? resource = null) + [Route("users/collaboration")] + [ApiPermission] + public IActionResult UserDocument() { - var result = await watchingService.GetWatchingUsersAsync(App.Id, resource, UserId, HttpContext.RequestAborted); - - return Ok(result); + return new YDotNetActionResult(collaboration.UserDocument(User.UserOrClientId()!)); } - /// - /// Get all comments. - /// - /// The name of the app. - /// The ID of the comments. - /// The current version. - /// - /// When passing in a version you can retrieve all updates since then. - /// - /// Comments returned.. - /// App not found.. - [HttpGet] - [Route("apps/{app}/comments/{commentsId}")] - [ProducesResponseType(typeof(CommentsDto), StatusCodes.Status200OK)] + [Route("apps/{app}/collaboration/{commentsId}")] [ApiPermissionOrAnonymous(PermissionIds.AppCommentsRead)] [ApiCosts(0)] - public async Task GetComments(string app, DomainId commentsId, [FromQuery] long version = EtagVersion.Any) - { - var result = await commentsLoader.GetCommentsAsync(Id(commentsId), version, HttpContext.RequestAborted); - - var response = Deferred.Response(() => - { - return CommentsDto.FromDomain(result); - }); - - Response.Headers[HeaderNames.ETag] = result.Version.ToString(CultureInfo.InvariantCulture); - - return Ok(response); - } - - /// - /// Create a new comment. - /// - /// The name of the app. - /// The ID of the comments. - /// The comment object that needs to created. - /// Comment created.. - /// Comment request not valid.. - /// App not found.. - [HttpPost] - [Route("apps/{app}/comments/{commentsId}")] - [ProducesResponseType(typeof(CommentDto), 201)] - [ApiPermissionOrAnonymous(PermissionIds.AppCommentsCreate)] - [ApiCosts(0)] - public async Task PostComment(string app, DomainId commentsId, [FromBody] UpsertCommentDto request) - { - var command = request.ToCreateCommand(commentsId); - - await CommandBus.PublishAsync(command, HttpContext.RequestAborted); - - var response = CommentDto.FromDomain(command); - - return CreatedAtAction(nameof(GetComments), new { app, commentsId }, response); - } - - /// - /// Update a comment. - /// - /// The name of the app. - /// The ID of the comments. - /// The ID of the comment. - /// The comment object that needs to updated. - /// Comment updated.. - /// Comment request not valid.. - /// Comment or app not found.. - [HttpPut] - [Route("apps/{app}/comments/{commentsId}/{commentId}")] - [ProducesResponseType(StatusCodes.Status204NoContent)] - [ApiPermissionOrAnonymous(PermissionIds.AppCommentsUpdate)] - [ApiCosts(0)] - public async Task PutComment(string app, DomainId commentsId, DomainId commentId, [FromBody] UpsertCommentDto request) - { - var command = request.ToUpdateComment(commentsId, commentId); - - await CommandBus.PublishAsync(command, HttpContext.RequestAborted); - - return NoContent(); - } - - /// - /// Delete a comment. - /// - /// The name of the app. - /// The ID of the comments. - /// The ID of the comment. - /// Comment deleted.. - /// Comment or app not found.. - [HttpDelete] - [Route("apps/{app}/comments/{commentsId}/{commentId}")] - [ProducesResponseType(StatusCodes.Status204NoContent)] - [ApiPermissionOrAnonymous(PermissionIds.AppCommentsDelete)] - [ApiCosts(0)] - public async Task DeleteComment(string app, DomainId commentsId, DomainId commentId) - { - var command = new DeleteComment - { - CommentsId = commentsId, - CommentId = commentId - }; - - await CommandBus.PublishAsync(command, HttpContext.RequestAborted); - - return NoContent(); - } - - private DomainId Id(DomainId commentsId) + public IActionResult CollaborationDocument(string app, DomainId commentsId) { - return DomainId.Combine(App.Id, commentsId); + return new YDotNetActionResult(collaboration.ResourceDocument(App.NamedId(), commentsId)); } } diff --git a/backend/src/Squidex/Areas/Api/Controllers/Comments/Models/CommentDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Comments/Models/CommentDto.cs deleted file mode 100644 index bece5d04b..000000000 --- a/backend/src/Squidex/Areas/Api/Controllers/Comments/Models/CommentDto.cs +++ /dev/null @@ -1,56 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using NodaTime; -using Squidex.Domain.Apps.Core.Comments; -using Squidex.Domain.Apps.Entities.Comments.Commands; -using Squidex.Infrastructure; -using Squidex.Infrastructure.Reflection; - -namespace Squidex.Areas.Api.Controllers.Comments.Models; - -public sealed class CommentDto -{ - /// - /// The ID of the comment. - /// - public DomainId Id { get; set; } - - /// - /// The time when the comment was created or updated last. - /// - public Instant Time { get; set; } - - /// - /// The user who created or updated the comment. - /// - public RefToken User { get; set; } - - /// - /// The text of the comment. - /// - public string Text { get; set; } - - /// - /// The url where the comment is created. - /// - public Uri? Url { get; set; } - - public static CommentDto FromDomain(Comment comment) - { - var result = SimpleMapper.Map(comment, new CommentDto()); - - return result; - } - - public static CommentDto FromDomain(CreateComment command) - { - var time = SystemClock.Instance.GetCurrentInstant(); - - return SimpleMapper.Map(command, new CommentDto { Id = command.CommentId, User = command.Actor, Time = time }); - } -} diff --git a/backend/src/Squidex/Areas/Api/Controllers/Comments/Models/CommentsDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Comments/Models/CommentsDto.cs deleted file mode 100644 index e2046e616..000000000 --- a/backend/src/Squidex/Areas/Api/Controllers/Comments/Models/CommentsDto.cs +++ /dev/null @@ -1,47 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using Squidex.Domain.Apps.Entities.Comments; -using Squidex.Infrastructure; - -namespace Squidex.Areas.Api.Controllers.Comments.Models; - -public sealed class CommentsDto -{ - /// - /// The created comments including the updates. - /// - public CommentDto[]? CreatedComments { get; set; } - - /// - /// The updates comments since the last version. - /// - public CommentDto[]? UpdatedComments { get; set; } - - /// - /// The deleted comments since the last version. - /// - public List? DeletedComments { get; set; } - - /// - /// The current version. - /// - public long Version { get; set; } - - public static CommentsDto FromDomain(CommentsResult comments) - { - var result = new CommentsDto - { - CreatedComments = comments.CreatedComments.Select(CommentDto.FromDomain).ToArray(), - UpdatedComments = comments.UpdatedComments.Select(CommentDto.FromDomain).ToArray(), - DeletedComments = comments.DeletedComments, - Version = comments.Version - }; - - return result; - } -} diff --git a/backend/src/Squidex/Areas/Api/Controllers/Comments/Models/UpsertCommentDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Comments/Models/UpsertCommentDto.cs deleted file mode 100644 index 0dfa2d6e9..000000000 --- a/backend/src/Squidex/Areas/Api/Controllers/Comments/Models/UpsertCommentDto.cs +++ /dev/null @@ -1,46 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using Squidex.Domain.Apps.Entities.Comments.Commands; -using Squidex.Infrastructure; -using Squidex.Infrastructure.Reflection; -using Squidex.Infrastructure.Validation; -using Squidex.Web; - -namespace Squidex.Areas.Api.Controllers.Comments.Models; - -[OpenApiRequest] -public sealed class UpsertCommentDto -{ - /// - /// The comment text. - /// - [LocalizedRequired] - public string Text { get; set; } - - /// - /// The url where the comment is created. - /// - public Uri? Url { get; set; } - - public CreateComment ToCreateCommand(DomainId commentsId) - { - return SimpleMapper.Map(this, new CreateComment - { - CommentsId = commentsId - }); - } - - public UpdateComment ToUpdateComment(DomainId commentsId, DomainId commentId) - { - return SimpleMapper.Map(this, new UpdateComment - { - CommentsId = commentsId, - CommentId = commentId - }); - } -} diff --git a/backend/src/Squidex/Areas/Api/Controllers/Comments/Notifications/UserNotificationsController.cs b/backend/src/Squidex/Areas/Api/Controllers/Comments/Notifications/UserNotificationsController.cs deleted file mode 100644 index bb07151b9..000000000 --- a/backend/src/Squidex/Areas/Api/Controllers/Comments/Notifications/UserNotificationsController.cs +++ /dev/null @@ -1,99 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using System.Globalization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Net.Http.Headers; -using Squidex.Areas.Api.Controllers.Comments.Models; -using Squidex.Domain.Apps.Entities.Comments; -using Squidex.Domain.Apps.Entities.Comments.Commands; -using Squidex.Infrastructure; -using Squidex.Infrastructure.Commands; -using Squidex.Infrastructure.Security; -using Squidex.Infrastructure.Translations; -using Squidex.Web; - -namespace Squidex.Areas.Api.Controllers.Comments.Notifications; - -/// -/// Update and query user notifications. -/// -[ApiExplorerSettings(GroupName = nameof(Notifications))] -public sealed class UserNotificationsController : ApiController -{ - private readonly ICommentsLoader commentsLoader; - - public UserNotificationsController(ICommandBus commandBus, ICommentsLoader commentsLoader) - : base(commandBus) - { - this.commentsLoader = commentsLoader; - } - - /// - /// Get all notifications. - /// - /// The user id. - /// The current version. - /// - /// When passing in a version you can retrieve all updates since then. - /// - /// All comments returned.. - [HttpGet] - [Route("users/{userId}/notifications")] - [ProducesResponseType(typeof(CommentsDto), StatusCodes.Status200OK)] - [ApiPermission] - public async Task GetNotifications(DomainId userId, [FromQuery] long version = EtagVersion.Any) - { - CheckPermissions(userId); - - var result = await commentsLoader.GetCommentsAsync(userId, version, HttpContext.RequestAborted); - - var response = Deferred.Response(() => - { - return CommentsDto.FromDomain(result); - }); - - Response.Headers[HeaderNames.ETag] = result.Version.ToString(CultureInfo.InvariantCulture); - - return Ok(response); - } - - /// - /// Delete a notification. - /// - /// The user id. - /// The ID of the comment. - /// Comment deleted.. - /// Comment not found.. - [HttpDelete] - [Route("users/{userId}/notifications/{commentId}")] - [ProducesResponseType(StatusCodes.Status204NoContent)] - [ApiPermission] - public async Task DeleteComment(DomainId userId, DomainId commentId) - { - CheckPermissions(userId); - - var commmand = new DeleteComment - { - AppId = CommentsCommand.NoApp, - CommentsId = userId, - CommentId = commentId - }; - - await CommandBus.PublishAsync(commmand, HttpContext.RequestAborted); - - return NoContent(); - } - - private void CheckPermissions(DomainId userId) - { - if (!string.Equals(userId.ToString(), User.OpenIdSubject(), StringComparison.Ordinal)) - { - throw new DomainForbiddenException(T.Get("comments.noPermissions")); - } - } -} diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs index f508d3052..8b83ded1b 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs @@ -43,8 +43,8 @@ public sealed class ContentsController : ApiController /// The name of the app. /// The name of the schema. /// The number of items to skip. - /// Contents returned.. - /// Schema or app not found.. + /// Contents returned. + /// Schema or app not found. /// /// You can read the generated documentation for your app at /api/content/{appName}/docs. /// @@ -68,8 +68,8 @@ public sealed class ContentsController : ApiController /// The name of the schema. /// The optional ids of the content to fetch. /// The optional json query. - /// Contents returned.. - /// Schema or app not found.. + /// Contents returned. + /// Schema or app not found. /// /// You can read the generated documentation for your app at /api/content/{appName}/docs. /// @@ -103,8 +103,8 @@ public sealed class ContentsController : ApiController /// The name of the app. /// The name of the schema. /// The required query object. - /// Contents returned.. - /// Schema or app not found.. + /// Contents returned. + /// Schema or app not found. /// /// You can read the generated documentation for your app at /api/content/{appName}/docs. /// @@ -138,8 +138,8 @@ public sealed class ContentsController : ApiController /// The name of the schema. /// The ID of the content to fetch. /// The optional version. - /// Content returned.. - /// Content, schema or app not found.. + /// Content returned. + /// Content, schema or app not found. /// /// You can read the generated documentation for your app at /api/content/{appName}/docs. /// @@ -175,9 +175,9 @@ public sealed class ContentsController : ApiController /// The name of the app. /// The name of the schema. /// The ID of the content to fetch. - /// Content is valid.. - /// Content not valid.. - /// Content, schema or app not found.. + /// Content is valid. + /// Content not valid. + /// Content, schema or app not found. /// /// You can read the generated documentation for your app at /api/content/{appName}/docs. /// @@ -202,8 +202,8 @@ public sealed class ContentsController : ApiController /// The name of the schema. /// The ID of the content to fetch. /// The optional json query. - /// Contents returned.. - /// Content, schema or app not found.. + /// Contents returned. + /// Content, schema or app not found. /// /// You can read the generated documentation for your app at /api/content/{appName}/docs. /// @@ -237,8 +237,8 @@ public sealed class ContentsController : ApiController /// The name of the schema. /// The ID of the content to fetch. /// The optional json query. - /// Content returned.. - /// Content, schema or app not found.. + /// Content returned. + /// Content, schema or app not found. /// /// You can read the generated documentation for your app at /api/content/{appName}/docs. /// @@ -272,8 +272,8 @@ public sealed class ContentsController : ApiController /// The name of the schema. /// The ID of the content to fetch. /// The version fo the content to fetch. - /// Content version returned.. - /// Content, schema or app not found.. + /// Content version returned. + /// Content, schema or app not found. /// /// You can read the generated documentation for your app at /api/content/{appName}/docs. /// @@ -307,9 +307,9 @@ public sealed class ContentsController : ApiController /// The name of the app. /// The name of the schema. /// The request parameters. - /// Content created.. - /// Content request not valid.. - /// Content, schema or app not found.. + /// Content created. + /// Content request not valid. + /// Content, schema or app not found. /// /// You can read the generated documentation for your app at /api/content/{appName}/docs. /// @@ -335,9 +335,9 @@ public sealed class ContentsController : ApiController /// The name of the app. /// The name of the schema. /// The import request. - /// Contents created.. - /// Content request not valid.. - /// Content references, schema or app not found.. + /// Contents created. + /// Content request not valid. + /// Content references, schema or app not found. /// /// You can read the generated documentation for your app at /api/content/{appName}/docs. /// @@ -365,9 +365,9 @@ public sealed class ContentsController : ApiController /// The name of the app. /// The name of the schema. /// The bulk update request. - /// Contents created, update or delete.. - /// Contents request not valid.. - /// Contents references, schema or app not found.. + /// Contents created, update or delete. + /// Contents request not valid. + /// Contents references, schema or app not found. /// /// You can read the generated documentation for your app at /api/content/{appName}/docs. /// @@ -395,9 +395,9 @@ public sealed class ContentsController : ApiController /// The name of the schema. /// The ID of the content item to update. /// The request parameters. - /// Content created or updated.. - /// Content request not valid.. - /// Content references, schema or app not found.. + /// Content created or updated. + /// Content request not valid. + /// Content references, schema or app not found. /// /// You can read the generated documentation for your app at /api/content/{appName}/docs. /// @@ -424,9 +424,9 @@ public sealed class ContentsController : ApiController /// The name of the schema. /// The ID of the content item to update. /// The full data for the content item. - /// Content updated.. - /// Content request not valid.. - /// Content references, schema or app not found.. + /// Content updated. + /// Content request not valid. + /// Content references, schema or app not found. /// /// You can read the generated documentation for your app at /api/content/{appName}/docs. /// @@ -453,9 +453,9 @@ public sealed class ContentsController : ApiController /// The name of the schema. /// The ID of the content item to patch. /// The patch for the content item. - /// Content patched.. - /// Content request not valid.. - /// Content, schema or app not found.. + /// Content patched. + /// Content request not valid. + /// Content, schema or app not found. /// /// You can read the generated documentation for your app at /api/content/{appName}/docs. /// @@ -482,9 +482,9 @@ public sealed class ContentsController : ApiController /// The name of the schema. /// The ID of the content item to change. /// The status request. - /// Content status changed.. - /// Content request not valid.. - /// Content, schema or app not found.. + /// Content status changed. + /// Content request not valid. + /// Content, schema or app not found. /// /// You can read the generated documentation for your app at /api/content/{appName}/docs. /// @@ -510,9 +510,9 @@ public sealed class ContentsController : ApiController /// The name of the app. /// The name of the schema. /// The ID of the content item to cancel. - /// Content status change cancelled.. - /// Content request not valid.. - /// Content, schema or app not found.. + /// Content status change cancelled. + /// Content request not valid. + /// Content, schema or app not found. /// /// You can read the generated documentation for your app at /api/content/{appName}/docs. /// @@ -538,8 +538,8 @@ public sealed class ContentsController : ApiController /// The name of the app. /// The name of the schema. /// The ID of the content item to create the draft for. - /// Content draft created.. - /// Content, schema or app not found.. + /// Content draft created. + /// Content, schema or app not found. /// /// You can read the generated documentation for your app at /api/content/{appName}/docs. /// @@ -565,8 +565,8 @@ public sealed class ContentsController : ApiController /// The name of the app. /// The name of the schema. /// The ID of the content item to delete the draft from. - /// Content draft deleted.. - /// Content, schema or app not found.. + /// Content draft deleted. + /// Content, schema or app not found. /// /// You can read the generated documentation for your app at /api/content/{appName}/docs. /// @@ -593,9 +593,9 @@ public sealed class ContentsController : ApiController /// The name of the schema. /// The ID of the content item to delete. /// The request parameters. - /// Content deleted.. - /// Content cannot be deleted.. - /// Content, schema or app not found.. + /// Content deleted. + /// Content cannot be deleted. + /// Content, schema or app not found. /// /// You can create an generated documentation for your app at /api/content/{appName}/docs. /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsSharedController.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsSharedController.cs index 93a2c54cc..32b219f30 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsSharedController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/ContentsSharedController.cs @@ -21,6 +21,7 @@ using Squidex.Web.Pipeline; namespace Squidex.Areas.Api.Controllers.Contents; [SchemaMustBePublished] +[ApiExplorerSettings(GroupName = nameof(Contents))] public sealed class ContentsSharedController : ApiController { private readonly IContentQueryService contentQuery; @@ -39,18 +40,97 @@ public sealed class ContentsSharedController : ApiController /// GraphQL endpoint. /// /// The name of the app. - /// Contents returned or mutated.. - /// App not found.. + /// The request parameters. + /// Contents returned or mutated. + /// App not found. /// /// You can read the generated documentation for your app at /api/content/{appName}/docs. /// [Route("content/{app}/graphql/")] - [Route("content/{app}/graphql/batch")] + [ProducesResponseType(typeof(object), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous] [ApiCosts(2)] [AcceptHeader.Unpublished] [IgnoreCacheFilter] - public IActionResult GetGraphQL(string app) + public IActionResult GetGraphQL(string app, GraphQLQueryDto request) + { + var options = new GraphQLHttpMiddlewareOptions + { + DefaultResponseContentType = new MediaTypeHeaderValue("application/json") + }; + + return new GraphQLExecutionActionResult(options); + } + + /// + /// GraphQL endpoint. + /// + /// The name of the app. + /// Contents returned or mutated. + /// App not found. + /// + /// You can read the generated documentation for your app at /api/content/{appName}/docs. + /// + [HttpPost("content/{app}/graphql/")] + [ProducesResponseType(typeof(object), StatusCodes.Status200OK)] + [ApiPermissionOrAnonymous] + [ApiCosts(2)] + [AcceptAnyBody] + [AcceptHeader.Unpublished] + [IgnoreCacheFilter] + public IActionResult PostGraphQL(string app) + { + var options = new GraphQLHttpMiddlewareOptions + { + DefaultResponseContentType = new MediaTypeHeaderValue("application/json") + }; + + return new GraphQLExecutionActionResult(options); + } + + /// + /// GraphQL batch endpoint. + /// + /// The name of the app. + /// The request object. + /// Contents returned or mutated. + /// App not found. + /// + /// You can read the generated documentation for your app at /api/content/{appName}/docs. + /// + [HttpGet("content/{app}/graphql/batch")] + [ProducesResponseType(typeof(object), StatusCodes.Status200OK)] + [ApiPermissionOrAnonymous] + [ApiCosts(2)] + [AcceptHeader.Unpublished] + [IgnoreCacheFilter] + public IActionResult GetGraphQLBatch(string app, GraphQLQueryDto request) + { + var options = new GraphQLHttpMiddlewareOptions + { + DefaultResponseContentType = new MediaTypeHeaderValue("application/json") + }; + + return new GraphQLExecutionActionResult(options); + } + + /// + /// GraphQL batch endpoint. + /// + /// The name of the app. + /// Contents returned or mutated. + /// App not found. + /// + /// You can read the generated documentation for your app at /api/content/{appName}/docs. + /// + [HttpPost("content/{app}/graphql/batch")] + [ProducesResponseType(typeof(object), StatusCodes.Status200OK)] + [ApiPermissionOrAnonymous] + [ApiCosts(2)] + [AcceptAnyBody] + [AcceptHeader.Unpublished] + [IgnoreCacheFilter] + public IActionResult PostGraphQLBatch(string app) { var options = new GraphQLHttpMiddlewareOptions { @@ -65,8 +145,8 @@ public sealed class ContentsSharedController : ApiController /// /// The name of the app. /// The query object. - /// Contents returned.. - /// App not found.. + /// Contents returned. + /// App not found. /// /// You can read the generated documentation for your app at /api/content/{appName}/docs. /// @@ -98,8 +178,8 @@ public sealed class ContentsSharedController : ApiController /// /// The name of the app. /// The required query object. - /// Contents returned.. - /// App not found.. + /// Contents returned. + /// App not found. /// /// You can read the generated documentation for your app at /api/content/{appName}/docs. /// @@ -132,9 +212,9 @@ public sealed class ContentsSharedController : ApiController /// The name of the app. /// The name of the schema. /// The bulk update request. - /// Contents created, update or delete.. - /// Contents request not valid.. - /// Contents references, schema or app not found.. + /// Contents created, update or delete. + /// Contents request not valid. + /// Contents references, schema or app not found. /// /// You can read the generated documentation for your app at /api/content/{appName}/docs. /// @@ -143,7 +223,7 @@ public sealed class ContentsSharedController : ApiController [ProducesResponseType(typeof(BulkResultDto[]), StatusCodes.Status200OK)] [ApiPermissionOrAnonymous(PermissionIds.AppContentsReadOwn)] [ApiCosts(5)] - public async Task BulkUpdateContents(string app, string schema, [FromBody] BulkUpdateContentsDto request) + public async Task BulkUpdateAllContents(string app, string schema, [FromBody] BulkUpdateContentsDto request) { var command = request.ToCommand(true); diff --git a/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/GraphQLQueryDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/GraphQLQueryDto.cs new file mode 100644 index 000000000..8e11f52f6 --- /dev/null +++ b/backend/src/Squidex/Areas/Api/Controllers/Contents/Models/GraphQLQueryDto.cs @@ -0,0 +1,31 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Microsoft.AspNetCore.Mvc; + +namespace Squidex.Areas.Api.Controllers.Contents.Models; + +public sealed class GraphQLQueryDto +{ + /// + /// The optional version of the asset. + /// + [FromQuery(Name = "The query string")] + public string Query { get; set; } + + /// + /// The optional operation variables. + /// + [FromQuery(Name = "variables")] + public string? Variables { get; set; } + + /// + /// The optional operation name. + /// + [FromQuery(Name = "operationName")] + public string? OperationName { get; set; } +} diff --git a/backend/src/Squidex/Areas/Api/Controllers/Diagnostics/DiagnosticsController.cs b/backend/src/Squidex/Areas/Api/Controllers/Diagnostics/DiagnosticsController.cs index 371a0c185..a91cb1ffa 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Diagnostics/DiagnosticsController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Diagnostics/DiagnosticsController.cs @@ -30,8 +30,8 @@ public sealed class DiagnosticsController : ApiController /// /// Creates a dump and writes it into storage.. /// - /// Dump created successful.. - /// Not configured.. + /// Dump created successful. + /// Not configured. [HttpGet] [Route("diagnostics/dump")] [ProducesResponseType(StatusCodes.Status204NoContent)] @@ -51,8 +51,8 @@ public sealed class DiagnosticsController : ApiController /// /// Creates a gc dump and writes it into storage. /// - /// Dump created successful.. - /// Not configured.. + /// Dump created successful. + /// Not configured. [HttpGet] [Route("diagnostics/gcdump")] [ProducesResponseType(StatusCodes.Status204NoContent)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/EventConsumers/EventConsumersController.cs b/backend/src/Squidex/Areas/Api/Controllers/EventConsumers/EventConsumersController.cs index df5058cb9..3017d42be 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/EventConsumers/EventConsumersController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/EventConsumers/EventConsumersController.cs @@ -31,7 +31,7 @@ public sealed class EventConsumersController : ApiController /// /// Get event consumers. /// - /// Event consumers returned.. + /// Event consumers returned. [HttpGet] [Route("event-consumers/")] [ProducesResponseType(typeof(EventConsumersDto), StatusCodes.Status200OK)] @@ -49,8 +49,8 @@ public sealed class EventConsumersController : ApiController /// Start an event consumer. /// /// The name of the event consumer. - /// Event consumer started asynchronously.. - /// Event consumer not found.. + /// Event consumer started asynchronously. + /// Event consumer not found. [HttpPut] [Route("event-consumers/{consumerName}/start/")] [ProducesResponseType(typeof(EventConsumerDto), StatusCodes.Status200OK)] @@ -68,8 +68,8 @@ public sealed class EventConsumersController : ApiController /// Stop an event consumer. /// /// The name of the event consumer. - /// Event consumer stopped asynchronously.. - /// Event consumer not found.. + /// Event consumer stopped asynchronously. + /// Event consumer not found. [HttpPut] [Route("event-consumers/{consumerName}/stop/")] [ProducesResponseType(typeof(EventConsumerDto), StatusCodes.Status200OK)] @@ -87,8 +87,8 @@ public sealed class EventConsumersController : ApiController /// Reset an event consumer. /// /// The name of the event consumer. - /// Event consumer resetted asynchronously.. - /// Event consumer not found.. + /// Event consumer resetted asynchronously. + /// Event consumer not found. [HttpPut] [Route("event-consumers/{consumerName}/reset/")] [ProducesResponseType(typeof(EventConsumerDto), StatusCodes.Status200OK)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/History/HistoryController.cs b/backend/src/Squidex/Areas/Api/Controllers/History/HistoryController.cs index 675078c98..5be7085bd 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/History/HistoryController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/History/HistoryController.cs @@ -33,8 +33,8 @@ public sealed class HistoryController : ApiController /// /// The name of the app. /// The name of the channel. - /// Events returned.. - /// App not found.. + /// Events returned. + /// App not found. [HttpGet] [Route("apps/{app}/history/")] [ProducesResponseType(typeof(HistoryEventDto[]), StatusCodes.Status200OK)] @@ -54,8 +54,8 @@ public sealed class HistoryController : ApiController /// /// The ID of the team. /// The name of the channel. - /// Events returned.. - /// Team not found.. + /// Events returned. + /// Team not found. [HttpGet] [Route("teams/{team}/history/")] [ProducesResponseType(typeof(HistoryEventDto[]), StatusCodes.Status200OK)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Languages/LanguagesController.cs b/backend/src/Squidex/Areas/Api/Controllers/Languages/LanguagesController.cs index fd30e5e80..99343debd 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Languages/LanguagesController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Languages/LanguagesController.cs @@ -30,7 +30,7 @@ public sealed class LanguagesController : ApiController /// /// Provide a list of supported language codes, following the ISO2Code standard. /// - /// Supported language codes returned.. + /// Supported language codes returned. [HttpGet] [Route("languages/")] [ProducesResponseType(typeof(LanguageDto[]), StatusCodes.Status200OK)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/News/NewsController.cs b/backend/src/Squidex/Areas/Api/Controllers/News/NewsController.cs index 01a827364..f9780725a 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/News/NewsController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/News/NewsController.cs @@ -31,7 +31,7 @@ public sealed class NewsController : ApiController /// Get features since version. /// /// The latest received version. - /// Latest features returned.. + /// Latest features returned. [HttpGet] [Route("news/features/")] [ProducesResponseType(typeof(FeaturesDto), StatusCodes.Status200OK)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Ping/PingController.cs b/backend/src/Squidex/Areas/Api/Controllers/Ping/PingController.cs index feb38ba74..e45d4a759 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Ping/PingController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Ping/PingController.cs @@ -29,7 +29,7 @@ public sealed class PingController : ApiController /// /// Get API information. /// - /// Infos returned.. + /// Infos returned. [HttpGet] [Route("info/")] [ProducesResponseType(typeof(ExposedValues), StatusCodes.Status200OK)] @@ -41,7 +41,7 @@ public sealed class PingController : ApiController /// /// Get ping status of the API. /// - /// Service ping successful.. + /// Service ping successful. /// /// Can be used to test, if the Squidex API is alive and responding. /// @@ -57,7 +57,7 @@ public sealed class PingController : ApiController /// Get ping status. /// /// The name of the app. - /// Service ping successful.. + /// Service ping successful. /// /// Can be used to test, if the Squidex API is alive and responding. /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Plans/AppPlansController.cs b/backend/src/Squidex/Areas/Api/Controllers/Plans/AppPlansController.cs index 8f8335ec8..cd16967f8 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Plans/AppPlansController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Plans/AppPlansController.cs @@ -43,8 +43,8 @@ public sealed class AppPlansController : ApiController /// Get app plan information. /// /// The name of the app. - /// App plan information returned.. - /// App not found.. + /// App plan information returned. + /// App not found. [HttpGet] [Route("apps/{app}/plans/")] [ProducesResponseType(typeof(PlansDto), StatusCodes.Status200OK)] @@ -101,9 +101,9 @@ public sealed class AppPlansController : ApiController /// /// The name of the app. /// Plan object that needs to be changed. - /// Plan changed or redirect url returned.. - /// Plan not owned by user.. - /// App not found.. + /// Plan changed or redirect url returned. + /// Plan not owned by user. + /// App not found. [HttpPut] [Route("apps/{app}/plan/")] [ProducesResponseType(typeof(PlanChangedDto), StatusCodes.Status200OK)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Plans/TeamPlansController.cs b/backend/src/Squidex/Areas/Api/Controllers/Plans/TeamPlansController.cs index 3cacfe48d..8985a15f8 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Plans/TeamPlansController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Plans/TeamPlansController.cs @@ -43,8 +43,8 @@ public sealed class TeamPlansController : ApiController /// Get team plan information. /// /// The name of the team. - /// Team plan information returned.. - /// Team not found.. + /// Team plan information returned. + /// Team not found. [HttpGet] [Route("teams/{team}/plans/")] [ProducesResponseType(typeof(PlansDto), StatusCodes.Status200OK)] @@ -90,8 +90,8 @@ public sealed class TeamPlansController : ApiController /// /// The name of the team. /// Plan object that needs to be changed. - /// Plan changed or redirect url returned.. - /// Team not found.. + /// Plan changed or redirect url returned. + /// Team not found. [HttpPut] [Route("teams/{team}/plan/")] [ProducesResponseType(typeof(PlanChangedDto), StatusCodes.Status200OK)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Rules/RulesController.cs b/backend/src/Squidex/Areas/Api/Controllers/Rules/RulesController.cs index 767d3823d..37df73f64 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Rules/RulesController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Rules/RulesController.cs @@ -58,7 +58,7 @@ public sealed class RulesController : ApiController /// /// Get supported rule actions. /// - /// Rule actions returned.. + /// Rule actions returned. [HttpGet] [Route("rules/actions/")] [ProducesResponseType(typeof(Dictionary), StatusCodes.Status200OK)] @@ -82,8 +82,8 @@ public sealed class RulesController : ApiController /// Get rules. /// /// The name of the app. - /// Rules returned.. - /// App not found.. + /// Rules returned. + /// App not found. [HttpGet] [Route("apps/{app}/rules/")] [ProducesResponseType(typeof(RulesDto), StatusCodes.Status200OK)] @@ -106,9 +106,9 @@ public sealed class RulesController : ApiController /// /// The name of the app. /// The rule object that needs to be added to the app. - /// Rule created.. - /// Rule request not valid.. - /// App not found.. + /// Rule created. + /// Rule request not valid. + /// App not found. [HttpPost] [Route("apps/{app}/rules/")] [ProducesResponseType(typeof(RuleDto), 201)] @@ -127,7 +127,7 @@ public sealed class RulesController : ApiController /// Cancel the current run. /// /// The name of the app. - /// Rule run cancelled.. + /// Rule run cancelled. [HttpDelete] [Route("apps/{app}/rules/run")] [ProducesResponseType(StatusCodes.Status204NoContent)] @@ -146,9 +146,9 @@ public sealed class RulesController : ApiController /// The name of the app. /// The ID of the rule to update. /// The rule object that needs to be added to the app. - /// Rule updated.. - /// Rule request not valid.. - /// Rule or app not found.. + /// Rule updated. + /// Rule request not valid. + /// Rule or app not found. [HttpPut] [Route("apps/{app}/rules/{id}/")] [ProducesResponseType(typeof(RuleDto), StatusCodes.Status200OK)] @@ -168,8 +168,8 @@ public sealed class RulesController : ApiController /// /// The name of the app. /// The ID of the rule to enable. - /// Rule enabled.. - /// Rule or app not found.. + /// Rule enabled. + /// Rule or app not found. [HttpPut] [Route("apps/{app}/rules/{id}/enable/")] [ProducesResponseType(typeof(RuleDto), StatusCodes.Status200OK)] @@ -189,8 +189,8 @@ public sealed class RulesController : ApiController /// /// The name of the app. /// The ID of the rule to disable. - /// Rule disabled.. - /// Rule or app not found.. + /// Rule disabled. + /// Rule or app not found. [HttpPut] [Route("apps/{app}/rules/{id}/disable/")] [ProducesResponseType(typeof(RuleDto), StatusCodes.Status200OK)] @@ -210,8 +210,8 @@ public sealed class RulesController : ApiController /// /// The name of the app. /// The ID of the rule to disable. - /// Rule triggered.. - /// Rule or app not found.. + /// Rule triggered. + /// Rule or app not found. [HttpPut] [Route("apps/{app}/rules/{id}/trigger/")] [ProducesResponseType(StatusCodes.Status204NoContent)] @@ -232,7 +232,7 @@ public sealed class RulesController : ApiController /// The name of the app. /// The ID of the rule to run. /// Runs the rule from snapeshots if possible. - /// Rule started.. + /// Rule started. [HttpPut] [Route("apps/{app}/rules/{id}/run")] [ProducesResponseType(StatusCodes.Status204NoContent)] @@ -250,7 +250,7 @@ public sealed class RulesController : ApiController /// /// The name of the app. /// The ID of the rule to cancel. - /// Rule events cancelled.. + /// Rule events cancelled. [HttpDelete] [Route("apps/{app}/rules/{id}/events/")] [ProducesResponseType(StatusCodes.Status204NoContent)] @@ -268,8 +268,8 @@ public sealed class RulesController : ApiController /// /// The name of the app. /// The rule to simulate. - /// Rule simulated.. - /// Rule or app not found.. + /// Rule simulated. + /// Rule or app not found. [HttpPost] [Route("apps/{app}/rules/simulate/")] [ProducesResponseType(typeof(SimulatedRuleEventsDto), StatusCodes.Status200OK)] @@ -291,8 +291,8 @@ public sealed class RulesController : ApiController /// /// The name of the app. /// The ID of the rule to simulate. - /// Rule simulated.. - /// Rule or app not found.. + /// Rule simulated. + /// Rule or app not found. [HttpGet] [Route("apps/{app}/rules/{id}/simulate/")] [ProducesResponseType(typeof(SimulatedRuleEventsDto), StatusCodes.Status200OK)] @@ -319,8 +319,8 @@ public sealed class RulesController : ApiController /// /// The name of the app. /// The ID of the rule to delete. - /// Rule deleted.. - /// Rule or app not found.. + /// Rule deleted. + /// Rule or app not found. [HttpDelete] [Route("apps/{app}/rules/{id}/")] [ProducesResponseType(StatusCodes.Status204NoContent)] @@ -342,8 +342,8 @@ public sealed class RulesController : ApiController /// The optional rule id to filter to events. /// The number of events to skip. /// The number of events to take. - /// Rule events returned.. - /// App not found.. + /// Rule events returned. + /// App not found. [HttpGet] [Route("apps/{app}/rules/events/")] [ProducesResponseType(typeof(RuleEventsDto), StatusCodes.Status200OK)] @@ -363,8 +363,8 @@ public sealed class RulesController : ApiController /// /// The name of the app. /// The event to enqueue. - /// Rule enqueued.. - /// App or rule event not found.. + /// Rule enqueued. + /// App or rule event not found. [HttpPut] [Route("apps/{app}/rules/events/{id}/")] [ProducesResponseType(StatusCodes.Status204NoContent)] @@ -389,8 +389,8 @@ public sealed class RulesController : ApiController /// /// The name of the app. /// The event to cancel. - /// Rule event cancelled.. - /// App or rule event not found.. + /// Rule event cancelled. + /// App or rule event not found. [HttpDelete] [Route("apps/{app}/rules/events/{id}/")] [ProducesResponseType(StatusCodes.Status204NoContent)] @@ -414,7 +414,7 @@ public sealed class RulesController : ApiController /// Cancels all events. /// /// The name of the app. - /// Events cancelled.. + /// Events cancelled. [HttpDelete] [Route("apps/{app}/rules/events/")] [ProducesResponseType(StatusCodes.Status204NoContent)] @@ -430,7 +430,7 @@ public sealed class RulesController : ApiController /// /// Provide a list of all event types that are used in rules. /// - /// Rule events returned.. + /// Rule events returned. [HttpGet] [Route("rules/eventtypes")] [ProducesResponseType(typeof(string[]), StatusCodes.Status200OK)] @@ -446,8 +446,8 @@ public sealed class RulesController : ApiController /// Provide the json schema for the event with the specified name. /// /// The type name of the event. - /// Rule event type found.. - /// Rule event not found.. + /// Rule event type found. + /// Rule event not found. [HttpGet] [Route("rules/eventtypes/{type}")] [ProducesResponseType(typeof(object), StatusCodes.Status200OK)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ArrayFieldPropertiesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ArrayFieldPropertiesDto.cs index 933f4703d..e686f213a 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ArrayFieldPropertiesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ArrayFieldPropertiesDto.cs @@ -25,6 +25,11 @@ public sealed class ArrayFieldPropertiesDto : FieldPropertiesDto /// public int? MaxItems { get; set; } + /// + /// The calculated default value for the field value. + /// + public ArrayCalculatedDefaultValue CalculatedDefaultValue { get; set; } + /// /// The fields that must be unique. /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ComponentsFieldPropertiesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ComponentsFieldPropertiesDto.cs index f048b4f8a..7301f8ed0 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ComponentsFieldPropertiesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ComponentsFieldPropertiesDto.cs @@ -26,6 +26,11 @@ public sealed class ComponentsFieldPropertiesDto : FieldPropertiesDto /// public int? MaxItems { get; set; } + /// + /// The calculated default value for the field value. + /// + public ArrayCalculatedDefaultValue CalculatedDefaultValue { get; set; } + /// /// The ID of the embedded schemas. /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ReferencesFieldPropertiesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ReferencesFieldPropertiesDto.cs index 8e54fe870..1fc6d02a7 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ReferencesFieldPropertiesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ReferencesFieldPropertiesDto.cs @@ -51,6 +51,11 @@ public sealed class ReferencesFieldPropertiesDto : FieldPropertiesDto /// public bool MustBePublished { get; set; } + /// + /// The initial query that is applied in the UI. + /// + public string? Query { get; init; } + /// /// The editor that is used to manage this field. /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/StringFieldPropertiesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/StringFieldPropertiesDto.cs index 3da6a0f4f..7de5d52a1 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/StringFieldPropertiesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/StringFieldPropertiesDto.cs @@ -71,6 +71,11 @@ public sealed class StringFieldPropertiesDto : FieldPropertiesDto /// public int? MaxWords { get; set; } + /// + /// The class names for the editor. + /// + public ReadonlyList? ClassNames { get; set; } + /// /// The allowed values for the field value. /// diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemaFieldsController.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemaFieldsController.cs index 0cb24c17d..3e0f1f29b 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemaFieldsController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemaFieldsController.cs @@ -32,10 +32,10 @@ public sealed class SchemaFieldsController : ApiController /// The name of the app. /// The name of the schema. /// The field object that needs to be added to the schema. - /// Schema field created.. - /// Schema request not valid.. - /// Schema or app not found.. - /// Schema field name already in use.. + /// Schema field created. + /// Schema request not valid. + /// Schema or app not found. + /// Schema field name already in use. [HttpPost] [Route("apps/{app}/schemas/{schema}/fields/")] [ProducesResponseType(typeof(SchemaDto), 201)] @@ -57,10 +57,10 @@ public sealed class SchemaFieldsController : ApiController /// The name of the schema. /// The parent field id. /// The field object that needs to be added to the schema. - /// Schema field created.. - /// Schema request not valid.. - /// Schema field name already in use.. - /// Schema, field or app not found.. + /// Schema field created. + /// Schema request not valid. + /// Schema field name already in use. + /// Schema, field or app not found. [HttpPost] [Route("apps/{app}/schemas/{schema}/fields/{parentId:long}/nested/")] [ProducesResponseType(typeof(SchemaDto), 201)] @@ -81,9 +81,9 @@ public sealed class SchemaFieldsController : ApiController /// The name of the app. /// The name of the schema. /// The request that contains the field names. - /// Schema UI fields defined.. - /// Schema request not valid.. - /// Schema or app not found.. + /// Schema UI fields defined. + /// Schema request not valid. + /// Schema or app not found. [HttpPut] [Route("apps/{app}/schemas/{schema}/fields/ui/")] [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] @@ -104,9 +104,9 @@ public sealed class SchemaFieldsController : ApiController /// The name of the app. /// The name of the schema. /// The request that contains the field ids. - /// Schema fields reordered.. - /// Schema request not valid.. - /// Schema or app not found.. + /// Schema fields reordered. + /// Schema request not valid. + /// Schema or app not found. [HttpPut] [Route("apps/{app}/schemas/{schema}/fields/ordering/")] [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] @@ -128,9 +128,9 @@ public sealed class SchemaFieldsController : ApiController /// The name of the schema. /// The parent field id. /// The request that contains the field ids. - /// Schema fields reordered.. - /// Schema field request not valid.. - /// Schema, field or app not found.. + /// Schema fields reordered. + /// Schema field request not valid. + /// Schema, field or app not found. [HttpPut] [Route("apps/{app}/schemas/{schema}/fields/{parentId:long}/nested/ordering/")] [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] @@ -152,9 +152,9 @@ public sealed class SchemaFieldsController : ApiController /// The name of the schema. /// The ID of the field to update. /// The field object that needs to be added to the schema. - /// Schema field updated.. - /// Schema field request not valid.. - /// Schema, field or app not found.. + /// Schema field updated. + /// Schema field request not valid. + /// Schema, field or app not found. [HttpPut] [Route("apps/{app}/schemas/{schema}/fields/{id:long}/")] [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] @@ -177,9 +177,9 @@ public sealed class SchemaFieldsController : ApiController /// The parent field id. /// The ID of the field to update. /// The field object that needs to be added to the schema. - /// Schema field updated.. - /// Schema field request not valid or field locked.. - /// Schema, field or app not found.. + /// Schema field updated. + /// Schema field request not valid or field locked. + /// Schema, field or app not found. [HttpPut] [Route("apps/{app}/schemas/{schema}/fields/{parentId:long}/nested/{id:long}/")] [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] @@ -200,9 +200,9 @@ public sealed class SchemaFieldsController : ApiController /// The name of the app. /// The name of the schema. /// The ID of the field to lock. - /// Schema field shown.. - /// Schema field request not valid or field locked.. - /// Schema, field or app not found.. + /// Schema field shown. + /// Schema field request not valid or field locked. + /// Schema, field or app not found. /// /// A locked field cannot be updated or deleted. /// @@ -227,9 +227,9 @@ public sealed class SchemaFieldsController : ApiController /// The name of the schema. /// The parent field id. /// The ID of the field to lock. - /// Schema field hidden.. - /// Schema field request not valid or field locked.. - /// Field, schema, or app not found.. + /// Schema field hidden. + /// Schema field request not valid or field locked. + /// Field, schema, or app not found. /// /// A locked field cannot be edited or deleted. /// @@ -253,9 +253,9 @@ public sealed class SchemaFieldsController : ApiController /// The name of the app. /// The name of the schema. /// The ID of the field to hide. - /// Schema field hidden.. - /// Schema field request not valid or field locked.. - /// Schema, field or app not found.. + /// Schema field hidden. + /// Schema field request not valid or field locked. + /// Schema, field or app not found. /// /// A hidden field is not part of the API response, but can still be edited in the portal. /// @@ -280,9 +280,9 @@ public sealed class SchemaFieldsController : ApiController /// The name of the schema. /// The parent field id. /// The ID of the field to hide. - /// Schema field hidden.. - /// Schema field request not valid or field locked.. - /// Field, schema, or app not found.. + /// Schema field hidden. + /// Schema field request not valid or field locked. + /// Field, schema, or app not found. /// /// A hidden field is not part of the API response, but can still be edited in the portal. /// @@ -306,9 +306,9 @@ public sealed class SchemaFieldsController : ApiController /// The name of the app. /// The name of the schema. /// The ID of the field to show. - /// Schema field shown.. - /// Schema field request not valid or field locked.. - /// Schema, field or app not found.. + /// Schema field shown. + /// Schema field request not valid or field locked. + /// Schema, field or app not found. /// /// A hidden field is not part of the API response, but can still be edited in the portal. /// @@ -333,9 +333,9 @@ public sealed class SchemaFieldsController : ApiController /// The name of the schema. /// The parent field id. /// The ID of the field to show. - /// Schema field shown.. - /// Schema field request not valid or field locked.. - /// Schema, field or app not found.. + /// Schema field shown. + /// Schema field request not valid or field locked. + /// Schema, field or app not found. /// /// A hidden field is not part of the API response, but can still be edited in the portal. /// @@ -359,9 +359,9 @@ public sealed class SchemaFieldsController : ApiController /// The name of the app. /// The name of the schema. /// The ID of the field to enable. - /// Schema field enabled.. - /// Schema field request not valid or field locked.. - /// Schema, field or app not found.. + /// Schema field enabled. + /// Schema field request not valid or field locked. + /// Schema, field or app not found. /// /// A disabled field cannot not be edited in the squidex portal anymore, but will be part of the API response. /// @@ -386,9 +386,9 @@ public sealed class SchemaFieldsController : ApiController /// The name of the schema. /// The parent field id. /// The ID of the field to enable. - /// Schema field enabled.. - /// Schema field request not valid or field locked.. - /// Schema, field or app not found.. + /// Schema field enabled. + /// Schema field request not valid or field locked. + /// Schema, field or app not found. /// /// A disabled field cannot not be edited in the squidex portal anymore, but will be part of the API response. /// @@ -412,9 +412,9 @@ public sealed class SchemaFieldsController : ApiController /// The name of the app. /// The name of the schema. /// The ID of the field to disable. - /// Schema field disabled.. - /// Schema field request not valid or field locked.. - /// Schema, field or app not found.. + /// Schema field disabled. + /// Schema field request not valid or field locked. + /// Schema, field or app not found. /// /// A disabled field cannot not be edited in the squidex portal anymore, but will be part of the API response. /// @@ -439,9 +439,9 @@ public sealed class SchemaFieldsController : ApiController /// The name of the schema. /// The parent field id. /// The ID of the field to disable. - /// Schema field disabled.. - /// Schema field request not valid or field locked.. - /// Schema, field or app not found.. + /// Schema field disabled. + /// Schema field request not valid or field locked. + /// Schema, field or app not found. /// /// A disabled field cannot not be edited in the squidex portal anymore, but will be part of the API response. /// @@ -465,9 +465,9 @@ public sealed class SchemaFieldsController : ApiController /// The name of the app. /// The name of the schema. /// The ID of the field to disable. - /// Schema field deleted.. - /// Schema field request not valid or field locked.. - /// Schema, field or app not found.. + /// Schema field deleted. + /// Schema field request not valid or field locked. + /// Schema, field or app not found. [HttpDelete] [Route("apps/{app}/schemas/{schema}/fields/{id:long}/")] [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] @@ -489,9 +489,9 @@ public sealed class SchemaFieldsController : ApiController /// The name of the schema. /// The parent field id. /// The ID of the field to disable. - /// Schema field deleted.. - /// Schema field request not valid or field locked.. - /// Schema, field or app not found.. + /// Schema field deleted. + /// Schema field request not valid or field locked. + /// Schema, field or app not found. [HttpDelete] [Route("apps/{app}/schemas/{schema}/fields/{parentId:long}/nested/{id:long}/")] [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemasController.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemasController.cs index e6a3f8a81..bab9a523d 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemasController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/SchemasController.cs @@ -40,8 +40,8 @@ public sealed class SchemasController : ApiController /// Get schemas. /// /// The name of the app. - /// Schemas returned.. - /// App not found.. + /// Schemas returned. + /// App not found. [HttpGet] [Route("apps/{app}/schemas/")] [ProducesResponseType(typeof(SchemasDto), StatusCodes.Status200OK)] @@ -66,8 +66,8 @@ public sealed class SchemasController : ApiController /// /// The name of the app. /// The name of the schema to retrieve. - /// Schema found.. - /// Schema or app not found.. + /// Schema found. + /// Schema or app not found. [HttpGet] [Route("apps/{app}/schemas/{schema}/")] [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] @@ -90,9 +90,9 @@ public sealed class SchemasController : ApiController /// /// The name of the app. /// The schema object that needs to be added to the app. - /// Schema created.. - /// Schema request not valid.. - /// Schema name already in use.. + /// Schema created. + /// Schema request not valid. + /// Schema name already in use. [HttpPost] [Route("apps/{app}/schemas/")] [ProducesResponseType(typeof(SchemaDto), 201)] @@ -113,9 +113,9 @@ public sealed class SchemasController : ApiController /// The name of the app. /// The name of the schema. /// The schema object that needs to updated. - /// Schema updated.. - /// Schema request not valid.. - /// Schema or app not found.. + /// Schema updated. + /// Schema request not valid. + /// Schema or app not found. [HttpPut] [Route("apps/{app}/schemas/{schema}/")] [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] @@ -136,9 +136,9 @@ public sealed class SchemasController : ApiController /// The name of the app. /// The name of the schema. /// The schema object that needs to updated. - /// Schema updated.. - /// Schema request not valid.. - /// Schema or app not found.. + /// Schema updated. + /// Schema request not valid. + /// Schema or app not found. [HttpPut] [Route("apps/{app}/schemas/{schema}/sync")] [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] @@ -159,9 +159,9 @@ public sealed class SchemasController : ApiController /// The name of the app. /// The name of the schema. /// The schema object that needs to updated. - /// Schema updated.. - /// Schema request not valid.. - /// Schema or app not found.. + /// Schema updated. + /// Schema request not valid. + /// Schema or app not found. [HttpPut] [Route("apps/{app}/schemas/{schema}/category")] [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] @@ -182,9 +182,9 @@ public sealed class SchemasController : ApiController /// The name of the app. /// The name of the schema. /// The preview urls for the schema. - /// Schema updated.. - /// Schema request not valid.. - /// Schema or app not found.. + /// Schema updated. + /// Schema request not valid. + /// Schema or app not found. [HttpPut] [Route("apps/{app}/schemas/{schema}/preview-urls")] [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] @@ -205,9 +205,9 @@ public sealed class SchemasController : ApiController /// The name of the app. /// The name of the schema. /// The schema scripts object that needs to updated. - /// Schema updated.. - /// Schema request not valid.. - /// Schema or app not found.. + /// Schema updated. + /// Schema request not valid. + /// Schema or app not found. [HttpPut] [Route("apps/{app}/schemas/{schema}/scripts/")] [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] @@ -228,9 +228,9 @@ public sealed class SchemasController : ApiController /// The name of the app. /// The name of the schema. /// The schema rules object that needs to updated. - /// Schema updated.. - /// Schema request not valid.. - /// Schema or app not found.. + /// Schema updated. + /// Schema request not valid. + /// Schema or app not found. [HttpPut] [Route("apps/{app}/schemas/{schema}/rules/")] [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] @@ -250,8 +250,8 @@ public sealed class SchemasController : ApiController /// /// The name of the app. /// The name of the schema to publish. - /// Schema published.. - /// Schema or app not found.. + /// Schema published. + /// Schema or app not found. [HttpPut] [Route("apps/{app}/schemas/{schema}/publish/")] [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] @@ -271,8 +271,8 @@ public sealed class SchemasController : ApiController /// /// The name of the app. /// The name of the schema to unpublish. - /// Schema unpublished.. - /// Schema or app not found.. + /// Schema unpublished. + /// Schema or app not found. [HttpPut] [Route("apps/{app}/schemas/{schema}/unpublish/")] [ProducesResponseType(typeof(SchemaDto), StatusCodes.Status200OK)] @@ -292,8 +292,8 @@ public sealed class SchemasController : ApiController /// /// The name of the app. /// The name of the schema to delete. - /// Schema deleted.. - /// Schema or app not found.. + /// Schema deleted. + /// Schema or app not found. [HttpDelete] [Route("apps/{app}/schemas/{schema}/")] [ProducesResponseType(StatusCodes.Status204NoContent)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Search/SearchController.cs b/backend/src/Squidex/Areas/Api/Controllers/Search/SearchController.cs index 8271cdd0a..ba4bfe8f4 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Search/SearchController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Search/SearchController.cs @@ -33,8 +33,8 @@ public class SearchController : ApiController /// /// The name of the app. /// The search query. - /// Search results returned.. - /// App not found.. + /// Search results returned. + /// App not found. [HttpGet] [Route("apps/{app}/search/")] [ProducesResponseType(typeof(SearchResultDto[]), StatusCodes.Status200OK)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Statistics/UsagesController.cs b/backend/src/Squidex/Areas/Api/Controllers/Statistics/UsagesController.cs index 4c028e887..a770b8809 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Statistics/UsagesController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Statistics/UsagesController.cs @@ -56,8 +56,8 @@ public sealed class UsagesController : ApiController /// Get api calls as log file. /// /// The name of the app. - /// Usage tracking results returned.. - /// App not found.. + /// Usage tracking results returned. + /// App not found. [HttpGet] [Route("apps/{app}/usages/log/")] [ProducesResponseType(typeof(LogDownloadDto), StatusCodes.Status200OK)] @@ -103,8 +103,8 @@ public sealed class UsagesController : ApiController /// The name of the app. /// The from date. /// The to date. - /// API call returned.. - /// App not found.. + /// API call returned. + /// App not found. [HttpGet] [Route("apps/{app}/usages/calls/{fromDate}/{toDate}/")] [ProducesResponseType(typeof(CallsUsageDtoDto), StatusCodes.Status200OK)] @@ -128,8 +128,8 @@ public sealed class UsagesController : ApiController /// The name of the team. /// The from date. /// The to date. - /// API call returned.. - /// Team not found.. + /// API call returned. + /// Team not found. [HttpGet] [Route("teams/{team}/usages/calls/{fromDate}/{toDate}/")] [ProducesResponseType(typeof(CallsUsageDtoDto), StatusCodes.Status200OK)] @@ -151,8 +151,8 @@ public sealed class UsagesController : ApiController /// Get total asset size. /// /// The name of the app. - /// Storage usage returned.. - /// App not found.. + /// Storage usage returned. + /// App not found. [HttpGet] [Route("apps/{app}/usages/storage/today/")] [ProducesResponseType(typeof(CurrentStorageDto), StatusCodes.Status200OK)] @@ -174,8 +174,8 @@ public sealed class UsagesController : ApiController /// Get total asset size by team. /// /// The ID of the team. - /// Storage usage returned.. - /// Team not found.. + /// Storage usage returned. + /// Team not found. [HttpGet] [Route("teams/{team}/usages/storage/today/")] [ProducesResponseType(typeof(CurrentStorageDto), StatusCodes.Status200OK)] @@ -199,8 +199,8 @@ public sealed class UsagesController : ApiController /// The name of the app. /// The from date. /// The to date. - /// Storage usage returned.. - /// App not found.. + /// Storage usage returned. + /// App not found. [HttpGet] [Route("apps/{app}/usages/storage/{fromDate}/{toDate}/")] [ProducesResponseType(typeof(StorageUsagePerDateDto[]), StatusCodes.Status200OK)] @@ -221,8 +221,8 @@ public sealed class UsagesController : ApiController /// The ID of the team. /// The from date. /// The to date. - /// Storage usage returned.. - /// Team not found.. + /// Storage usage returned. + /// Team not found. [HttpGet] [Route("teams/{team}/usages/storage/{fromDate}/{toDate}/")] [ProducesResponseType(typeof(StorageUsagePerDateDto[]), StatusCodes.Status200OK)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Teams/TeamContributorsController.cs b/backend/src/Squidex/Areas/Api/Controllers/Teams/TeamContributorsController.cs index a8ae9959b..7594bd0b6 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Teams/TeamContributorsController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Teams/TeamContributorsController.cs @@ -36,8 +36,8 @@ public sealed class TeamContributorsController : ApiController /// Get team contributors. /// /// The ID of the team. - /// Contributors returned.. - /// Team not found.. + /// Contributors returned. + /// Team not found. [HttpGet] [Route("teams/{team}/contributors/")] [ProducesResponseType(typeof(ContributorsDto), StatusCodes.Status200OK)] @@ -60,9 +60,9 @@ public sealed class TeamContributorsController : ApiController /// /// The ID of the team. /// Contributor object that needs to be added to the team. - /// Contributor assigned to team.. - /// Contributor request not valid.. - /// Team not found.. + /// Contributor assigned to team. + /// Contributor request not valid. + /// Team not found. [HttpPost] [Route("teams/{team}/contributors/")] [ProducesResponseType(typeof(ContributorsDto), StatusCodes.Status201Created)] @@ -81,8 +81,8 @@ public sealed class TeamContributorsController : ApiController /// Remove yourself. /// /// The ID of the team. - /// Contributor removed.. - /// Contributor or team not found.. + /// Contributor removed. + /// Contributor or team not found. [HttpDelete] [Route("teams/{team}/contributors/me/")] [ProducesResponseType(typeof(ContributorsDto), StatusCodes.Status200OK)] @@ -102,8 +102,8 @@ public sealed class TeamContributorsController : ApiController /// /// The ID of the team. /// The ID of the contributor. - /// Contributor removed.. - /// Contributor or team not found.. + /// Contributor removed. + /// Contributor or team not found. [HttpDelete] [Route("teams/{team}/contributors/{id}/")] [ProducesResponseType(typeof(ContributorsDto), StatusCodes.Status200OK)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Teams/TeamsController.cs b/backend/src/Squidex/Areas/Api/Controllers/Teams/TeamsController.cs index e414697f9..e73f666ab 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Teams/TeamsController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Teams/TeamsController.cs @@ -33,7 +33,7 @@ public sealed class TeamsController : ApiController /// /// Get your teams. /// - /// Teams returned.. + /// Teams returned. /// /// You can only retrieve the list of teams when you are authenticated as a user (OpenID implicit flow). /// You will retrieve all teams, where you are assigned as a contributor. @@ -61,8 +61,8 @@ public sealed class TeamsController : ApiController /// Get an team by name. /// /// The name of the team. - /// Teams returned.. - /// Team not found.. + /// Teams returned. + /// Team not found. [HttpGet] [Route("teams/{team}")] [ProducesResponseType(typeof(TeamDto), StatusCodes.Status200OK)] @@ -84,9 +84,9 @@ public sealed class TeamsController : ApiController /// Create a new team. /// /// The team object that needs to be added to Squidex. - /// Team created.. - /// Team request not valid.. - /// Team name is already in use.. + /// Team created. + /// Team request not valid. + /// Team name is already in use. /// /// You can only create an team when you are authenticated as a user (OpenID implicit flow). /// You will be assigned as owner of the new team automatically. @@ -108,9 +108,9 @@ public sealed class TeamsController : ApiController /// /// The name of the team to update. /// The values to update. - /// Team updated.. - /// Team request not valid.. - /// Team not found.. + /// Team updated. + /// Team request not valid. + /// Team not found. [HttpPut] [Route("teams/{team}/")] [ProducesResponseType(typeof(TeamDto), StatusCodes.Status200OK)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Templates/TemplatesController.cs b/backend/src/Squidex/Areas/Api/Controllers/Templates/TemplatesController.cs index 4a531882b..9c9bb7d69 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Templates/TemplatesController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Templates/TemplatesController.cs @@ -30,7 +30,7 @@ public sealed class TemplatesController : ApiController /// /// Get all templates. /// - /// Templates returned.. + /// Templates returned. [HttpGet] [Route("templates/")] [ProducesResponseType(typeof(TemplatesDto), StatusCodes.Status200OK)] @@ -48,8 +48,8 @@ public sealed class TemplatesController : ApiController /// Get template details. /// /// The name of the template. - /// Template returned.. - /// Template not found.. + /// Template returned. + /// Template not found. [HttpGet] [Route("templates/{name}")] [ProducesResponseType(typeof(TemplateDetailsDto), StatusCodes.Status200OK)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Translations/TranslationsController.cs b/backend/src/Squidex/Areas/Api/Controllers/Translations/TranslationsController.cs index 3ff65235f..8899dd06c 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Translations/TranslationsController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Translations/TranslationsController.cs @@ -37,7 +37,7 @@ public sealed class TranslationsController : ApiController /// /// The name of the app. /// The translation request. - /// Text translated.. + /// Text translated. [HttpPost] [Route("apps/{app}/translations/")] [ProducesResponseType(typeof(TranslationDto), StatusCodes.Status200OK)] @@ -56,7 +56,7 @@ public sealed class TranslationsController : ApiController /// /// The name of the app. /// The question request. - /// Question asked.. + /// Question asked. [HttpPost] [Route("apps/{app}/ask/")] [ProducesResponseType(typeof(string[]), StatusCodes.Status200OK)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/UI/MyUIOptions.cs b/backend/src/Squidex/Areas/Api/Controllers/UI/MyUIOptions.cs index 0798f6715..058226fdc 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/UI/MyUIOptions.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/UI/MyUIOptions.cs @@ -53,6 +53,9 @@ public sealed record MyUIOptions [JsonPropertyName("markerProject")] public string MarkerProject { get; set; } + [JsonPropertyName("collaborationService")] + public string CollaborationService { get; set; } + public sealed class MapOptions { [JsonPropertyName("type")] diff --git a/backend/src/Squidex/Areas/Api/Controllers/UI/UIController.cs b/backend/src/Squidex/Areas/Api/Controllers/UI/UIController.cs index cd3eda137..d27a40599 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/UI/UIController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/UI/UIController.cs @@ -36,7 +36,7 @@ public sealed class UIController : ApiController /// /// Get ui settings. /// - /// UI settings returned.. + /// UI settings returned. [HttpGet] [Route("ui/settings/")] [ProducesResponseType(typeof(Dictionary), StatusCodes.Status200OK)] @@ -63,8 +63,8 @@ public sealed class UIController : ApiController /// Get ui settings. /// /// The name of the app. - /// UI settings returned.. - /// App not found.. + /// UI settings returned. + /// App not found. [HttpGet] [Route("apps/{app}/ui/settings/")] [ProducesResponseType(typeof(Dictionary), StatusCodes.Status200OK)] @@ -80,8 +80,8 @@ public sealed class UIController : ApiController /// Get my ui settings. /// /// The name of the app. - /// UI settings returned.. - /// App not found.. + /// UI settings returned. + /// App not found. [HttpGet] [Route("apps/{app}/ui/settings/me")] [ProducesResponseType(typeof(Dictionary), StatusCodes.Status200OK)] @@ -98,8 +98,8 @@ public sealed class UIController : ApiController /// /// The name of the setting. /// The request with the value to update. - /// UI setting set.. - /// App not found.. + /// UI setting set. + /// App not found. [HttpPut] [Route("ui/settings/{key}")] [ApiPermission] @@ -116,8 +116,8 @@ public sealed class UIController : ApiController /// The name of the app. /// The name of the setting. /// The request with the value to update. - /// UI setting set.. - /// App not found.. + /// UI setting set. + /// App not found. [HttpPut] [Route("apps/{app}/ui/settings/{key}")] [ApiPermission] @@ -134,8 +134,8 @@ public sealed class UIController : ApiController /// The name of the app. /// The name of the setting. /// The request with the value to update. - /// UI setting set.. - /// App not found.. + /// UI setting set. + /// App not found. [HttpPut] [Route("apps/{app}/ui/settings/me/{key}")] [ApiPermission] @@ -150,8 +150,8 @@ public sealed class UIController : ApiController /// Remove ui settings. /// /// The name of the setting. - /// UI setting removed.. - /// App not found.. + /// UI setting removed. + /// App not found. [HttpDelete] [Route("ui/settings/{key}")] [ApiPermission] @@ -167,8 +167,8 @@ public sealed class UIController : ApiController /// /// The name of the app. /// The name of the setting. - /// UI setting removed.. - /// App not found.. + /// UI setting removed. + /// App not found. [HttpDelete] [Route("apps/{app}/ui/settings/{key}")] [ApiPermission] @@ -184,8 +184,8 @@ public sealed class UIController : ApiController /// /// The name of the app. /// The name of the setting. - /// UI setting removed.. - /// App not found.. + /// UI setting removed. + /// App not found. [HttpDelete] [Route("apps/{app}/ui/settings/me/{key}")] [ApiPermission] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Users/UserManagementController.cs b/backend/src/Squidex/Areas/Api/Controllers/Users/UserManagementController.cs index 364d240bc..cc3d3ea1f 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Users/UserManagementController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Users/UserManagementController.cs @@ -37,7 +37,7 @@ public sealed class UserManagementController : ApiController /// Optional query to search by email address or username. /// The number of users to skip. /// The number of users to return. - /// Users returned.. + /// Users returned. [HttpGet] [Route("user-management/")] [ProducesResponseType(typeof(UsersDto), StatusCodes.Status200OK)] @@ -55,8 +55,8 @@ public sealed class UserManagementController : ApiController /// Get a user by ID. /// /// The ID of the user. - /// User returned.. - /// User not found.. + /// User returned. + /// User not found. [HttpGet] [Route("user-management/{id}/")] [ProducesResponseType(typeof(UserDto), StatusCodes.Status200OK)] @@ -79,8 +79,8 @@ public sealed class UserManagementController : ApiController /// Create a new user. /// /// The user object that needs to be added. - /// User created.. - /// User request not valid.. + /// User created. + /// User request not valid. [HttpPost] [Route("user-management/")] [ProducesResponseType(typeof(UserDto), StatusCodes.Status201Created)] @@ -99,9 +99,9 @@ public sealed class UserManagementController : ApiController /// /// The ID of the user. /// The user object that needs to be updated. - /// User created.. - /// User request not valid.. - /// User not found.. + /// User created. + /// User request not valid. + /// User not found. [HttpPut] [Route("user-management/{id}/")] [ProducesResponseType(typeof(UserDto), StatusCodes.Status200OK)] @@ -119,9 +119,9 @@ public sealed class UserManagementController : ApiController /// Lock a user. /// /// The ID of the user to lock. - /// User locked.. - /// User is the current user.. - /// User not found.. + /// User locked. + /// User is the current user. + /// User not found. [HttpPut] [Route("user-management/{id}/lock/")] [ProducesResponseType(typeof(UserDto), StatusCodes.Status200OK)] @@ -144,9 +144,9 @@ public sealed class UserManagementController : ApiController /// Unlock a user. /// /// The ID of the user to unlock. - /// User unlocked.. - /// User is the current user.. - /// User not found.. + /// User unlocked. + /// User is the current user. + /// User not found. [HttpPut] [Route("user-management/{id}/unlock/")] [ProducesResponseType(typeof(UserDto), StatusCodes.Status200OK)] @@ -169,9 +169,9 @@ public sealed class UserManagementController : ApiController /// Delete a User. /// /// The ID of the user to delete. - /// User deleted.. - /// User is the current user.. - /// User not found.. + /// User deleted. + /// User is the current user. + /// User not found. [HttpDelete] [Route("user-management/{id}/")] [ProducesResponseType(StatusCodes.Status204NoContent)] diff --git a/backend/src/Squidex/Areas/Api/Controllers/Users/UsersController.cs b/backend/src/Squidex/Areas/Api/Controllers/Users/UsersController.cs index 1d5b27a08..4d201235a 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Users/UsersController.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Users/UsersController.cs @@ -60,7 +60,7 @@ public sealed class UsersController : ApiController /// /// Get the user resources. /// - /// User resources returned.. + /// User resources returned. [HttpGet] [Route("")] [ProducesResponseType(typeof(ResourcesDto), StatusCodes.Status200OK)] @@ -76,7 +76,7 @@ public sealed class UsersController : ApiController /// Update the user profile. /// /// The values to update. - /// User updated.. + /// User updated. [HttpPost] [Route("user")] [ProducesResponseType(StatusCodes.Status204NoContent)] @@ -95,7 +95,7 @@ public sealed class UsersController : ApiController /// /// Search the user by query that contains the email address or the part of the email address. /// - /// Users returned.. + /// Users returned. [HttpGet] [Route("users/")] [ProducesResponseType(typeof(UserDto[]), StatusCodes.Status200OK)] @@ -122,8 +122,8 @@ public sealed class UsersController : ApiController /// Get user by id. /// /// The ID of the user (GUID). - /// User found.. - /// User not found.. + /// User found. + /// User not found. [HttpGet] [Route("users/{id}/")] [ProducesResponseType(typeof(UserDto), StatusCodes.Status200OK)] @@ -153,8 +153,8 @@ public sealed class UsersController : ApiController /// Get user picture by id. /// /// The ID of the user (GUID). - /// User found and image or fallback returned.. - /// User not found.. + /// User found and image or fallback returned. + /// User not found. [HttpGet] [Route("users/{id}/picture/")] [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK)] diff --git a/backend/src/Squidex/Areas/Frontend/Middlewares/IndexExtensions.cs b/backend/src/Squidex/Areas/Frontend/Middlewares/IndexExtensions.cs index e4acf17f2..81584e7e0 100644 --- a/backend/src/Squidex/Areas/Frontend/Middlewares/IndexExtensions.cs +++ b/backend/src/Squidex/Areas/Frontend/Middlewares/IndexExtensions.cs @@ -10,8 +10,6 @@ using System.Globalization; using System.Text.Json; using Microsoft.Extensions.Options; using Squidex.Areas.Api.Controllers.UI; -using Squidex.Domain.Apps.Entities.History; -using Squidex.Web; namespace Squidex.Areas.Frontend.Middlewares; @@ -39,28 +37,12 @@ public static class IndexExtensions { var clonedOptions = uiOptions with { - More = new Dictionary + More = new Dictionary(uiOptions.More) { ["culture"] = CultureInfo.CurrentUICulture.Name } }; - var jsonOptions = httpContext.RequestServices.GetRequiredService(); - - using var jsonDocument = JsonSerializer.SerializeToDocument(uiOptions, jsonOptions); - - if (httpContext.RequestServices.GetService() is ExposedValues values) - { - clonedOptions.More["info"] = values.ToString(); - } - - var notifo = httpContext.RequestServices!.GetService>()?.Value; - - if (notifo?.IsConfigured() == true) - { - clonedOptions.More["notifoApi"] = notifo.ApiUrl; - } - var options = httpContext.Features.Get(); if (options != null) diff --git a/backend/src/Squidex/Config/Authentication/IdentityServices.cs b/backend/src/Squidex/Config/Authentication/IdentityServices.cs index 669797580..14589250c 100644 --- a/backend/src/Squidex/Config/Authentication/IdentityServices.cs +++ b/backend/src/Squidex/Config/Authentication/IdentityServices.cs @@ -17,7 +17,7 @@ public static class IdentityServices services.Configure(config, "identity"); - services.AddHttpClient("USers"); + services.AddHttpClient("Users"); services.AddSingletonAs() .AsOptional(); diff --git a/backend/src/Squidex/Config/Domain/NotificationsServices.cs b/backend/src/Squidex/Config/Domain/CollaborationServices.cs similarity index 79% rename from backend/src/Squidex/Config/Domain/NotificationsServices.cs rename to backend/src/Squidex/Config/Domain/CollaborationServices.cs index d94f733b4..f23f36764 100644 --- a/backend/src/Squidex/Config/Domain/NotificationsServices.cs +++ b/backend/src/Squidex/Config/Domain/CollaborationServices.cs @@ -6,16 +6,17 @@ // ========================================================================== using Microsoft.Extensions.Options; +using Squidex.Domain.Apps.Entities.Collaboration; using Squidex.Domain.Apps.Entities.Invitation; -using Squidex.Domain.Apps.Entities.Notifications; using Squidex.Infrastructure.Email; using Squidex.Infrastructure.EventSourcing; +using YDotNet.Server; namespace Squidex.Config.Domain; -public static class NotificationsServices +public static class CollaborationServices { - public static void AddSquidexNotifications(this IServiceCollection services, IConfiguration config) + public static void AddSquidexCollaborations(this IServiceCollection services, IConfiguration config) { var emailOptions = config.GetSection("email:smtp").Get() ?? new (); @@ -40,5 +41,8 @@ public static class NotificationsServices services.AddSingletonAs() .As(); + + services.AddSingletonAs() + .As().As(); } } diff --git a/backend/src/Squidex/Config/Domain/CommandsServices.cs b/backend/src/Squidex/Config/Domain/CommandsServices.cs index fadc941de..8b92ebf66 100644 --- a/backend/src/Squidex/Config/Domain/CommandsServices.cs +++ b/backend/src/Squidex/Config/Domain/CommandsServices.cs @@ -12,7 +12,6 @@ using Squidex.Domain.Apps.Entities.Apps.Plans; using Squidex.Domain.Apps.Entities.Apps.Templates; using Squidex.Domain.Apps.Entities.Assets.Commands; using Squidex.Domain.Apps.Entities.Assets.DomainObject; -using Squidex.Domain.Apps.Entities.Comments.DomainObject; using Squidex.Domain.Apps.Entities.Contents; using Squidex.Domain.Apps.Entities.Contents.DomainObject; using Squidex.Domain.Apps.Entities.Invitation; @@ -106,9 +105,6 @@ public static class CommandsServices services.AddSingletonAs() .As(); - services.AddSingletonAs() - .As(); - services.AddSingletonAs() .As(); diff --git a/backend/src/Squidex/Config/Domain/CommentsServices.cs b/backend/src/Squidex/Config/Domain/CommentsServices.cs deleted file mode 100644 index ffe4d0532..000000000 --- a/backend/src/Squidex/Config/Domain/CommentsServices.cs +++ /dev/null @@ -1,22 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using Squidex.Domain.Apps.Entities.Comments; - -namespace Squidex.Config.Domain; - -public static class CommentsServices -{ - public static void AddSquidexComments(this IServiceCollection services) - { - services.AddSingletonAs() - .As(); - - services.AddSingletonAs() - .As(); - } -} diff --git a/backend/src/Squidex/Config/Domain/FontendServices.cs b/backend/src/Squidex/Config/Domain/FontendServices.cs new file mode 100644 index 000000000..79d7de7a4 --- /dev/null +++ b/backend/src/Squidex/Config/Domain/FontendServices.cs @@ -0,0 +1,74 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System.Text.Json; +using Microsoft.Extensions.Options; +using Squidex.Areas.Api.Controllers.UI; +using Squidex.Domain.Apps.Entities.History; +using Squidex.Hosting; +using Squidex.Text.ChatBots; +using Squidex.Text.Translations; +using Squidex.Web; + +namespace Squidex.Config.Domain; + +public static class FontendServices +{ + public static void AddSquidexFrontend(this IServiceCollection services) + { + services.Configure((services, options) => + { + var jsonOptions = services.GetRequiredService(); + + using var jsonDocument = JsonSerializer.SerializeToDocument(options, jsonOptions); + + if (services.GetService() is ExposedValues values) + { + options.More["info"] = values.ToString(); + } + }); + + services.Configure((services, options) => + { + var notifo = services.GetRequiredService>().Value; + + if (notifo.IsConfigured()) + { + options.More["notifoApi"] = notifo.ApiUrl; + } + }); + + services.Configure((services, options) => + { + var translator = services.GetRequiredService(); + + options.More["canUseTranslator"] = translator.IsConfigured; + }); + + services.Configure((services, options) => + { + var chatBot = services.GetRequiredService(); + + options.More["canUseChatBot"] = chatBot.IsConfigured; + }); + + services.Configure((services, options) => + { + if (string.IsNullOrWhiteSpace(options.CollaborationService)) + { + var urlGenerator = services.GetRequiredService(); + + var collaborationUrl = + urlGenerator.BuildUrl() + .Replace("https://", "wss://", StringComparison.OrdinalIgnoreCase) + .Replace("http://", "ws://", StringComparison.OrdinalIgnoreCase); + + options.CollaborationService = collaborationUrl; + } + }); + } +} diff --git a/backend/src/Squidex/Config/Domain/RuleServices.cs b/backend/src/Squidex/Config/Domain/RuleServices.cs index 7d845d82d..dea4f4c71 100644 --- a/backend/src/Squidex/Config/Domain/RuleServices.cs +++ b/backend/src/Squidex/Config/Domain/RuleServices.cs @@ -13,7 +13,7 @@ using Squidex.Domain.Apps.Core.Scripting; using Squidex.Domain.Apps.Core.Subscriptions; using Squidex.Domain.Apps.Core.Templates; using Squidex.Domain.Apps.Entities.Assets; -using Squidex.Domain.Apps.Entities.Comments; +using Squidex.Domain.Apps.Entities.Collaboration; using Squidex.Domain.Apps.Entities.Contents; using Squidex.Domain.Apps.Entities.Rules; using Squidex.Domain.Apps.Entities.Rules.Queries; diff --git a/backend/src/Squidex/Config/Domain/StoreServices.cs b/backend/src/Squidex/Config/Domain/StoreServices.cs index 168b59cb0..6009244c9 100644 --- a/backend/src/Squidex/Config/Domain/StoreServices.cs +++ b/backend/src/Squidex/Config/Domain/StoreServices.cs @@ -50,6 +50,7 @@ using Squidex.Infrastructure.Migrations; using Squidex.Infrastructure.MongoDb; using Squidex.Infrastructure.States; using Squidex.Infrastructure.UsageTracking; +using YDotNet.Server.MongoDB; namespace Squidex.Config.Domain; @@ -68,6 +69,12 @@ public static class StoreServices services.AddMongoAssetKeyValueStore(); services.AddSingleton(typeof(ISnapshotStore<>), typeof(MongoSnapshotStore<>)); + services.AddYDotNet() + .AddMongoStorage(options => + { + options.DatabaseName = mongoDatabaseName; + }); + services.AddSingletonAs(c => GetMongoClient(mongoConfiguration)) .As(); @@ -80,6 +87,9 @@ public static class StoreServices services.AddTransientAs() .As(); + services.AddTransientAs() + .As(); + services.AddTransientAs(c => new DeleteContentCollections(GetDatabase(c, mongoContentDatabaseName))) .As(); diff --git a/backend/src/Squidex/Config/Web/WebServices.cs b/backend/src/Squidex/Config/Web/WebServices.cs index 00456b0de..245ec9f39 100644 --- a/backend/src/Squidex/Config/Web/WebServices.cs +++ b/backend/src/Squidex/Config/Web/WebServices.cs @@ -75,6 +75,9 @@ public static class WebServices services.AddLocalization(); + services.AddYDotNet() + .AddWebSockets(); + services.AddMvc(options => { // Never change this order here. diff --git a/backend/src/Squidex/Squidex.csproj b/backend/src/Squidex/Squidex.csproj index ecbab32c3..55b82d17d 100644 --- a/backend/src/Squidex/Squidex.csproj +++ b/backend/src/Squidex/Squidex.csproj @@ -51,7 +51,7 @@ - + @@ -62,19 +62,25 @@ - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/backend/src/Squidex/Startup.cs b/backend/src/Squidex/Startup.cs index 0edaf078d..dc4a1bc17 100644 --- a/backend/src/Squidex/Startup.cs +++ b/backend/src/Squidex/Startup.cs @@ -45,11 +45,12 @@ public sealed class Startup services.AddSquidexAssetInfrastructure(config); services.AddSquidexAssets(config); services.AddSquidexBackups(); + services.AddSquidexCollaborations(config); services.AddSquidexCommands(config); - services.AddSquidexComments(); services.AddSquidexContents(config); services.AddSquidexControllerServices(config); services.AddSquidexEventSourcing(config); + services.AddSquidexFrontend(); services.AddSquidexGraphQL(); services.AddSquidexHealthChecks(config); services.AddSquidexHistory(config); @@ -58,7 +59,6 @@ public sealed class Startup services.AddSquidexLocalization(); services.AddSquidexMessaging(config); services.AddSquidexMigration(config); - services.AddSquidexNotifications(config); services.AddSquidexOpenApiSettings(); services.AddSquidexQueries(config); services.AddSquidexRules(config); diff --git a/backend/src/Squidex/appsettings.json b/backend/src/Squidex/appsettings.json index d1fd72c0c..349e0b2c9 100644 --- a/backend/src/Squidex/appsettings.json +++ b/backend/src/Squidex/appsettings.json @@ -355,11 +355,11 @@ "name": "Squidex", "stackdriver": { - // True, to enable stackdriver integration. - "enabled": false, + // True, to enable stackdriver integration. + "enabled": false, - // The ID of your Google Cloud project. - "projectId": "" + // The ID of your Google Cloud project. + "projectId": "" }, "otlp": { @@ -672,11 +672,16 @@ "version": "squidex:version" }, - // Kafka Producer configuration + // Kafka producer configuration "kafka": { "bootstrapServers": "" }, + // Deepdetect configuration + "deepdetect": { + "url": "" + }, + // The client information for twitter. "twitter": { "clientId": "QZhb3HQcGCvE6G8yNNP9ksNet", diff --git a/backend/src/Squidex/wwwroot/editor/squidex-editor.css b/backend/src/Squidex/wwwroot/editor/squidex-editor.css new file mode 100644 index 000000000..5a4692ecd --- /dev/null +++ b/backend/src/Squidex/wwwroot/editor/squidex-editor.css @@ -0,0 +1 @@ +.remirror-theme{width:100%}.remirror-theme{position:relative}.remirror-theme *{box-sizing:border-box}.remirror-editor{min-height:300px!important;max-height:500px}.MuiStack-root>.MuiBox-root{margin-right:5px}.MuiBox-root>.MuiButtonBase-root{border-color:#dedfe3!important;border-radius:0}.MuiBox-root>.MuiButtonBase-root{border-left-width:0!important}.MuiBox-root>.MuiBox-root:first-child>.MuiButtonBase-root{border-left-width:1px!important}.MuiStack-root>.MuiBox-root>.MuiButtonBase-root:first-child{border-left-width:1px!important}.MuiButtonBase-root.Mui-selected:hover{background-color:#3284f4!important}.remirror-editor-wrapper{padding-top:0!important}.custom-icon path{fill:#0000008a}.remirror-theme div.ProseMirror{border:1px solid #dedfe3!important;border-radius:0!important;box-shadow:none!important}.MuiTooltip-popper>div{background-color:#1a2129;border-radius:0;font-size:85%;font-weight:400;padding:.5rem}.MuiMenu-paper{transform:none!important}.squidex-editor-disabled{pointer-events:none}.squidex-editor-menu{border:1px solid #dedfe3;border-bottom:0;padding:5px}.squidex-editor-counter{border:1px solid #dedfe3;border-top:0;font-size:85%;font-weight:400;opacity:.8;padding:4px 10px 4px 4px;text-align:right}.squidex-editor-image-view{border:1px solid #dedfe3;border-radius:0;display:inline-block;margin-top:15px;margin-bottom:15px;overflow:hidden}.squidex-editor-image-buttons{bottom:10px;left:10px;position:absolute}.squidex-editor-image-element{display:block;max-width:400px;max-height:400px}.squidex-editor-image-info{left:10px;top:10px;position:absolute;background-color:#3284f4;color:#fff;font-size:85%;font-weight:400;padding:2px 6px}.squidex-editor-content-link{align-items:center;border-radius:2px;border:1px solid #dedfe3;padding:10px;display:flex;flex-direction:row;flex-wrap:nowrap;margin-top:10px;margin-bottom:10px}.squidex-editor-content-schema{display:block;overflow-x:hidden;overflow-y:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%;min-width:0;width:auto;border-right:1px solid #c2c4cc;color:#8b8f9d;flex-shrink:0;padding-left:10px;padding-right:10px;width:200px}.squidex-editor-content-name{display:block;overflow-x:hidden;overflow-y:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%;min-width:0;width:auto;padding-left:10px;padding-right:0}.squidex-editor-html{margin-bottom:10px;margin-top:10px;position:relative}.squidex-editor-html-label{left:6px;top:0;position:absolute;color:#8b8f9d;font-size:85%;font-weight:400}.squidex-editor-html textarea{font-family:monospace;padding:30px 20px 20px}.squidex-editor-button{align-items:center;background-color:#fff;border-radius:0;border:1px solid #dedfe3;bottom:10px;display:inline-flex;font-size:85%;font-weight:400;margin-right:5px;padding:6px 12px}.squidex-editor-button:hover{background-color:#f5f5f5}.squidex-editor-input{border:1px solid #dedfe3;border-radius:0;box-sizing:border-box;height:30px;margin-left:0;margin-right:5px;outline:none;padding:6px 12px}.squidex-editor-input:active{border-color:#3284f4}.squidex-editor-floating{border:1px solid #dedfe3}.squidex-editor-floating .MuiBox-root{margin-right:0!important}.squidex-editor-floating .MuiButtonBase-root{height:30px}.squidex-editor-modal-wrapper,.squidex-editor-modal-backdrop{bottom:0;left:0;right:0;top:0;position:absolute}.squidex-editor-modal-backdrop{background-color:#00000003}.squidex-editor-modal-window{left:50%;top:50%;background-color:#fff;border:0;border-radius:.25rem;box-sizing:border-box;box-shadow:0 3px 16px #0003;margin-top:-50px;margin-left:-150px;position:absolute;width:350px}.squidex-editor-modal-body{display:flex;flex-direction:row;flex-grow:1;padding-top:0!important}.squidex-editor-modal-body,.squidex-editor-modal-title{padding:15px}.squidex-editor-modal-title{font-size:85%}.squidex-editor-modal-window input{flex-grow:1}.b:before{content:"";font-family:monospace;font-size:90%}.b:after{content:"";font-family:monospace;font-size:90%} diff --git a/backend/src/Squidex/wwwroot/editor/squidex-editor.js b/backend/src/Squidex/wwwroot/editor/squidex-editor.js new file mode 100644 index 000000000..18ba2ea5d --- /dev/null +++ b/backend/src/Squidex/wwwroot/editor/squidex-editor.js @@ -0,0 +1,5015 @@ +var a_=Object.defineProperty;var l_=(e,t,r)=>t in e?a_(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var vc=(e,t,r)=>(l_(e,typeof t!="symbol"?t+"":t,r),r);function c_(e,t){for(var r=0;rn[o]})}}}return Object.freeze(Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}))}(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))n(o);new MutationObserver(o=>{for(const i of o)if(i.type==="childList")for(const s of i.addedNodes)s.tagName==="LINK"&&s.rel==="modulepreload"&&n(s)}).observe(document,{childList:!0,subtree:!0});function r(o){const i={};return o.integrity&&(i.integrity=o.integrity),o.referrerPolicy&&(i.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?i.credentials="include":o.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function n(o){if(o.ep)return;o.ep=!0;const i=r(o);fetch(o.href,i)}})();var Pu=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Dn(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var O4={exports:{}},Ah={},_4={exports:{}},we={};/** + * @license React + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Od=Symbol.for("react.element"),u_=Symbol.for("react.portal"),d_=Symbol.for("react.fragment"),f_=Symbol.for("react.strict_mode"),p_=Symbol.for("react.profiler"),h_=Symbol.for("react.provider"),m_=Symbol.for("react.context"),g_=Symbol.for("react.forward_ref"),v_=Symbol.for("react.suspense"),y_=Symbol.for("react.memo"),b_=Symbol.for("react.lazy"),Wx=Symbol.iterator;function x_(e){return e===null||typeof e!="object"?null:(e=Wx&&e[Wx]||e["@@iterator"],typeof e=="function"?e:null)}var A4={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},N4=Object.assign,R4={};function tc(e,t,r){this.props=e,this.context=t,this.refs=R4,this.updater=r||A4}tc.prototype.isReactComponent={};tc.prototype.setState=function(e,t){if(typeof e!="object"&&typeof e!="function"&&e!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")};tc.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")};function P4(){}P4.prototype=tc.prototype;function yv(e,t,r){this.props=e,this.context=t,this.refs=R4,this.updater=r||A4}var bv=yv.prototype=new P4;bv.constructor=yv;N4(bv,tc.prototype);bv.isPureReactComponent=!0;var Kx=Array.isArray,z4=Object.prototype.hasOwnProperty,xv={current:null},L4={key:!0,ref:!0,__self:!0,__source:!0};function I4(e,t,r){var n,o={},i=null,s=null;if(t!=null)for(n in t.ref!==void 0&&(s=t.ref),t.key!==void 0&&(i=""+t.key),t)z4.call(t,n)&&!L4.hasOwnProperty(n)&&(o[n]=t[n]);var a=arguments.length-2;if(a===1)o.children=r;else if(1(e.PlainExtension="RemirrorPlainExtension",e.NodeExtension="RemirrorNodeExtension",e.MarkExtension="RemirrorMarkExtension",e.PlainExtensionConstructor="RemirrorPlainExtensionConstructor",e.NodeExtensionConstructor="RemirrorNodeExtensionConstructor",e.MarkExtensionConstructor="RemirrorMarkExtensionConstructor",e.Manager="RemirrorManager",e.Preset="RemirrorPreset",e.PresetConstructor="RemirrorPresetConstructor",e))($t||{}),Ae=(e=>(e[e.Critical=1e6]="Critical",e[e.Highest=1e5]="Highest",e[e.High=1e4]="High",e[e.Medium=1e3]="Medium",e[e.Default=100]="Default",e[e.Low=10]="Low",e[e.Lowest=0]="Lowest",e))(Ae||{}),Nr=(e=>(e[e.None=0]="None",e[e.Create=1]="Create",e[e.EditorView=2]="EditorView",e[e.Runtime=3]="Runtime",e[e.Destroy=4]="Destroy",e))(Nr||{}),$=(e=>(e.Undo="_|undo|_",e.Redo="_|redo|_",e.Bold="_|bold|_",e.Italic="_|italic|_",e.Underline="_|underline|_",e.Strike="_|strike|_",e.Code="_|code|_",e.Paragraph="_|paragraph|_",e.H1="_|h1|_",e.H2="_|h2|_",e.H3="_|h3|_",e.H4="_|h4|_",e.H5="_|h5|_",e.H6="_|h6|_",e.TaskList="_|task|_",e.BulletList="_|bullet|_",e.OrderedList="_|number|_",e.Quote="_|quote|_",e.Divider="_|divider|_",e.Codeblock="_|codeblock|_",e.ClearFormatting="_|clear|_",e.Superscript="_|sup|_",e.Subscript="_|sub|_",e.LeftAlignment="_|left-align|_",e.CenterAlignment="_|center-align|_",e.RightAlignment="_|right-align|_",e.JustifyAlignment="_|justify-align|_",e.InsertLink="_|link|_",e.Find="_|find|_",e.FindBackwards="_|find-backwards|_",e.FindReplace="_|find-replace|_",e.AddFootnote="_|footnote|_",e.AddComment="_|comment|_",e.ContextMenu="_|context-menu|_",e.IncreaseFontSize="_|inc-font-size|_",e.DecreaseFontSize="_|dec-font-size|_",e.IncreaseIndent="_|indent|_",e.DecreaseIndent="_|dedent|_",e.Shortcuts="_|shortcuts|_",e.Copy="_|copy|_",e.Cut="_|cut|_",e.Paste="_|paste|_",e.PastePlain="_|paste-plain|_",e.SelectAll="_|select-all|_",e.Format="_|format|_",e))($||{}),B=(e=>(e.PROD="RMR0000",e.UNKNOWN="RMR0001",e.INVALID_COMMAND_ARGUMENTS="RMR0002",e.CUSTOM="RMR0003",e.CORE_HELPERS="RMR0004",e.MUTATION="RMR0005",e.INTERNAL="RMR0006",e.MISSING_REQUIRED_EXTENSION="RMR0007",e.MANAGER_PHASE_ERROR="RMR0008",e.INVALID_GET_EXTENSION="RMR0010",e.INVALID_MANAGER_ARGUMENTS="RMR0011",e.SCHEMA="RMR0012",e.HELPERS_CALLED_IN_OUTER_SCOPE="RMR0013",e.INVALID_MANAGER_EXTENSION="RMR0014",e.DUPLICATE_COMMAND_NAMES="RMR0016",e.DUPLICATE_HELPER_NAMES="RMR0017",e.NON_CHAINABLE_COMMAND="RMR0018",e.INVALID_EXTENSION="RMR0019",e.INVALID_CONTENT="RMR0021",e.INVALID_NAME="RMR0050",e.EXTENSION="RMR0100",e.EXTENSION_SPEC="RMR0101",e.EXTENSION_EXTRA_ATTRIBUTES="RMR0102",e.INVALID_SET_EXTENSION_OPTIONS="RMR0103",e.REACT_PROVIDER_CONTEXT="RMR0200",e.REACT_GET_ROOT_PROPS="RMR0201",e.REACT_EDITOR_VIEW="RMR0202",e.REACT_CONTROLLED="RMR0203",e.REACT_NODE_VIEW="RMR0204",e.REACT_GET_CONTEXT="RMR0205",e.REACT_COMPONENTS="RMR0206",e.REACT_HOOKS="RMR0207",e.I18N_CONTEXT="RMR0300",e))(B||{}),R_=function(t){return P_(t)&&!z_(t)};function P_(e){return!!e&&typeof e=="object"}function z_(e){var t=Object.prototype.toString.call(e);return t==="[object RegExp]"||t==="[object Date]"||D_(e)}var L_=typeof Symbol=="function"&&Symbol.for,I_=L_?Symbol.for("react.element"):60103;function D_(e){return e.$$typeof===I_}function $_(e){return Array.isArray(e)?[]:{}}function zu(e,t){return t.clone!==!1&&t.isMergeableObject(e)?El($_(e),e,t):e}function H_(e,t,r){return e.concat(t).map(function(n){return zu(n,r)})}function B_(e,t){if(!t.customMerge)return El;var r=t.customMerge(e);return typeof r=="function"?r:El}function F_(e){return Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(e).filter(function(t){return Object.propertyIsEnumerable.call(e,t)}):[]}function Jx(e){return Object.keys(e).concat(F_(e))}function H4(e,t){try{return t in e}catch{return!1}}function V_(e,t){return H4(e,t)&&!(Object.hasOwnProperty.call(e,t)&&Object.propertyIsEnumerable.call(e,t))}function j_(e,t,r){var n={};return r.isMergeableObject(e)&&Jx(e).forEach(function(o){n[o]=zu(e[o],r)}),Jx(t).forEach(function(o){V_(e,o)||(H4(e,o)&&r.isMergeableObject(t[o])?n[o]=B_(o,r)(e[o],t[o],r):n[o]=zu(t[o],r))}),n}function El(e,t,r){r=r||{},r.arrayMerge=r.arrayMerge||H_,r.isMergeableObject=r.isMergeableObject||R_,r.cloneUnlessOtherwiseSpecified=zu;var n=Array.isArray(t),o=Array.isArray(e),i=n===o;return i?n?r.arrayMerge(e,t,r):j_(e,t,r):zu(t,r)}El.all=function(t,r){if(!Array.isArray(t))throw new Error("first argument should be an array");return t.reduce(function(n,o){return El(n,o,r)},{})};var U_=El,W_=U_;const K_=Dn(W_);var q_=function e(t,r){if(t===r)return!0;if(t&&r&&typeof t=="object"&&typeof r=="object"){if(t.constructor!==r.constructor)return!1;var n,o,i;if(Array.isArray(t)){if(n=t.length,n!=r.length)return!1;for(o=n;o--!==0;)if(!e(t[o],r[o]))return!1;return!0}if(t.constructor===RegExp)return t.source===r.source&&t.flags===r.flags;if(t.valueOf!==Object.prototype.valueOf)return t.valueOf()===r.valueOf();if(t.toString!==Object.prototype.toString)return t.toString()===r.toString();if(i=Object.keys(t),n=i.length,n!==Object.keys(r).length)return!1;for(o=n;o--!==0;)if(!Object.prototype.hasOwnProperty.call(r,i[o]))return!1;for(o=n;o--!==0;){var s=i[o];if(!e(t[s],r[s]))return!1}return!0}return t!==t&&r!==r};const G_=Dn(q_);/*! + * isobject + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */var B4=function(t){return t!=null&&typeof t=="object"&&Array.isArray(t)===!1};/*! + * is-plain-object + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */var Y_=B4;function Xx(e){return Y_(e)===!0&&Object.prototype.toString.call(e)==="[object Object]"}var J_=function(t){var r,n;return!(Xx(t)===!1||(r=t.constructor,typeof r!="function")||(n=r.prototype,Xx(n)===!1)||n.hasOwnProperty("isPrototypeOf")===!1)};/*! + * is-extendable + * + * Copyright (c) 2015-2017, Jon Schlinkert. + * Released under the MIT License. + */var X_=J_,Q_=function(t){return X_(t)||typeof t=="function"||Array.isArray(t)};/*! + * object.omit + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */var Z_=Q_,eA=function(t,r,n){if(!Z_(t))return{};typeof r=="function"&&(n=r,r=[]),typeof r=="string"&&(r=[r]);for(var o=typeof n=="function",i=Object.keys(t),s={},a=0;a + * + * Copyright (c) 2014-2015 Jon Schlinkert, contributors. + * Licensed under the MIT License + */var tA=B4,rA=function(t,r){if(!tA(t)&&typeof t!="function")return{};var n={};if(typeof r=="string")return r in t&&(n[r]=t[r]),n;for(var o=r.length,i=-1;++i{let d=l.prefixes[u]||"",f=c;return r===!1&&(n&&(f=f.normalize("NFD").replace(new RegExp(`[^a-zA-ZØßø0-9${n.join("")}]`,"g"),"")),n||(f=f.normalize("NFD").replace(/[^a-zA-ZØßø0-9]/g,""),d="")),n&&(d=d.replace(new RegExp(`[^${n.join("")}]`,"g"),"")),u===0?d+f:!d&&!f?"":s&&!d&&o.match(/\s/)?" "+f:(d||o)+f}).filter(Boolean)}function iA(e){const t=e.matchAll(F4).next().value,r=t?t.index:0;return e.slice(0,r+1).toUpperCase()+e.slice(r+1).toLowerCase()}function j4(e,t){return V4(e,t).reduce((r,n)=>r+iA(n),"")}function Qx(e,t){return V4(e,{...t,prefix:"-"}).join("").toLowerCase()}function E1(e,t,r,n){var o,i=!1,s=0;function a(){o&&clearTimeout(o)}function l(){a(),i=!0}typeof t!="boolean"&&(n=r,r=t,t=void 0);function c(){for(var u=arguments.length,d=new Array(u),f=0;fe?m():t!==!0&&(o=setTimeout(n?b:m,n===void 0?e-h:e))}return c.cancel=l,c}function U4(e,t,r){return r===void 0?E1(e,t,!1):E1(e,r,t!==!1)}function it(e,t,r){const n=e[t];return W4(!Rh(n),r),n}function W4(e,t){if(!e)throw new sA(t)}var sA=class extends $4.BaseError{constructor(){super(...arguments),this.name="AssertionError"}};function At(e){return Object.entries(e)}function Lu(e){return Object.keys(e)}function Nh(e){return Object.values(e)}function fr(e,t,r){return e.includes(t,r)}function ee(e){return Object.assign(Object.create(null),e)}function K4(e){return Object.prototype.toString.call(e)}function q4(e){return K4(e).slice(8,-1)}function _d(e,t){return r=>typeof r!==e?!1:t?t(r):!0}function Ev(e){return t=>q4(t)===e}var Rh=_d("undefined"),oe=_d("string"),Jt=_d("number",e=>!Number.isNaN(e)),_e=_d("function");function aA(e){return e===null}function C1(e){return e===!0||e===!1}function ps(e){if(q4(e)!=="Object")return!1;const t=Object.getPrototypeOf(e);return t===null||t===Object.getPrototypeOf({})}function lA(e){return e==null||/^[bns]/.test(typeof e)}function es(e){return aA(e)||Rh(e)}function Zt(e){return!es(e)&&(_e(e)||_d("object")(e))}var cA=Ev("RegExp");function uA(e){return Ev("Map")(e)}function dA(e){return Ev("Set")(e)}function vp(e){return Zt(e)&&!uA(e)&&!dA(e)&&Object.keys(e).length===0}var ct=Array.isArray;function Mo(e){return ct(e)&&e.length===0}function Zx(e){return ct(e)&&e.length>0}function fA(e){return e.charAt(0).toUpperCase()+e.slice(1)}function xa(e,t,r=n=>!!n){t.lastIndex=0;const n=[],o=t.flags;let i;o.includes("g")||(t=new RegExp(t.source,`g${o}`));do i=t.exec(e),i&&n.push(i);while(r(i));return t.lastIndex=0,n}function yp(){const e=Date.now(),t=yp.last||e;return yp.last=e>t?e:t+1}yp.last=0;function Cl(e=""){return`${e}${yp().toString(36)}`}function G4(e){return Sv(e,t=>!Rh(t))}function pA(e){if(!ps(e))throw new Error("An invalid value was passed into this clone utility. Expected a plain object");return{...e}}var Y4=G_;function Ml(e,t=!1){const r=t?[...e].reverse():e,n=new Set(r);return t?[...n].reverse():[...n]}function J4(e){const t=[];for(const r of e){const n=ct(r)?J4(r):[r];t.push(...n)}return t}function X4(){}function Q4(...e){return K_.all(e,{isMergeableObject:ps})}function Ad({min:e,max:t,value:r}){return rt?t:r}function Z4(e){return e[e.length-1]}function ta(e,t){return[...e].map((r,n)=>({value:r,index:n})).sort((r,n)=>t(r.value,n.value)||r.index-n.index).map(({value:r})=>r)}function hA(e,t,r){try{if(oe(t)&&t in e)return e[t];ct(t)&&(t=`['${t.join("']['")}']`);let n=e;return t.replace(/\[\s*(["'])(.*?)\1\s*]|^\s*(\w+)\s*(?=\.|\[|$)|\.\s*(\w*)\s*(?=\.|\[|$)|\[\s*(-?\d+)\s*]/g,(o,i,s,a,l,c)=>(n=n[s||a||l||c],"")),n===void 0?r:n}catch{return r}}function mA(e,t){const r=pA(t);let n=r;for(const[o,i]of e.entries()){const s=o>=e.length-1;let a=n[i];if(s){if(ct(n)){const l=Number.parseInt(i.toString(),10);Jt(l)&&n.splice(l,1)}else Reflect.deleteProperty(n,i);return r}if(lA(a))return r;a=ct(a)?[...a]:{...a},n[i]=a,n=a}return r}function gA(e){return t=>hA(t,e)}function eE(e,t,r=!1){const n=[],o=new Set,i=_e(t)?t:gA(t),s=r?[...e].reverse():e;for(const a of s){const l=i(a);o.has(l)||(o.add(l),n.push(a))}return r?n.reverse():n}function Cv(e,t){const r=ct(e)?e[0]:e;return Jt(t)?r<=t?Array.from({length:t+1-r},(n,o)=>o+r):Array.from({length:r+1-t},(n,o)=>-1*o+r):Array.from({length:Math.abs(r)},(n,o)=>(r<0?-1:1)*o)}function ek(e,...t){const r=t.filter(Jt);return e>=Math.min(...r)&&e<=Math.max(...r)}function tE(e){return _e(e)?e():e}var rE="https://remirror.io/docs/errors",vA={[B.UNKNOWN]:"An error occurred but we're not quite sure why. 🧐",[B.INVALID_COMMAND_ARGUMENTS]:"The arguments passed to the command method were invalid.",[B.CUSTOM]:"This is a custom error, possibly thrown by an external library.",[B.CORE_HELPERS]:"An error occurred in a function called from the `@remirror/core-helpers` library.",[B.MUTATION]:"Mutation of immutable value detected.",[B.INTERNAL]:"This is an error which should not occur and is internal to the remirror codebase.",[B.MISSING_REQUIRED_EXTENSION]:"Your editor is missing a required extension.",[B.MANAGER_PHASE_ERROR]:"This occurs when accessing a method or property before it is available.",[B.INVALID_GET_EXTENSION]:"The user requested an invalid extension from the getExtensions method. Please check the `createExtensions` return method is returning an extension with the defined constructor.",[B.INVALID_MANAGER_ARGUMENTS]:"Invalid value(s) passed into `Manager` constructor. Only `Presets` and `Extensions` are supported.",[B.SCHEMA]:"There is a problem with the schema or you are trying to access a node / mark that doesn't exists.",[B.HELPERS_CALLED_IN_OUTER_SCOPE]:"The `helpers` method which is passed into the ``create*` method should only be called within returned method since it relies on an active view (not present in the outer scope).",[B.INVALID_MANAGER_EXTENSION]:"You requested an invalid extension from the manager.",[B.DUPLICATE_COMMAND_NAMES]:"Command method names must be unique within the editor.",[B.DUPLICATE_HELPER_NAMES]:"Helper method names must be unique within the editor.",[B.NON_CHAINABLE_COMMAND]:"Attempted to chain a non chainable command.",[B.INVALID_EXTENSION]:"The provided extension is invalid.",[B.INVALID_CONTENT]:"The content provided to the editor is not supported.",[B.INVALID_NAME]:"An invalid name was used for the extension.",[B.EXTENSION]:"An error occurred within an extension. More details should be made available.",[B.EXTENSION_SPEC]:"The spec was defined without calling the `defaults`, `parse` or `dom` methods.",[B.EXTENSION_EXTRA_ATTRIBUTES]:"Extra attributes must either be a string or an object.",[B.INVALID_SET_EXTENSION_OPTIONS]:"A call to `extension.setOptions` was made with invalid keys.",[B.REACT_PROVIDER_CONTEXT]:"`useRemirrorContext` was called outside of the `remirror` context. It can only be used within an active remirror context created by the ``.",[B.REACT_GET_ROOT_PROPS]:"`getRootProps` has been attached to the DOM more than once. It should only be attached to the dom once per editor.",[B.REACT_EDITOR_VIEW]:"A problem occurred adding the editor view to the dom.",[B.REACT_CONTROLLED]:"There is a problem with your controlled editor setup.",[B.REACT_NODE_VIEW]:"Something went wrong with your custom ReactNodeView Component.",[B.REACT_GET_CONTEXT]:"You attempted to call `getContext` provided by the `useRemirror` prop during the first render of the editor. This is not possible and should only be after the editor first mounts.",[B.REACT_COMPONENTS]:"An error occurred within a remirror component.",[B.REACT_HOOKS]:"An error occurred within a remirror hook.",[B.I18N_CONTEXT]:"You called `useI18n()` outside of an `I18nProvider` context."};function yA(e){return oe(e)&&fr(Nh(B),e)}function bA(e,t){const r=vA[e],n=r?`${r} + +`:"",o=t?`${t} + +`:"";return`${n}${o}For more information visit ${rE}#${e.toLowerCase()}`}var nE=class extends $4.BaseError{constructor({code:e,message:t,disableLogging:r=!1}={}){const n=yA(e)?e:B.CUSTOM;super(bA(n,t)),this.errorCode=n,this.url=`${rE}#${n.toLowerCase()}`,r||console.error(this.message)}static create(e={}){return new nE(e)}};function re(e,t){if(!e)throw nE.create(t)}function Ph(e){if(typeof e!="object"||e===null)return e;const t=Symbol.toStringTag in e&&e[Symbol.toStringTag]==="Module"?e.default??e:e;return t&&typeof e=="object"&&"__esModule"in t&&t.__esModule&&t.default!==void 0?t.default:t}function $s(e,t={}){return e}function Kt(e){this.content=e}Kt.prototype={constructor:Kt,find:function(e){for(var t=0;t>1}};Kt.from=function(e){if(e instanceof Kt)return e;var t=[];if(e)for(var r in e)t.push(r,e[r]);return new Kt(t)};function oE(e,t,r){for(let n=0;;n++){if(n==e.childCount||n==t.childCount)return e.childCount==t.childCount?null:r;let o=e.child(n),i=t.child(n);if(o==i){r+=o.nodeSize;continue}if(!o.sameMarkup(i))return r;if(o.isText&&o.text!=i.text){for(let s=0;o.text[s]==i.text[s];s++)r++;return r}if(o.content.size||i.content.size){let s=oE(o.content,i.content,r+1);if(s!=null)return s}r+=o.nodeSize}}function iE(e,t,r,n){for(let o=e.childCount,i=t.childCount;;){if(o==0||i==0)return o==i?null:{a:r,b:n};let s=e.child(--o),a=t.child(--i),l=s.nodeSize;if(s==a){r-=l,n-=l;continue}if(!s.sameMarkup(a))return{a:r,b:n};if(s.isText&&s.text!=a.text){let c=0,u=Math.min(s.text.length,a.text.length);for(;ct&&n(l,o+a,i||null,s)!==!1&&l.content.size){let u=a+1;l.nodesBetween(Math.max(0,t-u),Math.min(l.content.size,r-u),n,o+u)}a=c}}descendants(t){this.nodesBetween(0,this.size,t)}textBetween(t,r,n,o){let i="",s=!0;return this.nodesBetween(t,r,(a,l)=>{a.isText?(i+=a.text.slice(Math.max(t,l)-l,r-l),s=!n):a.isLeaf?(o?i+=typeof o=="function"?o(a):o:a.type.spec.leafText&&(i+=a.type.spec.leafText(a)),s=!n):!s&&a.isBlock&&(i+=n,s=!0)},0),i}append(t){if(!t.size)return this;if(!this.size)return t;let r=this.lastChild,n=t.firstChild,o=this.content.slice(),i=0;for(r.isText&&r.sameMarkup(n)&&(o[o.length-1]=r.withText(r.text+n.text),i=1);it)for(let i=0,s=0;st&&((sr)&&(a.isText?a=a.cut(Math.max(0,t-s),Math.min(a.text.length,r-s)):a=a.cut(Math.max(0,t-s-1),Math.min(a.content.size,r-s-1))),n.push(a),o+=a.nodeSize),s=l}return new R(n,o)}cutByIndex(t,r){return t==r?R.empty:t==0&&r==this.content.length?this:new R(this.content.slice(t,r))}replaceChild(t,r){let n=this.content[t];if(n==r)return this;let o=this.content.slice(),i=this.size+r.nodeSize-n.nodeSize;return o[t]=r,new R(o,i)}addToStart(t){return new R([t].concat(this.content),this.size+t.nodeSize)}addToEnd(t){return new R(this.content.concat(t),this.size+t.nodeSize)}eq(t){if(this.content.length!=t.content.length)return!1;for(let r=0;rthis.size||t<0)throw new RangeError(`Position ${t} outside of fragment (${this})`);for(let n=0,o=0;;n++){let i=this.child(n),s=o+i.nodeSize;if(s>=t)return s==t||r>0?rf(n+1,s):rf(n,o);o=s}}toString(){return"<"+this.toStringInner()+">"}toStringInner(){return this.content.join(", ")}toJSON(){return this.content.length?this.content.map(t=>t.toJSON()):null}static fromJSON(t,r){if(!r)return R.empty;if(!Array.isArray(r))throw new RangeError("Invalid input for Fragment.fromJSON");return new R(r.map(t.nodeFromJSON))}static fromArray(t){if(!t.length)return R.empty;let r,n=0;for(let o=0;othis.type.rank&&(r||(r=t.slice(0,o)),r.push(this),n=!0),r&&r.push(i)}}return r||(r=t.slice()),n||r.push(this),r}removeFromSet(t){for(let r=0;rn.type.rank-o.type.rank),r}}Te.none=[];class xp extends Error{}class K{constructor(t,r,n){this.content=t,this.openStart=r,this.openEnd=n}get size(){return this.content.size-this.openStart-this.openEnd}insertAt(t,r){let n=aE(this.content,t+this.openStart,r);return n&&new K(n,this.openStart,this.openEnd)}removeBetween(t,r){return new K(sE(this.content,t+this.openStart,r+this.openStart),this.openStart,this.openEnd)}eq(t){return this.content.eq(t.content)&&this.openStart==t.openStart&&this.openEnd==t.openEnd}toString(){return this.content+"("+this.openStart+","+this.openEnd+")"}toJSON(){if(!this.content.size)return null;let t={content:this.content.toJSON()};return this.openStart>0&&(t.openStart=this.openStart),this.openEnd>0&&(t.openEnd=this.openEnd),t}static fromJSON(t,r){if(!r)return K.empty;let n=r.openStart||0,o=r.openEnd||0;if(typeof n!="number"||typeof o!="number")throw new RangeError("Invalid input for Slice.fromJSON");return new K(R.fromJSON(t,r.content),n,o)}static maxOpen(t,r=!0){let n=0,o=0;for(let i=t.firstChild;i&&!i.isLeaf&&(r||!i.type.spec.isolating);i=i.firstChild)n++;for(let i=t.lastChild;i&&!i.isLeaf&&(r||!i.type.spec.isolating);i=i.lastChild)o++;return new K(t,n,o)}}K.empty=new K(R.empty,0,0);function sE(e,t,r){let{index:n,offset:o}=e.findIndex(t),i=e.maybeChild(n),{index:s,offset:a}=e.findIndex(r);if(o==t||i.isText){if(a!=r&&!e.child(s).isText)throw new RangeError("Removing non-flat range");return e.cut(0,t).append(e.cut(r))}if(n!=s)throw new RangeError("Removing non-flat range");return e.replaceChild(n,i.copy(sE(i.content,t-o-1,r-o-1)))}function aE(e,t,r,n){let{index:o,offset:i}=e.findIndex(t),s=e.maybeChild(o);if(i==t||s.isText)return n&&!n.canReplace(o,o,r)?null:e.cut(0,t).append(r).append(e.cut(t));let a=aE(s.content,t-i-1,r);return a&&e.replaceChild(o,s.copy(a))}function xA(e,t,r){if(r.openStart>e.depth)throw new xp("Inserted content deeper than insertion position");if(e.depth-r.openStart!=t.depth-r.openEnd)throw new xp("Inconsistent open depths");return lE(e,t,r,0)}function lE(e,t,r,n){let o=e.index(n),i=e.node(n);if(o==t.index(n)&&n=0&&e.isText&&e.sameMarkup(t[r])?t[r]=e.withText(t[r].text+e.text):t.push(e)}function mu(e,t,r,n){let o=(t||e).node(r),i=0,s=t?t.index(r):o.childCount;e&&(i=e.index(r),e.depth>r?i++:e.textOffset&&(qs(e.nodeAfter,n),i++));for(let a=i;ao&&M1(e,t,o+1),s=n.depth>o&&M1(r,n,o+1),a=[];return mu(null,e,o,a),i&&s&&t.index(o)==r.index(o)?(cE(i,s),qs(Gs(i,uE(e,t,r,n,o+1)),a)):(i&&qs(Gs(i,kp(e,t,o+1)),a),mu(t,r,o,a),s&&qs(Gs(s,kp(r,n,o+1)),a)),mu(n,null,o,a),new R(a)}function kp(e,t,r){let n=[];if(mu(null,e,r,n),e.depth>r){let o=M1(e,t,r+1);qs(Gs(o,kp(e,t,r+1)),n)}return mu(t,null,r,n),new R(n)}function kA(e,t){let r=t.depth-e.openStart,o=t.node(r).copy(e.content);for(let i=r-1;i>=0;i--)o=t.node(i).copy(R.from(o));return{start:o.resolveNoCache(e.openStart+r),end:o.resolveNoCache(o.content.size-e.openEnd-r)}}class Tl{constructor(t,r,n){this.pos=t,this.path=r,this.parentOffset=n,this.depth=r.length/3-1}resolveDepth(t){return t==null?this.depth:t<0?this.depth+t:t}get parent(){return this.node(this.depth)}get doc(){return this.node(0)}node(t){return this.path[this.resolveDepth(t)*3]}index(t){return this.path[this.resolveDepth(t)*3+1]}indexAfter(t){return t=this.resolveDepth(t),this.index(t)+(t==this.depth&&!this.textOffset?0:1)}start(t){return t=this.resolveDepth(t),t==0?0:this.path[t*3-1]+1}end(t){return t=this.resolveDepth(t),this.start(t)+this.node(t).content.size}before(t){if(t=this.resolveDepth(t),!t)throw new RangeError("There is no position before the top-level node");return t==this.depth+1?this.pos:this.path[t*3-1]}after(t){if(t=this.resolveDepth(t),!t)throw new RangeError("There is no position after the top-level node");return t==this.depth+1?this.pos:this.path[t*3-1]+this.path[t*3].nodeSize}get textOffset(){return this.pos-this.path[this.path.length-1]}get nodeAfter(){let t=this.parent,r=this.index(this.depth);if(r==t.childCount)return null;let n=this.pos-this.path[this.path.length-1],o=t.child(r);return n?t.child(r).cut(n):o}get nodeBefore(){let t=this.index(this.depth),r=this.pos-this.path[this.path.length-1];return r?this.parent.child(t).cut(0,r):t==0?null:this.parent.child(t-1)}posAtIndex(t,r){r=this.resolveDepth(r);let n=this.path[r*3],o=r==0?0:this.path[r*3-1]+1;for(let i=0;i0;r--)if(this.start(r)<=t&&this.end(r)>=t)return r;return 0}blockRange(t=this,r){if(t.pos=0;n--)if(t.pos<=this.end(n)&&(!r||r(this.node(n))))return new ra(this,t,n);return null}sameParent(t){return this.pos-this.parentOffset==t.pos-t.parentOffset}max(t){return t.pos>this.pos?t:this}min(t){return t.pos=0&&r<=t.content.size))throw new RangeError("Position "+r+" out of range");let n=[],o=0,i=r;for(let s=t;;){let{index:a,offset:l}=s.content.findIndex(i),c=i-l;if(n.push(s,a,o+l),!c||(s=s.child(a),s.isText))break;i=c-1,o+=l+1}return new Tl(r,n,i)}static resolveCached(t,r){for(let o=0;ot&&this.nodesBetween(t,r,i=>(n.isInSet(i.marks)&&(o=!0),!o)),o}get isBlock(){return this.type.isBlock}get isTextblock(){return this.type.isTextblock}get inlineContent(){return this.type.inlineContent}get isInline(){return this.type.isInline}get isText(){return this.type.isText}get isLeaf(){return this.type.isLeaf}get isAtom(){return this.type.isAtom}toString(){if(this.type.spec.toDebugString)return this.type.spec.toDebugString(this);let t=this.type.name;return this.content.size&&(t+="("+this.content.toStringInner()+")"),dE(this.marks,t)}contentMatchAt(t){let r=this.type.contentMatch.matchFragment(this.content,0,t);if(!r)throw new Error("Called contentMatchAt on a node with invalid content");return r}canReplace(t,r,n=R.empty,o=0,i=n.childCount){let s=this.contentMatchAt(t).matchFragment(n,o,i),a=s&&s.matchFragment(this.content,r);if(!a||!a.validEnd)return!1;for(let l=o;lr.type.name)}`);this.content.forEach(r=>r.check())}toJSON(){let t={type:this.type.name};for(let r in this.attrs){t.attrs=this.attrs;break}return this.content.size&&(t.content=this.content.toJSON()),this.marks.length&&(t.marks=this.marks.map(r=>r.toJSON())),t}static fromJSON(t,r){if(!r)throw new RangeError("Invalid input for Node.fromJSON");let n=null;if(r.marks){if(!Array.isArray(r.marks))throw new RangeError("Invalid mark data for Node.fromJSON");n=r.marks.map(t.markFromJSON)}if(r.type=="text"){if(typeof r.text!="string")throw new RangeError("Invalid text node in JSON");return t.text(r.text,n)}let o=R.fromJSON(t,r.content);return t.nodeType(r.type).create(r.attrs,o,n)}};Fi.prototype.text=void 0;class wp extends Fi{constructor(t,r,n,o){if(super(t,r,null,o),!n)throw new RangeError("Empty text nodes are not allowed");this.text=n}toString(){return this.type.spec.toDebugString?this.type.spec.toDebugString(this):dE(this.marks,JSON.stringify(this.text))}get textContent(){return this.text}textBetween(t,r){return this.text.slice(t,r)}get nodeSize(){return this.text.length}mark(t){return t==this.marks?this:new wp(this.type,this.attrs,this.text,t)}withText(t){return t==this.text?this:new wp(this.type,this.attrs,t,this.marks)}cut(t=0,r=this.text.length){return t==0&&r==this.text.length?this:this.withText(this.text.slice(t,r))}eq(t){return this.sameMarkup(t)&&this.text==t.text}toJSON(){let t=super.toJSON();return t.text=this.text,t}}function dE(e,t){for(let r=e.length-1;r>=0;r--)t=e[r].type.name+"("+t+")";return t}class na{constructor(t){this.validEnd=t,this.next=[],this.wrapCache=[]}static parse(t,r){let n=new EA(t,r);if(n.next==null)return na.empty;let o=fE(n);n.next&&n.err("Unexpected trailing text");let i=NA(AA(o));return RA(i,n),i}matchType(t){for(let r=0;rc.createAndFill()));for(let c=0;c=this.next.length)throw new RangeError(`There's no ${t}th edge in this content match`);return this.next[t]}toString(){let t=[];function r(n){t.push(n);for(let o=0;o{let i=o+(n.validEnd?"*":" ")+" ";for(let s=0;s"+t.indexOf(n.next[s].next);return i}).join(` +`)}}na.empty=new na(!0);class EA{constructor(t,r){this.string=t,this.nodeTypes=r,this.inline=null,this.pos=0,this.tokens=t.split(/\s*(?=\b|\W|$)/),this.tokens[this.tokens.length-1]==""&&this.tokens.pop(),this.tokens[0]==""&&this.tokens.shift()}get next(){return this.tokens[this.pos]}eat(t){return this.next==t&&(this.pos++||!0)}err(t){throw new SyntaxError(t+" (in content expression '"+this.string+"')")}}function fE(e){let t=[];do t.push(CA(e));while(e.eat("|"));return t.length==1?t[0]:{type:"choice",exprs:t}}function CA(e){let t=[];do t.push(MA(e));while(e.next&&e.next!=")"&&e.next!="|");return t.length==1?t[0]:{type:"seq",exprs:t}}function MA(e){let t=_A(e);for(;;)if(e.eat("+"))t={type:"plus",expr:t};else if(e.eat("*"))t={type:"star",expr:t};else if(e.eat("?"))t={type:"opt",expr:t};else if(e.eat("{"))t=TA(e,t);else break;return t}function tk(e){/\D/.test(e.next)&&e.err("Expected number, got '"+e.next+"'");let t=Number(e.next);return e.pos++,t}function TA(e,t){let r=tk(e),n=r;return e.eat(",")&&(e.next!="}"?n=tk(e):n=-1),e.eat("}")||e.err("Unclosed braced range"),{type:"range",min:r,max:n,expr:t}}function OA(e,t){let r=e.nodeTypes,n=r[t];if(n)return[n];let o=[];for(let i in r){let s=r[i];s.groups.indexOf(t)>-1&&o.push(s)}return o.length==0&&e.err("No node type or group '"+t+"' found"),o}function _A(e){if(e.eat("(")){let t=fE(e);return e.eat(")")||e.err("Missing closing paren"),t}else if(/\W/.test(e.next))e.err("Unexpected token '"+e.next+"'");else{let t=OA(e,e.next).map(r=>(e.inline==null?e.inline=r.isInline:e.inline!=r.isInline&&e.err("Mixing inline and block content"),{type:"name",value:r}));return e.pos++,t.length==1?t[0]:{type:"choice",exprs:t}}}function AA(e){let t=[[]];return o(i(e,0),r()),t;function r(){return t.push([])-1}function n(s,a,l){let c={term:l,to:a};return t[s].push(c),c}function o(s,a){s.forEach(l=>l.to=a)}function i(s,a){if(s.type=="choice")return s.exprs.reduce((l,c)=>l.concat(i(c,a)),[]);if(s.type=="seq")for(let l=0;;l++){let c=i(s.exprs[l],a);if(l==s.exprs.length-1)return c;o(c,a=r())}else if(s.type=="star"){let l=r();return n(a,l),o(i(s.expr,l),l),[n(l)]}else if(s.type=="plus"){let l=r();return o(i(s.expr,a),l),o(i(s.expr,l),l),[n(l)]}else{if(s.type=="opt")return[n(a)].concat(i(s.expr,a));if(s.type=="range"){let l=a;for(let c=0;c{e[s].forEach(({term:a,to:l})=>{if(!a)return;let c;for(let u=0;u{c||o.push([a,c=[]]),c.indexOf(u)==-1&&c.push(u)})})});let i=t[n.join(",")]=new na(n.indexOf(e.length-1)>-1);for(let s=0;s-1}allowsMarks(t){if(this.markSet==null)return!0;for(let r=0;rn[i]=new vE(i,r,s));let o=r.spec.topNode||"doc";if(!n[o])throw new RangeError("Schema is missing its top node type ('"+o+"')");if(!n.text)throw new RangeError("Every schema needs a 'text' type");for(let i in n.text.attrs)throw new RangeError("The text node type should not have attributes");return n}};class PA{constructor(t){this.hasDefault=Object.prototype.hasOwnProperty.call(t,"default"),this.default=t.default}get isRequired(){return!this.hasDefault}}class Nd{constructor(t,r,n,o){this.name=t,this.rank=r,this.schema=n,this.spec=o,this.attrs=gE(o.attrs),this.excluded=null;let i=hE(this.attrs);this.instance=i?new Te(this,i):null}create(t=null){return!t&&this.instance?this.instance:new Te(this,mE(this.attrs,t))}static compile(t,r){let n=Object.create(null),o=0;return t.forEach((i,s)=>n[i]=new Nd(i,o++,r,s)),n}removeFromSet(t){for(var r=0;r-1}}let zA=class{constructor(t){this.cached=Object.create(null);let r=this.spec={};for(let o in t)r[o]=t[o];r.nodes=Kt.from(t.nodes),r.marks=Kt.from(t.marks||{}),this.nodes=O1.compile(this.spec.nodes,this),this.marks=Nd.compile(this.spec.marks,this);let n=Object.create(null);for(let o in this.nodes){if(o in this.marks)throw new RangeError(o+" can not be both a node and a mark");let i=this.nodes[o],s=i.spec.content||"",a=i.spec.marks;i.contentMatch=n[s]||(n[s]=na.parse(s,this.nodes)),i.inlineContent=i.contentMatch.inlineContent,i.markSet=a=="_"?null:a?nk(this,a.split(" ")):a==""||!i.inlineContent?[]:null}for(let o in this.marks){let i=this.marks[o],s=i.spec.excludes;i.excluded=s==null?[i]:s==""?[]:nk(this,s.split(" "))}this.nodeFromJSON=this.nodeFromJSON.bind(this),this.markFromJSON=this.markFromJSON.bind(this),this.topNodeType=this.nodes[this.spec.topNode||"doc"],this.cached.wrappings=Object.create(null)}node(t,r=null,n,o){if(typeof t=="string")t=this.nodeType(t);else if(t instanceof O1){if(t.schema!=this)throw new RangeError("Node type from different schema used ("+t.name+")")}else throw new RangeError("Invalid node type: "+t);return t.createChecked(r,n,o)}text(t,r){let n=this.nodes.text;return new wp(n,n.defaultAttrs,t,Te.setFrom(r))}mark(t,r){return typeof t=="string"&&(t=this.marks[t]),t.create(r)}nodeFromJSON(t){return Fi.fromJSON(this,t)}markFromJSON(t){return Te.fromJSON(this,t)}nodeType(t){let r=this.nodes[t];if(!r)throw new RangeError("Unknown node type: "+t);return r}};function nk(e,t){let r=[];for(let n=0;n-1)&&r.push(s=l)}if(!s)throw new SyntaxError("Unknown mark type: '"+t[n]+"'")}return r}let Mv=class _1{constructor(t,r){this.schema=t,this.rules=r,this.tags=[],this.styles=[],r.forEach(n=>{n.tag?this.tags.push(n):n.style&&this.styles.push(n)}),this.normalizeLists=!this.tags.some(n=>{if(!/^(ul|ol)\b/.test(n.tag)||!n.node)return!1;let o=t.nodes[n.node];return o.contentMatch.matchType(o)})}parse(t,r={}){let n=new ik(this,r,!1);return n.addAll(t,r.from,r.to),n.finish()}parseSlice(t,r={}){let n=new ik(this,r,!0);return n.addAll(t,r.from,r.to),K.maxOpen(n.finish())}matchTag(t,r,n){for(let o=n?this.tags.indexOf(n)+1:0;ot.length&&(a.charCodeAt(t.length)!=61||a.slice(t.length+1)!=r))){if(s.getAttrs){let l=s.getAttrs(r);if(l===!1)continue;s.attrs=l||void 0}return s}}}static schemaRules(t){let r=[];function n(o){let i=o.priority==null?50:o.priority,s=0;for(;s{n(s=sk(s)),s.mark||s.ignore||s.clearMark||(s.mark=o)})}for(let o in t.nodes){let i=t.nodes[o].spec.parseDOM;i&&i.forEach(s=>{n(s=sk(s)),s.node||s.ignore||s.mark||(s.node=o)})}return r}static fromSchema(t){return t.cached.domParser||(t.cached.domParser=new _1(t,_1.schemaRules(t)))}};const yE={address:!0,article:!0,aside:!0,blockquote:!0,canvas:!0,dd:!0,div:!0,dl:!0,fieldset:!0,figcaption:!0,figure:!0,footer:!0,form:!0,h1:!0,h2:!0,h3:!0,h4:!0,h5:!0,h6:!0,header:!0,hgroup:!0,hr:!0,li:!0,noscript:!0,ol:!0,output:!0,p:!0,pre:!0,section:!0,table:!0,tfoot:!0,ul:!0},LA={head:!0,noscript:!0,object:!0,script:!0,style:!0,title:!0},bE={ol:!0,ul:!0},Sp=1,Ep=2,gu=4;function ok(e,t,r){return t!=null?(t?Sp:0)|(t==="full"?Ep:0):e&&e.whitespace=="pre"?Sp|Ep:r&~gu}class nf{constructor(t,r,n,o,i,s,a){this.type=t,this.attrs=r,this.marks=n,this.pendingMarks=o,this.solid=i,this.options=a,this.content=[],this.activeMarks=Te.none,this.stashMarks=[],this.match=s||(a&gu?null:t.contentMatch)}findWrapping(t){if(!this.match){if(!this.type)return[];let r=this.type.contentMatch.fillBefore(R.from(t));if(r)this.match=this.type.contentMatch.matchFragment(r);else{let n=this.type.contentMatch,o;return(o=n.findWrapping(t.type))?(this.match=n,o):null}}return this.match.findWrapping(t.type)}finish(t){if(!(this.options&Sp)){let n=this.content[this.content.length-1],o;if(n&&n.isText&&(o=/[ \t\r\n\u000c]+$/.exec(n.text))){let i=n;n.text.length==o[0].length?this.content.pop():this.content[this.content.length-1]=i.withText(i.text.slice(0,i.text.length-o[0].length))}}let r=R.from(this.content);return!t&&this.match&&(r=r.append(this.match.fillBefore(R.empty,!0))),this.type?this.type.create(this.attrs,r,this.marks):r}popFromStashMark(t){for(let r=this.stashMarks.length-1;r>=0;r--)if(t.eq(this.stashMarks[r]))return this.stashMarks.splice(r,1)[0]}applyPending(t){for(let r=0,n=this.pendingMarks;rthis.addAll(t)),s&&this.sync(a),this.needsBlock=l}else this.withStyleRules(t,()=>{this.addElementByRule(t,i,i.consuming===!1?o:void 0)})}leafFallback(t){t.nodeName=="BR"&&this.top.type&&this.top.type.inlineContent&&this.addTextNode(t.ownerDocument.createTextNode(` +`))}ignoreFallback(t){t.nodeName=="BR"&&(!this.top.type||!this.top.type.inlineContent)&&this.findPlace(this.parser.schema.text("-"))}readStyles(t){let r=Te.none,n=Te.none;for(let o=0;o{s.clearMark(a)&&(n=a.addToSet(n))}):r=this.parser.schema.marks[s.mark].create(s.attrs).addToSet(r),s.consuming===!1)i=s;else break}return[r,n]}addElementByRule(t,r,n){let o,i,s;r.node?(i=this.parser.schema.nodes[r.node],i.isLeaf?this.insertNode(i.create(r.attrs))||this.leafFallback(t):o=this.enter(i,r.attrs||null,r.preserveWhitespace)):(s=this.parser.schema.marks[r.mark].create(r.attrs),this.addPendingMark(s));let a=this.top;if(i&&i.isLeaf)this.findInside(t);else if(n)this.addElement(t,n);else if(r.getContent)this.findInside(t),r.getContent(t,this.parser.schema).forEach(l=>this.insertNode(l));else{let l=t;typeof r.contentElement=="string"?l=t.querySelector(r.contentElement):typeof r.contentElement=="function"?l=r.contentElement(t):r.contentElement&&(l=r.contentElement),this.findAround(t,l,!0),this.addAll(l)}o&&this.sync(a)&&this.open--,s&&this.removePendingMark(s,a)}addAll(t,r,n){let o=r||0;for(let i=r?t.childNodes[r]:t.firstChild,s=n==null?null:t.childNodes[n];i!=s;i=i.nextSibling,++o)this.findAtPoint(t,o),this.addDOM(i);this.findAtPoint(t,o)}findPlace(t){let r,n;for(let o=this.open;o>=0;o--){let i=this.nodes[o],s=i.findWrapping(t);if(s&&(!r||r.length>s.length)&&(r=s,n=i,!s.length)||i.solid)break}if(!r)return!1;this.sync(n);for(let o=0;othis.open){for(;r>this.open;r--)this.nodes[r-1].content.push(this.nodes[r].finish(t));this.nodes.length=this.open+1}}finish(){return this.open=0,this.closeExtra(this.isOpen),this.nodes[0].finish(this.isOpen||this.options.topOpen)}sync(t){for(let r=this.open;r>=0;r--)if(this.nodes[r]==t)return this.open=r,!0;return!1}get currentPos(){this.closeExtra();let t=0;for(let r=this.open;r>=0;r--){let n=this.nodes[r].content;for(let o=n.length-1;o>=0;o--)t+=n[o].nodeSize;r&&t++}return t}findAtPoint(t,r){if(this.find)for(let n=0;n-1)return t.split(/\s*\|\s*/).some(this.matchesContext,this);let r=t.split("/"),n=this.options.context,o=!this.isOpen&&(!n||n.parent.type==this.nodes[0].type),i=-(n?n.depth+1:0)+(o?0:1),s=(a,l)=>{for(;a>=0;a--){let c=r[a];if(c==""){if(a==r.length-1||a==0)continue;for(;l>=i;l--)if(s(a-1,l))return!0;return!1}else{let u=l>0||l==0&&o?this.nodes[l].type:n&&l>=i?n.node(l-i).type:null;if(!u||u.name!=c&&u.groups.indexOf(c)==-1)return!1;l--}}return!0};return s(r.length-1,this.open)}textblockFromContext(){let t=this.options.context;if(t)for(let r=t.depth;r>=0;r--){let n=t.node(r).contentMatchAt(t.indexAfter(r)).defaultType;if(n&&n.isTextblock&&n.defaultAttrs)return n}for(let r in this.parser.schema.nodes){let n=this.parser.schema.nodes[r];if(n.isTextblock&&n.defaultAttrs)return n}}addPendingMark(t){let r=BA(t,this.top.pendingMarks);r&&this.top.stashMarks.push(r),this.top.pendingMarks=t.addToSet(this.top.pendingMarks)}removePendingMark(t,r){for(let n=this.open;n>=0;n--){let o=this.nodes[n];if(o.pendingMarks.lastIndexOf(t)>-1)o.pendingMarks=t.removeFromSet(o.pendingMarks);else{o.activeMarks=t.removeFromSet(o.activeMarks);let s=o.popFromStashMark(t);s&&o.type&&o.type.allowsMarkType(s.type)&&(o.activeMarks=s.addToSet(o.activeMarks))}if(o==r)break}}}function IA(e){for(let t=e.firstChild,r=null;t;t=t.nextSibling){let n=t.nodeType==1?t.nodeName.toLowerCase():null;n&&bE.hasOwnProperty(n)&&r?(r.appendChild(t),t=r):n=="li"?r=t:n&&(r=null)}}function DA(e,t){return(e.matches||e.msMatchesSelector||e.webkitMatchesSelector||e.mozMatchesSelector).call(e,t)}function $A(e){let t=/\s*([\w-]+)\s*:\s*([^;]+)/g,r,n=[];for(;r=t.exec(e);)n.push(r[1],r[2].trim());return n}function sk(e){let t={};for(let r in e)t[r]=e[r];return t}function HA(e,t){let r=t.schema.nodes;for(let n in r){let o=r[n];if(!o.allowsMarkType(e))continue;let i=[],s=a=>{i.push(a);for(let l=0;l{if(i.length||s.marks.length){let a=0,l=0;for(;a=0;o--){let i=this.serializeMark(t.marks[o],t.isInline,r);i&&((i.contentDOM||i.dom).appendChild(n),n=i.dom)}return n}serializeMark(t,r,n={}){let o=this.marks[t.type.name];return o&&an.renderSpec(lg(n),o(t,r))}static renderSpec(t,r,n=null){if(typeof r=="string")return{dom:t.createTextNode(r)};if(r.nodeType!=null)return{dom:r};if(r.dom&&r.dom.nodeType!=null)return r;let o=r[0],i=o.indexOf(" ");i>0&&(n=o.slice(0,i),o=o.slice(i+1));let s,a=n?t.createElementNS(n,o):t.createElement(o),l=r[1],c=1;if(l&&typeof l=="object"&&l.nodeType==null&&!Array.isArray(l)){c=2;for(let u in l)if(l[u]!=null){let d=u.indexOf(" ");d>0?a.setAttributeNS(u.slice(0,d),u.slice(d+1),l[u]):a.setAttribute(u,l[u])}}for(let u=c;uc)throw new RangeError("Content hole must be the only child of its parent node");return{dom:a,contentDOM:a}}else{let{dom:f,contentDOM:p}=an.renderSpec(t,d,n);if(a.appendChild(f),p){if(s)throw new RangeError("Multiple content holes");s=p}}}return{dom:a,contentDOM:s}}static fromSchema(t){return t.cached.domSerializer||(t.cached.domSerializer=new an(this.nodesFromSchema(t),this.marksFromSchema(t)))}static nodesFromSchema(t){let r=ak(t.nodes);return r.text||(r.text=n=>n.text),r}static marksFromSchema(t){return ak(t.marks)}}function ak(e){let t={};for(let r in e){let n=e[r].spec.toDOM;n&&(t[r]=n)}return t}function lg(e){return e.document||window.document}const xE=65535,kE=Math.pow(2,16);function FA(e,t){return e+t*kE}function lk(e){return e&xE}function VA(e){return(e-(e&xE))/kE}const wE=1,SE=2,If=4,EE=8;class A1{constructor(t,r,n){this.pos=t,this.delInfo=r,this.recover=n}get deleted(){return(this.delInfo&EE)>0}get deletedBefore(){return(this.delInfo&(wE|If))>0}get deletedAfter(){return(this.delInfo&(SE|If))>0}get deletedAcross(){return(this.delInfo&If)>0}}class nn{constructor(t,r=!1){if(this.ranges=t,this.inverted=r,!t.length&&nn.empty)return nn.empty}recover(t){let r=0,n=lk(t);if(!this.inverted)for(let o=0;ot)break;let c=this.ranges[a+i],u=this.ranges[a+s],d=l+c;if(t<=d){let f=c?t==l?-1:t==d?1:r:r,p=l+o+(f<0?0:u);if(n)return p;let h=t==(r<0?l:d)?null:FA(a/3,t-l),m=t==l?SE:t==d?wE:If;return(r<0?t!=l:t!=d)&&(m|=EE),new A1(p,m,h)}o+=u-c}return n?t+o:new A1(t+o,0,null)}touches(t,r){let n=0,o=lk(r),i=this.inverted?2:1,s=this.inverted?1:2;for(let a=0;at)break;let c=this.ranges[a+i],u=l+c;if(t<=u&&a==o*3)return!0;n+=this.ranges[a+s]-c}return!1}forEach(t){let r=this.inverted?2:1,n=this.inverted?1:2;for(let o=0,i=0;o=0;r--){let o=t.getMirror(r);this.appendMap(t.maps[r].invert(),o!=null&&o>r?n-o-1:void 0)}}invert(){let t=new ul;return t.appendMappingInverted(this),t}map(t,r=1){if(this.mirror)return this._map(t,r,!0);for(let n=this.from;ni&&l!s.isAtom||!a.type.allowsMarkType(this.mark.type)?s:s.mark(this.mark.addToSet(s.marks)),o),r.openStart,r.openEnd);return yt.fromReplace(t,this.from,this.to,i)}invert(){return new eo(this.from,this.to,this.mark)}map(t){let r=t.mapResult(this.from,1),n=t.mapResult(this.to,-1);return r.deleted&&n.deleted||r.pos>=n.pos?null:new Ko(r.pos,n.pos,this.mark)}merge(t){return t instanceof Ko&&t.mark.eq(this.mark)&&this.from<=t.to&&this.to>=t.from?new Ko(Math.min(this.from,t.from),Math.max(this.to,t.to),this.mark):null}toJSON(){return{stepType:"addMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(t,r){if(typeof r.from!="number"||typeof r.to!="number")throw new RangeError("Invalid input for AddMarkStep.fromJSON");return new Ko(r.from,r.to,t.markFromJSON(r.mark))}}Rt.jsonID("addMark",Ko);class eo extends Rt{constructor(t,r,n){super(),this.from=t,this.to=r,this.mark=n}apply(t){let r=t.slice(this.from,this.to),n=new K(Tv(r.content,o=>o.mark(this.mark.removeFromSet(o.marks)),t),r.openStart,r.openEnd);return yt.fromReplace(t,this.from,this.to,n)}invert(){return new Ko(this.from,this.to,this.mark)}map(t){let r=t.mapResult(this.from,1),n=t.mapResult(this.to,-1);return r.deleted&&n.deleted||r.pos>=n.pos?null:new eo(r.pos,n.pos,this.mark)}merge(t){return t instanceof eo&&t.mark.eq(this.mark)&&this.from<=t.to&&this.to>=t.from?new eo(Math.min(this.from,t.from),Math.max(this.to,t.to),this.mark):null}toJSON(){return{stepType:"removeMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(t,r){if(typeof r.from!="number"||typeof r.to!="number")throw new RangeError("Invalid input for RemoveMarkStep.fromJSON");return new eo(r.from,r.to,t.markFromJSON(r.mark))}}Rt.jsonID("removeMark",eo);class Ii extends Rt{constructor(t,r){super(),this.pos=t,this.mark=r}apply(t){let r=t.nodeAt(this.pos);if(!r)return yt.fail("No node at mark step's position");let n=r.type.create(r.attrs,null,this.mark.addToSet(r.marks));return yt.fromReplace(t,this.pos,this.pos+1,new K(R.from(n),0,r.isLeaf?0:1))}invert(t){let r=t.nodeAt(this.pos);if(r){let n=this.mark.addToSet(r.marks);if(n.length==r.marks.length){for(let o=0;on.pos?null:new bt(r.pos,n.pos,o,i,this.slice,this.insert,this.structure)}toJSON(){let t={stepType:"replaceAround",from:this.from,to:this.to,gapFrom:this.gapFrom,gapTo:this.gapTo,insert:this.insert};return this.slice.size&&(t.slice=this.slice.toJSON()),this.structure&&(t.structure=!0),t}static fromJSON(t,r){if(typeof r.from!="number"||typeof r.to!="number"||typeof r.gapFrom!="number"||typeof r.gapTo!="number"||typeof r.insert!="number")throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON");return new bt(r.from,r.to,r.gapFrom,r.gapTo,K.fromJSON(t,r.slice),r.insert,!!r.structure)}}Rt.jsonID("replaceAround",bt);function N1(e,t,r){let n=e.resolve(t),o=r-t,i=n.depth;for(;o>0&&i>0&&n.indexAfter(i)==n.node(i).childCount;)i--,o--;if(o>0){let s=n.node(i).maybeChild(n.indexAfter(i));for(;o>0;){if(!s||s.isLeaf)return!0;s=s.firstChild,o--}}return!1}function jA(e,t,r,n){let o=[],i=[],s,a;e.doc.nodesBetween(t,r,(l,c,u)=>{if(!l.isInline)return;let d=l.marks;if(!n.isInSet(d)&&u.type.allowsMarkType(n.type)){let f=Math.max(c,t),p=Math.min(c+l.nodeSize,r),h=n.addToSet(d);for(let m=0;me.step(l)),i.forEach(l=>e.step(l))}function UA(e,t,r,n){let o=[],i=0;e.doc.nodesBetween(t,r,(s,a)=>{if(!s.isInline)return;i++;let l=null;if(n instanceof Nd){let c=s.marks,u;for(;u=n.isInSet(c);)(l||(l=[])).push(u),c=u.removeFromSet(c)}else n?n.isInSet(s.marks)&&(l=[n]):l=s.marks;if(l&&l.length){let c=Math.min(a+s.nodeSize,r);for(let u=0;ue.step(new eo(s.from,s.to,s.style)))}function WA(e,t,r,n=r.contentMatch){let o=e.doc.nodeAt(t),i=[],s=t+1;for(let a=0;a=0;a--)e.step(i[a])}function KA(e,t,r){return(t==0||e.canReplace(t,e.childCount))&&(r==e.childCount||e.canReplace(0,r))}function rc(e){let r=e.parent.content.cutByIndex(e.startIndex,e.endIndex);for(let n=e.depth;;--n){let o=e.$from.node(n),i=e.$from.index(n),s=e.$to.indexAfter(n);if(nr;h--)m||n.index(h)>0?(m=!0,u=R.from(n.node(h).copy(u)),d++):l--;let f=R.empty,p=0;for(let h=i,m=!1;h>r;h--)m||o.after(h+1)=0;s--){if(n.size){let a=r[s].type.contentMatch.matchFragment(n);if(!a||!a.validEnd)throw new RangeError("Wrapper type given to Transform.wrap does not form valid content of its parent wrapper")}n=R.from(r[s].type.create(r[s].attrs,n))}let o=t.start,i=t.end;e.step(new bt(o,i,o,i,new K(n,0,0),r.length,!0))}function XA(e,t,r,n,o){if(!n.isTextblock)throw new RangeError("Type given to setBlockType should be a textblock");let i=e.steps.length;e.doc.nodesBetween(t,r,(s,a)=>{if(s.isTextblock&&!s.hasMarkup(n,o)&&QA(e.doc,e.mapping.slice(i).map(a),n)){e.clearIncompatible(e.mapping.slice(i).map(a,1),n);let l=e.mapping.slice(i),c=l.map(a,1),u=l.map(a+s.nodeSize,1);return e.step(new bt(c,u,c+1,u-1,new K(R.from(n.create(o,null,s.marks)),0,0),1,!0)),!1}})}function QA(e,t,r){let n=e.resolve(t),o=n.index();return n.parent.canReplaceWith(o,o+1,r)}function ZA(e,t,r,n,o){let i=e.doc.nodeAt(t);if(!i)throw new RangeError("No node at given position");r||(r=i.type);let s=r.create(n,null,o||i.marks);if(i.isLeaf)return e.replaceWith(t,t+i.nodeSize,s);if(!r.validContent(i.content))throw new RangeError("Invalid content for node type "+r.name);e.step(new bt(t,t+i.nodeSize,t+1,t+i.nodeSize-1,new K(R.from(s),0,0),1,!0))}function dl(e,t,r=1,n){let o=e.resolve(t),i=o.depth-r,s=n&&n[n.length-1]||o.parent;if(i<0||o.parent.type.spec.isolating||!o.parent.canReplace(o.index(),o.parent.childCount)||!s.type.validContent(o.parent.content.cutByIndex(o.index(),o.parent.childCount)))return!1;for(let c=o.depth-1,u=r-2;c>i;c--,u--){let d=o.node(c),f=o.index(c);if(d.type.spec.isolating)return!1;let p=d.content.cutByIndex(f,d.childCount),h=n&&n[u+1];h&&(p=p.replaceChild(0,h.type.create(h.attrs)));let m=n&&n[u]||d;if(!d.canReplace(f+1,d.childCount)||!m.type.validContent(p))return!1}let a=o.indexAfter(i),l=n&&n[0];return o.node(i).canReplaceWith(a,a,l?l.type:o.node(i+1).type)}function eN(e,t,r=1,n){let o=e.doc.resolve(t),i=R.empty,s=R.empty;for(let a=o.depth,l=o.depth-r,c=r-1;a>l;a--,c--){i=R.from(o.node(a).copy(i));let u=n&&n[c];s=R.from(u?u.type.create(u.attrs,s):o.node(a).copy(s))}e.step(new Dt(t,t,new K(i.append(s),r,r),!0))}function Rd(e,t){let r=e.resolve(t),n=r.index();return tN(r.nodeBefore,r.nodeAfter)&&r.parent.canReplace(n,n+1)}function tN(e,t){return!!(e&&t&&!e.isLeaf&&e.canAppend(t))}function rN(e,t,r){let n=new Dt(t-r,t+r,K.empty,!0);e.step(n)}function CE(e,t,r){let n=e.resolve(t);if(n.parent.canReplaceWith(n.index(),n.index(),r))return t;if(n.parentOffset==0)for(let o=n.depth-1;o>=0;o--){let i=n.index(o);if(n.node(o).canReplaceWith(i,i,r))return n.before(o+1);if(i>0)return null}if(n.parentOffset==n.parent.content.size)for(let o=n.depth-1;o>=0;o--){let i=n.indexAfter(o);if(n.node(o).canReplaceWith(i,i,r))return n.after(o+1);if(i=0;s--){let a=s==n.depth?0:n.pos<=(n.start(s+1)+n.end(s+1))/2?-1:1,l=n.index(s)+(a>0?1:0),c=n.node(s),u=!1;if(i==1)u=c.canReplace(l,l,o);else{let d=c.contentMatchAt(l).findWrapping(o.firstChild.type);u=d&&c.canReplaceWith(l,l,d[0])}if(u)return a==0?n.pos:a<0?n.before(s+1):n.after(s+1)}return null}function _v(e,t,r=t,n=K.empty){if(t==r&&!n.size)return null;let o=e.resolve(t),i=e.resolve(r);return ME(o,i,n)?new Dt(t,r,n):new oN(o,i,n).fit()}function ME(e,t,r){return!r.openStart&&!r.openEnd&&e.start()==t.start()&&e.parent.canReplace(e.index(),t.index(),r.content)}class oN{constructor(t,r,n){this.$from=t,this.$to=r,this.unplaced=n,this.frontier=[],this.placed=R.empty;for(let o=0;o<=t.depth;o++){let i=t.node(o);this.frontier.push({type:i.type,match:i.contentMatchAt(t.indexAfter(o))})}for(let o=t.depth;o>0;o--)this.placed=R.from(t.node(o).copy(this.placed))}get depth(){return this.frontier.length-1}fit(){for(;this.unplaced.size;){let c=this.findFittable();c?this.placeNodes(c):this.openMore()||this.dropNode()}let t=this.mustMoveInline(),r=this.placed.size-this.depth-this.$from.depth,n=this.$from,o=this.close(t<0?this.$to:n.doc.resolve(t));if(!o)return null;let i=this.placed,s=n.depth,a=o.depth;for(;s&&a&&i.childCount==1;)i=i.firstChild.content,s--,a--;let l=new K(i,s,a);return t>-1?new bt(n.pos,t,this.$to.pos,this.$to.end(),l,r):l.size||n.pos!=this.$to.pos?new Dt(n.pos,o.pos,l):null}findFittable(){let t=this.unplaced.openStart;for(let r=this.unplaced.content,n=0,o=this.unplaced.openEnd;n1&&(o=0),i.type.spec.isolating&&o<=n){t=n;break}r=i.content}for(let r=1;r<=2;r++)for(let n=r==1?t:this.unplaced.openStart;n>=0;n--){let o,i=null;n?(i=ug(this.unplaced.content,n-1).firstChild,o=i.content):o=this.unplaced.content;let s=o.firstChild;for(let a=this.depth;a>=0;a--){let{type:l,match:c}=this.frontier[a],u,d=null;if(r==1&&(s?c.matchType(s.type)||(d=c.fillBefore(R.from(s),!1)):i&&l.compatibleContent(i.type)))return{sliceDepth:n,frontierDepth:a,parent:i,inject:d};if(r==2&&s&&(u=c.findWrapping(s.type)))return{sliceDepth:n,frontierDepth:a,parent:i,wrap:u};if(i&&c.matchType(i.type))break}}}openMore(){let{content:t,openStart:r,openEnd:n}=this.unplaced,o=ug(t,r);return!o.childCount||o.firstChild.isLeaf?!1:(this.unplaced=new K(t,r+1,Math.max(n,o.size+r>=t.size-n?r+1:0)),!0)}dropNode(){let{content:t,openStart:r,openEnd:n}=this.unplaced,o=ug(t,r);if(o.childCount<=1&&r>0){let i=t.size-r<=r+o.size;this.unplaced=new K(zc(t,r-1,1),r-1,i?r-1:n)}else this.unplaced=new K(zc(t,r,1),r,n)}placeNodes({sliceDepth:t,frontierDepth:r,parent:n,inject:o,wrap:i}){for(;this.depth>r;)this.closeFrontierNode();if(i)for(let m=0;m1||l==0||m.content.size)&&(d=b,u.push(TE(m.mark(f.allowedMarks(m.marks)),c==1?l:0,c==a.childCount?p:-1)))}let h=c==a.childCount;h||(p=-1),this.placed=Lc(this.placed,r,R.from(u)),this.frontier[r].match=d,h&&p<0&&n&&n.type==this.frontier[this.depth].type&&this.frontier.length>1&&this.closeFrontierNode();for(let m=0,b=a;m1&&o==this.$to.end(--n);)++o;return o}findCloseLevel(t){e:for(let r=Math.min(this.depth,t.depth);r>=0;r--){let{match:n,type:o}=this.frontier[r],i=r=0;a--){let{match:l,type:c}=this.frontier[a],u=dg(t,a,c,l,!0);if(!u||u.childCount)continue e}return{depth:r,fit:s,move:i?t.doc.resolve(t.after(r+1)):t}}}}close(t){let r=this.findCloseLevel(t);if(!r)return null;for(;this.depth>r.depth;)this.closeFrontierNode();r.fit.childCount&&(this.placed=Lc(this.placed,r.depth,r.fit)),t=r.move;for(let n=r.depth+1;n<=t.depth;n++){let o=t.node(n),i=o.type.contentMatch.fillBefore(o.content,!0,t.index(n));this.openFrontierNode(o.type,o.attrs,i)}return t}openFrontierNode(t,r=null,n){let o=this.frontier[this.depth];o.match=o.match.matchType(t),this.placed=Lc(this.placed,this.depth,R.from(t.create(r,n))),this.frontier.push({type:t,match:t.contentMatch})}closeFrontierNode(){let r=this.frontier.pop().match.fillBefore(R.empty,!0);r.childCount&&(this.placed=Lc(this.placed,this.frontier.length,r))}}function zc(e,t,r){return t==0?e.cutByIndex(r,e.childCount):e.replaceChild(0,e.firstChild.copy(zc(e.firstChild.content,t-1,r)))}function Lc(e,t,r){return t==0?e.append(r):e.replaceChild(e.childCount-1,e.lastChild.copy(Lc(e.lastChild.content,t-1,r)))}function ug(e,t){for(let r=0;r1&&(n=n.replaceChild(0,TE(n.firstChild,t-1,n.childCount==1?r-1:0))),t>0&&(n=e.type.contentMatch.fillBefore(n).append(n),r<=0&&(n=n.append(e.type.contentMatch.matchFragment(n).fillBefore(R.empty,!0)))),e.copy(n)}function dg(e,t,r,n,o){let i=e.node(t),s=o?e.indexAfter(t):e.index(t);if(s==i.childCount&&!r.compatibleContent(i.type))return null;let a=n.fillBefore(i.content,!0,s);return a&&!iN(r,i.content,s)?a:null}function iN(e,t,r){for(let n=r;n0;f--,p--){let h=o.node(f).type.spec;if(h.defining||h.definingAsContext||h.isolating)break;s.indexOf(f)>-1?a=f:o.before(f)==p&&s.splice(1,0,-f)}let l=s.indexOf(a),c=[],u=n.openStart;for(let f=n.content,p=0;;p++){let h=f.firstChild;if(c.push(h),p==n.openStart)break;f=h.content}for(let f=u-1;f>=0;f--){let p=c[f],h=sN(p.type);if(h&&!p.sameMarkup(o.node(Math.abs(a)-1)))u=f;else if(h||!p.type.isTextblock)break}for(let f=n.openStart;f>=0;f--){let p=(f+u+1)%(n.openStart+1),h=c[p];if(h)for(let m=0;m=0&&(e.replace(t,r,n),!(e.steps.length>d));f--){let p=s[f];p<0||(t=o.before(p),r=i.after(p))}}function OE(e,t,r,n,o){if(tn){let i=o.contentMatchAt(0),s=i.fillBefore(e).append(e);e=s.append(i.matchFragment(s).fillBefore(R.empty,!0))}return e}function lN(e,t,r,n){if(!n.isInline&&t==r&&e.doc.resolve(t).parent.content.size){let o=CE(e.doc,t,n.type);o!=null&&(t=r=o)}e.replaceRange(t,r,new K(R.from(n),0,0))}function cN(e,t,r){let n=e.doc.resolve(t),o=e.doc.resolve(r),i=_E(n,o);for(let s=0;s0&&(l||n.node(a-1).canReplace(n.index(a-1),o.indexAfter(a-1))))return e.delete(n.before(a),o.after(a))}for(let s=1;s<=n.depth&&s<=o.depth;s++)if(t-n.start(s)==n.depth-s&&r>n.end(s)&&o.end(s)-r!=o.depth-s)return e.delete(n.before(s),r);e.delete(t,r)}function _E(e,t){let r=[],n=Math.min(e.depth,t.depth);for(let o=n;o>=0;o--){let i=e.start(o);if(it.pos+(t.depth-o)||e.node(o).type.spec.isolating||t.node(o).type.spec.isolating)break;(i==t.start(o)||o==e.depth&&o==t.depth&&e.parent.inlineContent&&t.parent.inlineContent&&o&&t.start(o-1)==i-1)&&r.push(o)}return r}class fl extends Rt{constructor(t,r,n){super(),this.pos=t,this.attr=r,this.value=n}apply(t){let r=t.nodeAt(this.pos);if(!r)return yt.fail("No node at attribute step's position");let n=Object.create(null);for(let i in r.attrs)n[i]=r.attrs[i];n[this.attr]=this.value;let o=r.type.create(n,null,r.marks);return yt.fromReplace(t,this.pos,this.pos+1,new K(R.from(o),0,r.isLeaf?0:1))}getMap(){return nn.empty}invert(t){return new fl(this.pos,this.attr,t.nodeAt(this.pos).attrs[this.attr])}map(t){let r=t.mapResult(this.pos,1);return r.deletedAfter?null:new fl(r.pos,this.attr,this.value)}toJSON(){return{stepType:"attr",pos:this.pos,attr:this.attr,value:this.value}}static fromJSON(t,r){if(typeof r.pos!="number"||typeof r.attr!="string")throw new RangeError("Invalid input for AttrStep.fromJSON");return new fl(r.pos,r.attr,r.value)}}Rt.jsonID("attr",fl);class Iu extends Rt{constructor(t,r){super(),this.attr=t,this.value=r}apply(t){let r=Object.create(null);for(let o in t.attrs)r[o]=t.attrs[o];r[this.attr]=this.value;let n=t.type.create(r,t.content,t.marks);return yt.ok(n)}getMap(){return nn.empty}invert(t){return new Iu(this.attr,t.attrs[this.attr])}map(t){return this}toJSON(){return{stepType:"docAttr",attr:this.attr,value:this.value}}static fromJSON(t,r){if(typeof r.attr!="string")throw new RangeError("Invalid input for DocAttrStep.fromJSON");return new Iu(r.attr,r.value)}}Rt.jsonID("docAttr",Iu);let _l=class extends Error{};_l=function e(t){let r=Error.call(this,t);return r.__proto__=e.prototype,r};_l.prototype=Object.create(Error.prototype);_l.prototype.constructor=_l;_l.prototype.name="TransformError";class uN{constructor(t){this.doc=t,this.steps=[],this.docs=[],this.mapping=new ul}get before(){return this.docs.length?this.docs[0]:this.doc}step(t){let r=this.maybeStep(t);if(r.failed)throw new _l(r.failed);return this}maybeStep(t){let r=t.apply(this.doc);return r.failed||this.addStep(t,r.doc),r}get docChanged(){return this.steps.length>0}addStep(t,r){this.docs.push(this.doc),this.steps.push(t),this.mapping.appendMap(t.getMap()),this.doc=r}replace(t,r=t,n=K.empty){let o=_v(this.doc,t,r,n);return o&&this.step(o),this}replaceWith(t,r,n){return this.replace(t,r,new K(R.from(n),0,0))}delete(t,r){return this.replace(t,r,K.empty)}insert(t,r){return this.replaceWith(t,t,r)}replaceRange(t,r,n){return aN(this,t,r,n),this}replaceRangeWith(t,r,n){return lN(this,t,r,n),this}deleteRange(t,r){return cN(this,t,r),this}lift(t,r){return qA(this,t,r),this}join(t,r=1){return rN(this,t,r),this}wrap(t,r){return JA(this,t,r),this}setBlockType(t,r=t,n,o=null){return XA(this,t,r,n,o),this}setNodeMarkup(t,r,n=null,o){return ZA(this,t,r,n,o),this}setNodeAttribute(t,r,n){return this.step(new fl(t,r,n)),this}setDocAttribute(t,r){return this.step(new Iu(t,r)),this}addNodeMark(t,r){return this.step(new Ii(t,r)),this}removeNodeMark(t,r){if(!(r instanceof Te)){let n=this.doc.nodeAt(t);if(!n)throw new RangeError("No node at position "+t);if(r=r.isInSet(n.marks),!r)return this}return this.step(new Ol(t,r)),this}split(t,r=1,n){return eN(this,t,r,n),this}addMark(t,r,n){return jA(this,t,r,n),this}removeMark(t,r,n){return UA(this,t,r,n),this}clearIncompatible(t,r,n){return WA(this,t,r,n),this}}const fg=Object.create(null);class be{constructor(t,r,n){this.$anchor=t,this.$head=r,this.ranges=n||[new dN(t.min(r),t.max(r))]}get anchor(){return this.$anchor.pos}get head(){return this.$head.pos}get from(){return this.$from.pos}get to(){return this.$to.pos}get $from(){return this.ranges[0].$from}get $to(){return this.ranges[0].$to}get empty(){let t=this.ranges;for(let r=0;r=0;i--){let s=r<0?Fa(t.node(0),t.node(i),t.before(i+1),t.index(i),r,n):Fa(t.node(0),t.node(i),t.after(i+1),t.index(i)+1,r,n);if(s)return s}return null}static near(t,r=1){return this.findFrom(t,r)||this.findFrom(t,-r)||new kr(t.node(0))}static atStart(t){return Fa(t,t,0,0,1)||new kr(t)}static atEnd(t){return Fa(t,t,t.content.size,t.childCount,-1)||new kr(t)}static fromJSON(t,r){if(!r||!r.type)throw new RangeError("Invalid input for Selection.fromJSON");let n=fg[r.type];if(!n)throw new RangeError(`No selection type ${r.type} defined`);return n.fromJSON(t,r)}static jsonID(t,r){if(t in fg)throw new RangeError("Duplicate use of selection JSON ID "+t);return fg[t]=r,r.prototype.jsonID=t,r}getBookmark(){return le.between(this.$anchor,this.$head).getBookmark()}}be.prototype.visible=!0;class dN{constructor(t,r){this.$from=t,this.$to=r}}let uk=!1;function dk(e){!uk&&!e.parent.inlineContent&&(uk=!0,console.warn("TextSelection endpoint not pointing into a node with inline content ("+e.parent.type.name+")"))}class le extends be{constructor(t,r=t){dk(t),dk(r),super(t,r)}get $cursor(){return this.$anchor.pos==this.$head.pos?this.$head:null}map(t,r){let n=t.resolve(r.map(this.head));if(!n.parent.inlineContent)return be.near(n);let o=t.resolve(r.map(this.anchor));return new le(o.parent.inlineContent?o:n,n)}replace(t,r=K.empty){if(super.replace(t,r),r==K.empty){let n=this.$from.marksAcross(this.$to);n&&t.ensureMarks(n)}}eq(t){return t instanceof le&&t.anchor==this.anchor&&t.head==this.head}getBookmark(){return new zh(this.anchor,this.head)}toJSON(){return{type:"text",anchor:this.anchor,head:this.head}}static fromJSON(t,r){if(typeof r.anchor!="number"||typeof r.head!="number")throw new RangeError("Invalid input for TextSelection.fromJSON");return new le(t.resolve(r.anchor),t.resolve(r.head))}static create(t,r,n=r){let o=t.resolve(r);return new this(o,n==r?o:t.resolve(n))}static between(t,r,n){let o=t.pos-r.pos;if((!n||o)&&(n=o>=0?1:-1),!r.parent.inlineContent){let i=be.findFrom(r,n,!0)||be.findFrom(r,-n,!0);if(i)r=i.$head;else return be.near(r,n)}return t.parent.inlineContent||(o==0?t=r:(t=(be.findFrom(t,-n,!0)||be.findFrom(t,n,!0)).$anchor,t.pos0?0:1);o>0?s=0;s+=o){let a=t.child(s);if(a.isAtom){if(!i&&ce.isSelectable(a))return ce.create(e,r-(o<0?a.nodeSize:0))}else{let l=Fa(e,a,r+o,o<0?a.childCount:0,o,i);if(l)return l}r+=a.nodeSize*o}return null}function fk(e,t,r){let n=e.steps.length-1;if(n{s==null&&(s=u)}),e.setSelection(be.near(e.doc.resolve(s),r))}const pk=1,of=2,hk=4;class pN extends uN{constructor(t){super(t.doc),this.curSelectionFor=0,this.updated=0,this.meta=Object.create(null),this.time=Date.now(),this.curSelection=t.selection,this.storedMarks=t.storedMarks}get selection(){return this.curSelectionFor0}setStoredMarks(t){return this.storedMarks=t,this.updated|=of,this}ensureMarks(t){return Te.sameSet(this.storedMarks||this.selection.$from.marks(),t)||this.setStoredMarks(t),this}addStoredMark(t){return this.ensureMarks(t.addToSet(this.storedMarks||this.selection.$head.marks()))}removeStoredMark(t){return this.ensureMarks(t.removeFromSet(this.storedMarks||this.selection.$head.marks()))}get storedMarksSet(){return(this.updated&of)>0}addStep(t,r){super.addStep(t,r),this.updated=this.updated&~of,this.storedMarks=null}setTime(t){return this.time=t,this}replaceSelection(t){return this.selection.replace(this,t),this}replaceSelectionWith(t,r=!0){let n=this.selection;return r&&(t=t.mark(this.storedMarks||(n.empty?n.$from.marks():n.$from.marksAcross(n.$to)||Te.none))),n.replaceWith(this,t),this}deleteSelection(){return this.selection.replace(this),this}insertText(t,r,n){let o=this.doc.type.schema;if(r==null)return t?this.replaceSelectionWith(o.text(t),!0):this.deleteSelection();{if(n==null&&(n=r),n=n??r,!t)return this.deleteRange(r,n);let i=this.storedMarks;if(!i){let s=this.doc.resolve(r);i=n==r?s.marks():s.marksAcross(this.doc.resolve(n))}return this.replaceRangeWith(r,n,o.text(t,i)),this.selection.empty||this.setSelection(be.near(this.selection.$to)),this}}setMeta(t,r){return this.meta[typeof t=="string"?t:t.key]=r,this}getMeta(t){return this.meta[typeof t=="string"?t:t.key]}get isGeneric(){for(let t in this.meta)return!1;return!0}scrollIntoView(){return this.updated|=hk,this}get scrolledIntoView(){return(this.updated&hk)>0}}function mk(e,t){return!t||!e?e:e.bind(t)}class Ic{constructor(t,r,n){this.name=t,this.init=mk(r.init,n),this.apply=mk(r.apply,n)}}const hN=[new Ic("doc",{init(e){return e.doc||e.schema.topNodeType.createAndFill()},apply(e){return e.doc}}),new Ic("selection",{init(e,t){return e.selection||be.atStart(t.doc)},apply(e){return e.selection}}),new Ic("storedMarks",{init(e){return e.storedMarks||null},apply(e,t,r,n){return n.selection.$cursor?e.storedMarks:null}}),new Ic("scrollToSelection",{init(){return 0},apply(e,t){return e.scrolledIntoView?t+1:t}})];class pg{constructor(t,r){this.schema=t,this.plugins=[],this.pluginsByKey=Object.create(null),this.fields=hN.slice(),r&&r.forEach(n=>{if(this.pluginsByKey[n.key])throw new RangeError("Adding different instances of a keyed plugin ("+n.key+")");this.plugins.push(n),this.pluginsByKey[n.key]=n,n.spec.state&&this.fields.push(new Ic(n.key,n.spec.state,n))})}}class Hs{constructor(t){this.config=t}get schema(){return this.config.schema}get plugins(){return this.config.plugins}apply(t){return this.applyTransaction(t).state}filterTransaction(t,r=-1){for(let n=0;nn.toJSON())),t&&typeof t=="object")for(let n in t){if(n=="doc"||n=="selection")throw new RangeError("The JSON fields `doc` and `selection` are reserved");let o=t[n],i=o.spec.state;i&&i.toJSON&&(r[n]=i.toJSON.call(o,this[o.key]))}return r}static fromJSON(t,r,n){if(!r)throw new RangeError("Invalid input for EditorState.fromJSON");if(!t.schema)throw new RangeError("Required config field 'schema' missing");let o=new pg(t.schema,t.plugins),i=new Hs(o);return o.fields.forEach(s=>{if(s.name=="doc")i.doc=Fi.fromJSON(t.schema,r.doc);else if(s.name=="selection")i.selection=be.fromJSON(i.doc,r.selection);else if(s.name=="storedMarks")r.storedMarks&&(i.storedMarks=r.storedMarks.map(t.schema.markFromJSON));else{if(n)for(let a in n){let l=n[a],c=l.spec.state;if(l.key==s.name&&c&&c.fromJSON&&Object.prototype.hasOwnProperty.call(r,a)){i[s.name]=c.fromJSON.call(l,t,r[a],i);return}}i[s.name]=s.init(t,i)}}),i}}function AE(e,t,r){for(let n in e){let o=e[n];o instanceof Function?o=o.bind(t):n=="handleDOMEvents"&&(o=AE(o,t,{})),r[n]=o}return r}class Ro{constructor(t){this.spec=t,this.props={},t.props&&AE(t.props,this,this.props),this.key=t.key?t.key.key:NE("plugin")}getState(t){return t[this.key]}}const hg=Object.create(null);function NE(e){return e in hg?e+"$"+ ++hg[e]:(hg[e]=0,e+"$")}class ka{constructor(t="key"){this.key=NE(t)}get(t){return t.config.pluginsByKey[this.key]}getState(t){return t[this.key]}}var mN=/[A-Z]/g,gN=/^ms-/,mg={};function vN(e){return"-"+e.toLowerCase()}function yN(e){if(mg.hasOwnProperty(e))return mg[e];var t=e.replace(mN,vN);return mg[e]=gN.test(t)?"-"+t:t}function bN(e){return yN(e)}function xN(e,t){return bN(e)+":"+t}function kN(e){var t="";for(var r in e){var n=e[r];typeof n!="string"&&typeof n!="number"||(t&&(t+=";"),t+=xN(r,n))}return t}function wN(){return typeof document<"u"?document:null}var RE=wN;function PE(e,t){if(typeof e!="string")return[e];var r=[e];typeof t=="string"||Array.isArray(t)?t={brackets:t}:t||(t={});var n=t.brackets?Array.isArray(t.brackets)?t.brackets:[t.brackets]:["{}","[]","()"],o=t.escape||"___",i=!!t.flat;n.forEach(function(l){var c=new RegExp(["\\",l[0],"[^\\",l[0],"\\",l[1],"]*\\",l[1]].join("")),u=[];function d(f,p,h){var m=r.push(f.slice(l[0].length,-l[1].length))-1;return u.push(m),o+m+o}r.forEach(function(f,p){for(var h,m=0;f!=h;)if(h=f,f=f.replace(c,d),m++>1e4)throw Error("References have circular dependency. Please, check them.");r[p]=f}),u=u.reverse(),r=r.map(function(f){return u.forEach(function(p){f=f.replace(new RegExp("(\\"+o+p+"\\"+o+")","g"),l[0]+"$1"+l[1])}),f})});var s=new RegExp("\\"+o+"([0-9]+)\\"+o);function a(l,c,u){for(var d=[],f,p=0;f=s.exec(l);){if(p++>1e4)throw Error("Circular references in parenthesis");d.push(l.slice(0,f.index)),d.push(a(c[f[1]],c)),l=l.slice(f.index+f[0].length)}return d.push(l),d}return i?r:a(r[0],r)}function zE(e,t){if(t&&t.flat){var r=t&&t.escape||"___",n=e[0],o;if(!n)return"";for(var i=new RegExp("\\"+r+"([0-9]+)\\"+r),s=0;n!=o;){if(s++>1e4)throw Error("Circular references in "+e);o=n,n=n.replace(i,a)}return n}return e.reduce(function l(c,u){return Array.isArray(u)&&(u=u.reduce(l,"")),c+u},"");function a(l,c){if(e[c]==null)throw Error("Reference "+c+"is undefined");return e[c]}}function Nv(e,t){return Array.isArray(e)?zE(e,t):PE(e,t)}Nv.parse=PE;Nv.stringify=zE;var SN=Nv;const EN=Dn(SN),CN={id:"extension.command.copy.label",message:"Copy",comment:"Label for copy command."},MN={id:"extension.command.copy.description",message:"Copy the selected text",comment:"Description for copy command."},TN={id:"extension.command.cut.label",message:"Cut",comment:"Label for cut command."},ON={id:"extension.command.cut.description",message:"Cut the selected text",comment:"Description for cut command."},_N={id:"extension.command.paste.label",message:"Paste",comment:"Label for paste command."},AN={id:"extension.command.paste.description",message:"Paste content into the editor",comment:"Description for paste command."},NN={id:"extension.command.select-all.label",message:"Select all",comment:"Label for select all command."},RN={id:"extension.command.select-all.description",message:"Select all content within the editor",comment:"Description for select all command."};var ts=Object.freeze({__proto__:null,COPY_DESCRIPTION:MN,COPY_LABEL:CN,CUT_DESCRIPTION:ON,CUT_LABEL:TN,PASTE_DESCRIPTION:AN,PASTE_LABEL:_N,SELECT_ALL_DESCRIPTION:RN,SELECT_ALL_LABEL:NN});const PN={id:"keyboard.shortcut.escape",message:"Enter",comment:"Label for escape key in shortcuts."},zN={id:"keyboard.shortcut.command",message:"Command",comment:"Label for command key in shortcuts."},LN={id:"keyboard.shortcut.control",message:"Control",comment:"Label for control key in shortcuts."},IN={id:"keyboard.shortcut.enter",message:"Enter",comment:"Label for enter key in shortcuts."},DN={id:"keyboard.shortcut.shift",message:"Shift",comment:"Label for shift key in shortcuts."},$N={id:"keyboard.shortcut.alt",message:"Alt",comment:"Label for alt key in shortcuts."},HN={id:"keyboard.shortcut.capsLock",message:"Caps Lock",comment:"Label for caps lock key in shortcuts."},BN={id:"keyboard.shortcut.backspace",message:"Backspace",comment:"Label for backspace key in shortcuts."},FN={id:"keyboard.shortcut.tab",message:"Tab",comment:"Label for tab key in shortcuts."},VN={id:"keyboard.shortcut.space",message:"Space",comment:"Label for space key in shortcuts."},jN={id:"keyboard.shortcut.delete",message:"Delete",comment:"Label for delete key in shortcuts."},UN={id:"keyboard.shortcut.pageUp",message:"Page Up",comment:"Label for page up key in shortcuts."},WN={id:"keyboard.shortcut.pageDown",message:"Page Down",comment:"Label for page down key in shortcuts."},KN={id:"keyboard.shortcut.home",message:"Home",comment:"Label for home key in shortcuts."},qN={id:"keyboard.shortcut.end",message:"End",comment:"Label for end key in shortcuts."},GN={id:"keyboard.shortcut.arrowLeft",message:"Arrow Left",comment:"Label for arrow left key in shortcuts."},YN={id:"keyboard.shortcut.arrowRight",message:"Arrow Right",comment:"Label for arrow right key in shortcuts."},JN={id:"keyboard.shortcut.arrowUp",message:"Arrow Up",comment:"Label for arrow up key in shortcuts."},XN={id:"keyboard.shortcut.arrowDown",message:"Arrow Down",comment:"Label for arrowDown key in shortcuts."};var Mt=Object.freeze({__proto__:null,ALT_KEY:$N,ARROW_DOWN_KEY:XN,ARROW_LEFT_KEY:GN,ARROW_RIGHT_KEY:YN,ARROW_UP_KEY:JN,BACKSPACE_KEY:BN,CAPS_LOCK_KEY:HN,COMMAND_KEY:zN,CONTROL_KEY:LN,DELETE_KEY:jN,END_KEY:qN,ENTER_KEY:IN,ESCAPE_KEY:PN,HOME_KEY:KN,PAGE_DOWN_KEY:WN,PAGE_UP_KEY:UN,SHIFT_KEY:DN,SPACE_KEY:VN,TAB_KEY:FN});const QN={id:"extension.command.toggle-blockquote.label",message:"Blockquote",comment:"Label for blockquote formatting command."},ZN={id:"extension.command.toggle-blockquote.description",message:"Add blockquote formatting to the selected text",comment:"Description for blockquote formatting command."};var gk=Object.freeze({__proto__:null,DESCRIPTION:ZN,LABEL:QN});const eR={id:"extension.command.toggle-bold.label",message:"Bold",comment:"Label for bold formatting command."},tR={id:"extension.command.toggle-bold.description",message:"Add bold formatting to the selected text",comment:"Description for bold formatting command."};var vk=Object.freeze({__proto__:null,DESCRIPTION:tR,LABEL:eR});const rR={id:"extension.command.toggle-code-block.label",message:"Codeblock",comment:"Label for the code block command."},nR={id:"extension.command.toggle-code-block.description",message:"Add a code block",comment:"Description for the code block command."};var oR=Object.freeze({__proto__:null,DESCRIPTION:nR,LABEL:rR});const iR={id:"extension.command.toggle-code.label",message:"Code",comment:"Label for the inline code formatting."},sR={id:"extension.command.toggle-code.description",message:"Add inline code formatting to the selected text",comment:"Description for the inline code formatting command."};var aR=Object.freeze({__proto__:null,DESCRIPTION:sR,LABEL:iR});const lR={id:"extension.command.set-font-size.label",message:"Font size",comment:"Label for adding a font size."},cR={id:"extension.command.set-font-size.description",message:"Set the font size for the selected text.",comment:"Description for adding a font size."},uR={id:"extension.command.increase-font-size.label",message:"Increase",comment:"Label for increasing the font size."},dR={id:"extension.command.increase-font-size.description",message:"Increase the font size",comment:"Description for increasing the font size."},fR={id:"extension.command.decrease-font-size.label",message:"Decrease",comment:"Label for decreasing the font size."},pR={id:"extension.command.decrease-font-size.description",message:"Decrease the font size.",comment:"Description for decreasing the font size."};var Al=Object.freeze({__proto__:null,DECREASE_DESCRIPTION:pR,DECREASE_LABEL:fR,INCREASE_DESCRIPTION:dR,INCREASE_LABEL:uR,SET_DESCRIPTION:cR,SET_LABEL:lR});const hR={id:"extension.command.toggle-heading.label",message:`{level, select, 1 {Heading 1} +2 {Heading 2} +3 {Heading 3} +4 {Heading 4} +5 {Heading 5} +6 {Heading 6} +other {Heading}}`,comment:"Label for heading command with support for levels."};var mR=Object.freeze({__proto__:null,LABEL:hR});const gR={id:"extension.command.undo.label",message:"Undo",comment:"Label for undo."},vR={id:"extension.command.undo.description",message:"Undo the most recent action",comment:"Description for undo."},yR={id:"extension.command.redo.label",message:"Redo",comment:"Label for redo."},bR={id:"extension.command.redo.description",message:"Redo the most recent action",comment:"Description for redo."};var Cp=Object.freeze({__proto__:null,REDO_DESCRIPTION:bR,REDO_LABEL:yR,UNDO_DESCRIPTION:vR,UNDO_LABEL:gR});const xR={id:"extension.command.insert-horizontal-rule.label",message:"Divider",comment:"Label for inserting a horizontal rule (divider) command."},kR={id:"extension.command.insert-horizontal-rule.description",message:"Separate content with a diving horizontal line",comment:"Description for inserting a horizontal rule (divider) command."};var yk=Object.freeze({__proto__:null,DESCRIPTION:kR,LABEL:xR});const wR={id:"extension.command.toggle-italic.label",message:"Italic",comment:"Label for italic formatting command."},SR={id:"extension.command.toggle-italic.description",message:"Italicize the selected text",comment:"Description for italic formatting command."};var bk=Object.freeze({__proto__:null,DESCRIPTION:SR,LABEL:wR});const ER={id:"extension.command.toggle-ordered-list.label",message:"Ordered list",comment:"Label for inserting an ordered list into the editor."},CR={id:"extension.command.toggle-bullet-list.description",message:"Bulleted list",comment:"Description for inserting a bullet list into the editor."},MR={id:"extension.command.toggle-task-list.description",message:"Tasked list",comment:"Description for inserting a task list into the editor."};var Rv=Object.freeze({__proto__:null,BULLET_LIST_LABEL:CR,ORDERED_LIST_LABEL:ER,TASK_LIST_LABEL:MR});const TR={id:"extension.command.increase-indent.label",message:"Increase indentation",comment:"Label for increasing the indentation level."},OR={id:"extension.command.decrease-indent.label",message:"Decrease indentation",comment:"Label for decreasing the indentation level of the current node block."},_R={id:"extension.command.center-align.label",message:"Center align",comment:"Center align the text in the current node."},AR={id:"extension.command.justify-align.label",message:"Justify",comment:"Justify the alignment of the selected nodes."},NR={id:"extension.command.right-align.label",message:"Right align",comment:"Right align the selected nodes."},RR={id:"extension.command.left-align.label",message:"Left align",comment:"Left align the selected nodes."};var nc=Object.freeze({__proto__:null,CENTER_ALIGN_LABEL:_R,DECREASE_INDENT_LABEL:OR,INCREASE_INDENT_LABEL:TR,JUSTIFY_ALIGN_LABEL:AR,LEFT_ALIGN_LABEL:RR,RIGHT_ALIGN_LABEL:NR});const PR={id:"extension.command.insert-paragraph.label",message:"Insert Paragraph",comment:"Label for inserting a paragraph."},zR={id:"extension.command.insert-paragraph.description",message:"Insert a new paragraph",comment:"Description for inserting a paragraph."},LR={id:"extension.command.convert-paragraph.label",message:"Convert Paragraph",comment:"Label for converting the current node into a paragraph."},IR={id:"extension.command.convert-paragraph.description",message:"Convert current block into a paragraph block.",comment:"Description for converting a paragraph."};var Mp=Object.freeze({__proto__:null,CONVERT_DESCRIPTION:IR,CONVERT_LABEL:LR,INSERT_DESCRIPTION:zR,INSERT_LABEL:PR});const DR={id:"extension.command.toggle-strike.label",message:"Strikethrough",comment:"Label for strike formatting command."},$R={id:"extension.command.toggle-strike.description",message:"Strikethrough the selected text",comment:"Description for strike formatting command."};var xk=Object.freeze({__proto__:null,DESCRIPTION:$R,LABEL:DR});const HR={id:"extension.command.toggle-underline.label",message:"Underline",comment:"Label for underline formatting command."},BR={id:"extension.command.toggle-underline.description",message:"Underline the selected text",comment:"Description for underline formatting command."};var kk=Object.freeze({__proto__:null,DESCRIPTION:BR,LABEL:HR});class wa{constructor(t,r){this.match=t,this.match=t,this.handler=typeof r=="string"?FR(r):r}}function FR(e){return function(t,r,n,o){let i=e;if(r[1]){let s=r[0].lastIndexOf(r[1]);i+=r[0].slice(s+r[1].length),n+=s;let a=n-o;a>0&&(i=r[0].slice(s-a,s)+i,n=o)}return t.tr.insertText(i,n,o)}}const VR=500;function jR({rules:e}){let t=new Ro({state:{init(){return null},apply(r,n){let o=r.getMeta(this);return o||(r.selectionSet||r.docChanged?null:n)}},props:{handleTextInput(r,n,o,i){return wk(r,n,o,i,e,t)},handleDOMEvents:{compositionend:r=>{setTimeout(()=>{let{$cursor:n}=r.state.selection;n&&wk(r,n.pos,n.pos,"",e,t)})}}},isInputRules:!0});return t}function wk(e,t,r,n,o,i){if(e.composing)return!1;let s=e.state,a=s.doc.resolve(t);if(a.parent.type.spec.code)return!1;let l=a.parent.textBetween(Math.max(0,a.parentOffset-VR),a.parentOffset,null,"")+n;for(let c=0;c{let r=e.plugins;for(let n=0;n=0;l--)s.step(a.steps[l].invert(a.docs[l]));if(i.text){let l=s.doc.resolve(i.from).marks();s.replaceWith(i.from,i.to,e.schema.text(i.text,l))}else s.delete(i.from,i.to);t(s)}return!0}}return!1};function Lh(e,t,r=null,n){return new wa(e,(o,i,s,a)=>{let l=r instanceof Function?r(i):r,c=o.tr.delete(s,a),u=c.doc.resolve(s),d=u.blockRange(),f=d&&Ov(d,t,l);if(!f)return null;c.wrap(d,f);let p=c.doc.resolve(s-1).nodeBefore;return p&&p.type==t&&Rd(c.doc,s-1)&&(!n||n(i,p))&&c.join(s-1),c})}function WR(e,t,r=null){return new wa(e,(n,o,i,s)=>{let a=n.doc.resolve(i),l=r instanceof Function?r(o):r;return a.node(-1).canReplaceWith(a.index(-1),a.indexAfter(-1),t)?n.tr.delete(i,s).setBlockType(i,i,t,l):null})}const br=function(e){for(var t=0;;t++)if(e=e.previousSibling,!e)return t},Du=function(e){let t=e.assignedSlot||e.parentNode;return t&&t.nodeType==11?t.host:t};let Sk=null;const Fo=function(e,t,r){let n=Sk||(Sk=document.createRange());return n.setEnd(e,r??e.nodeValue.length),n.setStart(e,t||0),n},oa=function(e,t,r,n){return r&&(Ek(e,t,r,n,-1)||Ek(e,t,r,n,1))},KR=/^(img|br|input|textarea|hr)$/i;function Ek(e,t,r,n,o){for(;;){if(e==r&&t==n)return!0;if(t==(o<0?0:yo(e))){let i=e.parentNode;if(!i||i.nodeType!=1||Pv(e)||KR.test(e.nodeName)||e.contentEditable=="false")return!1;t=br(e)+(o<0?0:1),e=i}else if(e.nodeType==1){if(e=e.childNodes[t+(o<0?-1:0)],e.contentEditable=="false")return!1;t=o<0?yo(e):0}else return!1}}function yo(e){return e.nodeType==3?e.nodeValue.length:e.childNodes.length}function qR(e,t,r){for(let n=t==0,o=t==yo(e);n||o;){if(e==r)return!0;let i=br(e);if(e=e.parentNode,!e)return!1;n=n&&i==0,o=o&&i==yo(e)}}function Pv(e){let t;for(let r=e;r&&!(t=r.pmViewDesc);r=r.parentNode);return t&&t.node&&t.node.isBlock&&(t.dom==e||t.contentDOM==e)}const Ih=function(e){return e.focusNode&&oa(e.focusNode,e.focusOffset,e.anchorNode,e.anchorOffset)};function Ds(e,t){let r=document.createEvent("Event");return r.initEvent("keydown",!0,!0),r.keyCode=e,r.key=r.code=t,r}function GR(e){let t=e.activeElement;for(;t&&t.shadowRoot;)t=t.shadowRoot.activeElement;return t}function YR(e,t,r){if(e.caretPositionFromPoint)try{let n=e.caretPositionFromPoint(t,r);if(n)return{node:n.offsetNode,offset:n.offset}}catch{}if(e.caretRangeFromPoint){let n=e.caretRangeFromPoint(t,r);if(n)return{node:n.startContainer,offset:n.startOffset}}}const To=typeof navigator<"u"?navigator:null,Ck=typeof document<"u"?document:null,hs=To&&To.userAgent||"",R1=/Edge\/(\d+)/.exec(hs),LE=/MSIE \d/.exec(hs),P1=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(hs),Ir=!!(LE||P1||R1),Vi=LE?document.documentMode:P1?+P1[1]:R1?+R1[1]:0,oo=!Ir&&/gecko\/(\d+)/i.test(hs);oo&&+(/Firefox\/(\d+)/.exec(hs)||[0,0])[1];const z1=!Ir&&/Chrome\/(\d+)/.exec(hs),dr=!!z1,JR=z1?+z1[1]:0,Sr=!Ir&&!!To&&/Apple Computer/.test(To.vendor),Nl=Sr&&(/Mobile\/\w+/.test(hs)||!!To&&To.maxTouchPoints>2),wn=Nl||(To?/Mac/.test(To.platform):!1),XR=To?/Win/.test(To.platform):!1,Jn=/Android \d/.test(hs),Pd=!!Ck&&"webkitFontSmoothing"in Ck.documentElement.style,QR=Pd?+(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent)||[0,0])[1]:0;function ZR(e){return{left:0,right:e.documentElement.clientWidth,top:0,bottom:e.documentElement.clientHeight}}function Lo(e,t){return typeof e=="number"?e:e[t]}function eP(e){let t=e.getBoundingClientRect(),r=t.width/e.offsetWidth||1,n=t.height/e.offsetHeight||1;return{left:t.left,right:t.left+e.clientWidth*r,top:t.top,bottom:t.top+e.clientHeight*n}}function Mk(e,t,r){let n=e.someProp("scrollThreshold")||0,o=e.someProp("scrollMargin")||5,i=e.dom.ownerDocument;for(let s=r||e.dom;s;s=Du(s)){if(s.nodeType!=1)continue;let a=s,l=a==i.body,c=l?ZR(i):eP(a),u=0,d=0;if(t.topc.bottom-Lo(n,"bottom")&&(d=t.bottom-t.top>c.bottom-c.top?t.top+Lo(o,"top")-c.top:t.bottom-c.bottom+Lo(o,"bottom")),t.leftc.right-Lo(n,"right")&&(u=t.right-c.right+Lo(o,"right")),u||d)if(l)i.defaultView.scrollBy(u,d);else{let f=a.scrollLeft,p=a.scrollTop;d&&(a.scrollTop+=d),u&&(a.scrollLeft+=u);let h=a.scrollLeft-f,m=a.scrollTop-p;t={left:t.left-h,top:t.top-m,right:t.right-h,bottom:t.bottom-m}}if(l||/^(fixed|sticky)$/.test(getComputedStyle(s).position))break}}function tP(e){let t=e.dom.getBoundingClientRect(),r=Math.max(0,t.top),n,o;for(let i=(t.left+t.right)/2,s=r+1;s=r-20){n=a,o=l.top;break}}return{refDOM:n,refTop:o,stack:IE(e.dom)}}function IE(e){let t=[],r=e.ownerDocument;for(let n=e;n&&(t.push({dom:n,top:n.scrollTop,left:n.scrollLeft}),e!=r);n=Du(n));return t}function rP({refDOM:e,refTop:t,stack:r}){let n=e?e.getBoundingClientRect().top:0;DE(r,n==0?0:n-t)}function DE(e,t){for(let r=0;r=a){s=Math.max(h.bottom,s),a=Math.min(h.top,a);let m=h.left>t.left?h.left-t.left:h.right=(h.left+h.right)/2?1:0));continue}}else h.top>t.top&&!l&&h.left<=t.left&&h.right>=t.left&&(l=u,c={left:Math.max(h.left,Math.min(h.right,t.left)),top:h.top});!r&&(t.left>=h.right&&t.top>=h.top||t.left>=h.left&&t.top>=h.bottom)&&(i=d+1)}}return!r&&l&&(r=l,o=c,n=0),r&&r.nodeType==3?oP(r,o):!r||n&&r.nodeType==1?{node:e,offset:i}:$E(r,o)}function oP(e,t){let r=e.nodeValue.length,n=document.createRange();for(let o=0;o=(i.left+i.right)/2?1:0)}}return{node:e,offset:0}}function zv(e,t){return e.left>=t.left-1&&e.left<=t.right+1&&e.top>=t.top-1&&e.top<=t.bottom+1}function iP(e,t){let r=e.parentNode;return r&&/^li$/i.test(r.nodeName)&&t.left(s.left+s.right)/2?1:-1}return e.docView.posFromDOM(n,o,i)}function aP(e,t,r,n){let o=-1;for(let i=t,s=!1;i!=e.dom;){let a=e.docView.nearestDesc(i,!0);if(!a)return null;if(a.dom.nodeType==1&&(a.node.isBlock&&a.parent&&!s||!a.contentDOM)){let l=a.dom.getBoundingClientRect();if(a.node.isBlock&&a.parent&&!s&&(s=!0,l.left>n.left||l.top>n.top?o=a.posBefore:(l.right-1?o:e.docView.posFromDOM(t,r,-1)}function HE(e,t,r){let n=e.childNodes.length;if(n&&r.topt.top&&o++}let c;Pd&&o&&n.nodeType==1&&(c=n.childNodes[o-1]).nodeType==1&&c.contentEditable=="false"&&c.getBoundingClientRect().top>=t.top&&o--,n==e.dom&&o==n.childNodes.length-1&&n.lastChild.nodeType==1&&t.top>n.lastChild.getBoundingClientRect().bottom?a=e.state.doc.content.size:(o==0||n.nodeType!=1||n.childNodes[o-1].nodeName!="BR")&&(a=aP(e,n,o,t))}a==null&&(a=sP(e,s,t));let l=e.docView.nearestDesc(s,!0);return{pos:a,inside:l?l.posAtStart-l.border:-1}}function Tk(e){return e.top=0&&o==n.nodeValue.length?(l--,u=1):r<0?l--:c++,yc(wi(Fo(n,l,c),u),u<0)}if(!e.state.doc.resolve(t-(i||0)).parent.inlineContent){if(i==null&&o&&(r<0||o==yo(n))){let l=n.childNodes[o-1];if(l.nodeType==1)return gg(l.getBoundingClientRect(),!1)}if(i==null&&o=0)}if(i==null&&o&&(r<0||o==yo(n))){let l=n.childNodes[o-1],c=l.nodeType==3?Fo(l,yo(l)-(s?0:1)):l.nodeType==1&&(l.nodeName!="BR"||!l.nextSibling)?l:null;if(c)return yc(wi(c,1),!1)}if(i==null&&o=0)}function yc(e,t){if(e.width==0)return e;let r=t?e.left:e.right;return{top:e.top,bottom:e.bottom,left:r,right:r}}function gg(e,t){if(e.height==0)return e;let r=t?e.top:e.bottom;return{top:r,bottom:r,left:e.left,right:e.right}}function FE(e,t,r){let n=e.state,o=e.root.activeElement;n!=t&&e.updateState(t),o!=e.dom&&e.focus();try{return r()}finally{n!=t&&e.updateState(n),o!=e.dom&&o&&o.focus()}}function uP(e,t,r){let n=t.selection,o=r=="up"?n.$from:n.$to;return FE(e,t,()=>{let{node:i}=e.docView.domFromPos(o.pos,r=="up"?-1:1);for(;;){let a=e.docView.nearestDesc(i,!0);if(!a)break;if(a.node.isBlock){i=a.contentDOM||a.dom;break}i=a.dom.parentNode}let s=BE(e,o.pos,1);for(let a=i.firstChild;a;a=a.nextSibling){let l;if(a.nodeType==1)l=a.getClientRects();else if(a.nodeType==3)l=Fo(a,0,a.nodeValue.length).getClientRects();else continue;for(let c=0;cu.top+1&&(r=="up"?s.top-u.top>(u.bottom-s.top)*2:u.bottom-s.bottom>(s.bottom-u.top)*2))return!1}}return!0})}const dP=/[\u0590-\u08ac]/;function fP(e,t,r){let{$head:n}=t.selection;if(!n.parent.isTextblock)return!1;let o=n.parentOffset,i=!o,s=o==n.parent.content.size,a=e.domSelection();return!dP.test(n.parent.textContent)||!a.modify?r=="left"||r=="backward"?i:s:FE(e,t,()=>{let{focusNode:l,focusOffset:c,anchorNode:u,anchorOffset:d}=e.domSelectionRange(),f=a.caretBidiLevel;a.modify("move",r,"character");let p=n.depth?e.docView.domAfterPos(n.before()):e.dom,{focusNode:h,focusOffset:m}=e.domSelectionRange(),b=h&&!p.contains(h.nodeType==1?h:h.parentNode)||l==h&&c==m;try{a.collapse(u,d),l&&(l!=u||c!=d)&&a.extend&&a.extend(l,c)}catch{}return f!=null&&(a.caretBidiLevel=f),b})}let Ok=null,_k=null,Ak=!1;function pP(e,t,r){return Ok==t&&_k==r?Ak:(Ok=t,_k=r,Ak=r=="up"||r=="down"?uP(e,t,r):fP(e,t,r))}const _n=0,Nk=1,Bs=2,Oo=3;class zd{constructor(t,r,n,o){this.parent=t,this.children=r,this.dom=n,this.contentDOM=o,this.dirty=_n,n.pmViewDesc=this}matchesWidget(t){return!1}matchesMark(t){return!1}matchesNode(t,r,n){return!1}matchesHack(t){return!1}parseRule(){return null}stopEvent(t){return!1}get size(){let t=0;for(let r=0;rbr(this.contentDOM);else if(this.contentDOM&&this.contentDOM!=this.dom&&this.dom.contains(this.contentDOM))o=t.compareDocumentPosition(this.contentDOM)&2;else if(this.dom.firstChild){if(r==0)for(let i=t;;i=i.parentNode){if(i==this.dom){o=!1;break}if(i.previousSibling)break}if(o==null&&r==t.childNodes.length)for(let i=t;;i=i.parentNode){if(i==this.dom){o=!0;break}if(i.nextSibling)break}}return o??n>0?this.posAtEnd:this.posAtStart}nearestDesc(t,r=!1){for(let n=!0,o=t;o;o=o.parentNode){let i=this.getDesc(o),s;if(i&&(!r||i.node))if(n&&(s=i.nodeDOM)&&!(s.nodeType==1?s.contains(t.nodeType==1?t:t.parentNode):s==t))n=!1;else return i}}getDesc(t){let r=t.pmViewDesc;for(let n=r;n;n=n.parent)if(n==this)return r}posFromDOM(t,r,n){for(let o=t;o;o=o.parentNode){let i=this.getDesc(o);if(i)return i.localPosFromDOM(t,r,n)}return-1}descAt(t){for(let r=0,n=0;rt||s instanceof jE){o=t-i;break}i=a}if(o)return this.children[n].domFromPos(o-this.children[n].border,r);for(let i;n&&!(i=this.children[n-1]).size&&i instanceof VE&&i.side>=0;n--);if(r<=0){let i,s=!0;for(;i=n?this.children[n-1]:null,!(!i||i.dom.parentNode==this.contentDOM);n--,s=!1);return i&&r&&s&&!i.border&&!i.domAtom?i.domFromPos(i.size,r):{node:this.contentDOM,offset:i?br(i.dom)+1:0}}else{let i,s=!0;for(;i=n=u&&r<=c-l.border&&l.node&&l.contentDOM&&this.contentDOM.contains(l.contentDOM))return l.parseRange(t,r,u);t=s;for(let d=a;d>0;d--){let f=this.children[d-1];if(f.size&&f.dom.parentNode==this.contentDOM&&!f.emptyChildAt(1)){o=br(f.dom)+1;break}t-=f.size}o==-1&&(o=0)}if(o>-1&&(c>r||a==this.children.length-1)){r=c;for(let u=a+1;up&&sr){let p=a;a=l,l=p}let f=document.createRange();f.setEnd(l.node,l.offset),f.setStart(a.node,a.offset),c.removeAllRanges(),c.addRange(f)}}ignoreMutation(t){return!this.contentDOM&&t.type!="selection"}get contentLost(){return this.contentDOM&&this.contentDOM!=this.dom&&!this.dom.contains(this.contentDOM)}markDirty(t,r){for(let n=0,o=0;o=n:tn){let a=n+i.border,l=s-i.border;if(t>=a&&r<=l){this.dirty=t==n||r==s?Bs:Nk,t==a&&r==l&&(i.contentLost||i.dom.parentNode!=this.contentDOM)?i.dirty=Oo:i.markDirty(t-a,r-a);return}else i.dirty=i.dom==i.contentDOM&&i.dom.parentNode==this.contentDOM&&!i.children.length?Bs:Oo}n=s}this.dirty=Bs}markParentsDirty(){let t=1;for(let r=this.parent;r;r=r.parent,t++){let n=t==1?Bs:Nk;r.dirty{if(!i)return o;if(i.parent)return i.parent.posBeforeChild(i)})),!r.type.spec.raw){if(s.nodeType!=1){let a=document.createElement("span");a.appendChild(s),s=a}s.contentEditable="false",s.classList.add("ProseMirror-widget")}super(t,[],s,null),this.widget=r,this.widget=r,i=this}matchesWidget(t){return this.dirty==_n&&t.type.eq(this.widget.type)}parseRule(){return{ignore:!0}}stopEvent(t){let r=this.widget.spec.stopEvent;return r?r(t):!1}ignoreMutation(t){return t.type!="selection"||this.widget.spec.ignoreSelection}destroy(){this.widget.type.destroy(this.dom),super.destroy()}get domAtom(){return!0}get side(){return this.widget.type.side}}class hP extends zd{constructor(t,r,n,o){super(t,[],r,null),this.textDOM=n,this.text=o}get size(){return this.text.length}localPosFromDOM(t,r){return t!=this.textDOM?this.posAtStart+(r?this.size:0):this.posAtStart+r}domFromPos(t){return{node:this.textDOM,offset:t}}ignoreMutation(t){return t.type==="characterData"&&t.target.nodeValue==t.oldValue}}class ia extends zd{constructor(t,r,n,o){super(t,[],n,o),this.mark=r}static create(t,r,n,o){let i=o.nodeViews[r.type.name],s=i&&i(r,o,n);return(!s||!s.dom)&&(s=an.renderSpec(document,r.type.spec.toDOM(r,n))),new ia(t,r,s.dom,s.contentDOM||s.dom)}parseRule(){return this.dirty&Oo||this.mark.type.spec.reparseInView?null:{mark:this.mark.type.name,attrs:this.mark.attrs,contentElement:this.contentDOM}}matchesMark(t){return this.dirty!=Oo&&this.mark.eq(t)}markDirty(t,r){if(super.markDirty(t,r),this.dirty!=_n){let n=this.parent;for(;!n.node;)n=n.parent;n.dirty0&&(i=D1(i,0,t,n));for(let a=0;a{if(!l)return s;if(l.parent)return l.parent.posBeforeChild(l)},n,o),u=c&&c.dom,d=c&&c.contentDOM;if(r.isText){if(!u)u=document.createTextNode(r.text);else if(u.nodeType!=3)throw new RangeError("Text must be rendered as a DOM text node")}else u||({dom:u,contentDOM:d}=an.renderSpec(document,r.type.spec.toDOM(r)));!d&&!r.isText&&u.nodeName!="BR"&&(u.hasAttribute("contenteditable")||(u.contentEditable="false"),r.type.spec.draggable&&(u.draggable=!0));let f=u;return u=KE(u,n,r),c?l=new mP(t,r,n,o,u,d||null,f,c,i,s+1):r.isText?new Dh(t,r,n,o,u,f,i):new ji(t,r,n,o,u,d||null,f,i,s+1)}parseRule(){if(this.node.type.spec.reparseInView)return null;let t={node:this.node.type.name,attrs:this.node.attrs};if(this.node.type.whitespace=="pre"&&(t.preserveWhitespace="full"),!this.contentDOM)t.getContent=()=>this.node.content;else if(!this.contentLost)t.contentElement=this.contentDOM;else{for(let r=this.children.length-1;r>=0;r--){let n=this.children[r];if(this.dom.contains(n.dom.parentNode)){t.contentElement=n.dom.parentNode;break}}t.contentElement||(t.getContent=()=>R.empty)}return t}matchesNode(t,r,n){return this.dirty==_n&&t.eq(this.node)&&I1(r,this.outerDeco)&&n.eq(this.innerDeco)}get size(){return this.node.nodeSize}get border(){return this.node.isLeaf?0:1}updateChildren(t,r){let n=this.node.inlineContent,o=r,i=t.composing?this.localCompositionInfo(t,r):null,s=i&&i.pos>-1?i:null,a=i&&i.pos<0,l=new vP(this,s&&s.node,t);xP(this.node,this.innerDeco,(c,u,d)=>{c.spec.marks?l.syncToMarks(c.spec.marks,n,t):c.type.side>=0&&!d&&l.syncToMarks(u==this.node.childCount?Te.none:this.node.child(u).marks,n,t),l.placeWidget(c,t,o)},(c,u,d,f)=>{l.syncToMarks(c.marks,n,t);let p;l.findNodeMatch(c,u,d,f)||a&&t.state.selection.from>o&&t.state.selection.to-1&&l.updateNodeAt(c,u,d,p,t)||l.updateNextNode(c,u,d,t,f,o)||l.addNode(c,u,d,t,o),o+=c.nodeSize}),l.syncToMarks([],n,t),this.node.isTextblock&&l.addTextblockHacks(),l.destroyRest(),(l.changed||this.dirty==Bs)&&(s&&this.protectLocalComposition(t,s),UE(this.contentDOM,this.children,t),Nl&&kP(this.dom))}localCompositionInfo(t,r){let{from:n,to:o}=t.state.selection;if(!(t.state.selection instanceof le)||nr+this.node.content.size)return null;let i=t.domSelectionRange(),s=wP(i.focusNode,i.focusOffset);if(!s||!this.dom.contains(s.parentNode))return null;if(this.node.inlineContent){let a=s.nodeValue,l=SP(this.node.content,a,n-r,o-r);return l<0?null:{node:s,pos:l,text:a}}else return{node:s,pos:-1,text:""}}protectLocalComposition(t,{node:r,pos:n,text:o}){if(this.getDesc(r))return;let i=r;for(;i.parentNode!=this.contentDOM;i=i.parentNode){for(;i.previousSibling;)i.parentNode.removeChild(i.previousSibling);for(;i.nextSibling;)i.parentNode.removeChild(i.nextSibling);i.pmViewDesc&&(i.pmViewDesc=void 0)}let s=new hP(this,i,r,o);t.input.compositionNodes.push(s),this.children=D1(this.children,n,n+o.length,t,s)}update(t,r,n,o){return this.dirty==Oo||!t.sameMarkup(this.node)?!1:(this.updateInner(t,r,n,o),!0)}updateInner(t,r,n,o){this.updateOuterDeco(r),this.node=t,this.innerDeco=n,this.contentDOM&&this.updateChildren(o,this.posAtStart),this.dirty=_n}updateOuterDeco(t){if(I1(t,this.outerDeco))return;let r=this.nodeDOM.nodeType!=1,n=this.dom;this.dom=WE(this.dom,this.nodeDOM,L1(this.outerDeco,this.node,r),L1(t,this.node,r)),this.dom!=n&&(n.pmViewDesc=void 0,this.dom.pmViewDesc=this),this.outerDeco=t}selectNode(){this.nodeDOM.nodeType==1&&this.nodeDOM.classList.add("ProseMirror-selectednode"),(this.contentDOM||!this.node.type.spec.draggable)&&(this.dom.draggable=!0)}deselectNode(){this.nodeDOM.nodeType==1&&this.nodeDOM.classList.remove("ProseMirror-selectednode"),(this.contentDOM||!this.node.type.spec.draggable)&&this.dom.removeAttribute("draggable")}get domAtom(){return this.node.isAtom}}function Rk(e,t,r,n,o){KE(n,t,e);let i=new ji(void 0,e,t,r,n,n,n,o,0);return i.contentDOM&&i.updateChildren(o,0),i}class Dh extends ji{constructor(t,r,n,o,i,s,a){super(t,r,n,o,i,null,s,a,0)}parseRule(){let t=this.nodeDOM.parentNode;for(;t&&t!=this.dom&&!t.pmIsDeco;)t=t.parentNode;return{skip:t||!0}}update(t,r,n,o){return this.dirty==Oo||this.dirty!=_n&&!this.inParent()||!t.sameMarkup(this.node)?!1:(this.updateOuterDeco(r),(this.dirty!=_n||t.text!=this.node.text)&&t.text!=this.nodeDOM.nodeValue&&(this.nodeDOM.nodeValue=t.text,o.trackWrites==this.nodeDOM&&(o.trackWrites=null)),this.node=t,this.dirty=_n,!0)}inParent(){let t=this.parent.contentDOM;for(let r=this.nodeDOM;r;r=r.parentNode)if(r==t)return!0;return!1}domFromPos(t){return{node:this.nodeDOM,offset:t}}localPosFromDOM(t,r,n){return t==this.nodeDOM?this.posAtStart+Math.min(r,this.node.text.length):super.localPosFromDOM(t,r,n)}ignoreMutation(t){return t.type!="characterData"&&t.type!="selection"}slice(t,r,n){let o=this.node.cut(t,r),i=document.createTextNode(o.text);return new Dh(this.parent,o,this.outerDeco,this.innerDeco,i,i,n)}markDirty(t,r){super.markDirty(t,r),this.dom!=this.nodeDOM&&(t==0||r==this.nodeDOM.nodeValue.length)&&(this.dirty=Oo)}get domAtom(){return!1}}class jE extends zd{parseRule(){return{ignore:!0}}matchesHack(t){return this.dirty==_n&&this.dom.nodeName==t}get domAtom(){return!0}get ignoreForCoords(){return this.dom.nodeName=="IMG"}}class mP extends ji{constructor(t,r,n,o,i,s,a,l,c,u){super(t,r,n,o,i,s,a,c,u),this.spec=l}update(t,r,n,o){if(this.dirty==Oo)return!1;if(this.spec.update){let i=this.spec.update(t,r,n);return i&&this.updateInner(t,r,n,o),i}else return!this.contentDOM&&!t.isLeaf?!1:super.update(t,r,n,o)}selectNode(){this.spec.selectNode?this.spec.selectNode():super.selectNode()}deselectNode(){this.spec.deselectNode?this.spec.deselectNode():super.deselectNode()}setSelection(t,r,n,o){this.spec.setSelection?this.spec.setSelection(t,r,n):super.setSelection(t,r,n,o)}destroy(){this.spec.destroy&&this.spec.destroy(),super.destroy()}stopEvent(t){return this.spec.stopEvent?this.spec.stopEvent(t):!1}ignoreMutation(t){return this.spec.ignoreMutation?this.spec.ignoreMutation(t):super.ignoreMutation(t)}}function UE(e,t,r){let n=e.firstChild,o=!1;for(let i=0;i>1,s=Math.min(i,t.length);for(;o-1)a>this.index&&(this.changed=!0,this.destroyBetween(this.index,a)),this.top=this.top.children[this.index];else{let l=ia.create(this.top,t[i],r,n);this.top.children.splice(this.index,0,l),this.top=l,this.changed=!0}this.index=0,i++}}findNodeMatch(t,r,n,o){let i=-1,s;if(o>=this.preMatch.index&&(s=this.preMatch.matches[o-this.preMatch.index]).parent==this.top&&s.matchesNode(t,r,n))i=this.top.children.indexOf(s,this.index);else for(let a=this.index,l=Math.min(this.top.children.length,a+5);a0;){let a;for(;;)if(n){let c=r.children[n-1];if(c instanceof ia)r=c,n=c.children.length;else{a=c,n--;break}}else{if(r==t)break e;n=r.parent.children.indexOf(r),r=r.parent}let l=a.node;if(l){if(l!=e.child(o-1))break;--o,i.set(a,o),s.push(a)}}return{index:o,matched:i,matches:s.reverse()}}function bP(e,t){return e.type.side-t.type.side}function xP(e,t,r,n){let o=t.locals(e),i=0;if(o.length==0){for(let c=0;ci;)a.push(o[s++]);let h=i+f.nodeSize;if(f.isText){let b=h;s!b.inline):a.slice();n(f,m,t.forChild(i,f),p),i=h}}function kP(e){if(e.nodeName=="UL"||e.nodeName=="OL"){let t=e.style.cssText;e.style.cssText=t+"; list-style: square !important",window.getComputedStyle(e).listStyle,e.style.cssText=t}}function wP(e,t){for(;;){if(e.nodeType==3)return e;if(e.nodeType==1&&t>0){if(e.childNodes.length>t&&e.childNodes[t].nodeType==3)return e.childNodes[t];e=e.childNodes[t-1],t=yo(e)}else if(e.nodeType==1&&t=r){if(i>=n&&l.slice(n-t.length-a,n-a)==t)return n-t.length;let c=a=0&&c+t.length+a>=r)return a+c;if(r==n&&l.length>=n+t.length-a&&l.slice(n-a,n-a+t.length)==t)return n}}return-1}function D1(e,t,r,n,o){let i=[];for(let s=0,a=0;s=r||u<=t?i.push(l):(cr&&i.push(l.slice(r-c,l.size,n)))}return i}function Lv(e,t=null){let r=e.domSelectionRange(),n=e.state.doc;if(!r.focusNode)return null;let o=e.docView.nearestDesc(r.focusNode),i=o&&o.size==0,s=e.docView.posFromDOM(r.focusNode,r.focusOffset,1);if(s<0)return null;let a=n.resolve(s),l,c;if(Ih(r)){for(l=a;o&&!o.node;)o=o.parent;let u=o.node;if(o&&u.isAtom&&ce.isSelectable(u)&&o.parent&&!(u.isInline&&qR(r.focusNode,r.focusOffset,o.dom))){let d=o.posBefore;c=new ce(s==d?a:n.resolve(d))}}else{let u=e.docView.posFromDOM(r.anchorNode,r.anchorOffset,1);if(u<0)return null;l=n.resolve(u)}if(!c){let u=t=="pointer"||e.state.selection.head{(r.anchorNode!=n||r.anchorOffset!=o)&&(t.removeEventListener("selectionchange",e.input.hideSelectionGuard),setTimeout(()=>{(!qE(e)||e.state.selection.visible)&&e.dom.classList.remove("ProseMirror-hideselection")},20))})}function CP(e){let t=e.domSelection(),r=document.createRange(),n=e.cursorWrapper.dom,o=n.nodeName=="IMG";o?r.setEnd(n.parentNode,br(n)+1):r.setEnd(n,0),r.collapse(!1),t.removeAllRanges(),t.addRange(r),!o&&!e.state.selection.visible&&Ir&&Vi<=11&&(n.disabled=!0,n.disabled=!1)}function GE(e,t){if(t instanceof ce){let r=e.docView.descAt(t.from);r!=e.lastSelectedViewDesc&&(Dk(e),r&&r.selectNode(),e.lastSelectedViewDesc=r)}else Dk(e)}function Dk(e){e.lastSelectedViewDesc&&(e.lastSelectedViewDesc.parent&&e.lastSelectedViewDesc.deselectNode(),e.lastSelectedViewDesc=void 0)}function Iv(e,t,r,n){return e.someProp("createSelectionBetween",o=>o(e,t,r))||le.between(t,r,n)}function $k(e){return e.editable&&!e.hasFocus()?!1:YE(e)}function YE(e){let t=e.domSelectionRange();if(!t.anchorNode)return!1;try{return e.dom.contains(t.anchorNode.nodeType==3?t.anchorNode.parentNode:t.anchorNode)&&(e.editable||e.dom.contains(t.focusNode.nodeType==3?t.focusNode.parentNode:t.focusNode))}catch{return!1}}function MP(e){let t=e.docView.domFromPos(e.state.selection.anchor,0),r=e.domSelectionRange();return oa(t.node,t.offset,r.anchorNode,r.anchorOffset)}function $1(e,t){let{$anchor:r,$head:n}=e.selection,o=t>0?r.max(n):r.min(n),i=o.parent.inlineContent?o.depth?e.doc.resolve(t>0?o.after():o.before()):null:o;return i&&be.findFrom(i,t)}function Oi(e,t){return e.dispatch(e.state.tr.setSelection(t).scrollIntoView()),!0}function Hk(e,t,r){let n=e.state.selection;if(n instanceof le)if(r.indexOf("s")>-1){let{$head:o}=n,i=o.textOffset?null:t<0?o.nodeBefore:o.nodeAfter;if(!i||i.isText||!i.isLeaf)return!1;let s=e.state.doc.resolve(o.pos+i.nodeSize*(t<0?-1:1));return Oi(e,new le(n.$anchor,s))}else if(n.empty){if(e.endOfTextblock(t>0?"forward":"backward")){let o=$1(e.state,t);return o&&o instanceof ce?Oi(e,o):!1}else if(!(wn&&r.indexOf("m")>-1)){let o=n.$head,i=o.textOffset?null:t<0?o.nodeBefore:o.nodeAfter,s;if(!i||i.isText)return!1;let a=t<0?o.pos-i.nodeSize:o.pos;return i.isAtom||(s=e.docView.descAt(a))&&!s.contentDOM?ce.isSelectable(i)?Oi(e,new ce(t<0?e.state.doc.resolve(o.pos-i.nodeSize):o)):Pd?Oi(e,new le(e.state.doc.resolve(t<0?a:a+i.nodeSize))):!1:!1}}else return!1;else{if(n instanceof ce&&n.node.isInline)return Oi(e,new le(t>0?n.$to:n.$from));{let o=$1(e.state,t);return o?Oi(e,o):!1}}}function Tp(e){return e.nodeType==3?e.nodeValue.length:e.childNodes.length}function yu(e,t){let r=e.pmViewDesc;return r&&r.size==0&&(t<0||e.nextSibling||e.nodeName!="BR")}function Aa(e,t){return t<0?TP(e):OP(e)}function TP(e){let t=e.domSelectionRange(),r=t.focusNode,n=t.focusOffset;if(!r)return;let o,i,s=!1;for(oo&&r.nodeType==1&&n0){if(r.nodeType!=1)break;{let a=r.childNodes[n-1];if(yu(a,-1))o=r,i=--n;else if(a.nodeType==3)r=a,n=r.nodeValue.length;else break}}else{if(JE(r))break;{let a=r.previousSibling;for(;a&&yu(a,-1);)o=r.parentNode,i=br(a),a=a.previousSibling;if(a)r=a,n=Tp(r);else{if(r=r.parentNode,r==e.dom)break;n=0}}}s?H1(e,r,n):o&&H1(e,o,i)}function OP(e){let t=e.domSelectionRange(),r=t.focusNode,n=t.focusOffset;if(!r)return;let o=Tp(r),i,s;for(;;)if(n{e.state==o&&Qo(e)},50)}function Bk(e,t){let r=e.state.doc.resolve(t);if(!(dr||XR)&&r.parent.inlineContent){let o=e.coordsAtPos(t);if(t>r.start()){let i=e.coordsAtPos(t-1),s=(i.top+i.bottom)/2;if(s>o.top&&s1)return i.lefto.top&&s1)return i.left>o.left?"ltr":"rtl"}}return getComputedStyle(e.dom).direction=="rtl"?"rtl":"ltr"}function Fk(e,t,r){let n=e.state.selection;if(n instanceof le&&!n.empty||r.indexOf("s")>-1||wn&&r.indexOf("m")>-1)return!1;let{$from:o,$to:i}=n;if(!o.parent.inlineContent||e.endOfTextblock(t<0?"up":"down")){let s=$1(e.state,t);if(s&&s instanceof ce)return Oi(e,s)}if(!o.parent.inlineContent){let s=t<0?o:i,a=n instanceof kr?be.near(s,t):be.findFrom(s,t);return a?Oi(e,a):!1}return!1}function Vk(e,t){if(!(e.state.selection instanceof le))return!0;let{$head:r,$anchor:n,empty:o}=e.state.selection;if(!r.sameParent(n))return!0;if(!o)return!1;if(e.endOfTextblock(t>0?"forward":"backward"))return!0;let i=!r.textOffset&&(t<0?r.nodeBefore:r.nodeAfter);if(i&&!i.isText){let s=e.state.tr;return t<0?s.delete(r.pos-i.nodeSize,r.pos):s.delete(r.pos,r.pos+i.nodeSize),e.dispatch(s),!0}return!1}function jk(e,t,r){e.domObserver.stop(),t.contentEditable=r,e.domObserver.start()}function NP(e){if(!Sr||e.state.selection.$head.parentOffset>0)return!1;let{focusNode:t,focusOffset:r}=e.domSelectionRange();if(t&&t.nodeType==1&&r==0&&t.firstChild&&t.firstChild.contentEditable=="false"){let n=t.firstChild;jk(e,n,"true"),setTimeout(()=>jk(e,n,"false"),20)}return!1}function RP(e){let t="";return e.ctrlKey&&(t+="c"),e.metaKey&&(t+="m"),e.altKey&&(t+="a"),e.shiftKey&&(t+="s"),t}function PP(e,t){let r=t.keyCode,n=RP(t);if(r==8||wn&&r==72&&n=="c")return Vk(e,-1)||Aa(e,-1);if(r==46&&!t.shiftKey||wn&&r==68&&n=="c")return Vk(e,1)||Aa(e,1);if(r==13||r==27)return!0;if(r==37||wn&&r==66&&n=="c"){let o=r==37?Bk(e,e.state.selection.from)=="ltr"?-1:1:-1;return Hk(e,o,n)||Aa(e,o)}else if(r==39||wn&&r==70&&n=="c"){let o=r==39?Bk(e,e.state.selection.from)=="ltr"?1:-1:1;return Hk(e,o,n)||Aa(e,o)}else{if(r==38||wn&&r==80&&n=="c")return Fk(e,-1,n)||Aa(e,-1);if(r==40||wn&&r==78&&n=="c")return NP(e)||Fk(e,1,n)||Aa(e,1);if(n==(wn?"m":"c")&&(r==66||r==73||r==89||r==90))return!0}return!1}function XE(e,t){e.someProp("transformCopied",p=>{t=p(t,e)});let r=[],{content:n,openStart:o,openEnd:i}=t;for(;o>1&&i>1&&n.childCount==1&&n.firstChild.childCount==1;){o--,i--;let p=n.firstChild;r.push(p.type.name,p.attrs!=p.type.defaultAttrs?p.attrs:null),n=p.content}let s=e.someProp("clipboardSerializer")||an.fromSchema(e.state.schema),a=nC(),l=a.createElement("div");l.appendChild(s.serializeFragment(n,{document:a}));let c=l.firstChild,u,d=0;for(;c&&c.nodeType==1&&(u=rC[c.nodeName.toLowerCase()]);){for(let p=u.length-1;p>=0;p--){let h=a.createElement(u[p]);for(;l.firstChild;)h.appendChild(l.firstChild);l.appendChild(h),d++}c=l.firstChild}c&&c.nodeType==1&&c.setAttribute("data-pm-slice",`${o} ${i}${d?` -${d}`:""} ${JSON.stringify(r)}`);let f=e.someProp("clipboardTextSerializer",p=>p(t,e))||t.content.textBetween(0,t.content.size,` + +`);return{dom:l,text:f}}function QE(e,t,r,n,o){let i=o.parent.type.spec.code,s,a;if(!r&&!t)return null;let l=t&&(n||i||!r);if(l){if(e.someProp("transformPastedText",f=>{t=f(t,i||n,e)}),i)return t?new K(R.from(e.state.schema.text(t.replace(/\r\n?/g,` +`))),0,0):K.empty;let d=e.someProp("clipboardTextParser",f=>f(t,o,n,e));if(d)a=d;else{let f=o.marks(),{schema:p}=e.state,h=an.fromSchema(p);s=document.createElement("div"),t.split(/(?:\r\n?|\n)+/).forEach(m=>{let b=s.appendChild(document.createElement("p"));m&&b.appendChild(h.serializeNode(p.text(m,f)))})}}else e.someProp("transformPastedHTML",d=>{r=d(r,e)}),s=IP(r),Pd&&DP(s);let c=s&&s.querySelector("[data-pm-slice]"),u=c&&/^(\d+) (\d+)(?: -(\d+))? (.*)/.exec(c.getAttribute("data-pm-slice")||"");if(u&&u[3])for(let d=+u[3];d>0;d--){let f=s.firstChild;for(;f&&f.nodeType!=1;)f=f.nextSibling;if(!f)break;s=f}if(a||(a=(e.someProp("clipboardParser")||e.someProp("domParser")||Mv.fromSchema(e.state.schema)).parseSlice(s,{preserveWhitespace:!!(l||u),context:o,ruleFromNode(f){return f.nodeName=="BR"&&!f.nextSibling&&f.parentNode&&!zP.test(f.parentNode.nodeName)?{ignore:!0}:null}})),u)a=$P(Uk(a,+u[1],+u[2]),u[4]);else if(a=K.maxOpen(LP(a.content,o),!0),a.openStart||a.openEnd){let d=0,f=0;for(let p=a.content.firstChild;d{a=d(a,e)}),a}const zP=/^(a|abbr|acronym|b|cite|code|del|em|i|ins|kbd|label|output|q|ruby|s|samp|span|strong|sub|sup|time|u|tt|var)$/i;function LP(e,t){if(e.childCount<2)return e;for(let r=t.depth;r>=0;r--){let o=t.node(r).contentMatchAt(t.index(r)),i,s=[];if(e.forEach(a=>{if(!s)return;let l=o.findWrapping(a.type),c;if(!l)return s=null;if(c=s.length&&i.length&&eC(l,i,a,s[s.length-1],0))s[s.length-1]=c;else{s.length&&(s[s.length-1]=tC(s[s.length-1],i.length));let u=ZE(a,l);s.push(u),o=o.matchType(u.type),i=l}}),s)return R.from(s)}return e}function ZE(e,t,r=0){for(let n=t.length-1;n>=r;n--)e=t[n].create(null,R.from(e));return e}function eC(e,t,r,n,o){if(o1&&(i=0),o=r&&(a=t<0?s.contentMatchAt(0).fillBefore(a,i<=o).append(a):a.append(s.contentMatchAt(s.childCount).fillBefore(R.empty,!0))),e.replaceChild(t<0?0:e.childCount-1,s.copy(a))}function Uk(e,t,r){return t]*>)*/.exec(e);t&&(e=e.slice(t[0].length));let r=nC().createElement("div"),n=/<([a-z][^>\s]+)/i.exec(e),o;if((o=n&&rC[n[1].toLowerCase()])&&(e=o.map(i=>"<"+i+">").join("")+e+o.map(i=>"").reverse().join("")),r.innerHTML=e,o)for(let i=0;i=0;a-=2){let l=r.nodes[n[a]];if(!l||l.hasRequiredAttrs())break;o=R.from(l.create(n[a+1],o)),i++,s++}return new K(o,i,s)}const Er={},Cr={},HP={touchstart:!0,touchmove:!0};class BP{constructor(){this.shiftKey=!1,this.mouseDown=null,this.lastKeyCode=null,this.lastKeyCodeTime=0,this.lastClick={time:0,x:0,y:0,type:""},this.lastSelectionOrigin=null,this.lastSelectionTime=0,this.lastIOSEnter=0,this.lastIOSEnterFallbackTimeout=-1,this.lastFocus=0,this.lastTouch=0,this.lastAndroidDelete=0,this.composing=!1,this.composingTimeout=-1,this.compositionNodes=[],this.compositionEndedAt=-2e8,this.compositionID=1,this.compositionPendingChanges=0,this.domChangeCount=0,this.eventHandlers=Object.create(null),this.hideSelectionGuard=null}}function FP(e){for(let t in Er){let r=Er[t];e.dom.addEventListener(t,e.input.eventHandlers[t]=n=>{jP(e,n)&&!Dv(e,n)&&(e.editable||!(n.type in Cr))&&r(e,n)},HP[t]?{passive:!0}:void 0)}Sr&&e.dom.addEventListener("input",()=>null),F1(e)}function Di(e,t){e.input.lastSelectionOrigin=t,e.input.lastSelectionTime=Date.now()}function VP(e){e.domObserver.stop();for(let t in e.input.eventHandlers)e.dom.removeEventListener(t,e.input.eventHandlers[t]);clearTimeout(e.input.composingTimeout),clearTimeout(e.input.lastIOSEnterFallbackTimeout)}function F1(e){e.someProp("handleDOMEvents",t=>{for(let r in t)e.input.eventHandlers[r]||e.dom.addEventListener(r,e.input.eventHandlers[r]=n=>Dv(e,n))})}function Dv(e,t){return e.someProp("handleDOMEvents",r=>{let n=r[t.type];return n?n(e,t)||t.defaultPrevented:!1})}function jP(e,t){if(!t.bubbles)return!0;if(t.defaultPrevented)return!1;for(let r=t.target;r!=e.dom;r=r.parentNode)if(!r||r.nodeType==11||r.pmViewDesc&&r.pmViewDesc.stopEvent(t))return!1;return!0}function UP(e,t){!Dv(e,t)&&Er[t.type]&&(e.editable||!(t.type in Cr))&&Er[t.type](e,t)}Cr.keydown=(e,t)=>{let r=t;if(e.input.shiftKey=r.keyCode==16||r.shiftKey,!iC(e,r)&&(e.input.lastKeyCode=r.keyCode,e.input.lastKeyCodeTime=Date.now(),!(Jn&&dr&&r.keyCode==13)))if(r.keyCode!=229&&e.domObserver.forceFlush(),Nl&&r.keyCode==13&&!r.ctrlKey&&!r.altKey&&!r.metaKey){let n=Date.now();e.input.lastIOSEnter=n,e.input.lastIOSEnterFallbackTimeout=setTimeout(()=>{e.input.lastIOSEnter==n&&(e.someProp("handleKeyDown",o=>o(e,Ds(13,"Enter"))),e.input.lastIOSEnter=0)},200)}else e.someProp("handleKeyDown",n=>n(e,r))||PP(e,r)?r.preventDefault():Di(e,"key")};Cr.keyup=(e,t)=>{t.keyCode==16&&(e.input.shiftKey=!1)};Cr.keypress=(e,t)=>{let r=t;if(iC(e,r)||!r.charCode||r.ctrlKey&&!r.altKey||wn&&r.metaKey)return;if(e.someProp("handleKeyPress",o=>o(e,r))){r.preventDefault();return}let n=e.state.selection;if(!(n instanceof le)||!n.$from.sameParent(n.$to)){let o=String.fromCharCode(r.charCode);!/[\r\n]/.test(o)&&!e.someProp("handleTextInput",i=>i(e,n.$from.pos,n.$to.pos,o))&&e.dispatch(e.state.tr.insertText(o).scrollIntoView()),r.preventDefault()}};function $h(e){return{left:e.clientX,top:e.clientY}}function WP(e,t){let r=t.x-e.clientX,n=t.y-e.clientY;return r*r+n*n<100}function $v(e,t,r,n,o){if(n==-1)return!1;let i=e.state.doc.resolve(n);for(let s=i.depth+1;s>0;s--)if(e.someProp(t,a=>s>i.depth?a(e,r,i.nodeAfter,i.before(s),o,!0):a(e,r,i.node(s),i.before(s),o,!1)))return!0;return!1}function pl(e,t,r){e.focused||e.focus();let n=e.state.tr.setSelection(t);r=="pointer"&&n.setMeta("pointer",!0),e.dispatch(n)}function KP(e,t){if(t==-1)return!1;let r=e.state.doc.resolve(t),n=r.nodeAfter;return n&&n.isAtom&&ce.isSelectable(n)?(pl(e,new ce(r),"pointer"),!0):!1}function qP(e,t){if(t==-1)return!1;let r=e.state.selection,n,o;r instanceof ce&&(n=r.node);let i=e.state.doc.resolve(t);for(let s=i.depth+1;s>0;s--){let a=s>i.depth?i.nodeAfter:i.node(s);if(ce.isSelectable(a)){n&&r.$from.depth>0&&s>=r.$from.depth&&i.before(r.$from.depth+1)==r.$from.pos?o=i.before(r.$from.depth):o=i.before(s);break}}return o!=null?(pl(e,ce.create(e.state.doc,o),"pointer"),!0):!1}function GP(e,t,r,n,o){return $v(e,"handleClickOn",t,r,n)||e.someProp("handleClick",i=>i(e,t,n))||(o?qP(e,r):KP(e,r))}function YP(e,t,r,n){return $v(e,"handleDoubleClickOn",t,r,n)||e.someProp("handleDoubleClick",o=>o(e,t,n))}function JP(e,t,r,n){return $v(e,"handleTripleClickOn",t,r,n)||e.someProp("handleTripleClick",o=>o(e,t,n))||XP(e,r,n)}function XP(e,t,r){if(r.button!=0)return!1;let n=e.state.doc;if(t==-1)return n.inlineContent?(pl(e,le.create(n,0,n.content.size),"pointer"),!0):!1;let o=n.resolve(t);for(let i=o.depth+1;i>0;i--){let s=i>o.depth?o.nodeAfter:o.node(i),a=o.before(i);if(s.inlineContent)pl(e,le.create(n,a+1,a+1+s.content.size),"pointer");else if(ce.isSelectable(s))pl(e,ce.create(n,a),"pointer");else continue;return!0}}function Hv(e){return Op(e)}const oC=wn?"metaKey":"ctrlKey";Er.mousedown=(e,t)=>{let r=t;e.input.shiftKey=r.shiftKey;let n=Hv(e),o=Date.now(),i="singleClick";o-e.input.lastClick.time<500&&WP(r,e.input.lastClick)&&!r[oC]&&(e.input.lastClick.type=="singleClick"?i="doubleClick":e.input.lastClick.type=="doubleClick"&&(i="tripleClick")),e.input.lastClick={time:o,x:r.clientX,y:r.clientY,type:i};let s=e.posAtCoords($h(r));s&&(i=="singleClick"?(e.input.mouseDown&&e.input.mouseDown.done(),e.input.mouseDown=new QP(e,s,r,!!n)):(i=="doubleClick"?YP:JP)(e,s.pos,s.inside,r)?r.preventDefault():Di(e,"pointer"))};class QP{constructor(t,r,n,o){this.view=t,this.pos=r,this.event=n,this.flushed=o,this.delayedSelectionSync=!1,this.mightDrag=null,this.startDoc=t.state.doc,this.selectNode=!!n[oC],this.allowDefault=n.shiftKey;let i,s;if(r.inside>-1)i=t.state.doc.nodeAt(r.inside),s=r.inside;else{let u=t.state.doc.resolve(r.pos);i=u.parent,s=u.depth?u.before():0}const a=o?null:n.target,l=a?t.docView.nearestDesc(a,!0):null;this.target=l?l.dom:null;let{selection:c}=t.state;(n.button==0&&i.type.spec.draggable&&i.type.spec.selectable!==!1||c instanceof ce&&c.from<=s&&c.to>s)&&(this.mightDrag={node:i,pos:s,addAttr:!!(this.target&&!this.target.draggable),setUneditable:!!(this.target&&oo&&!this.target.hasAttribute("contentEditable"))}),this.target&&this.mightDrag&&(this.mightDrag.addAttr||this.mightDrag.setUneditable)&&(this.view.domObserver.stop(),this.mightDrag.addAttr&&(this.target.draggable=!0),this.mightDrag.setUneditable&&setTimeout(()=>{this.view.input.mouseDown==this&&this.target.setAttribute("contentEditable","false")},20),this.view.domObserver.start()),t.root.addEventListener("mouseup",this.up=this.up.bind(this)),t.root.addEventListener("mousemove",this.move=this.move.bind(this)),Di(t,"pointer")}done(){this.view.root.removeEventListener("mouseup",this.up),this.view.root.removeEventListener("mousemove",this.move),this.mightDrag&&this.target&&(this.view.domObserver.stop(),this.mightDrag.addAttr&&this.target.removeAttribute("draggable"),this.mightDrag.setUneditable&&this.target.removeAttribute("contentEditable"),this.view.domObserver.start()),this.delayedSelectionSync&&setTimeout(()=>Qo(this.view)),this.view.input.mouseDown=null}up(t){if(this.done(),!this.view.dom.contains(t.target))return;let r=this.pos;this.view.state.doc!=this.startDoc&&(r=this.view.posAtCoords($h(t))),this.updateAllowDefault(t),this.allowDefault||!r?Di(this.view,"pointer"):GP(this.view,r.pos,r.inside,t,this.selectNode)?t.preventDefault():t.button==0&&(this.flushed||Sr&&this.mightDrag&&!this.mightDrag.node.isAtom||dr&&!this.view.state.selection.visible&&Math.min(Math.abs(r.pos-this.view.state.selection.from),Math.abs(r.pos-this.view.state.selection.to))<=2)?(pl(this.view,be.near(this.view.state.doc.resolve(r.pos)),"pointer"),t.preventDefault()):Di(this.view,"pointer")}move(t){this.updateAllowDefault(t),Di(this.view,"pointer"),t.buttons==0&&this.done()}updateAllowDefault(t){!this.allowDefault&&(Math.abs(this.event.x-t.clientX)>4||Math.abs(this.event.y-t.clientY)>4)&&(this.allowDefault=!0)}}Er.touchstart=e=>{e.input.lastTouch=Date.now(),Hv(e),Di(e,"pointer")};Er.touchmove=e=>{e.input.lastTouch=Date.now(),Di(e,"pointer")};Er.contextmenu=e=>Hv(e);function iC(e,t){return e.composing?!0:Sr&&Math.abs(t.timeStamp-e.input.compositionEndedAt)<500?(e.input.compositionEndedAt=-2e8,!0):!1}const ZP=Jn?5e3:-1;Cr.compositionstart=Cr.compositionupdate=e=>{if(!e.composing){e.domObserver.flush();let{state:t}=e,r=t.selection.$from;if(t.selection.empty&&(t.storedMarks||!r.textOffset&&r.parentOffset&&r.nodeBefore.marks.some(n=>n.type.spec.inclusive===!1)))e.markCursor=e.state.storedMarks||r.marks(),Op(e,!0),e.markCursor=null;else if(Op(e),oo&&t.selection.empty&&r.parentOffset&&!r.textOffset&&r.nodeBefore.marks.length){let n=e.domSelectionRange();for(let o=n.focusNode,i=n.focusOffset;o&&o.nodeType==1&&i!=0;){let s=i<0?o.lastChild:o.childNodes[i-1];if(!s)break;if(s.nodeType==3){e.domSelection().collapse(s,s.nodeValue.length);break}else o=s,i=-1}}e.input.composing=!0}sC(e,ZP)};Cr.compositionend=(e,t)=>{e.composing&&(e.input.composing=!1,e.input.compositionEndedAt=t.timeStamp,e.input.compositionPendingChanges=e.domObserver.pendingRecords().length?e.input.compositionID:0,e.input.compositionPendingChanges&&Promise.resolve().then(()=>e.domObserver.flush()),e.input.compositionID++,sC(e,20))};function sC(e,t){clearTimeout(e.input.composingTimeout),t>-1&&(e.input.composingTimeout=setTimeout(()=>Op(e),t))}function aC(e){for(e.composing&&(e.input.composing=!1,e.input.compositionEndedAt=e6());e.input.compositionNodes.length>0;)e.input.compositionNodes.pop().markParentsDirty()}function e6(){let e=document.createEvent("Event");return e.initEvent("event",!0,!0),e.timeStamp}function Op(e,t=!1){if(!(Jn&&e.domObserver.flushingSoon>=0)){if(e.domObserver.forceFlush(),aC(e),t||e.docView&&e.docView.dirty){let r=Lv(e);return r&&!r.eq(e.state.selection)?e.dispatch(e.state.tr.setSelection(r)):e.updateState(e.state),!0}return!1}}function t6(e,t){if(!e.dom.parentNode)return;let r=e.dom.parentNode.appendChild(document.createElement("div"));r.appendChild(t),r.style.cssText="position: fixed; left: -10000px; top: 10px";let n=getSelection(),o=document.createRange();o.selectNodeContents(t),e.dom.blur(),n.removeAllRanges(),n.addRange(o),setTimeout(()=>{r.parentNode&&r.parentNode.removeChild(r),e.focus()},50)}const Rl=Ir&&Vi<15||Nl&&QR<604;Er.copy=Cr.cut=(e,t)=>{let r=t,n=e.state.selection,o=r.type=="cut";if(n.empty)return;let i=Rl?null:r.clipboardData,s=n.content(),{dom:a,text:l}=XE(e,s);i?(r.preventDefault(),i.clearData(),i.setData("text/html",a.innerHTML),i.setData("text/plain",l)):t6(e,a),o&&e.dispatch(e.state.tr.deleteSelection().scrollIntoView().setMeta("uiEvent","cut"))};function r6(e){return e.openStart==0&&e.openEnd==0&&e.content.childCount==1?e.content.firstChild:null}function n6(e,t){if(!e.dom.parentNode)return;let r=e.input.shiftKey||e.state.selection.$from.parent.type.spec.code,n=e.dom.parentNode.appendChild(document.createElement(r?"textarea":"div"));r||(n.contentEditable="true"),n.style.cssText="position: fixed; left: -10000px; top: 10px",n.focus();let o=e.input.shiftKey&&e.input.lastKeyCode!=45;setTimeout(()=>{e.focus(),n.parentNode&&n.parentNode.removeChild(n),r?$u(e,n.value,null,o,t):$u(e,n.textContent,n.innerHTML,o,t)},50)}function $u(e,t,r,n,o){let i=QE(e,t,r,n,e.state.selection.$from);if(e.someProp("handlePaste",l=>l(e,o,i||K.empty)))return!0;if(!i)return!1;let s=r6(i),a=s?e.state.tr.replaceSelectionWith(s,n):e.state.tr.replaceSelection(i);return e.dispatch(a.scrollIntoView().setMeta("paste",!0).setMeta("uiEvent","paste")),!0}Cr.paste=(e,t)=>{let r=t;if(e.composing&&!Jn)return;let n=Rl?null:r.clipboardData,o=e.input.shiftKey&&e.input.lastKeyCode!=45;n&&$u(e,n.getData("text/plain"),n.getData("text/html"),o,r)?r.preventDefault():n6(e,r)};class o6{constructor(t,r){this.slice=t,this.move=r}}const lC=wn?"altKey":"ctrlKey";Er.dragstart=(e,t)=>{let r=t,n=e.input.mouseDown;if(n&&n.done(),!r.dataTransfer)return;let o=e.state.selection,i=o.empty?null:e.posAtCoords($h(r));if(!(i&&i.pos>=o.from&&i.pos<=(o instanceof ce?o.to-1:o.to))){if(n&&n.mightDrag)e.dispatch(e.state.tr.setSelection(ce.create(e.state.doc,n.mightDrag.pos)));else if(r.target&&r.target.nodeType==1){let c=e.docView.nearestDesc(r.target,!0);c&&c.node.type.spec.draggable&&c!=e.docView&&e.dispatch(e.state.tr.setSelection(ce.create(e.state.doc,c.posBefore)))}}let s=e.state.selection.content(),{dom:a,text:l}=XE(e,s);r.dataTransfer.clearData(),r.dataTransfer.setData(Rl?"Text":"text/html",a.innerHTML),r.dataTransfer.effectAllowed="copyMove",Rl||r.dataTransfer.setData("text/plain",l),e.dragging=new o6(s,!r[lC])};Er.dragend=e=>{let t=e.dragging;window.setTimeout(()=>{e.dragging==t&&(e.dragging=null)},50)};Cr.dragover=Cr.dragenter=(e,t)=>t.preventDefault();Cr.drop=(e,t)=>{let r=t,n=e.dragging;if(e.dragging=null,!r.dataTransfer)return;let o=e.posAtCoords($h(r));if(!o)return;let i=e.state.doc.resolve(o.pos),s=n&&n.slice;s?e.someProp("transformPasted",h=>{s=h(s,e)}):s=QE(e,r.dataTransfer.getData(Rl?"Text":"text/plain"),Rl?null:r.dataTransfer.getData("text/html"),!1,i);let a=!!(n&&!r[lC]);if(e.someProp("handleDrop",h=>h(e,r,s||K.empty,a))){r.preventDefault();return}if(!s)return;r.preventDefault();let l=s?nN(e.state.doc,i.pos,s):i.pos;l==null&&(l=i.pos);let c=e.state.tr;a&&c.deleteSelection();let u=c.mapping.map(l),d=s.openStart==0&&s.openEnd==0&&s.content.childCount==1,f=c.doc;if(d?c.replaceRangeWith(u,u,s.content.firstChild):c.replaceRange(u,u,s),c.doc.eq(f))return;let p=c.doc.resolve(u);if(d&&ce.isSelectable(s.content.firstChild)&&p.nodeAfter&&p.nodeAfter.sameMarkup(s.content.firstChild))c.setSelection(new ce(p));else{let h=c.mapping.map(l);c.mapping.maps[c.mapping.maps.length-1].forEach((m,b,v,g)=>h=g),c.setSelection(Iv(e,p,c.doc.resolve(h)))}e.focus(),e.dispatch(c.setMeta("uiEvent","drop"))};Er.focus=e=>{e.input.lastFocus=Date.now(),e.focused||(e.domObserver.stop(),e.dom.classList.add("ProseMirror-focused"),e.domObserver.start(),e.focused=!0,setTimeout(()=>{e.docView&&e.hasFocus()&&!e.domObserver.currentSelection.eq(e.domSelectionRange())&&Qo(e)},20))};Er.blur=(e,t)=>{let r=t;e.focused&&(e.domObserver.stop(),e.dom.classList.remove("ProseMirror-focused"),e.domObserver.start(),r.relatedTarget&&e.dom.contains(r.relatedTarget)&&e.domObserver.currentSelection.clear(),e.focused=!1)};Er.beforeinput=(e,t)=>{if(dr&&Jn&&t.inputType=="deleteContentBackward"){e.domObserver.flushSoon();let{domChangeCount:n}=e.input;setTimeout(()=>{if(e.input.domChangeCount!=n||(e.dom.blur(),e.focus(),e.someProp("handleKeyDown",i=>i(e,Ds(8,"Backspace")))))return;let{$cursor:o}=e.state.selection;o&&o.pos>0&&e.dispatch(e.state.tr.delete(o.pos-1,o.pos).scrollIntoView())},50)}};for(let e in Cr)Er[e]=Cr[e];function Hu(e,t){if(e==t)return!0;for(let r in e)if(e[r]!==t[r])return!1;for(let r in t)if(!(r in e))return!1;return!0}class _p{constructor(t,r){this.toDOM=t,this.spec=r||Ys,this.side=this.spec.side||0}map(t,r,n,o){let{pos:i,deleted:s}=t.mapResult(r.from+o,this.side<0?-1:1);return s?null:new Ge(i-n,i-n,this)}valid(){return!0}eq(t){return this==t||t instanceof _p&&(this.spec.key&&this.spec.key==t.spec.key||this.toDOM==t.toDOM&&Hu(this.spec,t.spec))}destroy(t){this.spec.destroy&&this.spec.destroy(t)}}class Ui{constructor(t,r){this.attrs=t,this.spec=r||Ys}map(t,r,n,o){let i=t.map(r.from+o,this.spec.inclusiveStart?-1:1)-n,s=t.map(r.to+o,this.spec.inclusiveEnd?1:-1)-n;return i>=s?null:new Ge(i,s,this)}valid(t,r){return r.from=t&&(!i||i(a.spec))&&n.push(a.copy(a.from+o,a.to+o))}for(let s=0;st){let a=this.children[s]+1;this.children[s+2].findInner(t-a,r-a,n,o+a,i)}}map(t,r,n){return this==lr||t.maps.length==0?this:this.mapInner(t,r,0,0,n||Ys)}mapInner(t,r,n,o,i){let s;for(let a=0;a{let c=l+n,u;if(u=uC(r,a,c)){for(o||(o=this.children.slice());ia&&d.to=t){this.children[a]==t&&(n=this.children[a+2]);break}let i=t+1,s=i+r.content.size;for(let a=0;ai&&l.type instanceof Ui){let c=Math.max(i,l.from)-i,u=Math.min(s,l.to)-i;co.map(t,r,Ys));return Ri.from(n)}forChild(t,r){if(r.isLeaf)return Ee.empty;let n=[];for(let o=0;or instanceof Ee)?t:t.reduce((r,n)=>r.concat(n instanceof Ee?n:n.members),[]))}}}function i6(e,t,r,n,o,i,s){let a=e.slice();for(let c=0,u=i;c{let b=m-h-(p-f);for(let v=0;vg+u-d)continue;let y=a[v]+u-d;p>=y?a[v+1]=f<=y?-2:-1:h>=o&&b&&(a[v]+=b,a[v+1]+=b)}d+=b}),u=r.maps[c].map(u,-1)}let l=!1;for(let c=0;c=n.content.size){l=!0;continue}let f=r.map(e[c+1]+i,-1),p=f-o,{index:h,offset:m}=n.content.findIndex(d),b=n.maybeChild(h);if(b&&m==d&&m+b.nodeSize==p){let v=a[c+2].mapInner(r,b,u+1,e[c]+i+1,s);v!=lr?(a[c]=d,a[c+1]=p,a[c+2]=v):(a[c+1]=-2,l=!0)}else l=!0}if(l){let c=s6(a,e,t,r,o,i,s),u=Ap(c,n,0,s);t=u.local;for(let d=0;dr&&s.to{let c=uC(e,a,l+r);if(c){i=!0;let u=Ap(c,a,r+l+1,n);u!=lr&&o.push(l,l+a.nodeSize,u)}});let s=cC(i?dC(e):e,-r).sort(Js);for(let a=0;a0;)t++;e.splice(t,0,r)}function yg(e){let t=[];return e.someProp("decorations",r=>{let n=r(e.state);n&&n!=lr&&t.push(n)}),e.cursorWrapper&&t.push(Ee.create(e.state.doc,[e.cursorWrapper.deco])),Ri.from(t)}const a6={childList:!0,characterData:!0,characterDataOldValue:!0,attributes:!0,attributeOldValue:!0,subtree:!0},l6=Ir&&Vi<=11;class c6{constructor(){this.anchorNode=null,this.anchorOffset=0,this.focusNode=null,this.focusOffset=0}set(t){this.anchorNode=t.anchorNode,this.anchorOffset=t.anchorOffset,this.focusNode=t.focusNode,this.focusOffset=t.focusOffset}clear(){this.anchorNode=this.focusNode=null}eq(t){return t.anchorNode==this.anchorNode&&t.anchorOffset==this.anchorOffset&&t.focusNode==this.focusNode&&t.focusOffset==this.focusOffset}}class u6{constructor(t,r){this.view=t,this.handleDOMChange=r,this.queue=[],this.flushingSoon=-1,this.observer=null,this.currentSelection=new c6,this.onCharData=null,this.suppressingSelectionUpdates=!1,this.observer=window.MutationObserver&&new window.MutationObserver(n=>{for(let o=0;oo.type=="childList"&&o.removedNodes.length||o.type=="characterData"&&o.oldValue.length>o.target.nodeValue.length)?this.flushSoon():this.flush()}),l6&&(this.onCharData=n=>{this.queue.push({target:n.target,type:"characterData",oldValue:n.prevValue}),this.flushSoon()}),this.onSelectionChange=this.onSelectionChange.bind(this)}flushSoon(){this.flushingSoon<0&&(this.flushingSoon=window.setTimeout(()=>{this.flushingSoon=-1,this.flush()},20))}forceFlush(){this.flushingSoon>-1&&(window.clearTimeout(this.flushingSoon),this.flushingSoon=-1,this.flush())}start(){this.observer&&(this.observer.takeRecords(),this.observer.observe(this.view.dom,a6)),this.onCharData&&this.view.dom.addEventListener("DOMCharacterDataModified",this.onCharData),this.connectSelection()}stop(){if(this.observer){let t=this.observer.takeRecords();if(t.length){for(let r=0;rthis.flush(),20)}this.observer.disconnect()}this.onCharData&&this.view.dom.removeEventListener("DOMCharacterDataModified",this.onCharData),this.disconnectSelection()}connectSelection(){this.view.dom.ownerDocument.addEventListener("selectionchange",this.onSelectionChange)}disconnectSelection(){this.view.dom.ownerDocument.removeEventListener("selectionchange",this.onSelectionChange)}suppressSelectionUpdates(){this.suppressingSelectionUpdates=!0,setTimeout(()=>this.suppressingSelectionUpdates=!1,50)}onSelectionChange(){if($k(this.view)){if(this.suppressingSelectionUpdates)return Qo(this.view);if(Ir&&Vi<=11&&!this.view.state.selection.empty){let t=this.view.domSelectionRange();if(t.focusNode&&oa(t.focusNode,t.focusOffset,t.anchorNode,t.anchorOffset))return this.flushSoon()}this.flush()}}setCurSelection(){this.currentSelection.set(this.view.domSelectionRange())}ignoreSelectionChange(t){if(!t.focusNode)return!0;let r=new Set,n;for(let i=t.focusNode;i;i=Du(i))r.add(i);for(let i=t.anchorNode;i;i=Du(i))if(r.has(i)){n=i;break}let o=n&&this.view.docView.nearestDesc(n);if(o&&o.ignoreMutation({type:"selection",target:n.nodeType==3?n.parentNode:n}))return this.setCurSelection(),!0}pendingRecords(){if(this.observer)for(let t of this.observer.takeRecords())this.queue.push(t);return this.queue}flush(){let{view:t}=this;if(!t.docView||this.flushingSoon>-1)return;let r=this.pendingRecords();r.length&&(this.queue=[]);let n=t.domSelectionRange(),o=!this.suppressingSelectionUpdates&&!this.currentSelection.eq(n)&&$k(t)&&!this.ignoreSelectionChange(n),i=-1,s=-1,a=!1,l=[];if(t.editable)for(let u=0;u1){let u=l.filter(d=>d.nodeName=="BR");if(u.length==2){let d=u[0],f=u[1];d.parentNode&&d.parentNode.parentNode==f.parentNode?f.remove():d.remove()}}let c=null;i<0&&o&&t.input.lastFocus>Date.now()-200&&Math.max(t.input.lastTouch,t.input.lastClick.time)-1||o)&&(i>-1&&(t.docView.markDirty(i,s),d6(t)),this.handleDOMChange(i,s,a,l),t.docView&&t.docView.dirty?t.updateState(t.state):this.currentSelection.eq(n)||Qo(t),this.currentSelection.set(n))}registerMutation(t,r){if(r.indexOf(t.target)>-1)return null;let n=this.view.docView.nearestDesc(t.target);if(t.type=="attributes"&&(n==this.view.docView||t.attributeName=="contenteditable"||t.attributeName=="style"&&!t.oldValue&&!t.target.getAttribute("style"))||!n||n.ignoreMutation(t))return null;if(t.type=="childList"){for(let u=0;uo;b--){let v=n.childNodes[b-1],g=v.pmViewDesc;if(v.nodeName=="BR"&&!g){i=b;break}if(!g||g.size)break}let d=e.state.doc,f=e.someProp("domParser")||Mv.fromSchema(e.state.schema),p=d.resolve(s),h=null,m=f.parse(n,{topNode:p.parent,topMatch:p.parent.contentMatchAt(p.index()),topOpen:!0,from:o,to:i,preserveWhitespace:p.parent.type.whitespace=="pre"?"full":!0,findPositions:c,ruleFromNode:h6,context:p});if(c&&c[0].pos!=null){let b=c[0].pos,v=c[1]&&c[1].pos;v==null&&(v=b),h={anchor:b+s,head:v+s}}return{doc:m,sel:h,from:s,to:a}}function h6(e){let t=e.pmViewDesc;if(t)return t.parseRule();if(e.nodeName=="BR"&&e.parentNode){if(Sr&&/^(ul|ol)$/i.test(e.parentNode.nodeName)){let r=document.createElement("div");return r.appendChild(document.createElement("li")),{skip:r}}else if(e.parentNode.lastChild==e||Sr&&/^(tr|table)$/i.test(e.parentNode.nodeName))return{ignore:!0}}else if(e.nodeName=="IMG"&&e.getAttribute("mark-placeholder"))return{ignore:!0};return null}const m6=/^(a|abbr|acronym|b|bd[io]|big|br|button|cite|code|data(list)?|del|dfn|em|i|ins|kbd|label|map|mark|meter|output|q|ruby|s|samp|small|span|strong|su[bp]|time|u|tt|var)$/i;function g6(e,t,r,n,o){let i=e.input.compositionPendingChanges||(e.composing?e.input.compositionID:0);if(e.input.compositionPendingChanges=0,t<0){let C=e.input.lastSelectionTime>Date.now()-50?e.input.lastSelectionOrigin:null,T=Lv(e,C);if(T&&!e.state.selection.eq(T)){if(dr&&Jn&&e.input.lastKeyCode===13&&Date.now()-100z(e,Ds(13,"Enter"))))return;let N=e.state.tr.setSelection(T);C=="pointer"?N.setMeta("pointer",!0):C=="key"&&N.scrollIntoView(),i&&N.setMeta("composition",i),e.dispatch(N)}return}let s=e.state.doc.resolve(t),a=s.sharedDepth(r);t=s.before(a+1),r=e.state.doc.resolve(r).after(a+1);let l=e.state.selection,c=p6(e,t,r),u=e.state.doc,d=u.slice(c.from,c.to),f,p;e.input.lastKeyCode===8&&Date.now()-100Date.now()-225||Jn)&&o.some(C=>C.nodeType==1&&!m6.test(C.nodeName))&&(!h||h.endA>=h.endB)&&e.someProp("handleKeyDown",C=>C(e,Ds(13,"Enter")))){e.input.lastIOSEnter=0;return}if(!h)if(n&&l instanceof le&&!l.empty&&l.$head.sameParent(l.$anchor)&&!e.composing&&!(c.sel&&c.sel.anchor!=c.sel.head))h={start:l.from,endA:l.to,endB:l.to};else{if(c.sel){let C=Yk(e,e.state.doc,c.sel);if(C&&!C.eq(e.state.selection)){let T=e.state.tr.setSelection(C);i&&T.setMeta("composition",i),e.dispatch(T)}}return}if(dr&&e.cursorWrapper&&c.sel&&c.sel.anchor==e.cursorWrapper.deco.from&&c.sel.head==c.sel.anchor){let C=h.endB-h.start;c.sel={anchor:c.sel.anchor+C,head:c.sel.anchor+C}}e.input.domChangeCount++,e.state.selection.frome.state.selection.from&&h.start<=e.state.selection.from+2&&e.state.selection.from>=c.from?h.start=e.state.selection.from:h.endA=e.state.selection.to-2&&e.state.selection.to<=c.to&&(h.endB+=e.state.selection.to-h.endA,h.endA=e.state.selection.to)),Ir&&Vi<=11&&h.endB==h.start+1&&h.endA==h.start&&h.start>c.from&&c.doc.textBetween(h.start-c.from-1,h.start-c.from+1)=="  "&&(h.start--,h.endA--,h.endB--);let m=c.doc.resolveNoCache(h.start-c.from),b=c.doc.resolveNoCache(h.endB-c.from),v=u.resolve(h.start),g=m.sameParent(b)&&m.parent.inlineContent&&v.end()>=h.endA,y;if((Nl&&e.input.lastIOSEnter>Date.now()-225&&(!g||o.some(C=>C.nodeName=="DIV"||C.nodeName=="P"))||!g&&m.posC(e,Ds(13,"Enter")))){e.input.lastIOSEnter=0;return}if(e.state.selection.anchor>h.start&&y6(u,h.start,h.endA,m,b)&&e.someProp("handleKeyDown",C=>C(e,Ds(8,"Backspace")))){Jn&&dr&&e.domObserver.suppressSelectionUpdates();return}dr&&Jn&&h.endB==h.start&&(e.input.lastAndroidDelete=Date.now()),Jn&&!g&&m.start()!=b.start()&&b.parentOffset==0&&m.depth==b.depth&&c.sel&&c.sel.anchor==c.sel.head&&c.sel.head==h.endA&&(h.endB-=2,b=c.doc.resolveNoCache(h.endB-c.from),setTimeout(()=>{e.someProp("handleKeyDown",function(C){return C(e,Ds(13,"Enter"))})},20));let x=h.start,k=h.endA,w,E,M;if(g){if(m.pos==b.pos)Ir&&Vi<=11&&m.parentOffset==0&&(e.domObserver.suppressSelectionUpdates(),setTimeout(()=>Qo(e),20)),w=e.state.tr.delete(x,k),E=u.resolve(h.start).marksAcross(u.resolve(h.endA));else if(h.endA==h.endB&&(M=v6(m.parent.content.cut(m.parentOffset,b.parentOffset),v.parent.content.cut(v.parentOffset,h.endA-v.start()))))w=e.state.tr,M.type=="add"?w.addMark(x,k,M.mark):w.removeMark(x,k,M.mark);else if(m.parent.child(m.index()).isText&&m.index()==b.index()-(b.textOffset?0:1)){let C=m.parent.textBetween(m.parentOffset,b.parentOffset);if(e.someProp("handleTextInput",T=>T(e,x,k,C)))return;w=e.state.tr.insertText(C,x,k)}}if(w||(w=e.state.tr.replace(x,k,c.doc.slice(h.start-c.from,h.endB-c.from))),c.sel){let C=Yk(e,w.doc,c.sel);C&&!(dr&&Jn&&e.composing&&C.empty&&(h.start!=h.endB||e.input.lastAndroidDeletet.content.size?null:Iv(e,t.resolve(r.anchor),t.resolve(r.head))}function v6(e,t){let r=e.firstChild.marks,n=t.firstChild.marks,o=r,i=n,s,a,l;for(let u=0;uu.mark(a.addToSet(u.marks));else if(o.length==0&&i.length==1)a=i[0],s="remove",l=u=>u.mark(a.removeFromSet(u.marks));else return null;let c=[];for(let u=0;ur||bg(s,!0,!1)0&&(t||e.indexAfter(n)==e.node(n).childCount);)n--,o++,t=!1;if(r){let i=e.node(n).maybeChild(e.indexAfter(n));for(;i&&!i.isLeaf;)i=i.firstChild,o++}return o}function b6(e,t,r,n,o){let i=e.findDiffStart(t,r);if(i==null)return null;let{a:s,b:a}=e.findDiffEnd(t,r+e.size,r+t.size);if(o=="end"){let l=Math.max(0,i-Math.min(s,a));n-=s+l-i}if(s=s?i-n:0;i-=l,a=i+(a-s),s=i}else if(a=a?i-n:0;i-=l,s=i+(s-a),a=i}return{start:i,endA:s,endB:a}}class x6{constructor(t,r){this._root=null,this.focused=!1,this.trackWrites=null,this.mounted=!1,this.markCursor=null,this.cursorWrapper=null,this.lastSelectedViewDesc=void 0,this.input=new BP,this.prevDirectPlugins=[],this.pluginViews=[],this.requiresGeckoHackNode=!1,this.dragging=null,this._props=r,this.state=r.state,this.directPlugins=r.plugins||[],this.directPlugins.forEach(e2),this.dispatch=this.dispatch.bind(this),this.dom=t&&t.mount||document.createElement("div"),t&&(t.appendChild?t.appendChild(this.dom):typeof t=="function"?t(this.dom):t.mount&&(this.mounted=!0)),this.editable=Qk(this),Xk(this),this.nodeViews=Zk(this),this.docView=Rk(this.state.doc,Jk(this),yg(this),this.dom,this),this.domObserver=new u6(this,(n,o,i,s)=>g6(this,n,o,i,s)),this.domObserver.start(),FP(this),this.updatePluginViews()}get composing(){return this.input.composing}get props(){if(this._props.state!=this.state){let t=this._props;this._props={};for(let r in t)this._props[r]=t[r];this._props.state=this.state}return this._props}update(t){t.handleDOMEvents!=this._props.handleDOMEvents&&F1(this);let r=this._props;this._props=t,t.plugins&&(t.plugins.forEach(e2),this.directPlugins=t.plugins),this.updateStateInner(t.state,r)}setProps(t){let r={};for(let n in this._props)r[n]=this._props[n];r.state=this.state;for(let n in t)r[n]=t[n];this.update(r)}updateState(t){this.updateStateInner(t,this._props)}updateStateInner(t,r){let n=this.state,o=!1,i=!1;t.storedMarks&&this.composing&&(aC(this),i=!0),this.state=t;let s=n.plugins!=t.plugins||this._props.plugins!=r.plugins;if(s||this._props.plugins!=r.plugins||this._props.nodeViews!=r.nodeViews){let f=Zk(this);w6(f,this.nodeViews)&&(this.nodeViews=f,o=!0)}(s||r.handleDOMEvents!=this._props.handleDOMEvents)&&F1(this),this.editable=Qk(this),Xk(this);let a=yg(this),l=Jk(this),c=n.plugins!=t.plugins&&!n.doc.eq(t.doc)?"reset":t.scrollToSelection>n.scrollToSelection?"to selection":"preserve",u=o||!this.docView.matchesNode(t.doc,l,a);(u||!t.selection.eq(n.selection))&&(i=!0);let d=c=="preserve"&&i&&this.dom.style.overflowAnchor==null&&tP(this);if(i){this.domObserver.stop();let f=u&&(Ir||dr)&&!this.composing&&!n.selection.empty&&!t.selection.empty&&k6(n.selection,t.selection);if(u){let p=dr?this.trackWrites=this.domSelectionRange().focusNode:null;(o||!this.docView.update(t.doc,l,a,this))&&(this.docView.updateOuterDeco([]),this.docView.destroy(),this.docView=Rk(t.doc,l,a,this.dom,this)),p&&!this.trackWrites&&(f=!0)}f||!(this.input.mouseDown&&this.domObserver.currentSelection.eq(this.domSelectionRange())&&MP(this))?Qo(this,f):(GE(this,t.selection),this.domObserver.setCurSelection()),this.domObserver.start()}this.updatePluginViews(n),c=="reset"?this.dom.scrollTop=0:c=="to selection"?this.scrollToSelection():d&&rP(d)}scrollToSelection(){let t=this.domSelectionRange().focusNode;if(!this.someProp("handleScrollToSelection",r=>r(this)))if(this.state.selection instanceof ce){let r=this.docView.domAfterPos(this.state.selection.from);r.nodeType==1&&Mk(this,r.getBoundingClientRect(),t)}else Mk(this,this.coordsAtPos(this.state.selection.head,1),t)}destroyPluginViews(){let t;for(;t=this.pluginViews.pop();)t.destroy&&t.destroy()}updatePluginViews(t){if(!t||t.plugins!=this.state.plugins||this.directPlugins!=this.prevDirectPlugins){this.prevDirectPlugins=this.directPlugins,this.destroyPluginViews();for(let r=0;rr.ownerDocument.getSelection()),this._root=r}return t||document}updateRoot(){this._root=null}posAtCoords(t){return lP(this,t)}coordsAtPos(t,r=1){return BE(this,t,r)}domAtPos(t,r=0){return this.docView.domFromPos(t,r)}nodeDOM(t){let r=this.docView.descAt(t);return r?r.nodeDOM:null}posAtDOM(t,r,n=-1){let o=this.docView.posFromDOM(t,r,n);if(o==null)throw new RangeError("DOM position not inside the editor");return o}endOfTextblock(t,r){return pP(this,r||this.state,t)}pasteHTML(t,r){return $u(this,"",t,!1,r||new ClipboardEvent("paste"))}pasteText(t,r){return $u(this,t,null,!0,r||new ClipboardEvent("paste"))}destroy(){this.docView&&(VP(this),this.destroyPluginViews(),this.mounted?(this.docView.update(this.state.doc,[],yg(this),this),this.dom.textContent=""):this.dom.parentNode&&this.dom.parentNode.removeChild(this.dom),this.docView.destroy(),this.docView=null)}get isDestroyed(){return this.docView==null}dispatchEvent(t){return UP(this,t)}dispatch(t){let r=this._props.dispatchTransaction;r?r.call(this,t):this.updateState(this.state.apply(t))}domSelectionRange(){return Sr&&this.root.nodeType===11&&GR(this.dom.ownerDocument)==this.dom?f6(this):this.domSelection()}domSelection(){return this.root.getSelection()}}function Jk(e){let t=Object.create(null);return t.class="ProseMirror",t.contenteditable=String(e.editable),e.someProp("attributes",r=>{if(typeof r=="function"&&(r=r(e.state)),r)for(let n in r)n=="class"?t.class+=" "+r[n]:n=="style"?t.style=(t.style?t.style+";":"")+r[n]:!t[n]&&n!="contenteditable"&&n!="nodeName"&&(t[n]=String(r[n]))}),t.translate||(t.translate="no"),[Ge.node(0,e.state.doc.content.size,t)]}function Xk(e){if(e.markCursor){let t=document.createElement("img");t.className="ProseMirror-separator",t.setAttribute("mark-placeholder","true"),t.setAttribute("alt",""),e.cursorWrapper={dom:t,deco:Ge.widget(e.state.selection.head,t,{raw:!0,marks:e.markCursor})}}else e.cursorWrapper=null}function Qk(e){return!e.someProp("editable",t=>t(e.state)===!1)}function k6(e,t){let r=Math.min(e.$anchor.sharedDepth(e.head),t.$anchor.sharedDepth(t.head));return e.$anchor.start(r)!=t.$anchor.start(r)}function Zk(e){let t=Object.create(null);function r(n){for(let o in n)Object.prototype.hasOwnProperty.call(t,o)||(t[o]=n[o])}return e.someProp("nodeViews",r),e.someProp("markViews",r),t}function w6(e,t){let r=0,n=0;for(let o in e){if(e[o]!=t[o])return!0;r++}for(let o in t)n++;return r!=n}function e2(e){if(e.spec.state||e.spec.filterTransaction||e.spec.appendTransaction)throw new RangeError("Plugins passed directly to the view must not have a state component")}var S6=e=>{if(typeof e!="string")throw new TypeError("Expected a string");return e.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&").replace(/-/g,"\\x2d")};const E6=Dn(S6);var fC=(e,t,r)=>{if(!t.has(e))throw TypeError("Cannot "+r)},ge=(e,t,r)=>(fC(e,t,"read from private field"),r?r.call(e):t.get(e)),Io=(e,t,r)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,r)},qe=(e,t,r,n)=>(fC(e,t,"write to private field"),n?n.call(e,r):t.set(e,r),r);function C6(e){return!!(e.prev&&e.next&&e.prev.text.full!==e.next.text.full)}function M6(e){return!!(e.prev&&e.next&&e.prev.range.cursor!==e.next.range.cursor)}function T6(e){return!!(!e.prev&&e.next)}function O6(e){return!!(e.prev&&!e.next)}function _6(e){return!!(e.prev&&e.next&&e.prev.range.from!==e.next.range.from)}function A6(e){return e==="invalid-exit-split"}var N6=["jump-backward-exit","jump-forward-exit"],R6=["jump-backward-change","jump-forward-change"];function P6(e){var t,r;return fr(N6,(t=e.exit)==null?void 0:t.exitReason)||fr(R6,(r=e.change)==null?void 0:r.changeReason)}function t2(e){return!!(e&&e.query.full.length>=e.suggester.matchOffset)}function r2(e){return Zt(e)&&e instanceof le}function Pr(e){const{match:t,changeReason:r,exitReason:n}=e;return{...t,changeReason:r,exitReason:n}}function z6(e,t){const{invalidPrefixCharacters:r,validPrefixCharacters:n}=t;return r?!new RegExp(j1(r)).test(e):new RegExp(j1(n)).test(e)}function L6(e){const{text:t,regexp:r,$pos:n,suggester:o}=e,i=n.start();let s;return xa(t,r).forEach(a=>{const l=a.input.slice(Math.max(0,a.index-1),a.index);if(z6(l,o)){const c=a.index+i,u=a[0],d=a[1];if(!oe(u)||!oe(d))return;const f=c+u.length,p=Math.min(f,n.pos),h=p-c;c=n.pos&&(s={range:{from:c,to:f,cursor:p},match:a,query:{partial:u.slice(d.length,h),full:u.slice(d.length)},text:{partial:u.slice(0,h),full:u},textAfter:n.doc.textBetween(f,n.end(),Li,Li),textBefore:n.doc.textBetween(i,c,Li,Li),suggester:o})}}),s}function pC(e){const{$pos:t,suggester:r}=e,{char:n,name:o,startOfLine:i,supportedCharacters:s,matchOffset:a,multiline:l,caseInsensitive:c,unicode:u}=r,d=U6({char:n,matchOffset:a,startOfLine:i,supportedCharacters:s,multiline:l,caseInsensitive:c,unicode:u}),f=t.doc.textBetween(t.before(),t.end(),Li,Li);return L6({suggester:r,text:f,regexp:d,$pos:t,char:n,name:o})}function hC(e){const{state:t,match:r}=e;try{return pC({$pos:t.doc.resolve(r.range.cursor),suggester:r.suggester})}catch{return}}function mC(e){const{prev:t,next:r,state:n}=e;return!r&&t.range.from>=n.doc.nodeSize?{exit:Pr({match:t,exitReason:"delete"})}:!r||!t.query.partial?{exit:Pr({match:t,exitReason:"invalid-exit-split"})}:t.range.to===r.range.cursor?{exit:Pr({match:r,exitReason:"exit-end"})}:t.query.partial?{exit:Pr({match:r,exitReason:"exit-split"})}:{}}function I6(e){const{prev:t,next:r,state:n}=e,o=ee(),i=hC({state:n,match:t}),{exit:s}=i&&i.query.full!==t.query.full?mC({prev:t,next:i,state:n}):o;return t.range.from=t.range.to)?{exit:Pr({match:t,exitReason:"selection-outside"})}:n.pos>t.range.to?{exit:Pr({match:t,exitReason:"move-end"})}:n.pos<=t.range.from?{exit:Pr({match:t,exitReason:"move-start"})}:{}}function $6(e){const{prev:t,next:r,state:n,$pos:o}=e,i=ee();if(!t&&!r)return i;const s={prev:t,next:r};return _6(s)?I6({prev:s.prev,next:s.next,state:n}):T6(s)?{change:Pr({match:s.next,changeReason:"start"})}:O6(s)?D6({$pos:o,match:s.prev,state:n}):C6(s)?{change:Pr({match:s.next,changeReason:"change-character"})}:M6(s)?{change:Pr({match:s.next,changeReason:n.selection.empty?"move":"selection-inside"})}:i}function n2(e,t){for(let r=e.depth;r>0;r--){const n=e.node(r);if(t.includes(n.type.name))return!0}return!1}function V1(e,t){const{$from:r,$to:n}=e;return gC(e,t)?!0:Cv(r.pos,n.pos).some(o=>H6(r.doc.resolve(o),t))}function gC(e,t){const{$from:r,$to:n}=e,o=new Set((r.marksAcross(n)??[]).map(i=>i.type.name));return t.some(i=>o.has(i))}function H6(e,t){const r=new Set(e.marks().map(n=>n.type.name));return t.some(n=>r.has(n))}function B6(e,t){const{$cursor:r}=t,{validMarks:n,validNodes:o,invalidMarks:i,invalidNodes:s}=e;return!n&&!o&&Mo(i)&&Mo(s)?!0:!(n&&!gC(t,n)||o&&!n2(r,o)||!n&&V1(t,i)||!o&&n2(r,s))}function o2(e){const{suggesters:t,$pos:r,selectionEmpty:n}=e;for(const o of t)if(!(o.emptySelectionsOnly&&!n))try{const i=pC({suggester:o,$pos:r});if(!i)continue;const s={$from:r.doc.resolve(i.range.from),$to:r.doc.resolve(i.range.to),$cursor:r};if(B6(o,s)&&o.isValidPosition(s,i))return i}catch{}}function j1(e){return cA(e)?e.source:e}function F6(e){return e?"^":""}function V6(e,t){return`(?:${j1(e)}){${t},}`}function j6(e){return oe(e)?new RegExp(E6(e)):e}function U6(e){const{char:t,matchOffset:r,startOfLine:n,supportedCharacters:o,captureChar:i=!0,caseInsensitive:s=!1,multiline:a=!1,unicode:l=!1}=e,c=`g${a?"m":""}${s?"i":""}${l?"u":""}`;let u=j6(t).source;return i&&(u=`(${u})`),new RegExp(`${F6(n)}${u}${V6(o,r)}`,c)}var W6={appendTransaction:!1,priority:50,ignoredTag:"span",matchOffset:0,disableDecorations:!1,startOfLine:!1,suggestClassName:"suggest",suggestTag:"span",supportedCharacters:/\w+/,validPrefixCharacters:/^[\s\0]?$/,invalidPrefixCharacters:null,ignoredClassName:null,invalidMarks:[],invalidNodes:[],validMarks:null,validNodes:null,isValidPosition:()=>!0,checkNextValidSelection:null,emptySelectionsOnly:!1,caseInsensitive:!1,multiline:!1,unicode:!1,captureChar:!0},vC="__ignore_prosemirror_suggest_update__",Df,Dc,zt,Si,ja,po,Ot,Ei,Ua,yC=class{constructor(e){Io(this,Df,!1),Io(this,Dc,!1),Io(this,zt,void 0),Io(this,Si,void 0),Io(this,ja,void 0),Io(this,po,ee()),Io(this,Ot,Ee.empty),Io(this,Ei,!1),Io(this,Ua,!1),this.setMarkRemoved=()=>{qe(this,Ei,!0)},this.findNextTextSelection=r=>{const n=r.$from.doc,o=Math.min(n.nodeSize-2,r.to+1),i=n.resolve(o),s=be.findFrom(i,1,!0);if(r2(s))return s},this.ignoreNextExit=()=>{qe(this,Dc,!0)},this.addIgnored=({from:r,name:n,specific:o=!1})=>{const i=ge(this,zt).find(u=>u.name===n);if(!i)throw new Error(`No suggester exists for the name provided: ${n}`);const s=oe(i.char)?i.char.length:1,a=r+s,l=i.ignoredClassName?{class:i.ignoredClassName}:{},c=Ge.inline(r,a,{nodeName:i.ignoredTag,...l},{name:n,specific:o,char:i.char});qe(this,Ot,ge(this,Ot).add(this.view.state.doc,[c]))},this.removeIgnored=({from:r,name:n})=>{const o=ge(this,zt).find(a=>a.name===n);if(!o)throw new Error(`No suggester exists for the name provided: ${n}`);const i=oe(o.char)?o.char.length:1,s=ge(this,Ot).find(r,r+i)[0];!s||s.spec.name!==n||qe(this,Ot,ge(this,Ot).remove([s]))},this.clearIgnored=r=>{if(!r){qe(this,Ot,Ee.empty);return}const o=ge(this,Ot).find().filter(({spec:i})=>i.name===r);qe(this,Ot,ge(this,Ot).remove(o))},this.findMatchAtPosition=(r,n)=>{const o=n?ge(this,zt).filter(i=>i.name===n):ge(this,zt);return o2({suggesters:o,$pos:r,docChanged:!1,selectionEmpty:!0})},this.setLastChangeFromAppend=()=>{qe(this,Ua,!0)};const t=i2();qe(this,zt,e.map(t)),qe(this,zt,ta(ge(this,zt),(r,n)=>n.priority-r.priority))}static create(e){return new yC(e)}get decorationSet(){return ge(this,Ot)}get removed(){return ge(this,Ei)}get match(){return ge(this,Si)?ge(this,Si):ge(this,ja)&&ge(this,po).exit?ge(this,ja):void 0}init(e){return this.view=e,this}createProps(e){const{name:t,char:r}=e.suggester;return{view:this.view,addIgnored:this.addIgnored,clearIgnored:this.clearIgnored,ignoreNextExit:this.ignoreNextExit,setMarkRemoved:this.setMarkRemoved,name:t,char:r,...e}}shouldRunExit(){return ge(this,Dc)?(qe(this,Dc,!1),!1):!0}updateWithNextSelection(e){var t,r,n;const o=this.findNextTextSelection(e.selection);if(o)for(const i of ge(this,zt)){const s=(t=ge(this,po).change)==null?void 0:t.suggester.name,a=(r=ge(this,po).exit)==null?void 0:r.suggester.name;(n=i.checkNextValidSelection)==null||n.call(i,o.$from,e,{change:s,exit:a})}}changeHandler(e,t){const{change:r,exit:n}=ge(this,po),o=this.match;if(!r&&!n||!t2(o))return;const i=t===(n==null?void 0:n.suggester.appendTransaction)&&this.shouldRunExit(),s=t===(r==null?void 0:r.suggester.appendTransaction);if(!(!i&&!s)){if(r&&n&&P6({change:r,exit:n})){const a=this.createProps(n),l=this.createProps(r),c=n.range.from{const a=oe(s.char)?s.char.length:1;return i-o!==a});qe(this,Ot,t.remove(n))}shouldIgnoreMatch({range:e,suggester:{name:t}}){return ge(this,Ot).find().some(({spec:o,from:i})=>i!==e.from?!1:o.specific?o.name===t:!0)}resetState(){qe(this,po,ee()),qe(this,Si,void 0),qe(this,Ei,!1),qe(this,Ua,!1)}updateReasons(e){const{$pos:t,state:r}=e,n=ge(this,Df),o=ge(this,zt),i=r.selection.empty,s=r2(r.selection)?o2({suggesters:o,$pos:t,docChanged:n,selectionEmpty:i}):void 0;qe(this,Si,s&&this.shouldIgnoreMatch(s)?void 0:s),qe(this,po,$6({next:ge(this,Si),prev:ge(this,ja),state:r,$pos:t}))}addSuggester(e){const t=ge(this,zt).find(n=>n.name===e.name),r=i2();if(t)qe(this,zt,ge(this,zt).map(n=>n===t?r(e):n));else{const n=[...ge(this,zt),r(e)];qe(this,zt,ta(n,(o,i)=>i.priority-o.priority))}return()=>this.removeSuggester(e.name)}removeSuggester(e){const t=oe(e)?e:e.name;qe(this,zt,ge(this,zt).filter(r=>r.name!==t)),this.clearIgnored(t)}toJSON(){return this.match}apply(e){const{exit:t,change:r}=ge(this,po);if(ge(this,Ua)&&(qe(this,Ua,!1),!(t!=null&&t.suggester.appendTransaction)&&!(r!=null&&r.suggester.appendTransaction)))return this;const{tr:n,state:o}=e,i=n.docChanged||n.selectionSet;return n.getMeta(vC)||!i&&!ge(this,Ei)?this:(qe(this,Df,n.docChanged),this.mapIgnoredDecorations(n),t&&this.resetState(),qe(this,ja,ge(this,Si)),this.updateReasons({$pos:n.selection.$from,state:o}),this)}createDecorations(e){const t=this.match;if(!t2(t))return ge(this,Ot);const{disableDecorations:r}=t.suggester;if(_e(r)?r(e,t):r)return ge(this,Ot);const{range:o,suggester:i}=t,{name:s,suggestTag:a,suggestClassName:l}=i,{from:c,to:u}=o;return this.shouldIgnoreMatch(t)?ge(this,Ot):ge(this,Ot).add(e.doc,[Ge.inline(c,u,{nodeName:a,class:s?`${l} suggest-${s}`:l},{name:s})])}},K6=yC;Df=new WeakMap;Dc=new WeakMap;zt=new WeakMap;Si=new WeakMap;ja=new WeakMap;po=new WeakMap;Ot=new WeakMap;Ei=new WeakMap;Ua=new WeakMap;function i2(){const e=new Set;return t=>{if(e.has(t.name))throw new Error(`A suggester already exists with the name '${t.name}'. The name provided must be unique.`);const r={...W6,...t};return e.add(t.name),r}}var bC=new ka("suggest");function Vv(e){return bC.getState(e)}function s2(e,t){return Vv(e).addSuggester(t)}function a2(e){e.setMeta(vC,!0)}function q6(e,t){return Vv(e).removeSuggester(t)}function G6(...e){const t=K6.create(e);return new Ro({key:bC,view:r=>(t.init(r),{update:n=>t.changeHandler(n.state.tr,!1)}),state:{init:()=>t,apply:(r,n,o,i)=>t.apply({tr:r,state:i})},appendTransaction:(r,n,o)=>{const i=o.tr;return t.updateWithNextSelection(i),t.changeHandler(i,!0),i.docChanged||i.steps.length>0||i.selectionSet||i.storedMarksSet?(t.setLastChangeFromAppend(),i):null},props:{decorations:r=>t.createDecorations(r)}})}function jv(e,t){const r=Object.getPrototypeOf(t);let n=e.selection,o=e.doc,i=e.storedMarks;const s=ee();for(const[a,l]of Object.entries(t))s[a]={value:l};return Object.create(r,{...s,storedMarks:{get(){return i}},selection:{get(){return n}},doc:{get(){return o}},tr:{get(){return n=e.selection,o=e.doc,i=e.storedMarks,e}}})}function bu(e){return({state:t,dispatch:r,view:n,tr:o})=>e(jv(o,t),r,n)}function l2(e){return t=>{var r;return re(t.dispatch===void 0||t.dispatch===((r=t.view)==null?void 0:r.dispatch),{code:B.NON_CHAINABLE_COMMAND}),e(t)}}function Y6(...e){return({state:t,dispatch:r,view:n,tr:o,...i})=>{for(const s of e)if(s({state:t,dispatch:r,view:n,tr:o,...i}))return!0;return!1}}var on={get isBrowser(){return!!(typeof window<"u"&&typeof window.document<"u"&&window.navigator&&window.navigator.userAgent)},get isJSDOM(){return on.isBrowser&&window.navigator.userAgent.includes("jsdom")},get isNode(){return typeof process<"u"&&process.versions!=null&&process.versions.node!=null},get isIos(){return on.isBrowser&&/iPod|iPhone|iPad/.test(navigator.platform)},get isMac(){return on.isBrowser&&/Mac|iPod|iPhone|iPad/.test(navigator.platform)},get isApple(){return on.isNode?process.platform==="darwin":on.isBrowser?/Mac|iPod|iPhone|iPad/.test(window.navigator.platform):!1},get isDevelopment(){return!1},get isTest(){return!1},get isProduction(){return!0}};function kn(e,t){var r;const n=PC(e);return((r=n==null?void 0:n.getComputedStyle(e))==null?void 0:r.getPropertyValue(t))??""}function ar(e,t){return Object.assign(e.style,t)}var J6=["px","rem","em","in","q","mm","cm","pt","pc","vh","vw","vmin","vmax"],X6=/[\d-.]+(\w+)$/;function $f(e="0"){const t=e||"0",r=Number.parseFloat(t),n=t.match(X6),o=((n==null?void 0:n[1])??"px").toLowerCase();return[r,fr(J6,o)?o:"px"]}var Cn=96,hl=25.4,xC=72,kC=6;function Pl(e){if(et(e))return kn(e,"font-size")||Pl(e.parentElement);const t=PC(e);return t?kn(t.document.documentElement,"font-size"):""}function Q6(e){const t=LC(e),r=t.document.documentElement||t.document.body;return(n,o)=>{switch(o){case"rem":return n*Xs(Pl(r));case"em":return n*Xs(Pl(e),e==null?void 0:e.parentElement);case"in":return n*Cn;case"q":return n*Cn/hl/4;case"mm":return n*Cn/hl;case"cm":return n*Cn*10/hl;case"pt":return n*Cn/xC;case"pc":return n*Cn/kC;case"vh":return(n*t.innerHeight||r.clientWidth)/100;case"vw":return(n*t.innerWidth||r.clientHeight)/100;case"vmin":return n*Math.min(t.innerWidth||r.clientWidth,t.innerHeight||r.clientHeight)/100;case"vmax":return n*Math.max(t.innerWidth||r.clientWidth,t.innerHeight||r.clientHeight)/100;default:return n}}}var Hf=/^([a-z]+)\((.+)\)$/i;function wC(e,t){if(!Hf.test(e))return Number.NaN;const r=EN(e,{brackets:["()"],escape:"_",flat:!0});if(!r||r.length===0)return Number.NaN;function n(i){return i.replace(/_(\d+)_/g,(s,a)=>{const l=Number.parseFloat(a);return r[l]??""})}const o=Zo(r,0);for(const i of xa(o,Hf)){const s=Zo(i,1),c=n(Zo(i,2)).split(/\s*,\s*/).map(u=>{if(Hf.test(u)){const d=n(u);return wC(d,t)}return SC(u,t)});switch(s){case"min":return Math.min(...c);case"max":return Math.max(...c);case"clamp":{const[u,d,f]=c;if(Jt(u)&&Jt(d)&&Jt(f))return Ad({min:u,max:f,value:d});break}case"calc":return Number.NaN;default:return Number.NaN}}return Number.NaN}function SC(e,t){const[r,n]=$f(e);return t(r,n)}function Xs(e,t){const r=Q6(t);return Hf.test(e)?wC(e.toLowerCase(),r):SC(e,r)}function xg(e,t,r){const n=LC(r),o=n.document.documentElement||n.document.body,i=Xs(e,r);switch(t){case"px":return i;case"rem":return i/Xs(Pl(o));case"em":return i*Xs(Pl(r),r==null?void 0:r.parentElement);case"in":return i/Cn;case"q":return i/Cn*hl*4;case"mm":return i/Cn*hl;case"cm":return i/Cn/10*hl;case"pt":return i/Cn*xC;case"pc":return i/Cn*kC;case"vh":return i/(n.innerHeight||o.clientWidth)*100;case"vw":return i/(n.innerWidth||o.clientHeight)*100;case"vmin":return i/Math.min(n.innerWidth||o.clientWidth,n.innerHeight||o.clientHeight)*100;case"vmax":return i/Math.max(n.innerWidth||o.clientWidth,n.innerHeight||o.clientHeight)*100;default:return i}}function Np(e){return Zt(e)&&Jt(e.nodeType)&&oe(e.nodeName)}function et(e){return Np(e)&&e.nodeType===1}function Z6(e){return Np(e)&&e.nodeType===3}function Hh(e){const{types:t,node:r}=e;if(!r)return!1;const n=o=>o===r.type||o===r.type.name;return ct(t)?t.some(n):n(t)}function ez(e,t){const{tr:r}=t;return e.forEach(n=>{n.steps.forEach(o=>{r.step(o)})}),r}function tz({pos:e,tr:t}){const r=t.doc.nodeAt(e);return r&&t.delete(e,e+r.nodeSize),t}function rz({pos:e,tr:t,content:r}){const n=t.doc.nodeAt(e);return n&&t.replaceWith(e,e+n.nodeSize,r),t}function Ld(e){const{predicate:t,selection:r}=e,n=MC(r)?r.selection.$from:Kv(r)?r.$from:r;for(let o=n.depth;o>0;o--){const i=n.node(o),s=o>0?n.before(o):0,a=n.start(o),l=s+i.nodeSize;if(t(i,s))return{pos:s,depth:o,node:i,start:a,end:l}}}function nz(e){const{depth:t}=e,r=t>0?e.before(t):0,n=e.node(t),o=e.start(t),i=r+n.nodeSize;return{pos:r,start:o,node:n,end:i,depth:t}}function oz(e){const t=Ld({predicate:()=>!0,selection:e});return re(t,{message:"No parent node found for the selection provided."}),t}function rs(e){const{types:t,selection:r}=e;return Ld({predicate:n=>Hh({types:t,node:n}),selection:r})}function iz(e){const{types:t,selection:r}=e;if(!(!Dd(r)||!Hh({types:t,node:r.node})))return{pos:r.$from.pos,depth:r.$from.depth,start:r.$from.start(),end:r.$from.pos+r.node.nodeSize,node:r.node}}function Uv(e){return Kv(e)?e.empty:e.selection.empty}function sz(e){return e.docChanged||e.selectionSet}function EC(e){return!!Bu(e)}function Bu(e){const{state:t,type:r,attrs:n}=e,{selection:o,doc:i}=t,s=oe(r)?i.type.schema.nodes[r]:r;re(s,{code:B.SCHEMA,message:`No node exists for ${r}`});const a=iz({selection:o,types:r})??Ld({predicate:l=>l.type===s,selection:o});return!n||vp(n)||!a||a.node.hasMarkup(s,{...a.node.attrs,...n})?a:void 0}function Rp(...e){return t=>{if(!Zx(e))return!1;const[r,...n]=e;let o=!1;const i=(...l)=>()=>{if(!Zx(l))return!1;o=!0;const[,...c]=l;return Rp(...l)({...t,next:i(...c)})},s=i(...n),a=r({...t,next:s});return o||a?a:s()}}function az(e,t){const r=new Map,n=ee();for(const o of e)for(const[i,s]of At(o)){const l=[...r.get(i)??[],s],c=Rp(...l);r.set(i,l),n[i]=t(c)}return n}function lz(e){return az(e,t=>(r,n,o)=>t({state:r,dispatch:n,view:o,tr:r.tr,next:()=>!1}))}function Wv(e,t){const r=e.attrs??{};return Object.entries(t).every(([n,o])=>r[n]===o)}function cz(e){return OC(e,[Ko,bt,Dt,eo])}function oc(e){return Zt(e)}function ic(e,t){return ct(t)?fr(t,e[ti]):t===e[ti]}function uz(e){return Zt(e)&&e instanceof O1}function dz(e,t){return oe(e)?it(t.nodes,e):e}function CC(e){return Zt(e)&&e instanceof Nd}function fz(e,t){return oe(e)?it(t.marks,e):e}function Id(e){return Zt(e)&&e instanceof Fi}function pz(e){return Zt(e)&&e instanceof R}function hz(e){return Zt(e)&&e instanceof Te}function MC(e){return Zt(e)&&e instanceof Hs}function ms(e){return Zt(e)&&e instanceof le}function mz(e){return Zt(e)&&e instanceof kr}function Kv(e){return Zt(e)&&e instanceof be}function gz(e){return Zt(e)&&e instanceof Tl}function c2(e){const{trState:t,from:r,to:n,type:o,attrs:i={}}=e,{doc:s}=t,a=fz(o,s.type.schema);if(Object.keys(i).length===0)return s.rangeHasMark(r,n,a);let l=!1;return n>r&&s.nodesBetween(r,n,c=>l?!1:(l=(c.marks??[]).some(d=>d.type!==a?!1:Wv(d,i)),!l)),l}function Dd(e){return Zt(e)&&e instanceof ce}function Pp(e){const{trState:t,type:r,attrs:n={},from:o,to:i}=e,{selection:s,doc:a,storedMarks:l}=t,c=oe(r)?a.type.schema.marks[r]:r;if(re(c,{code:B.SCHEMA,message:`Mark type: ${r} does not exist on the current schema.`}),o&&i)try{return Math.max(o,i)d.type!==r?!1:Wv(d,n??{})):c2({...e,from:s.from,to:s.to})}function qv(e,t={}){const r=vz(e.type.schema);if(!r)return!1;const{ignoreAttributes:n,ignoreDocAttributes:o}=t;return n?TC(r,e):o?r.content.eq(e.content):r.eq(e)}function TC(e,t){if(e===t)return!0;const r=e.type===t.type&&Te.sameSet(e.marks,t.marks);function n(){if(e.content===t.content)return!0;if(e.content.size!==t.content.size)return!1;const o=[],i=[];e.content.forEach(s=>o.push(s)),t.content.forEach(s=>i.push(s));for(const[s,a]of o.entries()){const l=i[s];if(!l||!TC(a,l))return!1}return!0}return r&&n()}function vz(e){var t;return((t=e.nodes.doc)==null?void 0:t.createAndFill())??void 0}function Bh(e){for(const t of Object.values(e.nodes))if(t.name!=="doc"&&(t.isBlock||t.isTextblock))return t;re(!1,{code:B.SCHEMA,message:"No default block node found for the provided schema."})}function yz(e){return e.type===Bh(e.type.schema)}function Fh(e){return!!e&&e.type.isBlock&&!e.textContent&&!e.childCount}function _o(e,t,r){const n=e.parent.childAfter(e.parentOffset);if(!n.node)return;const o=oe(t)?t:t.name,i=n.node.marks.find(({type:d})=>d.name===o);let s=e.index(),a=e.start()+n.offset,l=s+1,c=a+n.node.nodeSize;if(!i)return r&&c0&&i.isInSet(e.parent.child(s-1).marks);)s-=1,a-=e.parent.child(s).nodeSize;for(;le instanceof r)}function xz(e){return eE(e,({from:r,to:n,prevFrom:o,prevTo:i})=>`${r}_${n}_${o}_${i}`).filter((r,n,o)=>!o.some((i,s)=>n===s?!1:r.prevFrom>=i.prevFrom&&r.prevTo<=i.prevTo&&r.from>=i.from&&r.to<=i.to))}function _C(e,t=[]){const r=[],{steps:n,mapping:o}=e,i=o.invert();n.forEach((a,l)=>{if(!OC(a,t))return;const c=[],u=a.getMap(),d=o.slice(l);if(u.ranges.length===0&&cz(a)){const{from:f,to:p}=a;c.push({from:f,to:p})}else u.forEach((f,p)=>{c.push({from:f,to:p})});c.forEach(f=>{const p=d.map(f.from,-1),h=d.map(f.to);r.push({from:p,to:h,prevFrom:i.map(p,-1),prevTo:i.map(h)})})});const s=ta(r,(a,l)=>a.from-l.from);return xz(s)}function kz(e,t){const r=[],n=_C(e,t);for(const o of n)try{const i=e.doc.resolve(o.from),s=e.doc.resolve(o.to),a=i.blockRange(s);a&&r.push(a)}catch{}return r}function wz(e){var t;return((t=e.content.firstChild)==null?void 0:t.textContent)??""}function Sz(e,t){if(!ms(e.selection))return;let{from:r,to:n}=e.selection;const o=(s,a)=>wz(le.between(e.doc.resolve(s),e.doc.resolve(a)).content());for(let s=o(r-1,r);s&&!t.test(s);r--,s=o(r-1,r));for(let s=o(n,n+1);s&&!t.test(s);n++,s=o(n,n+1));if(r===n)return;const i=e.doc.textBetween(r,n,wv,` + +`);return{from:r,to:n,text:i}}function AC(e){return Sz(e,/\W/)}function Zo(e,t=0){const r=ct(e)?e[t]:e;return W4(oe(r),`No match string found for match ${e}`),r??""}function Ez(e){return ms(e)?e.$cursor:void 0}function Cz(e,t){return Id(e)?t?e.type===t.nodes.doc:e.type.name==="doc":!1}function Mz(e){return Zt(e)&&Jt(e.anchor)&&Jt(e.head)}function jr(e,t){const r=t.nodeSize-2,n=0;let o;const i=l=>Ad({min:n,max:r,value:l});if(Kv(e))return e;if(e==="all")return new kr(t);if(e==="start"?o=n:e==="end"?o=r:gz(e)?o=e.pos:o=e,Jt(o))return o=i(o),le.near(t.resolve(o));if(Mz(o)){const l=i(o.anchor),c=i(o.head);return le.between(t.resolve(l),t.resolve(c))}const s=i(o.from),a=i(o.to);return le.between(t.resolve(s),t.resolve(a))}var Tz=3;function NC(e){const{content:t,schema:r,document:n,stringHandler:o,onError:i,attempts:s=0}=e,a=i&&s<=Tz||s===0;if(re(a,{code:B.INVALID_CONTENT,message:"The invalid content has been called recursively more than ${MAX_ATTEMPTS} times. The content is invalid and the error handler has not been able to recover properly."}),oe(t))return re(o,{code:B.INVALID_CONTENT,message:`The string '${t}' was added to the editor, but no \`stringHandler\` was added. Please provide a valid string handler which transforms your content to a \`ProsemirrorNode\` to prevent this error.`}),o({document:n,content:t,schema:r});if(MC(t))return t.doc;if(Id(t))return t;try{return r.nodeFromJSON(t)}catch(l){const c=Rz({schema:r,error:l,json:t}),u=i==null?void 0:i(c);return re(u,{code:B.INVALID_CONTENT,message:`An error occurred when processing the content. Please provide an \`onError\` handler to process the invalid content: ${JSON.stringify(c.invalidContent,null,2)}`}),NC({...e,content:u,attempts:s+1})}}function Vh(){const e=RE();if(e)return e;throw new Error(`Unable to retrieve the document from the global scope. +It seems that you are running Remirror in a non-browser environment. Remirror need browser APIs to work. +If you are using Jest (or other testing frameworks), make sure that you are using the JSDOM environment (https://jestjs.io/docs/29.0/configuration#testenvironment-string). +If you are using Next.js (or other server-side rendering frameworks), please use dynamic import with \`ssr: false\` to load the editor component without rendering it on the server (https://nextjs.org/docs/advanced-features/dynamic-import#with-no-ssr). +If you are using Node.js, you can install JSDOM and Remirror will try to use it automatically, or you can create a fake document and pass it to Remirror`)}function RC(e){var t;return(e==null?void 0:e.defaultView)??(typeof window<"u"?window:void 0)??((t=RE())==null?void 0:t.defaultView)}function PC(e){return RC(e==null?void 0:e.ownerDocument)}function zC(e){const t=RC(e)??Vh().defaultView;if(t)return t;throw new Error("Unable to retrieve the window from the global scope")}function LC(e){return zC(e==null?void 0:e.ownerDocument)}function Oz(e,t=Vh()){const r=Cz(e,e.type.schema)?e.content:R.from(e);return an.fromSchema(e.type.schema).serializeFragment(r,{document:t})}function _z(e,t){return new(zC(t)).DOMParser().parseFromString(`${e}`,"text/html").body}function Az(e,t=Vh()){const r=t.createElement("div");return r.append(Oz(e,t)),r.innerHTML}function U1(e){const{content:t,schema:r,document:n,fragment:o=!1,...i}=e,s=_z(t,n),a=Mv.fromSchema(r);return o?a.parseSlice(s,{...u2,...i}).content:a.parse(s,{...u2,...i})}var u2={preserveWhitespace:!1};function $d(e,t){const r=Lu(t.defaults());return Sv({...e},r)}function Gv(e,t){let r="";t&&(r=`${t.trim()}`);const n=kN(e);if(!n)return r;const o=(r.endsWith(";")," ");return`${r}${o}${n}`}var Nz={remove(e,t){let r=e;for(const n of t)n.invalidParentNode||(r=mA(n.path,r));return r}};function Rz({json:e,schema:t,...r}){const n=new Set(Lu(t.marks)),o=new Set(Lu(t.nodes)),i=IC({json:e,path:[],validNodes:o,validMarks:n});return{json:e,invalidContent:i,transformers:Nz,...r}}function IC(e){const{json:t,validMarks:r,validNodes:n,path:o=[]}=e,i={validMarks:r,validNodes:n},s=[],{type:a,marks:l,content:c}=t;let{invalidParentMark:u=!1,invalidParentNode:d=!1}=e;if(l){const f=[];for(const[p,h]of l.entries()){const m=oe(h)?h:h.type;r.has(m)||(f.unshift({name:m,path:[...o,"marks",`${p}`],type:"mark",invalidParentMark:u,invalidParentNode:d}),u=!0)}s.push(...f)}if(n.has(a)||(s.push({name:a,type:"node",path:o,invalidParentMark:u,invalidParentNode:d}),d=!0),c){const f=[];for(const[p,h]of c.entries())f.unshift(...IC({...i,json:h,path:[...o,"content",`${p}`],invalidParentMark:u,invalidParentNode:d}));s.unshift(...f)}return s}function Pz(e){return!!(ms(e)&&e.$cursor&&e.$cursor.parentOffset>=e.$cursor.parent.content.size)}function W1(e){return!!(ms(e)&&e.$cursor&&e.$cursor.parentOffset<=0)}function d2(e){const t=be.atStart(e.$anchor.doc);return!!(W1(e)&&t.anchor===e.anchor)}function zz(e){return({dispatch:t,tr:r})=>{const{type:n,attrs:o=ee(),appendText:i,range:s}=e,a=s?le.between(r.doc.resolve(s.from),r.doc.resolve(s.to)):r.selection,{$from:l,from:c,to:u}=a;let d=l.depth===0?r.doc.type.allowsMarkType(n):!1;return r.doc.nodesBetween(c,u,f=>{if(d)return!1;if(f.inlineContent&&f.type.allowsMarkType(n)){d=!0;return}}),d?(t==null||t(r.addMark(c,u,n.create(o))&&i?r.insertText(i):r),!0):!1}}function Lz({tr:e,dispatch:t}){const{$from:r,$to:n}=e.selection,o=r.blockRange(n),i=o&&rc(o);return!Jt(i)||!o?!1:(t==null||t(e.lift(o,i).scrollIntoView()),!0)}function DC(e,t={},r){return function(n){const{tr:o,dispatch:i,state:s}=n,a=oe(e)?it(s.schema.nodes,e):e,{from:l,to:c}=jr(r??o.selection,o.doc),u=o.doc.resolve(l),d=o.doc.resolve(c),f=u.blockRange(d),p=f&&Ov(f,a,t);return!p||!f?!1:(i==null||i(o.wrap(f,p).scrollIntoView()),!0)}}function $C(e,t={},r){return n=>{const{tr:o,state:i}=n,s=oe(e)?it(i.schema.nodes,e):e;return Bu({state:o,type:s,attrs:t})?Lz(n):DC(e,t,r)(n)}}function Fu(e,t,r,n=!0){return function(o){const{tr:i,dispatch:s,state:a}=o,l=oe(e)?it(a.schema.nodes,e):e,{from:c,to:u}=jr(r??i.selection,i.doc);let d=!1,f;return i.doc.nodesBetween(c,u,(p,h)=>{if(d)return!1;if(!p.isTextblock||p.hasMarkup(l,t))return;if(p.type===l){d=!0,f=p.attrs;return}const m=i.doc.resolve(h),b=m.index();d=m.parent.canReplaceWith(b,b+1,l),d&&(f=m.parent.attrs)}),d?(s==null||s(i.setBlockType(c,u,l,{...n?f:{},...t}).scrollIntoView()),!0):!1}}function Yv(e){return t=>{const{tr:r,state:n}=t,{type:o,attrs:i,preserveAttrs:s=!0}=e,a=Bu({state:r,type:o,attrs:i}),l=e.toggleType??Bh(n.schema);if(a)return Fu(l,{...s?a.node.attrs:{},...i})(t);const c=Bu({state:r,type:l,attrs:i});return Fu(o,{...s?c==null?void 0:c.node.attrs:{},...i})(t)}}function Iz(e=0){const t=navigator.userAgent.match(/Chrom(e|ium)\/(\d+)\./);return t?Number.parseInt(it(t,2),10)>=e:!1}function Dz(e,t){let{head:r,empty:n,anchor:o}=e;for(const i of t.steps)r=i.getMap().map(r);n?t.setSelection(le.near(t.doc.resolve(r))):t.setSelection(le.between(t.doc.resolve(o),t.doc.resolve(r)))}function $z(e){const{attrs:t={},appendText:r="",content:n="",keepSelection:o=!1,range:i}=e;return({state:s,tr:a,dispatch:l})=>{var c;const u=s.schema,d=jr(e.selection??i??a.selection,a.doc),f=d.$from.index(),{from:p,to:h,$from:m}=d,b=oe(e.type)?u.nodes[e.type]??u.marks[e.type]:e.type;if(re(oe(e.type)?b:!0,{code:B.SCHEMA,message:`Schema contains no marks or nodes with name ${b}`}),uz(b)){if(!m.parent.canReplaceWith(f,f,b))return!1;a.replaceWith(p,h,b.create(t,n?u.text(n):void 0))}else re(n,{message:"`replaceText` cannot be called without content when using a mark type"}),a.replaceWith(p,h,u.text(n,CC(b)?[b.create(t)]:void 0));return r&&a.insertText(r),o&&Dz(s.selection,a),l&&(Iz(60)&&((c=document.getSelection())==null||c.empty()),l(a)),!0}}function HC(e,t){const r=e.parent.childAfter(e.parentOffset);if(!r.node)return;const{marks:n,nodeSize:o}=r.node;if(n[0])return n[0].type;const s=e.start()+r.offset+o;return HC(e.doc.resolve(s+1))}function BC(e){return({dispatch:t,tr:r,state:n})=>{const{type:o,expand:i=!0,range:s}=e,a=jr(e.selection??s??r.selection,r.doc);let{from:l,to:c,$from:u,$to:d}=a;const f=oe(o)?n.schema.marks[o]:o;f!==null&&re(f,{code:B.SCHEMA,message:`Mark type: ${o} does not exist on the current schema.`});const p=f??HC(u);if(!p)return!1;const h=_o(u,p,d);return i&&h&&(l=Math.max(0,Math.min(l,h.from)),c=Math.min(Math.max(c,h.to),r.doc.nodeSize-2)),t==null||t(r.removeMark(l,Jt(c)?c:l,CC(f)?f:void 0)),!0}}function Hz(e){const t=["command","cmd","meta"];return on.isMac&&t.push("mod"),t.includes(e)}function Bz(e){const t=["control","ctrl"];return on.isMac||t.push("mod"),t.includes(e)}function Fz(e){const t=[];for(let r of e.split("-")){if(r=r.toLowerCase(),Hz(r)){t.push({type:"modifier",symbol:"⌘",key:"command",i18n:Mt.COMMAND_KEY});continue}if(Bz(r)){t.push({type:"modifier",symbol:"⌃",key:"control",i18n:Mt.CONTROL_KEY});continue}switch(r){case"shift":t.push({type:"modifier",symbol:"⇧",key:r,i18n:Mt.SHIFT_KEY});continue;case"alt":t.push({type:"modifier",symbol:"⌥",key:r,i18n:Mt.ALT_KEY});continue;case` +`:case"\r":case"enter":t.push({type:"named",symbol:"↵",key:r,i18n:Mt.ENTER_KEY});continue;case"backspace":t.push({type:"named",symbol:"⌫",key:r,i18n:Mt.BACKSPACE_KEY});continue;case"delete":t.push({type:"named",symbol:"⌦",key:r,i18n:Mt.DELETE_KEY});continue;case"escape":t.push({type:"named",symbol:"␛",key:r,i18n:Mt.ESCAPE_KEY});continue;case"tab":t.push({type:"named",symbol:"⇥",key:r,i18n:Mt.TAB_KEY});continue;case"capslock":t.push({type:"named",symbol:"⇪",key:r,i18n:Mt.CAPS_LOCK_KEY});continue;case"space":t.push({type:"named",symbol:"␣",key:r,i18n:Mt.SPACE_KEY});continue;case"pageup":t.push({type:"named",symbol:"⤒",key:r,i18n:Mt.PAGE_UP_KEY});continue;case"pagedown":t.push({type:"named",symbol:"⤓",key:r,i18n:Mt.PAGE_DOWN_KEY});continue;case"home":t.push({type:"named",key:r,i18n:Mt.HOME_KEY});continue;case"end":t.push({type:"named",key:r,i18n:Mt.END_KEY});continue;case"arrowleft":t.push({type:"named",symbol:"←",key:r,i18n:Mt.ARROW_LEFT_KEY});continue;case"arrowright":t.push({type:"named",symbol:"→",key:r,i18n:Mt.ARROW_RIGHT_KEY});continue;case"arrowup":t.push({type:"named",symbol:"→",key:r,i18n:Mt.ARROW_UP_KEY});continue;case"arrowdown":t.push({type:"named",symbol:"↓",key:r,i18n:Mt.ARROW_DOWN_KEY});continue;default:t.push({type:"char",key:r});continue}}return t}function Vz(e){const{node:t,predicate:r,descend:n=!0,action:o}=e;re(Id(t),{code:B.INTERNAL,message:'Invalid "node" parameter passed to "findChildren".'}),re(_e(r),{code:B.INTERNAL,message:'Invalid "predicate" parameter passed to "findChildren".'});const i=[];return t.descendants((s,a)=>{const l={node:s,pos:a};return r(l)&&(i.push(l),o==null||o(l)),n}),i}function jz(e){const{type:t,...r}=e;return Vz({...r,predicate:n=>n.node.type===t})}function Uz(e,t={}){const{descend:r=!1,predicate:n,StepTypes:o}=t,i=kz(e,o),s=[];for(const a of i){const{start:l,end:c}=a;e.doc.nodesBetween(l,c,(u,d)=>(((n==null?void 0:n(u,d,a))??!0)&&s.push({node:u,pos:d}),r))}return s}function Vu(e){const{regexp:t,type:r,getAttributes:n,ignoreWhitespace:o=!1,beforeDispatch:i,updateCaptured:s,shouldSkip:a,invalidMarks:l}=e;let c;const u=new wa(t,(d,f,p,h)=>{const{tr:m,schema:b}=d;c||(c=oe(r)?b.marks[r]:r,re(c,{code:B.SCHEMA,message:`Mark type: ${r} does not exist on the current schema.`}));let v=f[1],g=f[0];const y=VC({captureGroup:v,fullMatch:g,end:h,start:p,rule:u,state:d,ignoreWhitespace:o,invalidMarks:l,shouldSkip:a,updateCaptured:s});if(!y)return null;({start:p,end:h,captureGroup:v,fullMatch:g}=y);const x=_e(n)?n(f):n;let k=h,w=[];if(v){const E=g.search(/\S/),M=p+g.indexOf(v),C=M+v.length;w=m.storedMarks??[],Cp&&m.delete(p+E,M),k=p+E+v.length}return m.addMark(p,k,c.create(x)),m.setStoredMarks(w),i==null||i({tr:m,match:f,start:p,end:h}),m});return u}function FC(e){const{regexp:t,type:r,getAttributes:n,beforeDispatch:o,shouldSkip:i,ignoreWhitespace:s=!1,updateCaptured:a,invalidMarks:l}=e,c=new wa(t,(u,d,f,p)=>{const h=_e(n)?n(d):n,{tr:m,schema:b}=u,v=oe(r)?b.nodes[r]:r;let g=d[1],y=d[0];const x=VC({captureGroup:g,fullMatch:y,end:p,start:f,rule:c,state:u,ignoreWhitespace:s,invalidMarks:l,shouldSkip:i,updateCaptured:a});if(!x)return null;({start:f,end:p,captureGroup:g,fullMatch:y}=x),re(v,{code:B.SCHEMA,message:`No node exists for ${r} in the schema.`});const k=v.createAndFill(h);return k&&(m.replaceRangeWith(v.isBlock?m.doc.resolve(f).before():f,p,k),o==null||o({tr:m,match:[y,g??""],start:f,end:p})),m});return c}function VC({captureGroup:e,fullMatch:t,end:r,start:n,rule:o,ignoreWhitespace:i,shouldSkip:s,updateCaptured:a,state:l,invalidMarks:c}){var u;if(t==null)return null;const d=(a==null?void 0:a({captureGroup:e,fullMatch:t,start:n,end:r}))??{};e=d.captureGroup??e,t=d.fullMatch??t,n=d.start??n,r=d.end??r;const f=l.doc.resolve(n),p=l.doc.resolve(r);return c&&V1({$from:f,$to:p},c)||o.invalidMarks&&V1({$from:f,$to:p},o.invalidMarks)||i&&(e==null?void 0:e.trim())===""||s!=null&&s({state:l,captureGroup:e,fullMatch:t,start:n,end:r,ruleType:"mark"})||(u=o.shouldSkip)!=null&&u.call(o,{state:l,captureGroup:e,fullMatch:t,start:n,end:r,ruleType:"mark"})?null:{captureGroup:e,end:r,fullMatch:t,start:n}}var Wz=function(){const t=Array.prototype.slice.call(arguments).filter(Boolean),r={},n=[];t.forEach(i=>{(i?i.split(" "):[]).forEach(a=>{if(a.startsWith("atm_")){const[,l]=a.split("_");r[l]=a}else n.push(a)})});const o=[];for(const i in r)Object.prototype.hasOwnProperty.call(r,i)&&o.push(r[i]);return o.push(...n),o.join(" ")},Kz=Wz;const jC=(e,t)=>e.selection.empty?!1:(t&&t(e.tr.deleteSelection().scrollIntoView()),!0);function qz(e,t){let{$cursor:r}=e.selection;return!r||(t?!t.endOfTextblock("backward",e):r.parentOffset>0)?null:r}const UC=(e,t,r)=>{let n=qz(e,r);if(!n)return!1;let o=WC(n);if(!o){let s=n.blockRange(),a=s&&rc(s);return a==null?!1:(t&&t(e.tr.lift(s,a).scrollIntoView()),!0)}let i=o.nodeBefore;if(!i.type.spec.isolating&&GC(e,o,t))return!0;if(n.parent.content.size==0&&(zl(i,"end")||ce.isSelectable(i))){let s=_v(e.doc,n.before(),n.after(),K.empty);if(s&&s.slice.size{let{$head:n,empty:o}=e.selection,i=n;if(!o)return!1;if(n.parent.isTextblock){if(r?!r.endOfTextblock("backward",e):n.parentOffset>0)return!1;i=WC(n)}let s=i&&i.nodeBefore;return!s||!ce.isSelectable(s)?!1:(t&&t(e.tr.setSelection(ce.create(e.doc,i.pos-s.nodeSize)).scrollIntoView()),!0)};function WC(e){if(!e.parent.type.spec.isolating)for(let t=e.depth-1;t>=0;t--){if(e.index(t)>0)return e.doc.resolve(e.before(t+1));if(e.node(t).type.spec.isolating)break}return null}function Yz(e,t){let{$cursor:r}=e.selection;return!r||(t?!t.endOfTextblock("forward",e):r.parentOffset{let n=Yz(e,r);if(!n)return!1;let o=KC(n);if(!o)return!1;let i=o.nodeAfter;if(GC(e,o,t))return!0;if(n.parent.content.size==0&&(zl(i,"start")||ce.isSelectable(i))){let s=_v(e.doc,n.before(),n.after(),K.empty);if(s&&s.slice.size{let{$head:n,empty:o}=e.selection,i=n;if(!o)return!1;if(n.parent.isTextblock){if(r?!r.endOfTextblock("forward",e):n.parentOffset=0;t--){let r=e.node(t);if(e.index(t)+1{let{$head:r,$anchor:n}=e.selection;return!r.parent.type.spec.code||!r.sameParent(n)?!1:(t&&t(e.tr.insertText(` +`).scrollIntoView()),!0)};function Jv(e){for(let t=0;t{let{$head:r,$anchor:n}=e.selection;if(!r.parent.type.spec.code||!r.sameParent(n))return!1;let o=r.node(-1),i=r.indexAfter(-1),s=Jv(o.contentMatchAt(i));if(!s||!o.canReplaceWith(i,i,s))return!1;if(t){let a=r.after(),l=e.tr.replaceWith(a,a,s.createAndFill());l.setSelection(be.near(l.doc.resolve(a),1)),t(l.scrollIntoView())}return!0},Zz=(e,t)=>{let r=e.selection,{$from:n,$to:o}=r;if(r instanceof kr||n.parent.inlineContent||o.parent.inlineContent)return!1;let i=Jv(o.parent.contentMatchAt(o.indexAfter()));if(!i||!i.isTextblock)return!1;if(t){let s=(!n.parentOffset&&o.index(){let{$cursor:r}=e.selection;if(!r||r.parent.content.size)return!1;if(r.depth>1&&r.after()!=r.end(-1)){let i=r.before();if(dl(e.doc,i))return t&&t(e.tr.split(i).scrollIntoView()),!0}let n=r.blockRange(),o=n&&rc(n);return o==null?!1:(t&&t(e.tr.lift(n,o).scrollIntoView()),!0)};function tL(e){return(t,r)=>{let{$from:n,$to:o}=t.selection;if(t.selection instanceof ce&&t.selection.node.isBlock)return!n.parentOffset||!dl(t.doc,n.pos)?!1:(r&&r(t.tr.split(n.pos).scrollIntoView()),!0);if(!n.parent.isBlock)return!1;if(r){let i=o.parentOffset==o.parent.content.size,s=t.tr;(t.selection instanceof le||t.selection instanceof kr)&&s.deleteSelection();let a=n.depth==0?null:Jv(n.node(-1).contentMatchAt(n.indexAfter(-1))),l=e&&e(o.parent,i),c=l?[l]:i&&a?[{type:a}]:void 0,u=dl(s.doc,s.mapping.map(n.pos),1,c);if(!c&&!u&&dl(s.doc,s.mapping.map(n.pos),1,a?[{type:a}]:void 0)&&(a&&(c=[{type:a}]),u=!0),u&&(s.split(s.mapping.map(n.pos),1,c),!i&&!n.parentOffset&&n.parent.type!=a)){let d=s.mapping.map(n.before()),f=s.doc.resolve(d);a&&n.node(-1).canReplaceWith(f.index(),f.index()+1,a)&&s.setNodeMarkup(s.mapping.map(n.before()),a)}r(s.scrollIntoView())}return!0}}const rL=tL(),nL=(e,t)=>{let{$from:r,to:n}=e.selection,o,i=r.sharedDepth(n);return i==0?!1:(o=r.before(i),t&&t(e.tr.setSelection(ce.create(e.doc,o))),!0)},oL=(e,t)=>(t&&t(e.tr.setSelection(new kr(e.doc))),!0);function iL(e,t,r){let n=t.nodeBefore,o=t.nodeAfter,i=t.index();return!n||!o||!n.type.compatibleContent(o.type)?!1:!n.content.size&&t.parent.canReplace(i-1,i)?(r&&r(e.tr.delete(t.pos-n.nodeSize,t.pos).scrollIntoView()),!0):!t.parent.canReplace(i,i+1)||!(o.isTextblock||Rd(e.doc,t.pos))?!1:(r&&r(e.tr.clearIncompatible(t.pos,n.type,n.contentMatchAt(n.childCount)).join(t.pos).scrollIntoView()),!0)}function GC(e,t,r){let n=t.nodeBefore,o=t.nodeAfter,i,s;if(n.type.spec.isolating||o.type.spec.isolating)return!1;if(iL(e,t,r))return!0;let a=t.parent.canReplace(t.index(),t.index()+1);if(a&&(i=(s=n.contentMatchAt(n.childCount)).findWrapping(o.type))&&s.matchType(i[0]||o.type).validEnd){if(r){let d=t.pos+o.nodeSize,f=R.empty;for(let m=i.length-1;m>=0;m--)f=R.from(i[m].create(null,f));f=R.from(n.copy(f));let p=e.tr.step(new bt(t.pos-1,d,t.pos,d,new K(f,1,0),i.length,!0)),h=d+2*i.length;Rd(p.doc,h)&&p.join(h),r(p.scrollIntoView())}return!0}let l=be.findFrom(t,1),c=l&&l.$from.blockRange(l.$to),u=c&&rc(c);if(u!=null&&u>=t.depth)return r&&r(e.tr.lift(c,u).scrollIntoView()),!0;if(a&&zl(o,"start",!0)&&zl(n,"end")){let d=n,f=[];for(;f.push(d),!d.isTextblock;)d=d.lastChild;let p=o,h=1;for(;!p.isTextblock;p=p.firstChild)h++;if(d.canReplace(d.childCount,d.childCount,p.content)){if(r){let m=R.empty;for(let v=f.length-1;v>=0;v--)m=R.from(f[v].copy(m));let b=e.tr.step(new bt(t.pos-f.length,t.pos+o.nodeSize,t.pos+h,t.pos+o.nodeSize-h,new K(m,f.length,0),0,!0));r(b.scrollIntoView())}return!0}}return!1}function YC(e){return function(t,r){let n=t.selection,o=e<0?n.$from:n.$to,i=o.depth;for(;o.node(i).isInline;){if(!i)return!1;i--}return o.node(i).isTextblock?(r&&r(t.tr.setSelection(le.create(t.doc,e<0?o.start(i):o.end(i)))),!0):!1}}const sL=YC(-1),aL=YC(1);function lL(e,t,r){for(let n=0;n{if(s)return!1;s=a.inlineContent&&a.type.allowsMarkType(r)}),s)return!0}return!1}function cL(e,t=null){return function(r,n){let{empty:o,$cursor:i,ranges:s}=r.selection;if(o&&!i||!lL(r.doc,s,e))return!1;if(n)if(i)e.isInSet(r.storedMarks||i.marks())?n(r.tr.removeStoredMark(e)):n(r.tr.addStoredMark(e.create(t)));else{let a=!1,l=r.tr;for(let c=0;!a&&c",191:"?",192:"~",219:"{",220:"|",221:"}",222:'"'},dL=typeof navigator<"u"&&/Mac/.test(navigator.platform),fL=typeof navigator<"u"&&/MSIE \d|Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);for(var Yt=0;Yt<10;Yt++)ns[48+Yt]=ns[96+Yt]=String(Yt);for(var Yt=1;Yt<=24;Yt++)ns[Yt+111]="F"+Yt;for(var Yt=65;Yt<=90;Yt++)ns[Yt]=String.fromCharCode(Yt+32),zp[Yt]=String.fromCharCode(Yt);for(var Sg in ns)zp.hasOwnProperty(Sg)||(zp[Sg]=ns[Sg]);function pL(e){var t=dL&&e.metaKey&&e.shiftKey&&!e.ctrlKey&&!e.altKey||fL&&e.shiftKey&&e.key&&e.key.length==1||e.key=="Unidentified",r=!t&&e.key||(e.shiftKey?zp:ns)[e.keyCode]||e.key||"Unidentified";return r=="Esc"&&(r="Escape"),r=="Del"&&(r="Delete"),r=="Left"&&(r="ArrowLeft"),r=="Up"&&(r="ArrowUp"),r=="Right"&&(r="ArrowRight"),r=="Down"&&(r="ArrowDown"),r}const hL=typeof navigator<"u"?/Mac|iP(hone|[oa]d)/.test(navigator.platform):!1;function mL(e){let t=e.split(/-(?!$)/),r=t[t.length-1];r=="Space"&&(r=" ");let n,o,i,s;for(let a=0;a127)&&(i=ns[n.keyCode])&&i!=o){let a=t[Eg(i,n)];if(a&&a(r.state,r.dispatch,r))return!0}}return!1}}function vL(e){const t=ta(e,(i,s)=>(s.priority??Ae.Low)-(i.priority??Ae.Low)),r=[],n=[];for(const i of t)EL(i)?r.push(i):n.push(i);let o;return new Ro({key:yL,view:i=>(o=i,{}),props:{transformPasted:i=>{var s,a,l;const c=o.state.selection.$from,u=c.node().type.name,d=new Set(c.marks().map(f=>f.type.name));for(const f of r){if((s=f.ignoredNodes)!=null&&s.includes(u)||(a=f.ignoredMarks)!=null&&a.some(g=>d.has(g)))continue;const p=((l=i.content.firstChild)==null?void 0:l.textContent)??"",h=!o.state.selection.empty&&i.content.childCount===1&&p,m=xa(p,f.regexp)[0];if(h&&m&&f.type==="mark"&&f.replaceSelection){const{from:g,to:y}=o.state.selection,x=o.state.doc.slice(g,y),k=x.content.textBetween(0,x.content.size);if(typeof f.replaceSelection!="boolean"?f.replaceSelection(k):f.replaceSelection){const w=[],{getAttributes:E,markType:M}=f,C=_e(E)?E(m,!0):E,T=M.create(C);return x.content.forEach(N=>{if(N.isText){const z=T.addToSet(N.marks);w.push(N.mark(z))}}),K.maxOpen(R.fromArray(w))}}const{nodes:b,transformed:v}=wL(i.content,f,o.state.schema);v&&(i=f.type==="node"&&f.nodeType.isBlock?new K(R.fromArray(b),0,0):new K(R.fromArray(b),i.openStart,i.openEnd))}return OL(i)},handleDOMEvents:{paste:(i,s)=>{var a,l;const c=s;if(!((l=(a=i.props).editable)!=null&&l.call(a,i.state)))return!1;const{clipboardData:u}=c;if(!u)return!1;const d=[...u.items].map(p=>p.getAsFile()).filter(p=>!!p);if(d.length===0)return!1;const{selection:f}=i.state;for(const{fileHandler:p,regexp:h}of n){const m=h?d.filter(b=>h.test(b.type)):d;if(m.length!==0&&p({event:c,files:m,selection:f,view:i,type:"paste"}))return c.preventDefault(),!0}return!1},drop:(i,s)=>{var a,l,c;const u=s;if(!((l=(a=i.props).editable)!=null&&l.call(a,i.state)))return!1;const{dataTransfer:d,clientX:f,clientY:p}=u;if(!d)return!1;const h=TL(u);if(h.length===0)return!1;const m=((c=i.posAtCoords({left:f,top:p}))==null?void 0:c.pos)??i.state.selection.anchor;for(const{fileHandler:b,regexp:v}of n){const g=v?h.filter(y=>v.test(y.type)):h;if(g.length!==0&&b({event:u,files:g,pos:m,view:i,type:"drop"}))return u.preventDefault(),!0}return!1}}}})}var yL=new ka("pasteRule");function Cg(e,t){return function r(n){const{fragment:o,rule:i,nodes:s}=n,{regexp:a,ignoreWhitespace:l,ignoredMarks:c,ignoredNodes:u}=i;let d=!1;return o.forEach(f=>{if(u!=null&&u.includes(f.type.name)||CL(f)){s.push(f);return}if(!f.isText){const m=r({fragment:f.content,rule:i,nodes:[]});d||(d=m.transformed);const b=R.fromArray(m.nodes);f.type.validContent(b)?s.push(f.copy(b)):s.push(...m.nodes);return}if(f.marks.some(m=>ML(m)||(c==null?void 0:c.includes(m.type.name)))){s.push(f);return}const p=f.text??"";let h=0;for(const m of xa(p,a)){const b=m[1],v=m[0];if(l&&(b==null?void 0:b.trim())===""||!v)return;const g=m.index,y=g+v.length;g>h&&s.push(f.cut(h,g));let x=f.cut(g,y);if(v&&b){const k=v.search(/\S/),w=g+v.indexOf(b),E=w+b.length;k&&s.push(f.cut(g,g+k)),x=f.cut(w,E)}e({nodes:s,rule:i,textNode:x,match:m,schema:t}),d=!0,h=y}p&&h0?[...n.files]:(r=n.items)!=null&&r.length?[...n.items].map(o=>o.getAsFile()).filter(o=>!!o):[]:[]}function OL(e){const t=K.maxOpen(e.content);return t.openStart({events:{},emit(e,...t){(this.events[e]||[]).forEach(r=>r(...t))},on(e,t){return(this.events[e]=this.events[e]||[]).push(t),()=>this.events[e]=(this.events[e]||[]).filter(r=>r!==t)}});var _L=Object.defineProperty,AL=Object.getOwnPropertyDescriptor,Z=(e,t,r,n)=>{for(var o=n>1?void 0:n?AL(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&_L(t,r,o),o},XC=(e,t,r)=>{if(!t.has(e))throw TypeError("Cannot "+r)},G=(e,t,r)=>(XC(e,t,"read from private field"),r?r.call(e):t.get(e)),kt=(e,t,r)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,r)},Lt=(e,t,r,n)=>(XC(e,t,"write to private field"),n?n.call(e,r):t.set(e,r),r);function NL(e,t){return e===t}function p2(e){const{previousOptions:t,update:r,equals:n=NL}=e,o=$s({...t,...r}),i=ee(),s=Lu(t);for(const l of s){const c=t[l],u=o[l];if(n(c,u)){i[l]={changed:!1};continue}i[l]={changed:!0,previousValue:c,value:u}}const a=l=>{const c=ee();for(const u of l){const d=i[u];d!=null&&d.changed&&(c[u]=d.value)}return c};return{changes:$s(i),options:o,pickChanged:a}}var RL={[B.DUPLICATE_HELPER_NAMES]:"helper method",[B.DUPLICATE_COMMAND_NAMES]:"command method"};function QC(e){const{name:t,set:r,code:n}=e,o=RL[n];re(!r.has(t),{code:n,message:`There is a naming conflict for the name: ${t} used in this '${o}'. Please rename or remove from the editor to avoid runtime errors.`}),r.add(t)}function ju(...e){return Ml(Kz(...e).split(" ")).join(" ")}var h2="__IGNORE__",PL="__ALL__",sc=class{constructor(e,...[t]){this["~O"]={},this._mappedHandlers=ee(),this.populateMappedHandlers(),this._options=this._initialOptions=Q4(e,this.constructor.defaultOptions,t??ee(),this.createDefaultHandlerOptions()),this._dynamicKeys=this.getDynamicKeys(),this.init()}get options(){return this._options}get dynamicKeys(){return this._dynamicKeys}get initialOptions(){return this._initialOptions}init(){}getDynamicKeys(){const e=[],{customHandlerKeys:t,handlerKeys:r,staticKeys:n}=this.constructor;for(const o of Lu(this._options))n.includes(o)||r.includes(o)||t.includes(o)||e.push(o);return e}ensureAllKeysAreDynamic(e){}setOptions(e){var t;const r=this.getDynamicOptions();this.ensureAllKeysAreDynamic(e);const{changes:n,options:o,pickChanged:i}=p2({previousOptions:r,update:e});this.updateDynamicOptions(o),(t=this.onSetOptions)==null||t.call(this,{reason:"set",changes:n,options:o,pickChanged:i,initialOptions:this._initialOptions})}resetOptions(){var e;const t=this.getDynamicOptions(),{changes:r,options:n,pickChanged:o}=p2({previousOptions:t,update:this._initialOptions});this.updateDynamicOptions(n),(e=this.onSetOptions)==null||e.call(this,{reason:"reset",options:n,changes:r,pickChanged:o,initialOptions:this._initialOptions})}getDynamicOptions(){return Sv(this._options,[...this.constructor.customHandlerKeys,...this.constructor.handlerKeys])}updateDynamicOptions(e){this._options={...this._options,...e}}populateMappedHandlers(){for(const e of this.constructor.handlerKeys)this._mappedHandlers[e]=[]}createDefaultHandlerOptions(){const e=ee();for(const t of this.constructor.handlerKeys)e[t]=(...r)=>{var n;const{handlerKeyOptions:o}=this.constructor,i=(n=o[t])==null?void 0:n.reducer;let s=i==null?void 0:i.getDefault(...r);for(const[,a]of this._mappedHandlers[t]){const l=a(...r);if(s=i?i.accumulator(s,l,...r):l,zL(o,s,t))return s}return s};return e}addHandler(e,t,r=Ae.Default){return this._mappedHandlers[e].push([r,t]),this.sortHandlers(e),()=>this._mappedHandlers[e]=this._mappedHandlers[e].filter(([,n])=>n!==t)}hasHandlers(e){return(this._mappedHandlers[e]??[]).length>0}sortHandlers(e){this._mappedHandlers[e]=ta(this._mappedHandlers[e],([t],[r])=>r-t)}addCustomHandler(e,t){var r;return((r=this.onAddCustomHandler)==null?void 0:r.call(this,{[e]:t}))??X4}};sc.defaultOptions={};sc.staticKeys=[];sc.handlerKeys=[];sc.handlerKeyOptions={};sc.customHandlerKeys=[];function zL(e,t,r){const{[PL]:n}=e,o=e[r];return!n&&!o?!1:!!(o&&o.earlyReturnValue!==h2&&(_e(o.earlyReturnValue)?o.earlyReturnValue(t)===!0:t===o.earlyReturnValue)||n&&n.earlyReturnValue!==h2&&(_e(n.earlyReturnValue)?n.earlyReturnValue(t)===!0:t===n.earlyReturnValue))}var Wh=class extends sc{constructor(...e){super(LL,...e),this["~E"]={},this._extensions=eE(this.createExtensions(),t=>t.constructor),this.extensionMap=new Map;for(const t of this._extensions)this.extensionMap.set(t.constructor,t)}get priority(){return this.priorityOverride??this.options.priority??this.constructor.defaultPriority}get constructorName(){return`${j4(this.name)}Extension`}get store(){return re(this._store,{code:B.MANAGER_PHASE_ERROR,message:"An error occurred while attempting to access the 'extension.store' when the Manager has not yet set created the lifecycle methods."}),$s(this._store,{requireKeys:!0})}get extensions(){return this._extensions}replaceChildExtension(e,t){this.extensionMap.has(e)&&(this.extensionMap.set(e,t),this._extensions=this.extensions.map(r=>t.constructor===e?t:r))}createExtensions(){return[]}getExtension(e){const t=this.extensionMap.get(e);return re(t,{code:B.INVALID_GET_EXTENSION,message:`'${e.name}' does not exist within the preset: '${this.name}'`}),t}isOfType(e){return this.constructor===e}setStore(e){this._store||(this._store=e)}clone(...e){return new this.constructor(...e)}setPriority(e){this.priorityOverride=e}};Wh.defaultPriority=Ae.Default;var Ve=class extends Wh{static get[ti](){return $t.PlainExtensionConstructor}get[ti](){return $t.PlainExtension}},ci=class extends Wh{static get[ti](){return $t.MarkExtensionConstructor}get[ti](){return $t.MarkExtension}get type(){return it(this.store.schema.marks,this.name)}constructor(...e){super(...e)}};ci.disableExtraAttributes=!1;var er=class extends Wh{static get[ti](){return $t.NodeExtensionConstructor}get[ti](){return $t.NodeExtension}get type(){return it(this.store.schema.nodes,this.name)}constructor(...e){super(...e)}};er.disableExtraAttributes=!1;var LL={priority:void 0,extraAttributes:{},disableExtraAttributes:!1,exclude:{}};function ZC(e){return oc(e)&&ic(e,[$t.PlainExtension,$t.MarkExtension,$t.NodeExtension])}function IL(e){return oc(e)&&ic(e,[$t.PlainExtensionConstructor,$t.MarkExtensionConstructor,$t.NodeExtensionConstructor])}function e5(e){return oc(e)&&ic(e,$t.PlainExtension)}function Hd(e){return oc(e)&&ic(e,$t.NodeExtension)}function Kh(e){return oc(e)&&ic(e,$t.MarkExtension)}function pe(e){return t=>{const{defaultOptions:r,customHandlerKeys:n,handlerKeys:o,staticKeys:i,defaultPriority:s,handlerKeyOptions:a,...l}=e,c=t;r&&(c.defaultOptions=r),s&&(c.defaultPriority=s),a&&(c.handlerKeyOptions=a),c.staticKeys=i??[],c.handlerKeys=o??[],c.customHandlerKeys=n??[];for(const[u,d]of Object.entries(l))c[u]||(c[u]=d);return c}}var DL=class extends Ve{constructor(){super(...arguments),this.attributeList=[],this.attributeObject=ee(),this.updateAttributes=(e=!0)=>{this.transformAttributes(),e&&this.store.commands.forceUpdate("attributes")}}get name(){return"attributes"}onCreate(){this.transformAttributes(),this.store.setExtensionStore("updateAttributes",this.updateAttributes)}transformAttributes(){var e,t,r;if(this.attributeObject=ee(),(e=this.store.managerSettings.exclude)!=null&&e.attributes){this.store.setStoreKey("attributes",this.attributeObject);return}this.attributeList=[];for(const n of this.store.extensions){if((t=n.options.exclude)!=null&&t.attributes)continue;const o=(r=n.createAttributes)==null?void 0:r.call(n),i={...o,class:ju(...n.classNames??[],o==null?void 0:o.class)};this.attributeList.unshift(i)}for(const n of this.attributeList)this.attributeObject={...this.attributeObject,...n,class:ju(this.attributeObject.class,n.class)};this.store.setStoreKey("attributes",this.attributeObject)}};function He(e={}){return(t,r,n)=>{(t.decoratedHelpers??(t.decoratedHelpers={}))[r]=e}}function U(e={}){return(t,r,n)=>{(t.decoratedCommands??(t.decoratedCommands={}))[r]=e}}function je(e){return(t,r,n)=>{(t.decoratedKeybindings??(t.decoratedKeybindings={}))[r]=e}}var $L=class{constructor(e){this.promiseCreator=e,this.failureHandlers=[],this.successHandlers=[],this.validateHandlers=[],this.generateCommand=()=>t=>{let r=!0;const{view:n,tr:o,dispatch:i}=t;if(!n)return!1;for(const a of this.validateHandlers)if(!a({...t,dispatch:()=>{}})){r=!1;break}return!i||!r?r:(this.promiseCreator(t).then(a=>{this.runHandlers(this.successHandlers,{value:a,state:n.state,tr:n.state.tr,dispatch:n.dispatch,view:n})}).catch(a=>{this.runHandlers(this.failureHandlers,{error:a,state:n.state,tr:n.state.tr,dispatch:n.dispatch,view:n})}),i(o),!0)}}validate(e,t="push"){return this.validateHandlers[t](e),this}success(e,t="push"){return this.successHandlers[t](e),this}failure(e,t="push"){return this.failureHandlers[t](e),this}runHandlers(e,t){var r;for(const n of e)if(!n({...t,dispatch:()=>{}}))break;(r=t.dispatch)==null||r.call(t,t.tr)}};function is(e){const{type:t,attrs:r,range:n,selection:o}=e;return i=>{const{dispatch:s,tr:a,state:l}=i,c=oe(t)?l.schema.marks[t]:t;if(re(c,{code:B.SCHEMA,message:`Mark type: ${t} does not exist on the current schema.`}),n||o){const{from:u,to:d}=jr(o??n??a.selection,a.doc);return Pp({trState:a,type:t,...n})?s==null||s(a.removeMark(u,d,c)):s==null||s(a.addMark(u,d,c.create(r))),!0}return bu(cL(c,r))(i)}}function HL(e,t,r){for(const{$from:n,$to:o}of r){let i=n.depth===0?t.type.allowsMarkType(e):!1;if(t.nodesBetween(n.pos,o.pos,s=>{if(i)return!1;i=s.inlineContent&&s.type.allowsMarkType(e)}),i)return!0}return!1}function BL(e,t,r){return({tr:n,dispatch:o,state:i})=>{const s=jr(r??n.selection,n.doc),a=Ez(s),l=oe(e)?i.schema.marks[e]:e;if(re(l,{code:B.SCHEMA,message:`Mark type: ${e} does not exist on the current schema.`}),s.empty&&!a||!HL(l,n.doc,s.ranges))return!1;if(!o)return!0;if(a)return n.removeStoredMark(l),t&&n.addStoredMark(l.create(t)),o(n),!0;let c=!1;for(const{$from:u,$to:d}of s.ranges){if(c)break;c=n.doc.rangeHasMark(u.pos,d.pos,l)}for(const{$from:u,$to:d}of s.ranges)c&&n.removeMark(u.pos,d.pos,l),t&&n.addMark(u.pos,d.pos,l.create(t));return o(n),!0}}function FL(e,t={}){return({tr:r,dispatch:n,state:o})=>{const i=o.schema,s=r.selection,{from:a=s.from,to:l=a??s.to,marks:c={}}=t;if(!n)return!0;r.insertText(e,a,l);const u=it(r.steps,r.steps.length-1).getMap().map(l);for(const[d,f]of At(c))r.addMark(a,u,it(i.marks,d).create(f));return n(r),!0}}var xe=class extends Ve{constructor(){super(...arguments),this.decorated=new Map,this.forceUpdateTransaction=(e,...t)=>{const{forcedUpdates:r}=this.getCommandMeta(e);return this.setCommandMeta(e,{forcedUpdates:Ml([...r,...t])}),e}}get name(){return"commands"}get transaction(){const e=this.store.getState();this._transaction||(this._transaction=e.tr);const t=this._transaction.before.eq(e.doc),r=!Mo(this._transaction.steps);if(!t){const n=e.tr;if(r)for(const o of this._transaction.steps)n.step(o);this._transaction=n}return this._transaction}onCreate(){this.store.setStoreKey("getForcedUpdates",this.getForcedUpdates.bind(this))}onView(e){var t;const{extensions:r,helpers:n}=this.store,o=ee(),i=new Set;let s=ee();const a=c=>{var u;const d=ee(),f=()=>c??this.transaction;let p=[];const h=()=>p;for(const[b,v]of Object.entries(o))(u=s[b])!=null&&u.disableChaining||(d[b]=this.chainedFactory({chain:d,command:v.original,getTr:f,getChain:h}));const m=b=>{re(b===f(),{message:"Chaining currently only supports `CommandFunction` methods which do not use the `state.tr` property. Instead you should use the provided `tr` property."})};return d.run=(b={})=>{const v=p;p=[];for(const g of v)if(!g(m)&&b.exitEarly)return;e.dispatch(f())},d.tr=()=>{const b=p;p=[];for(const v of b)v(m);return f()},d.enabled=()=>{for(const b of p)if(!b())return!1;return!0},d.new=b=>a(b),d};for(const c of r){const u=((t=c.createCommands)==null?void 0:t.call(c))??{},d=c.decoratedCommands??{},f={};s={...s,decoratedCommands:d};for(const[p,h]of Object.entries(d)){const m=oe(h.shortcut)&&h.shortcut.startsWith("_|")?{shortcut:n.getNamedShortcut(h.shortcut,c.options)}:void 0;this.updateDecorated(p,{...h,name:c.name,...m}),u[p]=c[p].bind(c),h.active&&(f[p]=()=>{var b;return((b=h.active)==null?void 0:b.call(h,c.options,this.store))??!1})}vp(u)||this.addCommands({active:f,names:i,commands:o,extensionCommands:u})}const l=a();for(const[c,u]of Object.entries(l))a[c]=u;this.store.setStoreKey("commands",o),this.store.setStoreKey("chain",a),this.store.setExtensionStore("commands",o),this.store.setExtensionStore("chain",a)}onStateUpdate({state:e}){this._transaction=e.tr}createPlugin(){return{}}customDispatch(e){return e}insertText(e,t={}){return oe(e)?FL(e,t):this.store.createPlaceholderCommand({promise:e,placeholder:{type:"inline"},onSuccess:(r,n,o)=>this.insertText(r,{...t,...n})(o)}).generateCommand()}selectText(e,t={}){return({tr:r,dispatch:n})=>{const o=jr(e,r.doc);return r.selection.anchor===o.anchor&&r.selection.head===o.head&&!t.forceUpdate?!1:(n==null||n(r.setSelection(o)),!0)}}selectMark(e){return t=>{const{tr:r}=t,n=_o(r.selection.$from,e);return n?this.store.commands.selectText.original({from:n.from,to:n.to})(t):!1}}delete(e){return({tr:t,dispatch:r})=>{const{from:n,to:o}=e??t.selection;return r==null||r(t.delete(n,o)),!0}}emptyUpdate(e){return({tr:t,dispatch:r})=>(r&&(e==null||e(),r(t)),!0)}forceUpdate(...e){return({tr:t,dispatch:r})=>(r==null||r(this.forceUpdateTransaction(t,...e)),!0)}updateNodeAttributes(e,t){return({tr:r,dispatch:n})=>(n==null||n(r.setNodeMarkup(e,void 0,t)),!0)}setContent(e,t){return r=>{const{tr:n,dispatch:o}=r,i=this.store.manager.createState({content:e,selection:t});return i?(o==null||o(n.replaceRangeWith(0,n.doc.nodeSize-2,i.doc)),!0):!1}}resetContent(){return e=>{const{tr:t,dispatch:r}=e,n=this.store.manager.createEmptyDoc();return n?this.setContent(n)(e):(r==null||r(t.delete(0,t.doc.nodeSize)),!0)}}emptySelection(){return({tr:e,dispatch:t})=>e.selection.empty?!1:(t==null||t(e.setSelection(le.near(e.selection.$anchor))),!0)}insertNewLine(){return({dispatch:e,tr:t})=>ms(t.selection)?(e==null||e(t.insertText(` +`)),!0):!1}insertNode(e,t={}){return({dispatch:r,tr:n,state:o})=>{var i;const{attrs:s,range:a,selection:l,replaceEmptyParentBlock:c=!1}=t,{from:u,to:d,$from:f}=jr(l??a??n.selection,n.doc);if(Id(e)||pz(e)){const v=f.before(f.depth);return r==null||r(c&&u===d&&Fh(f.parent)?n.replaceWith(v,v+f.parent.nodeSize,e):n.replaceWith(u,d,e)),!0}const p=oe(e)?o.schema.nodes[e]:e;re(p,{code:B.SCHEMA,message:`The requested node type ${e} does not exist in the schema.`});const h=(i=t.marks)==null?void 0:i.map(v=>{if(v instanceof Te)return v;const g=oe(v)?o.schema.marks[v]:v;return re(g,{code:B.SCHEMA,message:`The requested mark type ${v} does not exist in the schema.`}),g.create()}),m=p.createAndFill(s,oe(t.content)?o.schema.text(t.content):t.content,h);if(!m)return!1;const b=u!==d;return r==null||r(b?n.replaceRangeWith(u,d,m):n.insert(u,m)),!0}}focus(e){return t=>{const{dispatch:r,tr:n}=t,{view:o}=this.store;if(e===!1||o.hasFocus()&&(e===void 0||e===!0))return!1;if(e===void 0||e===!0){const{from:i=0,to:s=i}=n.selection;e={from:i,to:s}}return r&&this.delayedFocus(),this.selectText(e)(t)}}blur(e){return t=>{const{view:r}=this.store;return r.hasFocus()?(requestAnimationFrame(()=>{r.dom.blur()}),e?this.selectText(e)(t):!0):!1}}setBlockNodeType(e,t,r,n=!0){return Fu(e,t,r,n)}toggleWrappingNode(e,t,r){return $C(e,t,r)}toggleBlockNodeItem(e){return Yv(e)}wrapInNode(e,t,r){return DC(e,t,r)}applyMark(e,t,r){return BL(e,t,r)}toggleMark(e){return is(e)}removeMark(e){return BC(e)}setMeta(e,t){return({tr:r})=>(r.setMeta(e,t),!0)}selectAll(){return this.selectText("all")}copy(){return e=>e.tr.selection.empty?!1:(e.dispatch&&document.execCommand("copy"),!0)}paste(){return this.store.createPlaceholderCommand({promise:async()=>{var e;return(e=navigator.clipboard)!=null&&e.readText?await navigator.clipboard.readText():""},placeholder:{type:"inline"},onSuccess:(e,t,r)=>this.insertNode(U1({content:e,schema:r.state.schema}),{selection:t})(r)}).generateCommand()}cut(){return e=>e.tr.selection.empty?!1:(e.dispatch&&document.execCommand("cut"),!0)}replaceText(e){return $z(e)}getAllCommandOptions(){const e={};for(const[t,r]of this.decorated)vp(r)||(e[t]=r);return e}getCommandOptions(e){return this.decorated.get(e)}getCommandProp(){return{tr:this.transaction,dispatch:this.store.view.dispatch,state:this.store.view.state,view:this.store.view}}updateDecorated(e,t){if(!t){this.decorated.delete(e);return}const r=this.decorated.get(e)??{name:""};this.decorated.set(e,{...r,...t})}handleIosFocus(){on.isIos&&this.store.view.dom.focus()}delayedFocus(){this.handleIosFocus(),requestAnimationFrame(()=>{this.store.view.focus(),this.store.view.dispatch(this.transaction.scrollIntoView())})}getForcedUpdates(e){return this.getCommandMeta(e).forcedUpdates}getCommandMeta(e){const t=e.getMeta(this.pluginKey)??{};return{...VL,...t}}setCommandMeta(e,t){const r=this.getCommandMeta(e);e.setMeta(this.pluginKey,{...r,...t})}addCommands(e){const{extensionCommands:t,commands:r,names:n,active:o}=e;for(const[i,s]of At(t))QC({name:i,set:n,code:B.DUPLICATE_COMMAND_NAMES}),re(!jL.has(i),{code:B.DUPLICATE_COMMAND_NAMES,message:"The command name you chose is forbidden."}),r[i]=this.createUnchainedCommand(s,o[i])}unchainedFactory(e){return(...t)=>{const{shouldDispatch:r=!0,command:n}=e,{view:o}=this.store,{state:i}=o;let s;return r&&(s=o.dispatch),n(...t)({state:i,dispatch:s,view:o,tr:i.tr})}}createUnchainedCommand(e,t){const r=this.unchainedFactory({command:e});return r.enabled=this.unchainedFactory({command:e,shouldDispatch:!1}),r.isEnabled=r.enabled,r.original=e,r.active=t,r}chainedFactory(e){return(...t)=>{const{chain:r,command:n,getTr:o,getChain:i}=e,s=i(),{view:a}=this.store,{state:l}=a;return s.push(c=>n(...t)({state:l,dispatch:c,view:a,tr:o()})),r}}};Z([U()],xe.prototype,"customDispatch",1);Z([U()],xe.prototype,"insertText",1);Z([U()],xe.prototype,"selectText",1);Z([U()],xe.prototype,"selectMark",1);Z([U()],xe.prototype,"delete",1);Z([U()],xe.prototype,"emptyUpdate",1);Z([U()],xe.prototype,"forceUpdate",1);Z([U()],xe.prototype,"updateNodeAttributes",1);Z([U()],xe.prototype,"setContent",1);Z([U()],xe.prototype,"resetContent",1);Z([U()],xe.prototype,"emptySelection",1);Z([U()],xe.prototype,"insertNewLine",1);Z([U()],xe.prototype,"insertNode",1);Z([U()],xe.prototype,"focus",1);Z([U()],xe.prototype,"blur",1);Z([U()],xe.prototype,"setBlockNodeType",1);Z([U()],xe.prototype,"toggleWrappingNode",1);Z([U()],xe.prototype,"toggleBlockNodeItem",1);Z([U()],xe.prototype,"wrapInNode",1);Z([U()],xe.prototype,"applyMark",1);Z([U()],xe.prototype,"toggleMark",1);Z([U()],xe.prototype,"removeMark",1);Z([U()],xe.prototype,"setMeta",1);Z([U({description:({t:e})=>e(ts.SELECT_ALL_DESCRIPTION),label:({t:e})=>e(ts.SELECT_ALL_LABEL),shortcut:$.SelectAll})],xe.prototype,"selectAll",1);Z([U({description:({t:e})=>e(ts.COPY_DESCRIPTION),label:({t:e})=>e(ts.COPY_LABEL),shortcut:$.Copy,icon:"fileCopyLine"})],xe.prototype,"copy",1);Z([U({description:({t:e})=>e(ts.PASTE_DESCRIPTION),label:({t:e})=>e(ts.PASTE_LABEL),shortcut:$.Paste,icon:"clipboardLine"})],xe.prototype,"paste",1);Z([U({description:({t:e})=>e(ts.CUT_DESCRIPTION),label:({t:e})=>e(ts.CUT_LABEL),shortcut:$.Cut,icon:"scissorsFill"})],xe.prototype,"cut",1);Z([U()],xe.prototype,"replaceText",1);Z([He()],xe.prototype,"getAllCommandOptions",1);Z([He()],xe.prototype,"getCommandOptions",1);Z([He()],xe.prototype,"getCommandProp",1);xe=Z([pe({defaultPriority:Ae.Highest,defaultOptions:{trackerClassName:"remirror-tracker-position",trackerNodeName:"span"},staticKeys:["trackerClassName","trackerNodeName"]})],xe);var VL={forcedUpdates:[]},jL=new Set(["run","chain","original","raw","enabled","tr","new"]),io=class extends Ve{constructor(){super(...arguments),this.placeholders=Ee.empty,this.placeholderWidgets=new Map,this.createPlaceholderCommand=e=>{const t=Cl(),{promise:r,placeholder:n,onFailure:o,onSuccess:i}=e;return new $L(r).validate(s=>this.addPlaceholder(t,n)(s)).success(s=>{const{state:a,tr:l,dispatch:c,view:u,value:d}=s,f=this.store.helpers.findPlaceholder(t);if(!f){const p=new Error("The placeholder has been removed");return(o==null?void 0:o({error:p,state:a,tr:l,dispatch:c,view:u}))??!1}return this.removePlaceholder(t)({state:a,tr:l,view:u,dispatch:()=>{}}),i(d,f,{state:a,tr:l,dispatch:c,view:u})}).failure(s=>(this.removePlaceholder(t)({...s,dispatch:()=>{}}),(o==null?void 0:o(s))??!1))}}get name(){return"decorations"}onCreate(){this.store.setExtensionStore("createPlaceholderCommand",this.createPlaceholderCommand)}createPlugin(){return{state:{init:()=>{},apply:e=>{var t,r,n,o,i,s;const{added:a,clearTrackers:l,removed:c,updated:u}=this.getMeta(e);if(l){this.placeholders=Ee.empty;for(const[,d]of this.placeholderWidgets)(r=(t=d.spec).onDestroy)==null||r.call(t,this.store.view,d.spec.element);this.placeholderWidgets.clear();return}this.placeholders=this.placeholders.map(e.mapping,e.doc,{onRemove:d=>{var f,p;const h=this.placeholderWidgets.get(d.id);h&&((p=(f=h.spec).onDestroy)==null||p.call(f,this.store.view,h.spec.element))}});for(const[,d]of this.placeholderWidgets)(o=(n=d.spec).onUpdate)==null||o.call(n,this.store.view,d.from,d.spec.element,d.spec.data);for(const d of a){if(d.type==="inline"){this.addInlinePlaceholder(d,e);continue}if(d.type==="node"){this.addNodePlaceholder(d,e);continue}if(d.type==="widget"){this.addWidgetPlaceholder(d,e);continue}}for(const{id:d,data:f}of u){const p=this.placeholderWidgets.get(d);if(!p)continue;const h=Ge.widget(p.from,p.spec.element,{...p.spec,data:f});this.placeholders=this.placeholders.remove([p]).add(e.doc,[h]),this.placeholderWidgets.set(d,h)}for(const d of c){const f=this.placeholders.find(void 0,void 0,h=>h.id===d&&h.__type===Na),p=this.placeholderWidgets.get(d);p&&((s=(i=p.spec).onDestroy)==null||s.call(i,this.store.view,p.spec.element)),this.placeholders=this.placeholders.remove(f),this.placeholderWidgets.delete(d)}}},props:{decorations:e=>{let t=this.options.decorations(e);t=t.add(e.doc,this.placeholders.find());for(const r of this.store.extensions){if(!r.createDecorations)continue;const n=r.createDecorations(e).find();t=t.add(e.doc,n)}return t},handleDOMEvents:{blur:e=>(this.options.persistentSelectionClass&&e.dispatch(e.state.tr.setMeta(m2,!1)),!1),focus:e=>(this.options.persistentSelectionClass&&e.dispatch(e.state.tr.setMeta(m2,!0)),!1)}}}}updateDecorations(){return({tr:e,dispatch:t})=>(t==null||t(e),!0)}addPlaceholder(e,t,r){return({dispatch:n,tr:o})=>this.addPlaceholderTransaction(e,t,o,!n)?(n==null||n(r?o.deleteSelection():o),!0):!1}updatePlaceholder(e,t){return({dispatch:r,tr:n})=>this.updatePlaceholderTransaction({id:e,data:t,tr:n,checkOnly:!r})?(r==null||r(n),!0):!1}removePlaceholder(e){return({dispatch:t,tr:r})=>this.removePlaceholderTransaction({id:e,tr:r,checkOnly:!t})?(t==null||t(r),!0):!1}clearPlaceholders(){return({tr:e,dispatch:t})=>this.clearPlaceholdersTransaction({tr:e,checkOnly:!t})?(t==null||t(e),!0):!1}findPlaceholder(e){return this.findAllPlaceholders().get(e)}findAllPlaceholders(){const e=new Map,t=this.placeholders.find(void 0,void 0,r=>r.__type===Na);for(const r of t)e.set(r.spec.id,{from:r.from,to:r.to});return e}createDecorations(e){var t,r,n;const{persistentSelectionClass:o}=this.options;return!o||(t=this.store.view)!=null&&t.hasFocus()||(n=(r=this.store.helpers).isInteracting)!=null&&n.call(r)?Ee.empty:WL(e,Ee.empty,{class:oe(o)?o:"selection"})}onApplyState(){}addWidgetPlaceholder(e,t){const{pos:r,createElement:n,onDestroy:o,onUpdate:i,className:s,nodeName:a,id:l,type:c}=e,u=(n==null?void 0:n(this.store.view,r))??document.createElement(a);u.classList.add(s);const d=Ge.widget(r,u,{id:l,__type:Na,type:c,element:u,onDestroy:o,onUpdate:i});this.placeholderWidgets.set(l,d),this.placeholders=this.placeholders.add(t.doc,[d])}addInlinePlaceholder(e,t){const{from:r=t.selection.from,to:n=t.selection.to,className:o,nodeName:i,id:s,type:a}=e;let l;if(r===n){const c=document.createElement(i);c.classList.add(o),l=Ge.widget(r,c,{id:s,type:a,__type:Na,widget:c})}else l=Ge.inline(r,n,{nodeName:i,class:o},{id:s,__type:Na});this.placeholders=this.placeholders.add(t.doc,[l])}addNodePlaceholder(e,t){const{pos:r,className:n,nodeName:o,id:i}=e,s=Jt(r)?t.doc.resolve(r):t.selection.$from,a=Jt(r)?s.nodeAfter?{pos:r,end:s.nodeAfter.nodeSize}:void 0:nz(s);if(!a)return;const l=Ge.node(a.pos,a.end,{nodeName:o,class:n},{id:i,__type:Na});this.placeholders=this.placeholders.add(t.doc,[l])}withRequiredBase(e,t){const{placeholderNodeName:r,placeholderClassName:n}=this.options,{nodeName:o=r,className:i,...s}=t,a=(i?[n,i]:[n]).join(" ");return{nodeName:o,className:a,...s,id:e}}getMeta(e){const t=e.getMeta(this.pluginKey)??{};return{...UL,...t}}setMeta(e,t){const r=this.getMeta(e);e.setMeta(this.pluginKey,{...r,...t})}addPlaceholderTransaction(e,t,r,n=!1){if(this.findPlaceholder(e))return!1;if(n)return!0;const{added:i}=this.getMeta(r);return this.setMeta(r,{added:[...i,this.withRequiredBase(e,t)]}),!0}updatePlaceholderTransaction(e){const{id:t,tr:r,checkOnly:n=!1,data:o}=e;if(!this.findPlaceholder(t))return!1;if(n)return!0;const{updated:s}=this.getMeta(r);return this.setMeta(r,{updated:Ml([...s,{id:t,data:o}])}),!0}removePlaceholderTransaction(e){const{id:t,tr:r,checkOnly:n=!1}=e;if(!this.findPlaceholder(t))return!1;if(n)return!0;const{removed:i}=this.getMeta(r);return this.setMeta(r,{removed:Ml([...i,t])}),!0}clearPlaceholdersTransaction(e){const{tr:t,checkOnly:r=!1}=e;return this.getPluginState()===Ee.empty?!1:(r||this.setMeta(t,{clearTrackers:!0}),!0)}};Z([U()],io.prototype,"updateDecorations",1);Z([U()],io.prototype,"addPlaceholder",1);Z([U()],io.prototype,"updatePlaceholder",1);Z([U()],io.prototype,"removePlaceholder",1);Z([U()],io.prototype,"clearPlaceholders",1);Z([He()],io.prototype,"findPlaceholder",1);Z([He()],io.prototype,"findAllPlaceholders",1);io=Z([pe({defaultOptions:{persistentSelectionClass:void 0,placeholderClassName:"placeholder",placeholderNodeName:"span"},staticKeys:["placeholderClassName","placeholderNodeName"],handlerKeys:["decorations"],handlerKeyOptions:{decorations:{reducer:{accumulator:(e,t,r)=>e.add(r.doc,t.find()),getDefault:()=>Ee.empty}}},defaultPriority:Ae.Low})],io);var UL={added:[],updated:[],clearTrackers:!1,removed:[]},Na="placeholderDecoration",m2="persistentSelectionFocus";function WL(e,t,r){const{selection:n,doc:o}=e;if(n.empty)return t;const{from:i,to:s}=n,a=Dd(n)?Ge.node(i,s,r):Ge.inline(i,s,r);return t.add(o,[a])}var K1=class extends Ve{get name(){return"docChanged"}onStateUpdate(e){const{firstUpdate:t,transactions:r,tr:n}=e;t||(r??[n]).some(o=>o==null?void 0:o.docChanged)&&this.options.docChanged(e)}};K1=Z([pe({handlerKeys:["docChanged"],handlerKeyOptions:{docChanged:{earlyReturnValue:!1}},defaultPriority:Ae.Lowest})],K1);var Rn=class extends Ve{get name(){return"helpers"}onCreate(){var e;this.store.setStringHandler("text",this.textToProsemirrorNode.bind(this)),this.store.setStringHandler("html",U1);const t=ee(),r=ee(),n=ee(),o=new Set;for(const i of this.store.extensions){Hd(i)&&(r[i.name]=a=>EC({state:this.store.getState(),type:i.type,attrs:a}),n[i.name]=a=>{var l;return(l=Bu({state:this.store.getState(),type:i.type,attrs:a}))==null?void 0:l.node.attrs}),Kh(i)&&(r[i.name]=a=>Pp({trState:this.store.getState(),type:i.type,attrs:a}),n[i.name]=a=>{const l=_o(this.store.getState().selection.$from,i.type);if(!l||!a)return l==null?void 0:l.mark.attrs;if(Wv(l.mark,a))return l.mark.attrs});const s=((e=i.createHelpers)==null?void 0:e.call(i))??{};for(const a of Object.keys(i.decoratedHelpers??{}))s[a]=i[a].bind(i);if(!vp(s))for(const[a,l]of At(s))QC({name:a,set:o,code:B.DUPLICATE_HELPER_NAMES}),t[a]=l}this.store.setStoreKey("attrs",n),this.store.setStoreKey("active",r),this.store.setStoreKey("helpers",t),this.store.setExtensionStore("attrs",n),this.store.setExtensionStore("active",r),this.store.setExtensionStore("helpers",t)}isSelectionEmpty(e=this.store.getState()){return Uv(e)}isViewEditable(e=this.store.getState()){var t,r;return((r=(t=this.store.view.props).editable)==null?void 0:r.call(t,e))??!1}getStateJSON(e=this.store.getState()){return e.toJSON()}getJSON(e=this.store.getState()){return e.doc.toJSON()}getRemirrorJSON(e=this.store.getState()){return this.getJSON(e)}insertHtml(e,t){return r=>{const{state:n}=r,o=U1({content:e,schema:n.schema,fragment:!0});return this.store.commands.insertNode.original(o,t)(r)}}getText({lineBreakDivider:e=` + +`,state:t=this.store.getState()}={}){return t.doc.textBetween(0,t.doc.content.size,e,Li)}getTextBetween(e,t,r=this.store.getState().doc){return r.textBetween(e,t,` + +`,Li)}getHTML(e=this.store.getState()){return Az(e.doc,this.store.document)}textToProsemirrorNode(e){const t=`
${e.content}
`;return this.store.stringHandlers.html({...e,content:t})}};Z([He()],Rn.prototype,"isSelectionEmpty",1);Z([He()],Rn.prototype,"isViewEditable",1);Z([He()],Rn.prototype,"getStateJSON",1);Z([He()],Rn.prototype,"getJSON",1);Z([He()],Rn.prototype,"getRemirrorJSON",1);Z([U()],Rn.prototype,"insertHtml",1);Z([He()],Rn.prototype,"getText",1);Z([He()],Rn.prototype,"getTextBetween",1);Z([He()],Rn.prototype,"getHTML",1);Rn=Z([pe({})],Rn);var q1=class extends Ve{get name(){return"inputRules"}onCreate(){this.store.setExtensionStore("rebuildInputRules",this.rebuildInputRules.bind(this))}createExternalPlugins(){return[this.generateInputRulesPlugin()]}generateInputRulesPlugin(){var e,t;const r=[],n=this.store.markTags[te.ExcludeInputRules];for(const o of this.store.extensions)if(!((e=this.store.managerSettings.exclude)!=null&&e.inputRules||!o.createInputRules||(t=o.options.exclude)!=null&&t.inputRules))for(const i of o.createInputRules())i.shouldSkip=this.options.shouldSkipInputRule,i.invalidMarks=n,r.push(i);return jR({rules:r})}rebuildInputRules(){this.store.updateExtensionPlugins(this)}};q1=Z([pe({defaultPriority:Ae.Default,handlerKeys:["shouldSkipInputRule"],handlerKeyOptions:{shouldSkipInputRule:{earlyReturnValue:!0}}})],q1);var Qn=class extends Ve{constructor(){super(...arguments),this.extraKeyBindings=[],this.backwardMarkExitTracker=new Map,this.keydownHandler=null,this.onAddCustomHandler=({keymap:e})=>{var t,r;if(e)return this.extraKeyBindings=[...this.extraKeyBindings,e],(r=(t=this.store).rebuildKeymap)==null||r.call(t),()=>{var n,o;this.extraKeyBindings=this.extraKeyBindings.filter(i=>i!==e),(o=(n=this.store).rebuildKeymap)==null||o.call(n)}},this.rebuildKeymap=()=>{this.setupKeydownHandler()}}get name(){return"keymap"}get shortcutMap(){const{shortcuts:e}=this.options;return oe(e)?YL[e]:e}onCreate(){this.store.setExtensionStore("rebuildKeymap",this.rebuildKeymap)}createExternalPlugins(){var e;return(e=this.store.managerSettings.exclude)!=null&&e.keymap?[]:(this.setupKeydownHandler(),[new Ro({props:{handleKeyDown:(t,r)=>{var n;return(n=this.keydownHandler)==null?void 0:n.call(this,t,r)}}})])}setupKeydownHandler(){const e=this.generateKeymapBindings();this.keydownHandler=Xv(e)}generateKeymapBindings(){var e;const t=[],r=this.shortcutMap,n=this.store.getExtension(xe),o=a=>l=>Bf({shortcut:l,map:r,store:this.store,options:a.options});for(const a of this.store.extensions){const l=a.decoratedKeybindings??{};if(!((e=a.options.exclude)!=null&&e.keymap)){a.createKeymap&&t.push(qL(a.createKeymap(o(a)),r));for(const[c,u]of At(l)){if(u.isActive&&!u.isActive(a.options,this.store))continue;const d=a[c].bind(a),f=Bf({shortcut:u.shortcut,map:r,options:a.options,store:this.store}),p=_e(u.priority)?u.priority(a.options,this.store):u.priority??Ae.Low,h=ee();for(const m of f)h[m]=d;t.push([p,h]),u.command&&n.updateDecorated(u.command,{shortcut:f})}}}const i=this.sortKeymaps([...this.extraKeyBindings,...t]);return lz(i)}arrowRightShortcut(e){const t=this.store.markTags[te.PreventExits],r=this.store.nodeTags[te.PreventExits];return this.exitMarkForwards(t,r)(e)}arrowLeftShortcut(e){const t=this.store.markTags[te.PreventExits],r=this.store.nodeTags[te.PreventExits];return Rp(this.exitNodeBackwards(r),this.exitMarkBackwards(t,r))(e)}backspace(e){const t=this.store.markTags[te.PreventExits],r=this.store.nodeTags[te.PreventExits];return Rp(this.exitNodeBackwards(r,!0),this.exitMarkBackwards(t,r,!0))(e)}createKeymap(){const{selectParentNodeOnEscape:e,undoInputRuleOnBackspace:t,excludeBaseKeymap:r}=this.options,n=ee();if(!r)for(const[o,i]of At(wg))n[o]=bu(i);return t&&wg.Backspace&&(n.Backspace=bu(jh(UR,wg.Backspace))),e&&(n.Escape=bu(nL)),[Ae.Low,n]}getNamedShortcut(e,t={}){return e.startsWith("_|")?Bf({shortcut:e,map:this.shortcutMap,store:this.store,options:t}):[e]}onSetOptions(e){var t,r;const{changes:n}=e;(n.excludeBaseKeymap.changed||n.selectParentNodeOnEscape.changed||n.undoInputRuleOnBackspace.changed)&&((r=(t=this.store).rebuildKeymap)==null||r.call(t))}sortKeymaps(e){return ta(e.map(t=>ct(t)?t:[Ae.Default,t]),(t,r)=>r[0]-t[0]).map(t=>t[1])}exitMarkForwards(e,t){return r=>{const{tr:n,dispatch:o}=r;if(!Pz(n.selection)||rs({selection:n.selection,types:t}))return!1;const a=n.selection.$from.marks().filter(l=>!e.includes(l.type.name));if(Mo(a))return!1;if(!o)return!0;for(const l of a)n.removeStoredMark(l);return o(n.insertText(" ",n.selection.from)),!0}}exitNodeBackwards(e,t=!1){return r=>{const{tr:n}=r;if(!(t?d2:W1)(n.selection))return!1;const i=n.selection.$anchor.node();return!Fh(i)||yz(i)||e.includes(i.type.name)?!1:this.store.commands.toggleBlockNodeItem.original({type:i.type})(r)}}exitMarkBackwards(e,t,r=!1){return n=>{const{tr:o,dispatch:i}=n;if(!(r?d2:W1)(o.selection)||this.backwardMarkExitTracker.has(o.selection.anchor))return this.backwardMarkExitTracker.clear(),!1;if(rs({selection:o.selection,types:t}))return!1;const l=[...o.storedMarks??[],...o.selection.$from.marks()].filter(c=>!e.includes(c.type.name));if(Mo(l))return!1;if(!i)return!0;for(const c of l)o.removeStoredMark(c);return this.backwardMarkExitTracker.set(o.selection.anchor,!0),i(o),!0}}};Z([je({shortcut:"ArrowRight",isActive:e=>e.exitMarksOnArrowPress})],Qn.prototype,"arrowRightShortcut",1);Z([je({shortcut:"ArrowLeft",isActive:e=>e.exitMarksOnArrowPress})],Qn.prototype,"arrowLeftShortcut",1);Z([je({shortcut:"Backspace",isActive:e=>e.exitMarksOnArrowPress})],Qn.prototype,"backspace",1);Z([He()],Qn.prototype,"getNamedShortcut",1);Qn=Z([pe({defaultPriority:Ae.Low,defaultOptions:{shortcuts:"default",undoInputRuleOnBackspace:!0,selectParentNodeOnEscape:!1,excludeBaseKeymap:!1,exitMarksOnArrowPress:!0},customHandlerKeys:["keymap"]})],Qn);function KL(e){return fr(Nh($),e)}function Bf({shortcut:e,map:t,options:r,store:n}){return oe(e)?[G1(e,t)]:ct(e)?e.map(o=>G1(o,t)):(e=e(r,n),Bf({shortcut:e,map:t,options:r,store:n}))}function G1(e,t){return KL(e)?t[e]:e}function qL(e,t){const r={};let n,o;ct(e)?[o,n]=e:n=e;for(const[i,s]of At(n))r[G1(i,t)]=s;return Rh(o)?r:[o,r]}var t5={[$.Copy]:"Mod-c",[$.Cut]:"Mod-x",[$.Paste]:"Mod-v",[$.PastePlain]:"Mod-Shift-v",[$.SelectAll]:"Mod-a",[$.Undo]:"Mod-z",[$.Redo]:on.isMac?"Shift-Mod-z":"Mod-y",[$.Bold]:"Mod-b",[$.Italic]:"Mod-i",[$.Underline]:"Mod-u",[$.Strike]:"Mod-d",[$.Code]:"Mod-`",[$.Paragraph]:"Mod-Shift-0",[$.H1]:"Mod-Shift-1",[$.H2]:"Mod-Shift-2",[$.H3]:"Mod-Shift-3",[$.H4]:"Mod-Shift-4",[$.H5]:"Mod-Shift-5",[$.H6]:"Mod-Shift-6",[$.TaskList]:"Mod-Shift-7",[$.BulletList]:"Mod-Shift-8",[$.OrderedList]:"Mod-Shift-9",[$.Quote]:"Mod->",[$.Divider]:"Mod-Shift-|",[$.Codeblock]:"Mod-Shift-~",[$.ClearFormatting]:"Mod-Shift-C",[$.Superscript]:"Mod-.",[$.Subscript]:"Mod-,",[$.LeftAlignment]:"Mod-Shift-L",[$.CenterAlignment]:"Mod-Shift-E",[$.RightAlignment]:"Mod-Shift-R",[$.JustifyAlignment]:"Mod-Shift-J",[$.InsertLink]:"Mod-k",[$.Find]:"Mod-f",[$.FindBackwards]:"Mod-Shift-f",[$.FindReplace]:"Mod-Shift-H",[$.AddFootnote]:"Mod-Alt-f",[$.AddComment]:"Mod-Alt-m",[$.ContextMenu]:"Mod-Shift-\\",[$.IncreaseFontSize]:"Mod-Shift-.",[$.DecreaseFontSize]:"Mod-Shift-,",[$.IncreaseIndent]:"Tab",[$.DecreaseIndent]:"Shift-Tab",[$.Shortcuts]:"Mod-/",[$.Format]:on.isMac?"Alt-Shift-f":"Shift-Ctrl-f"},GL={...t5,[$.Strike]:"Mod-Shift-S",[$.Code]:"Mod-Shift-M",[$.Paragraph]:"Mod-Alt-0",[$.H1]:"Mod-Alt-1",[$.H2]:"Mod-Alt-2",[$.H3]:"Mod-Alt-3",[$.H4]:"Mod-Alt-4",[$.H5]:"Mod-Alt-5",[$.H6]:"Mod-Alt-6",[$.OrderedList]:"Mod-Alt-7",[$.BulletList]:"Mod-Alt-8",[$.Quote]:"Mod-Alt-9",[$.ClearFormatting]:"Mod-\\",[$.IncreaseIndent]:"Mod-[",[$.DecreaseIndent]:"Mod-]"},YL={default:t5,googleDoc:GL},JL=class extends Ve{get name(){return"nodeViews"}createPlugin(){const e=[],t=ee();for(const r of this.store.extensions){if(!r.createNodeViews)continue;const n=r.createNodeViews();e.unshift(_e(n)?{[r.name]:n}:n)}e.unshift(this.store.managerSettings.nodeViews??{});for(const r of e)Object.assign(t,r);return{props:{nodeViews:t}}}},XL=class extends Ve{get name(){return"pasteRules"}createExternalPlugins(){return[this.generatePasteRulesPlugin()]}generatePasteRulesPlugin(){var e,t;const r=[];for(const n of this.store.extensions){if((e=this.store.managerSettings.exclude)!=null&&e.pasteRules||!n.createPasteRules||(t=n.options.exclude)!=null&&t.pasteRules)continue;const o=n.createPasteRules(),i=ct(o)?o:[o];r.push(...i)}return vL(r)}},Lp=class extends Ve{constructor(){super(...arguments),this.plugins=[],this.managerPlugins=[],this.applyStateHandlers=[],this.initStateHandlers=[],this.appendTransactionHandlers=[],this.pluginKeys=ee(),this.stateGetters=new Map,this.getPluginStateCreator=e=>t=>e.getState(t??this.store.getState()),this.getStateByName=e=>{const t=this.stateGetters.get(e);return re(t,{message:"No plugin exists for the requested extension name."}),t()}}get name(){return"plugins"}onCreate(){const{setStoreKey:e,setExtensionStore:t,managerSettings:r,extensions:n}=this.store;this.updateExtensionStore();const{plugins:o=[]}=r;this.updatePlugins(o,this.managerPlugins);for(const i of n)i.onApplyState&&this.applyStateHandlers.push(i.onApplyState.bind(i)),i.onInitState&&this.initStateHandlers.push(i.onInitState.bind(i)),i.onAppendTransaction&&this.appendTransactionHandlers.push(i.onAppendTransaction.bind(i)),this.extractExtensionPlugins(i);this.managerPlugins=o,this.store.setStoreKey("plugins",this.plugins),e("pluginKeys",this.pluginKeys),e("getPluginState",this.getStateByName),t("getPluginState",this.getStateByName)}createPlugin(){return{appendTransaction:(e,t,r)=>{const n=r.tr,o={previousState:t,tr:n,transactions:e,state:r};for(const i of this.appendTransactionHandlers)i(o);return this.options.appendTransaction(o),n.docChanged||n.steps.length>0||n.selectionSet||n.storedMarksSet?n:void 0},state:{init:(e,t)=>{for(const r of this.initStateHandlers)r(t)},apply:(e,t,r,n)=>{const o={previousState:r,state:n,tr:e};for(const i of this.applyStateHandlers)i(o);this.options.applyState(o)}}}}extractExtensionPlugins(e){var t,r;if(!(!e.createPlugin&&!e.createExternalPlugins||(t=this.store.managerSettings.exclude)!=null&&t.plugins||(r=e.options.exclude)!=null&&r.plugins)){if(e.createPlugin){const o=new ka(e.name);this.pluginKeys[e.name]=o;const i=this.getPluginStateCreator(o);e.pluginKey=o,e.getPluginState=i,this.stateGetters.set(e.name,i),this.stateGetters.set(e.constructor,i);const s={...e.createPlugin(),key:o},a=new Ro(s);this.updatePlugins([a],e.plugin?[e.plugin]:void 0),e.plugin=a}if(e.createExternalPlugins){const o=e.createExternalPlugins();this.updatePlugins(o,e.externalPlugins),e.externalPlugins=o}}}updatePlugins(e,t){if(!t||Mo(t)){this.plugins=[...this.plugins,...e];return}if(e.length!==t.length){this.plugins=[...this.plugins.filter(n=>!t.includes(n)),...e];return}const r=new Map;for(const[n,o]of e.entries())r.set(it(t,n),o);this.plugins=this.plugins.map(n=>t.includes(n)?r.get(n):n)}updateExtensionStore(){const{setExtensionStore:e}=this.store;e("updatePlugins",this.updatePlugins.bind(this)),e("dispatchPluginUpdate",this.dispatchPluginUpdate.bind(this)),e("updateExtensionPlugins",this.updateExtensionPlugins.bind(this))}updateExtensionPlugins(e){const t=ZC(e)?e:IL(e)?this.store.manager.getExtension(e):this.store.extensions.find(r=>r.name===e);re(t,{code:B.INVALID_MANAGER_EXTENSION,message:`The extension ${e} does not exist within the editor.`}),this.extractExtensionPlugins(t),this.store.setStoreKey("plugins",this.plugins),this.dispatchPluginUpdate()}dispatchPluginUpdate(){re(this.store.phase>=Nr.EditorView,{code:B.MANAGER_PHASE_ERROR,message:"`dispatchPluginUpdate` should only be called after the view has been added to the manager."});const{view:e,updateState:t}=this.store,r=e.state.reconfigure({plugins:this.plugins});t(r)}};Lp=Z([pe({defaultPriority:Ae.Highest,handlerKeys:["applyState","appendTransaction"]})],Lp);var Y1=class extends Ve{constructor(){super(...arguments),this.dynamicAttributes={marks:ee(),nodes:ee()}}get name(){return"schema"}onCreate(){const{managerSettings:e,tags:t,markNames:r,nodeNames:n,extensions:o}=this.store,{defaultBlockNode:i,disableExtraAttributes:s,nodeOverride:a,markOverride:l}=e,c=h=>!!(h&&t[te.Block].includes(h));if(e.schema){const{nodes:h,marks:m}=iI(e.schema);this.addSchema(e.schema,h,m);return}const u=c(i)?{doc:ee(),[i]:ee()}:ee(),d=ee(),f=QL({settings:e,gatheredSchemaAttributes:this.gatherExtraAttributes(o),nodeNames:n,markNames:r,tags:t});for(const h of o){f[h.name]={...f[h.name],...h.options.extraAttributes};const m=s===!0||h.options.disableExtraAttributes===!0||h.constructor.disableExtraAttributes===!0;if(Hd(h)){const{spec:b,dynamic:v}=g2({createExtensionSpec:(g,y)=>h.createNodeSpec(g,y),extraAttributes:it(f,h.name),override:{...a,...h.options.nodeOverride},ignoreExtraAttributes:m,name:h.constructorName,tags:h.tags});h.spec=b,u[h.name]=b,Object.keys(v).length>0&&(this.dynamicAttributes.nodes[h.name]=v)}if(Kh(h)){const{spec:b,dynamic:v}=g2({createExtensionSpec:(g,y)=>h.createMarkSpec(g,y),extraAttributes:it(f,h.name),override:{...l,...h.options.markOverride},ignoreExtraAttributes:m,name:h.constructorName,tags:h.tags??[]});h.spec=b,d[h.name]=b,Object.keys(v).length>0&&(this.dynamicAttributes.marks[h.name]=v)}}const p=new zA({nodes:u,marks:d,topNode:"doc"});this.addSchema(p,u,d)}createPlugin(){return{appendTransaction:(e,t,r)=>{const{tr:n}=r;return!e.some(i=>i.docChanged)||Object.keys(this.dynamicAttributes.nodes).length===0&&Object.keys(this.dynamicAttributes.marks).length===0?null:(n.doc.descendants((i,s)=>(this.checkAndUpdateDynamicNodes(i,s,n),this.checkAndUpdateDynamicMarks(i,s,n),!0)),n.steps.length>0?n:null)}}}addSchema(e,t,r){this.store.setStoreKey("nodes",t),this.store.setStoreKey("marks",r),this.store.setStoreKey("schema",e),this.store.setExtensionStore("schema",e),this.store.setStoreKey("defaultBlockNode",Bh(e).name);for(const n of Object.values(e.nodes))if(n.name!=="doc"&&(n.isBlock||n.isTextblock))break}checkAndUpdateDynamicNodes(e,t,r){for(const[n,o]of At(this.dynamicAttributes.nodes))if(e.type.name===n)for(const[i,s]of At(o)){if(!es(e.attrs[i]))continue;const a={...e.attrs,[i]:s(e)};r.setNodeMarkup(t,void 0,a),a2(r)}}checkAndUpdateDynamicMarks(e,t,r){for(const[n,o]of At(this.dynamicAttributes.marks)){const i=it(this.store.schema.marks,n),s=e.marks.find(a=>a.type.name===n);if(s)for(const[a,l]of At(o)){if(!es(s.attrs[a]))continue;const c=_o(r.doc.resolve(t),i);if(!c)continue;const{from:u,to:d}=c,f=i.create({...s.attrs,[a]:l(s)});r.removeMark(u,d,i).addMark(u,d,f),a2(r)}}}gatherExtraAttributes(e){const t=[];for(const r of e)r.createSchemaAttributes&&t.push(...r.createSchemaAttributes());return t}};Y1=Z([pe({defaultPriority:Ae.Highest})],Y1);function QL(e){const{settings:t,gatheredSchemaAttributes:r,nodeNames:n,markNames:o,tags:i}=e,s=ee();if(t.disableExtraAttributes)return s;const a=[...r,...t.extraAttributes??[]];for(const l of a??[]){const c=eI({identifiers:l.identifiers,nodeNames:n,markNames:o,tags:i});for(const u of c){const d=s[u]??{};s[u]={...d,...l.attributes}}}return s}function ZL(e){return ps(e)&&ct(e.tags)}function eI(e){const{identifiers:t,nodeNames:r,markNames:n,tags:o}=e;if(t==="nodes")return r;if(t==="marks")return n;if(t==="all")return[...r,...n];if(ct(t))return t;re(ZL(t),{code:B.EXTENSION_EXTRA_ATTRIBUTES,message:"Invalid value passed as an identifier when creating `extraAttributes`."});const{tags:i=[],names:s=[],behavior:a="any",excludeNames:l,excludeTags:c,type:u}=t,d=new Set,f=u==="mark"?n:u==="node"?r:[...n,...r],p=m=>f.includes(m)&&!(l!=null&&l.includes(m));for(const m of s)p(m)&&d.add(m);const h=new Map;for(const m of i)if(!(c!=null&&c.includes(m)))for(const b of o[m]){if(!p(b))continue;if(a==="any"){d.add(b);continue}const v=h.get(b)??new Set;v.add(m),h.set(b,v)}for(const[m,b]of h)b.size===i.length&&d.add(m);return[...d]}function g2(e){var t;const{createExtensionSpec:r,extraAttributes:n,ignoreExtraAttributes:o,name:i,tags:s,override:a}=e,l=ee();function c(b,v){l[b]=v}let u=!1;function d(){u=!0}const f=tI(n,o,d,c),p=rI(n,o),h=nI(n,o),m=r({defaults:f,parse:p,dom:h},a);return re(o||u,{code:B.EXTENSION_SPEC,message:`When creating a node specification you must call the 'defaults', and parse, and 'dom' methods. To avoid this error you can set the static property 'disableExtraAttributes' of '${i}' to 'true'.`}),m.group=[...((t=m.group)==null?void 0:t.split(" "))??[],...s].join(" ")||void 0,{spec:m,dynamic:l}}function Qv(e){return oe(e)||_e(e)?{default:e}:(re(e,{message:`${K4(e)} is not supported`,code:B.EXTENSION_EXTRA_ATTRIBUTES}),e)}function tI(e,t,r,n){return()=>{r();const o=ee();if(t)return o;for(const[i,s]of At(e)){let l=Qv(s).default;_e(l)&&(n(i,l),l=null),o[i]=l===void 0?{}:{default:l}}return o}}function rI(e,t){return r=>{const n=ee();if(t)return n;for(const[o,i]of At(e)){const{parseDOM:s,...a}=Qv(i);if(et(r)){if(es(s)){n[o]=r.getAttribute(o)??a.default;continue}if(_e(s)){n[o]=s(r)??a.default;continue}n[o]=r.getAttribute(s)??a.default}}return n}}function nI(e,t){return r=>{const n=ee();if(t)return n;function o(i,s){if(i){if(oe(i)){n[s]=i;return}if(ct(i)){const[a,l]=i;n[a]=l??r.attrs[s];return}for(const[a,l]of At(i))n[a]=l}}for(const[i,s]of At(e)){const{toDOM:a,parseDOM:l}=Qv(s);if(es(a)){const c=oe(l)?l:i;n[c]=r.attrs[i];continue}if(_e(a)){o(a(r.attrs,oI(r)),i);continue}o(a,i)}return n}}function oI(e){return Id(e)?{node:e}:hz(e)?{mark:e}:{}}function iI(e){const t=ee(),r=ee();for(const[n,o]of Object.entries(e.nodes))t[n]=o.spec;for(const[n,o]of Object.entries(e.marks))r[n]=o.spec;return{nodes:t,marks:r}}var Ll=class extends Ve{constructor(){super(...arguments),this.onAddCustomHandler=({suggester:e})=>{var t;if(!(!e||(t=this.store.managerSettings.exclude)!=null&&t.suggesters))return s2(this.store.getState(),e)}}get name(){return"suggest"}onCreate(){this.store.setExtensionStore("addSuggester",e=>s2(this.store.getState(),e)),this.store.setExtensionStore("removeSuggester",e=>q6(this.store.getState(),e))}createExternalPlugins(){var e,t;const r=[];for(const n of this.store.extensions){if((e=this.store.managerSettings.exclude)!=null&&e.suggesters)break;if(!n.createSuggesters||(t=n.options.exclude)!=null&&t.suggesters)continue;const o=n.createSuggesters(),i=ct(o)?o:[o];r.push(...i)}return[G6(...r)]}getSuggestState(e){return Vv(e??this.store.getState())}getSuggestMethods(){const{addIgnored:e,clearIgnored:t,removeIgnored:r,ignoreNextExit:n,setMarkRemoved:o,findMatchAtPosition:i,findNextTextSelection:s,setLastChangeFromAppend:a}=this.getSuggestState();return{addIgnored:e,clearIgnored:t,removeIgnored:r,ignoreNextExit:n,setMarkRemoved:o,findMatchAtPosition:i,findNextTextSelection:s,setLastChangeFromAppend:a}}isSuggesterActive(e){var t;return fr(ct(e)?e:[e],(t=this.getSuggestState().match)==null?void 0:t.suggester.name)}};Z([He()],Ll.prototype,"getSuggestState",1);Z([He()],Ll.prototype,"getSuggestMethods",1);Z([He()],Ll.prototype,"isSuggesterActive",1);Ll=Z([pe({customHandlerKeys:["suggester"]})],Ll);var J1=class extends Ve{constructor(){super(...arguments),this.allTags=ee(),this.plainTags=ee(),this.markTags=ee(),this.nodeTags=ee()}get name(){return"tags"}onCreate(){this.resetTags();for(const e of this.store.extensions)this.updateTagForExtension(e);this.store.setStoreKey("tags",this.allTags),this.store.setExtensionStore("tags",this.allTags),this.store.setStoreKey("plainTags",this.plainTags),this.store.setExtensionStore("plainTags",this.plainTags),this.store.setStoreKey("markTags",this.markTags),this.store.setExtensionStore("markTags",this.markTags),this.store.setStoreKey("nodeTags",this.nodeTags),this.store.setExtensionStore("nodeTags",this.nodeTags)}resetTags(){const e=ee(),t=ee(),r=ee(),n=ee();for(const o of Nh(te))e[o]=[],t[o]=[],r[o]=[],n[o]=[];this.allTags=e,this.plainTags=t,this.markTags=r,this.nodeTags=n}updateTagForExtension(e){var t,r;const n=new Set([...e.tags??[],...((t=e.createTags)==null?void 0:t.call(e))??[],...e.options.extraTags??[],...((r=this.store.managerSettings.extraTags)==null?void 0:r[e.name])??[]]);for(const o of n)re(sI(o),{code:B.EXTENSION,message:`The tag provided by the extension: ${e.constructorName} is not supported by the editor. To add custom tags you can use the 'mutateTag' method.`}),this.allTags[o].push(e.name),e5(e)&&this.plainTags[o].push(e.name),Kh(e)&&this.markTags[o].push(e.name),Hd(e)&&this.nodeTags[o].push(e.name);e.tags=[...n]}};J1=Z([pe({defaultPriority:Ae.Highest})],J1);function sI(e){return fr(Nh(te),e)}var aI=new ka("remirrorFilePlaceholderPlugin");function lI(){const e=new Ro({key:aI,state:{init(){return{set:Ee.empty,payloads:new Map}},apply(t,{set:r,payloads:n}){r=r.map(t.mapping,t.doc);const o=t.getMeta(e);if(o)if(o.type===0){const i=document.createElement("placeholder"),s=Ge.widget(o.pos,i,{id:o.id});r=r.add(t.doc,[s]),n.set(o.id,o.payload)}else o.type===1&&(r=r.remove(r.find(void 0,void 0,i=>i.id===o.id)),n.delete(o.id));return{set:r,payloads:n}}},props:{decorations(t){var r;return((r=e.getState(t))==null?void 0:r.set)??null}}});return e}var cI=class extends Ve{get name(){return"upload"}createExternalPlugins(){return[lI()]}};function uI(e={}){e={...{exitMarksOnArrowPress:Qn.defaultOptions.exitMarksOnArrowPress,excludeBaseKeymap:Qn.defaultOptions.excludeBaseKeymap,selectParentNodeOnEscape:Qn.defaultOptions.selectParentNodeOnEscape,undoInputRuleOnBackspace:Qn.defaultOptions.undoInputRuleOnBackspace,persistentSelectionClass:io.defaultOptions.persistentSelectionClass},...e};const r=S1(e,["excludeBaseKeymap","selectParentNodeOnEscape","undoInputRuleOnBackspace"]),n=S1(e,["persistentSelectionClass"]);return[new J1,new Y1,new DL,new Lp,new q1,new XL,new JL,new Ll,new xe,new Rn,new Qn(r),new K1,new cI,new io(n)]}var v2=class extends Ve{get name(){return"meta"}onCreate(){if(this.store.setStoreKey("getCommandMeta",this.getCommandMeta.bind(this)),!!this.options.capture)for(const e of this.store.extensions)this.captureCommands(e),this.captureKeybindings(e)}createPlugin(){return{}}captureCommands(e){const t=e.decoratedCommands??{},r=e.createCommands;for(const n of Object.keys(t)){const o=e[n];e[n]=(...i)=>s=>{var a;const l=o(...i)(s);return s.dispatch&&l&&this.setCommandMeta(s.tr,{type:"command",chain:s.dispatch!==((a=s.view)==null?void 0:a.dispatch),name:n,extension:e.name,decorated:!0}),l}}r&&(e.createCommands=()=>{const n=r();for(const[o,i]of Object.entries(n))n[o]=(...s)=>a=>{var l;const c=i(...s)(a);return a.dispatch&&c&&this.setCommandMeta(a.tr,{type:"command",chain:a.dispatch!==((l=a.view)==null?void 0:l.dispatch),name:o,extension:e.name,decorated:!1}),c};return n})}captureKeybindings(e){}getCommandMeta(e){return e.getMeta(this.pluginKey)??[]}setCommandMeta(e,t){const r=this.getCommandMeta(e);e.setMeta(this.pluginKey,[...r,t])}};v2=Z([pe({defaultOptions:{capture:on.isDevelopment},staticKeys:["capture"],defaultPriority:Ae.Highest})],v2);var Ff,$c,Vf,Wa,Ci,jf,Uf,dI=class{constructor(e){kt(this,Ff,Cl()),kt(this,$c,void 0),kt(this,Vf,void 0),kt(this,Wa,!0),kt(this,Ci,Uh()),kt(this,jf,void 0),kt(this,Uf,void 0),this.getState=()=>this.view.state??this.initialEditorState,this.getPreviousState=()=>this.previousState,this.dispatchTransaction=i=>{var s,a;re(!this.manager.destroyed,{code:B.MANAGER_PHASE_ERROR,message:"A transaction was dispatched to a manager that has already been destroyed. Please check your set up, or open an issue."}),i=((a=(s=this.props).onDispatchTransaction)==null?void 0:a.call(s,i,this.getState()))??i;const l=this.getState(),{state:c,transactions:u}=l.applyTransaction(i);Lt(this,Vf,l),this.updateState({state:c,tr:i,transactions:u});const d=this.manager.store.getForcedUpdates(i);Mo(d)||this.updateViewProps(...d)},this.onChange=(i=ee())=>{var s,a;const l=this.eventListenerProps(i);G(this,Wa)&&Lt(this,Wa,!1),(a=(s=this.props).onChange)==null||a.call(s,l)},this.onBlur=i=>{var s,a;const l=this.eventListenerProps();(a=(s=this.props).onBlur)==null||a.call(s,l,i),G(this,Ci).emit("blur",l,i)},this.onFocus=i=>{var s,a;const l=this.eventListenerProps();(a=(s=this.props).onFocus)==null||a.call(s,l,i),G(this,Ci).emit("focus",l,i)},this.setContent=(i,{triggerChange:s=!1}={})=>{const{doc:a}=this.manager.createState({content:i}),l=this.getState(),{state:c}=this.getState().applyTransaction(l.tr.replaceRangeWith(0,l.doc.nodeSize-2,a));if(s)return this.updateState({state:c,triggerChange:s});this.view.updateState(c)},this.clearContent=({triggerChange:i=!1}={})=>{this.setContent(this.manager.createEmptyDoc(),{triggerChange:i})},this.createStateFromContent=(i,s)=>this.manager.createState({content:i,selection:s}),this.focus=i=>{this.manager.store.commands.focus(i)},this.blur=i=>{this.manager.store.commands.blur(i)};const{getProps:t,initialEditorState:r,element:n}=e;if(Lt(this,$c,t),Lt(this,Uf,r),this.manager.attachFramework(this,this.updateListener.bind(this)),this.manager.view)return;const o=this.createView(r,n);this.manager.addView(o)}get addHandler(){return G(this,jf)??Lt(this,jf,G(this,Ci).on.bind(G(this,Ci)))}get updatableViewProps(){return{attributes:()=>this.getAttributes(),editable:()=>this.props.editable??!0}}get firstRender(){return G(this,Wa)}get props(){return G(this,$c).call(this)}get previousState(){return this.previousStateOverride??G(this,Vf)??this.initialEditorState}get manager(){return this.props.manager}get view(){return this.manager.view}get uid(){return G(this,Ff)}get initialEditorState(){return G(this,Uf)}updateListener(e){const{state:t,tr:r}=e;return G(this,Ci).emit("updated",this.eventListenerProps({state:t,tr:r}))}update(e){const{getProps:t}=e;return Lt(this,$c,t),this}updateViewProps(...e){const t=S1(this.updatableViewProps,e);this.view.setProps({...this.view.props,...t})}getAttributes(e){var t;const{attributes:r,autoFocus:n,classNames:o=[],label:i,editable:s}=this.props,a=(t=this.manager.store)==null?void 0:t.attributes,l=_e(r)?r(this.eventListenerProps()):r;let c={};(n||Jt(n))&&(c=e?{autoFocus:!0}:{autofocus:"true"});const u=Ml(ju(e&&"Prosemirror","remirror-editor",a==null?void 0:a.class,...o).split(" ")).join(" "),d={role:"textbox",...c,"aria-multiline":"true",...s??!0?{}:{"aria-readonly":"true"},"aria-label":i??"",...a,class:u};return G4({...d,...l})}addFocusListeners(){this.view.dom.addEventListener("blur",this.onBlur),this.view.dom.addEventListener("focus",this.onFocus)}removeFocusListeners(){this.view.dom.removeEventListener("blur",this.onBlur),this.view.dom.removeEventListener("focus",this.onFocus)}destroy(){G(this,Ci).emit("destroy"),this.view&&this.removeFocusListeners()}eventListenerProps(e=ee()){const{state:t,tr:r,transactions:n}=e;return{tr:r,transactions:n,internalUpdate:!r,view:this.view,firstRender:G(this,Wa),state:t??this.getState(),createStateFromContent:this.createStateFromContent,previousState:this.previousState,helpers:this.manager.store.helpers}}get baseOutput(){return{manager:this.manager,...this.manager.store,addHandler:this.addHandler,focus:this.focus,blur:this.blur,uid:G(this,Ff),view:this.view,getState:this.getState,getPreviousState:this.getPreviousState,getExtension:this.manager.getExtension.bind(this.manager),hasExtension:this.manager.hasExtension.bind(this.manager),clearContent:this.clearContent,setContent:this.setContent}}};Ff=new WeakMap;$c=new WeakMap;Vf=new WeakMap;Wa=new WeakMap;Ci=new WeakMap;jf=new WeakMap;Uf=new WeakMap;function fI(e,t){const r=[],n=new WeakMap,o=[],i=new WeakMap;let s=[];const a={duplicateMap:i,parentExtensions:o,gatheredExtensions:s,settings:t};for(const d of e)r5(a,{extension:d});s=ta(s,(d,f)=>f.priority-d.priority);const l=new WeakSet,c=new Set;for(const d of s){const f=d.constructor,p=d.name,h=i.get(f);re(h,{message:`No entries were found for the ExtensionConstructor ${d.name}`,code:B.INTERNAL}),!(l.has(f)||c.has(p))&&(l.add(f),c.add(p),r.push(d),n.set(f,d),h.forEach(m=>m==null?void 0:m.replaceChildExtension(f,d)))}const u=[];for(const d of r)pI({extension:d,found:l,missing:u});return re(Mo(u),{code:B.MISSING_REQUIRED_EXTENSION,message:u.map(({Constructor:d,extension:f})=>`The extension '${f.name}' requires '${d.name} in order to run correctly.`).join(` +`)}),{extensions:r,extensionMap:n}}function r5(e,t){var r;const{gatheredExtensions:n,duplicateMap:o,parentExtensions:i,settings:s}=e,{extension:a,parentExtension:l}=t;let{names:c=[]}=t;re(ZC(a),{code:B.INVALID_MANAGER_EXTENSION,message:`An invalid extension: ${a} was provided to the [[\`RemirrorManager\`]].`});const u=a.extensions;if(a.setPriority((r=s.priority)==null?void 0:r[a.name]),n.push(a),hI({duplicateMap:o,extension:a,parentExtension:l}),u.length!==0){if(c.includes(a.name)){`${c.join(" > ")}${a.name}`;return}c=[...c,a.name],i.push(a);for(const d of u)r5(e,{names:c,extension:d,parentExtension:a})}}function pI(e){const{extension:t,found:r,missing:n}=e;if(t.requiredExtensions)for(const o of t.requiredExtensions??[])r.has(o)||n.push({Constructor:o,extension:t})}function hI(e){const{duplicateMap:t,extension:r,parentExtension:n}=e,o=r.constructor,i=t.get(o),s=n?[n]:[];t.set(o,i?[...i,...s]:s)}function mI(e){var t,r,n,o;const{extension:i,nodeNames:s,markNames:a,plainNames:l,store:c,handlers:u}=e;i.setStore(c);const d=(t=i.onCreate)==null?void 0:t.bind(i),f=(r=i.onView)==null?void 0:r.bind(i),p=(n=i.onStateUpdate)==null?void 0:n.bind(i),h=(o=i.onDestroy)==null?void 0:o.bind(i);d&&u.create.push(d),f&&u.view.push(f),p&&u.update.push(p),h&&u.destroy.push(h),Kh(i)&&a.push(i.name),Hd(i)&&i.name!=="doc"&&s.push(i.name),e5(i)&&l.push(i.name)}var Mi,Hc,Wn,$o,Bc,Zr,Es,Fc,Cs,Vc,Ms,Kn,jc,Wf=class{constructor(e,t={}){kt(this,Mi,void 0),kt(this,Hc,ee()),kt(this,Wn,ee()),kt(this,$o,void 0),kt(this,Bc,void 0),kt(this,Zr,Nr.None),kt(this,Es,void 0),kt(this,Fc,!0),kt(this,Cs,{create:[],view:[],update:[],destroy:[]}),kt(this,Vc,[]),kt(this,Ms,Uh()),kt(this,Kn,void 0),kt(this,jc,void 0),this.getState=()=>{var o;return G(this,Zr)>=Nr.EditorView?this.view.state:(re(G(this,Kn),{code:B.MANAGER_PHASE_ERROR,message:"`getState` can only be called after the `Framework` or the `EditorView` has been added to the manager`. Check your plugins to make sure that the decorations callback uses the state argument."}),(o=G(this,Kn))==null?void 0:o.initialEditorState)},this.updateState=o=>{const i=this.getState();this.view.updateState(o),this.onStateUpdate({previousState:i,state:o})};const{extensions:r,extensionMap:n}=fI(e,t);Lt(this,Es,t),Lt(this,$o,$s(r)),Lt(this,Bc,n),Lt(this,Mi,this.createExtensionStore()),Lt(this,Zr,Nr.Create),this.setupLifecycleHandlers();for(const o of G(this,Cs).create){const i=o();i&&G(this,Vc).push(i)}}static create(e,t={}){return new Wf([...tE(e),...uI(t.builtin)],t)}get[ti](){return $t.Manager}get destroyed(){return G(this,Zr)===Nr.Destroy}get mounted(){return G(this,Zr)>=Nr.EditorView&&G(this,Zr)G(this,$o),enumerable:t},phase:{get:()=>G(this,Zr),enumerable:t},view:{get:()=>this.view,enumerable:t},managerSettings:{get:()=>$s(G(this,Es)),enumerable:t},getState:{value:this.getState,enumerable:t},updateState:{value:this.updateState,enumerable:t},isMounted:{value:()=>this.mounted,enumerable:t},getExtension:{value:this.getExtension.bind(this),enumerable:t},manager:{get:()=>this,enumerable:t},document:{get:()=>this.document,enumerable:t},stringHandlers:{get:()=>G(this,Hc),enumerable:t},currentState:{get:()=>r??(r=this.getState()),set:o=>{r=o},enumerable:t},previousState:{get:()=>n,set:o=>{n=o},enumerable:t}}),e.getStoreKey=this.getStoreKey.bind(this),e.setStoreKey=this.setStoreKey.bind(this),e.setExtensionStore=this.setExtensionStore.bind(this),e.setStringHandler=this.setStringHandler.bind(this),e}addView(e){if(G(this,Zr)>=Nr.EditorView)return this;Lt(this,Fc,!0),Lt(this,Zr,Nr.EditorView),G(this,Wn).view=e;for(const t of G(this,Cs).view){const r=t(e);r&&G(this,Vc).push(r)}return this}attachFramework(e,t){var r;G(this,Kn)!==e&&(G(this,Kn)&&(G(this,Kn).destroy(),(r=G(this,jc))==null||r.call(this)),Lt(this,Kn,e),Lt(this,jc,this.addHandler("stateUpdate",t)))}createEmptyDoc(){var e;const t=(e=this.schema.nodes.doc)==null?void 0:e.createAndFill();return re(t,{code:B.INVALID_CONTENT,message:"An empty node could not be created due to an invalid schema."}),t}createState(e={}){const{onError:t,defaultSelection:r="end"}=this.settings,{content:n=this.createEmptyDoc(),selection:o=r,stringHandler:i=this.settings.stringHandler}=e,{schema:s,plugins:a}=this.store,l=NC({stringHandler:oe(i)?this.stringHandlers[i]:i,document:this.document,content:n,onError:t,schema:s,selection:o});return Hs.create({schema:s,doc:l,plugins:a,selection:jr(o,l)})}addHandler(e,t){return G(this,Ms).on(e,t)}onStateUpdate(e){const t=G(this,Fc);G(this,Mi).currentState=e.state,G(this,Mi).previousState=e.previousState,t&&(Lt(this,Zr,Nr.Runtime),Lt(this,Fc,!1));const r={...e,firstUpdate:t};for(const n of G(this,Cs).update)n(r);G(this,Ms).emit("stateUpdate",r)}getExtension(e){const t=G(this,Bc).get(e);return re(t,{code:B.INVALID_MANAGER_EXTENSION,message:`'${e.name}' doesn't exist within this manager. Make sure it is properly added before attempting to use it.`}),t}hasExtension(e){return!!G(this,Bc).get(e)}clone(){const e=G(this,$o).map(r=>r.clone(r.options)),t=Wf.create(()=>e,G(this,Es));return G(this,Ms).emit("clone",t),t}recreate(e=[],t={}){const r=G(this,$o).map(o=>o.clone(o.initialOptions)),n=Wf.create(()=>[...r,...e],t);return G(this,Ms).emit("recreate",n),n}destroy(){var e,t,r,n,o,i;Lt(this,Zr,Nr.Destroy);for(const s of((e=this.view)==null?void 0:e.state.plugins)??[])(r=(t=s.getState(this.view.state))==null?void 0:t.destroy)==null||r.call(t);(n=G(this,Kn))==null||n.destroy(),(o=G(this,jc))==null||o.call(this);for(const s of G(this,Vc))s();for(const s of G(this,Cs).destroy)s();(i=this.view)==null||i.destroy(),G(this,Ms).emit("destroy")}includes(e){const t=[],r=[];for(const n of G(this,$o))t.push(n.name,n.constructorName),r.push(n.constructor);return e.every(n=>oe(n)?fr(t,n):fr(r,n))}},gI=Wf;Mi=new WeakMap;Hc=new WeakMap;Wn=new WeakMap;$o=new WeakMap;Bc=new WeakMap;Zr=new WeakMap;Es=new WeakMap;Fc=new WeakMap;Cs=new WeakMap;Vc=new WeakMap;Ms=new WeakMap;Kn=new WeakMap;jc=new WeakMap;function vI(e,t){return!oc(e)||!ic(e,$t.Manager)?!1:t?e.includes(t):!0}var yI=Object.defineProperty,bI=Object.getOwnPropertyDescriptor,Bd=(e,t,r,n)=>{for(var o=n>1?void 0:n?bI(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&yI(t,r,o),o},n5=/\S+/g;function o5(e){return e.type.isTextblock?1:e.type.isText?e.textBetween(0,e.nodeSize).length:0}function xI({doc:e},t){let r=0,n=0;return e.nodesBetween(0,e.nodeSize-2,(o,i)=>{if(n>0)return!1;const s=o5(o);return r+s>t?(n=i+1+(t-r),!1):(r+=s,!0)}),n}function kI({doc:e},t){let r=0,n=0;return e.nodesBetween(0,e.nodeSize-2,(o,i)=>{if(n>0)return!1;if(!o.type.isText)return!0;const s=o.textBetween(0,o.nodeSize),a=xa(s,n5);if(r+a.length>t){const l=t-r,c=a[l];return n=i+((c==null?void 0:c.index)??0),!1}return r+=a.length,!0}),n}var ss=class extends Ve{get name(){return"count"}getCountMaximum(){return this.options.maximum}getCharacterCount(e=this.store.getState()){let t=0;return e.doc.nodesBetween(0,e.doc.nodeSize-2,r=>(t+=o5(r),!0)),Math.max(t-1,0)}getWordCount(e=this.store.getState()){const t=this.store.helpers.getText({lineBreakDivider:" ",state:e});return xa(t,n5).length}isCountValid(e=this.store.getState()){const{maximumStrategy:t,maximum:r}=this.options;return r<1?!0:t==="CHARACTERS"?this.store.helpers.getCharacterCount(e)<=r:this.store.helpers.getWordCount(e)<=r}createDecorationSet(e){const{maximum:t=-1,maximumStrategy:r,maximumExceededClassName:n}=this.options,s=(r==="CHARACTERS"?xI:kI)(e,t);return Ee.create(e.doc,[Ge.inline(s,e.doc.nodeSize-2,{class:n})])}createExternalPlugins(){const{maximum:e}=this.options,t=new Ro({state:{init:(r,n)=>this.isCountValid(n)?{decorationSet:Ee.empty}:{decorationSet:this.createDecorationSet(n)},apply:(r,n,o,i)=>!r.docChanged||e<1?n:this.isCountValid(i)?{decorationSet:Ee.empty}:{decorationSet:this.createDecorationSet(i)}},props:{decorations(r){var n;return((n=t.getState(r))==null?void 0:n.decorationSet)??null}}});return[t]}};Bd([He()],ss.prototype,"getCountMaximum",1);Bd([He()],ss.prototype,"getCharacterCount",1);Bd([He()],ss.prototype,"getWordCount",1);Bd([He()],ss.prototype,"isCountValid",1);ss=Bd([pe({defaultOptions:{maximum:-1,maximumExceededClassName:"remirror-max-count-exceeded",maximumStrategy:"CHARACTERS"},staticKeys:["maximum","maximumStrategy","maximumExceededClassName"]})],ss);var i5={exports:{}},hn={},s5={exports:{}},a5={};/** + * @license React + * scheduler.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */(function(e){function t(A,P){var F=A.length;A.push(P);e:for(;0>>1,J=A[Y];if(0>>1;Yo(ue,F))deo(me,ue)?(A[Y]=me,A[de]=F,Y=de):(A[Y]=ue,A[ie]=F,Y=ie);else if(deo(me,F))A[Y]=me,A[de]=F,Y=de;else break e}}return P}function o(A,P){var F=A.sortIndex-P.sortIndex;return F!==0?F:A.id-P.id}if(typeof performance=="object"&&typeof performance.now=="function"){var i=performance;e.unstable_now=function(){return i.now()}}else{var s=Date,a=s.now();e.unstable_now=function(){return s.now()-a}}var l=[],c=[],u=1,d=null,f=3,p=!1,h=!1,m=!1,b=typeof setTimeout=="function"?setTimeout:null,v=typeof clearTimeout=="function"?clearTimeout:null,g=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function y(A){for(var P=r(c);P!==null;){if(P.callback===null)n(c);else if(P.startTime<=A)n(c),P.sortIndex=P.expirationTime,t(l,P);else break;P=r(c)}}function x(A){if(m=!1,y(A),!h)if(r(l)!==null)h=!0,L(k);else{var P=r(c);P!==null&&q(x,P.startTime-A)}}function k(A,P){h=!1,m&&(m=!1,v(M),M=-1),p=!0;var F=f;try{for(y(P),d=r(l);d!==null&&(!(d.expirationTime>P)||A&&!N());){var Y=d.callback;if(typeof Y=="function"){d.callback=null,f=d.priorityLevel;var J=Y(d.expirationTime<=P);P=e.unstable_now(),typeof J=="function"?d.callback=J:d===r(l)&&n(l),y(P)}else n(l);d=r(l)}if(d!==null)var Ne=!0;else{var ie=r(c);ie!==null&&q(x,ie.startTime-P),Ne=!1}return Ne}finally{d=null,f=F,p=!1}}var w=!1,E=null,M=-1,C=5,T=-1;function N(){return!(e.unstable_now()-TA||125Y?(A.sortIndex=F,t(c,A),r(l)===null&&A===r(c)&&(m?(v(M),M=-1):m=!0,q(x,F-Y))):(A.sortIndex=J,t(l,A),h||p||(h=!0,L(k))),A},e.unstable_shouldYield=N,e.unstable_wrapCallback=function(A){var P=f;return function(){var F=f;f=P;try{return A.apply(this,arguments)}finally{f=F}}}})(a5);s5.exports=a5;var wI=s5.exports;/** + * @license React + * react-dom.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var l5=S,fn=wI;function H(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,r=1;r"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),X1=Object.prototype.hasOwnProperty,SI=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,y2={},b2={};function EI(e){return X1.call(b2,e)?!0:X1.call(y2,e)?!1:SI.test(e)?b2[e]=!0:(y2[e]=!0,!1)}function CI(e,t,r,n){if(r!==null&&r.type===0)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return n?!1:r!==null?!r.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function MI(e,t,r,n){if(t===null||typeof t>"u"||CI(e,t,r,n))return!0;if(n)return!1;if(r!==null)switch(r.type){case 3:return!t;case 4:return t===!1;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}function Tr(e,t,r,n,o,i,s){this.acceptsBooleans=t===2||t===3||t===4,this.attributeName=n,this.attributeNamespace=o,this.mustUseProperty=r,this.propertyName=e,this.type=t,this.sanitizeURL=i,this.removeEmptyString=s}var Qt={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){Qt[e]=new Tr(e,0,!1,e,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0];Qt[t]=new Tr(t,1,!1,e[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(e){Qt[e]=new Tr(e,2,!1,e.toLowerCase(),null,!1,!1)});["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){Qt[e]=new Tr(e,2,!1,e,null,!1,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){Qt[e]=new Tr(e,3,!1,e.toLowerCase(),null,!1,!1)});["checked","multiple","muted","selected"].forEach(function(e){Qt[e]=new Tr(e,3,!0,e,null,!1,!1)});["capture","download"].forEach(function(e){Qt[e]=new Tr(e,4,!1,e,null,!1,!1)});["cols","rows","size","span"].forEach(function(e){Qt[e]=new Tr(e,6,!1,e,null,!1,!1)});["rowSpan","start"].forEach(function(e){Qt[e]=new Tr(e,5,!1,e.toLowerCase(),null,!1,!1)});var Zv=/[\-:]([a-z])/g;function ey(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var t=e.replace(Zv,ey);Qt[t]=new Tr(t,1,!1,e,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var t=e.replace(Zv,ey);Qt[t]=new Tr(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(Zv,ey);Qt[t]=new Tr(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(e){Qt[e]=new Tr(e,1,!1,e.toLowerCase(),null,!1,!1)});Qt.xlinkHref=new Tr("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(e){Qt[e]=new Tr(e,1,!1,e.toLowerCase(),null,!0,!0)});function ty(e,t,r,n){var o=Qt.hasOwnProperty(t)?Qt[t]:null;(o!==null?o.type!==0:n||!(2a||o[s]!==i[a]){var l=` +`+o[s].replace(" at new "," at ");return e.displayName&&l.includes("")&&(l=l.replace("",e.displayName)),l}while(1<=s&&0<=a);break}}}finally{Tg=!1,Error.prepareStackTrace=r}return(e=e?e.displayName||e.name:"")?Uc(e):""}function TI(e){switch(e.tag){case 5:return Uc(e.type);case 16:return Uc("Lazy");case 13:return Uc("Suspense");case 19:return Uc("SuspenseList");case 0:case 2:case 15:return e=Og(e.type,!1),e;case 11:return e=Og(e.type.render,!1),e;case 1:return e=Og(e.type,!0),e;default:return""}}function t0(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case Za:return"Fragment";case Qa:return"Portal";case Q1:return"Profiler";case ry:return"StrictMode";case Z1:return"Suspense";case e0:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case d5:return(e.displayName||"Context")+".Consumer";case u5:return(e._context.displayName||"Context")+".Provider";case ny:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case oy:return t=e.displayName||null,t!==null?t:t0(e.type)||"Memo";case _i:t=e._payload,e=e._init;try{return t0(e(t))}catch{}}return null}function OI(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=t.render,e=e.displayName||e.name||"",t.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return t0(t);case 8:return t===ry?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t}return null}function as(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function p5(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(t==="checkbox"||t==="radio")}function _I(e){var t=p5(e)?"checked":"value",r=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),n=""+e[t];if(!e.hasOwnProperty(t)&&typeof r<"u"&&typeof r.get=="function"&&typeof r.set=="function"){var o=r.get,i=r.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return o.call(this)},set:function(s){n=""+s,i.call(this,s)}}),Object.defineProperty(e,t,{enumerable:r.enumerable}),{getValue:function(){return n},setValue:function(s){n=""+s},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function af(e){e._valueTracker||(e._valueTracker=_I(e))}function h5(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var r=t.getValue(),n="";return e&&(n=p5(e)?e.checked?"true":"false":e.value),e=n,e!==r?(t.setValue(e),!0):!1}function Ip(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function r0(e,t){var r=t.checked;return ut({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:r??e._wrapperState.initialChecked})}function k2(e,t){var r=t.defaultValue==null?"":t.defaultValue,n=t.checked!=null?t.checked:t.defaultChecked;r=as(t.value!=null?t.value:r),e._wrapperState={initialChecked:n,initialValue:r,controlled:t.type==="checkbox"||t.type==="radio"?t.checked!=null:t.value!=null}}function m5(e,t){t=t.checked,t!=null&&ty(e,"checked",t,!1)}function n0(e,t){m5(e,t);var r=as(t.value),n=t.type;if(r!=null)n==="number"?(r===0&&e.value===""||e.value!=r)&&(e.value=""+r):e.value!==""+r&&(e.value=""+r);else if(n==="submit"||n==="reset"){e.removeAttribute("value");return}t.hasOwnProperty("value")?o0(e,t.type,r):t.hasOwnProperty("defaultValue")&&o0(e,t.type,as(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function w2(e,t,r){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var n=t.type;if(!(n!=="submit"&&n!=="reset"||t.value!==void 0&&t.value!==null))return;t=""+e._wrapperState.initialValue,r||t===e.value||(e.value=t),e.defaultValue=t}r=e.name,r!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,r!==""&&(e.name=r)}function o0(e,t,r){(t!=="number"||Ip(e.ownerDocument)!==e)&&(r==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+r&&(e.defaultValue=""+r))}var Wc=Array.isArray;function ml(e,t,r,n){if(e=e.options,t){t={};for(var o=0;o"+t.valueOf().toString()+"",t=lf.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}});function Wu(e,t){if(t){var r=e.firstChild;if(r&&r===e.lastChild&&r.nodeType===3){r.nodeValue=t;return}}e.textContent=t}var xu={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},AI=["Webkit","ms","Moz","O"];Object.keys(xu).forEach(function(e){AI.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),xu[t]=xu[e]})});function b5(e,t,r){return t==null||typeof t=="boolean"||t===""?"":r||typeof t!="number"||t===0||xu.hasOwnProperty(e)&&xu[e]?(""+t).trim():t+"px"}function x5(e,t){e=e.style;for(var r in t)if(t.hasOwnProperty(r)){var n=r.indexOf("--")===0,o=b5(r,t[r],n);r==="float"&&(r="cssFloat"),n?e.setProperty(r,o):e[r]=o}}var NI=ut({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function a0(e,t){if(t){if(NI[e]&&(t.children!=null||t.dangerouslySetInnerHTML!=null))throw Error(H(137,e));if(t.dangerouslySetInnerHTML!=null){if(t.children!=null)throw Error(H(60));if(typeof t.dangerouslySetInnerHTML!="object"||!("__html"in t.dangerouslySetInnerHTML))throw Error(H(61))}if(t.style!=null&&typeof t.style!="object")throw Error(H(62))}}function l0(e,t){if(e.indexOf("-")===-1)return typeof t.is=="string";switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var c0=null;function iy(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var u0=null,gl=null,vl=null;function C2(e){if(e=jd(e)){if(typeof u0!="function")throw Error(H(280));var t=e.stateNode;t&&(t=Xh(t),u0(e.stateNode,e.type,t))}}function k5(e){gl?vl?vl.push(e):vl=[e]:gl=e}function w5(){if(gl){var e=gl,t=vl;if(vl=gl=null,C2(e),t)for(e=0;e>>=0,e===0?32:31-(VI(e)/jI|0)|0}var cf=64,uf=4194304;function Kc(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function Bp(e,t){var r=e.pendingLanes;if(r===0)return 0;var n=0,o=e.suspendedLanes,i=e.pingedLanes,s=r&268435455;if(s!==0){var a=s&~o;a!==0?n=Kc(a):(i&=s,i!==0&&(n=Kc(i)))}else s=r&~o,s!==0?n=Kc(s):i!==0&&(n=Kc(i));if(n===0)return 0;if(t!==0&&t!==n&&!(t&o)&&(o=n&-n,i=t&-t,o>=i||o===16&&(i&4194240)!==0))return t;if(n&4&&(n|=r&16),t=e.entangledLanes,t!==0)for(e=e.entanglements,t&=n;0r;r++)t.push(e);return t}function Fd(e,t,r){e.pendingLanes|=t,t!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,t=31-to(t),e[t]=r}function qI(e,t){var r=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var n=e.eventTimes;for(e=e.expirationTimes;0=wu),z2=String.fromCharCode(32),L2=!1;function V5(e,t){switch(e){case"keyup":return k8.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function j5(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var el=!1;function S8(e,t){switch(e){case"compositionend":return j5(t);case"keypress":return t.which!==32?null:(L2=!0,z2);case"textInput":return e=t.data,e===z2&&L2?null:e;default:return null}}function E8(e,t){if(el)return e==="compositionend"||!py&&V5(e,t)?(e=B5(),qf=uy=$i=null,el=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:r,offset:t-e};e=n}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=H2(r)}}function q5(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?q5(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function G5(){for(var e=window,t=Ip();t instanceof e.HTMLIFrameElement;){try{var r=typeof t.contentWindow.location.href=="string"}catch{r=!1}if(r)e=t.contentWindow;else break;t=Ip(e.document)}return t}function hy(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}function P8(e){var t=G5(),r=e.focusedElem,n=e.selectionRange;if(t!==r&&r&&r.ownerDocument&&q5(r.ownerDocument.documentElement,r)){if(n!==null&&hy(r)){if(t=n.start,e=n.end,e===void 0&&(e=t),"selectionStart"in r)r.selectionStart=t,r.selectionEnd=Math.min(e,r.value.length);else if(e=(t=r.ownerDocument||document)&&t.defaultView||window,e.getSelection){e=e.getSelection();var o=r.textContent.length,i=Math.min(n.start,o);n=n.end===void 0?i:Math.min(n.end,o),!e.extend&&i>n&&(o=n,n=i,i=o),o=B2(r,i);var s=B2(r,n);o&&s&&(e.rangeCount!==1||e.anchorNode!==o.node||e.anchorOffset!==o.offset||e.focusNode!==s.node||e.focusOffset!==s.offset)&&(t=t.createRange(),t.setStart(o.node,o.offset),e.removeAllRanges(),i>n?(e.addRange(t),e.extend(s.node,s.offset)):(t.setEnd(s.node,s.offset),e.addRange(t)))}}for(t=[],e=r;e=e.parentNode;)e.nodeType===1&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof r.focus=="function"&&r.focus(),r=0;r=document.documentMode,tl=null,g0=null,Eu=null,v0=!1;function F2(e,t,r){var n=r.window===r?r.document:r.nodeType===9?r:r.ownerDocument;v0||tl==null||tl!==Ip(n)||(n=tl,"selectionStart"in n&&hy(n)?n={start:n.selectionStart,end:n.selectionEnd}:(n=(n.ownerDocument&&n.ownerDocument.defaultView||window).getSelection(),n={anchorNode:n.anchorNode,anchorOffset:n.anchorOffset,focusNode:n.focusNode,focusOffset:n.focusOffset}),Eu&&Xu(Eu,n)||(Eu=n,n=jp(g0,"onSelect"),0ol||(e.current=S0[ol],S0[ol]=null,ol--)}function Ye(e,t){ol++,S0[ol]=e.current,e.current=t}var ls={},pr=vs(ls),Dr=vs(!1),sa=ls;function Dl(e,t){var r=e.type.contextTypes;if(!r)return ls;var n=e.stateNode;if(n&&n.__reactInternalMemoizedUnmaskedChildContext===t)return n.__reactInternalMemoizedMaskedChildContext;var o={},i;for(i in r)o[i]=t[i];return n&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=o),o}function $r(e){return e=e.childContextTypes,e!=null}function Wp(){tt(Dr),tt(pr)}function G2(e,t,r){if(pr.current!==ls)throw Error(H(168));Ye(pr,t),Ye(Dr,r)}function nM(e,t,r){var n=e.stateNode;if(t=t.childContextTypes,typeof n.getChildContext!="function")return r;n=n.getChildContext();for(var o in n)if(!(o in t))throw Error(H(108,OI(e)||"Unknown",o));return ut({},r,n)}function Kp(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||ls,sa=pr.current,Ye(pr,e),Ye(Dr,Dr.current),!0}function Y2(e,t,r){var n=e.stateNode;if(!n)throw Error(H(169));r?(e=nM(e,t,sa),n.__reactInternalMemoizedMergedChildContext=e,tt(Dr),tt(pr),Ye(pr,e)):tt(Dr),Ye(Dr,r)}var Uo=null,Qh=!1,Vg=!1;function oM(e){Uo===null?Uo=[e]:Uo.push(e)}function W8(e){Qh=!0,oM(e)}function ys(){if(!Vg&&Uo!==null){Vg=!0;var e=0,t=$e;try{var r=Uo;for($e=1;e>=s,o-=s,qo=1<<32-to(t)+o|r<M?(C=E,E=null):C=E.sibling;var T=f(v,E,y[M],x);if(T===null){E===null&&(E=C);break}e&&E&&T.alternate===null&&t(v,E),g=i(T,g,M),w===null?k=T:w.sibling=T,w=T,E=C}if(M===y.length)return r(v,E),ot&&Ts(v,M),k;if(E===null){for(;MM?(C=E,E=null):C=E.sibling;var N=f(v,E,T.value,x);if(N===null){E===null&&(E=C);break}e&&E&&N.alternate===null&&t(v,E),g=i(N,g,M),w===null?k=N:w.sibling=N,w=N,E=C}if(T.done)return r(v,E),ot&&Ts(v,M),k;if(E===null){for(;!T.done;M++,T=y.next())T=d(v,T.value,x),T!==null&&(g=i(T,g,M),w===null?k=T:w.sibling=T,w=T);return ot&&Ts(v,M),k}for(E=n(v,E);!T.done;M++,T=y.next())T=p(E,v,M,T.value,x),T!==null&&(e&&T.alternate!==null&&E.delete(T.key===null?M:T.key),g=i(T,g,M),w===null?k=T:w.sibling=T,w=T);return e&&E.forEach(function(z){return t(v,z)}),ot&&Ts(v,M),k}function b(v,g,y,x){if(typeof y=="object"&&y!==null&&y.type===Za&&y.key===null&&(y=y.props.children),typeof y=="object"&&y!==null){switch(y.$$typeof){case sf:e:{for(var k=y.key,w=g;w!==null;){if(w.key===k){if(k=y.type,k===Za){if(w.tag===7){r(v,w.sibling),g=o(w,y.props.children),g.return=v,v=g;break e}}else if(w.elementType===k||typeof k=="object"&&k!==null&&k.$$typeof===_i&&rw(k)===w.type){r(v,w.sibling),g=o(w,y.props),g.ref=Ec(v,w,y),g.return=v,v=g;break e}r(v,w);break}else t(v,w);w=w.sibling}y.type===Za?(g=Zs(y.props.children,v.mode,x,y.key),g.return=v,v=g):(x=tp(y.type,y.key,y.props,null,v.mode,x),x.ref=Ec(v,g,y),x.return=v,v=x)}return s(v);case Qa:e:{for(w=y.key;g!==null;){if(g.key===w)if(g.tag===4&&g.stateNode.containerInfo===y.containerInfo&&g.stateNode.implementation===y.implementation){r(v,g.sibling),g=o(g,y.children||[]),g.return=v,v=g;break e}else{r(v,g);break}else t(v,g);g=g.sibling}g=Jg(y,v.mode,x),g.return=v,v=g}return s(v);case _i:return w=y._init,b(v,g,w(y._payload),x)}if(Wc(y))return h(v,g,y,x);if(bc(y))return m(v,g,y,x);vf(v,y)}return typeof y=="string"&&y!==""||typeof y=="number"?(y=""+y,g!==null&&g.tag===6?(r(v,g.sibling),g=o(g,y),g.return=v,v=g):(r(v,g),g=Yg(y,v.mode,x),g.return=v,v=g),s(v)):r(v,g)}return b}var Hl=fM(!0),pM=fM(!1),Ud={},wo=vs(Ud),td=vs(Ud),rd=vs(Ud);function Us(e){if(e===Ud)throw Error(H(174));return e}function Sy(e,t){switch(Ye(rd,t),Ye(td,e),Ye(wo,Ud),e=t.nodeType,e){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:s0(null,"");break;default:e=e===8?t.parentNode:t,t=e.namespaceURI||null,e=e.tagName,t=s0(t,e)}tt(wo),Ye(wo,t)}function Bl(){tt(wo),tt(td),tt(rd)}function hM(e){Us(rd.current);var t=Us(wo.current),r=s0(t,e.type);t!==r&&(Ye(td,e),Ye(wo,r))}function Ey(e){td.current===e&&(tt(wo),tt(td))}var at=vs(0);function Qp(e){for(var t=e;t!==null;){if(t.tag===13){var r=t.memoizedState;if(r!==null&&(r=r.dehydrated,r===null||r.data==="$?"||r.data==="$!"))return t}else if(t.tag===19&&t.memoizedProps.revealOrder!==void 0){if(t.flags&128)return t}else if(t.child!==null){t.child.return=t,t=t.child;continue}if(t===e)break;for(;t.sibling===null;){if(t.return===null||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var jg=[];function Cy(){for(var e=0;er?r:4,e(!0);var n=Ug.transition;Ug.transition={};try{e(!1),t()}finally{$e=r,Ug.transition=n}}function AM(){return zn().memoizedState}function Y8(e,t,r){var n=Xi(e);if(r={lane:n,action:r,hasEagerState:!1,eagerState:null,next:null},NM(e))RM(t,r);else if(r=lM(e,t,r,n),r!==null){var o=wr();ro(r,e,n,o),PM(r,t,n)}}function J8(e,t,r){var n=Xi(e),o={lane:n,action:r,hasEagerState:!1,eagerState:null,next:null};if(NM(e))RM(t,o);else{var i=e.alternate;if(e.lanes===0&&(i===null||i.lanes===0)&&(i=t.lastRenderedReducer,i!==null))try{var s=t.lastRenderedState,a=i(s,r);if(o.hasEagerState=!0,o.eagerState=a,so(a,s)){var l=t.interleaved;l===null?(o.next=o,ky(t)):(o.next=l.next,l.next=o),t.interleaved=o;return}}catch{}finally{}r=lM(e,t,o,n),r!==null&&(o=wr(),ro(r,e,n,o),PM(r,t,n))}}function NM(e){var t=e.alternate;return e===lt||t!==null&&t===lt}function RM(e,t){Cu=Zp=!0;var r=e.pending;r===null?t.next=t:(t.next=r.next,r.next=t),e.pending=t}function PM(e,t,r){if(r&4194240){var n=t.lanes;n&=e.pendingLanes,r|=n,t.lanes=r,ay(e,r)}}var eh={readContext:Pn,useCallback:or,useContext:or,useEffect:or,useImperativeHandle:or,useInsertionEffect:or,useLayoutEffect:or,useMemo:or,useReducer:or,useRef:or,useState:or,useDebugValue:or,useDeferredValue:or,useTransition:or,useMutableSource:or,useSyncExternalStore:or,useId:or,unstable_isNewReconciler:!1},X8={readContext:Pn,useCallback:function(e,t){return ho().memoizedState=[e,t===void 0?null:t],e},useContext:Pn,useEffect:ow,useImperativeHandle:function(e,t,r){return r=r!=null?r.concat([e]):null,Xf(4194308,4,CM.bind(null,t,e),r)},useLayoutEffect:function(e,t){return Xf(4194308,4,e,t)},useInsertionEffect:function(e,t){return Xf(4,2,e,t)},useMemo:function(e,t){var r=ho();return t=t===void 0?null:t,e=e(),r.memoizedState=[e,t],e},useReducer:function(e,t,r){var n=ho();return t=r!==void 0?r(t):t,n.memoizedState=n.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},n.queue=e,e=e.dispatch=Y8.bind(null,lt,e),[n.memoizedState,e]},useRef:function(e){var t=ho();return e={current:e},t.memoizedState=e},useState:nw,useDebugValue:Ay,useDeferredValue:function(e){return ho().memoizedState=e},useTransition:function(){var e=nw(!1),t=e[0];return e=G8.bind(null,e[1]),ho().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,r){var n=lt,o=ho();if(ot){if(r===void 0)throw Error(H(407));r=r()}else{if(r=t(),Ht===null)throw Error(H(349));la&30||vM(n,t,r)}o.memoizedState=r;var i={value:r,getSnapshot:t};return o.queue=i,ow(bM.bind(null,n,i,e),[e]),n.flags|=2048,id(9,yM.bind(null,n,i,r,t),void 0,null),r},useId:function(){var e=ho(),t=Ht.identifierPrefix;if(ot){var r=Go,n=qo;r=(n&~(1<<32-to(n)-1)).toString(32)+r,t=":"+t+"R"+r,r=nd++,0<\/script>",e=e.removeChild(e.firstChild)):typeof n.is=="string"?e=s.createElement(r,{is:n.is}):(e=s.createElement(r),r==="select"&&(s=e,n.multiple?s.multiple=!0:n.size&&(s.size=n.size))):e=s.createElementNS(e,r),e[bo]=t,e[ed]=n,VM(e,t,!1,!1),t.stateNode=e;e:{switch(s=l0(r,n),r){case"dialog":Ze("cancel",e),Ze("close",e),o=n;break;case"iframe":case"object":case"embed":Ze("load",e),o=n;break;case"video":case"audio":for(o=0;oVl&&(t.flags|=128,n=!0,Cc(i,!1),t.lanes=4194304)}else{if(!n)if(e=Qp(s),e!==null){if(t.flags|=128,n=!0,r=e.updateQueue,r!==null&&(t.updateQueue=r,t.flags|=4),Cc(i,!0),i.tail===null&&i.tailMode==="hidden"&&!s.alternate&&!ot)return ir(t),null}else 2*vt()-i.renderingStartTime>Vl&&r!==1073741824&&(t.flags|=128,n=!0,Cc(i,!1),t.lanes=4194304);i.isBackwards?(s.sibling=t.child,t.child=s):(r=i.last,r!==null?r.sibling=s:t.child=s,i.last=s)}return i.tail!==null?(t=i.tail,i.rendering=t,i.tail=t.sibling,i.renderingStartTime=vt(),t.sibling=null,r=at.current,Ye(at,n?r&1|2:r&1),t):(ir(t),null);case 22:case 23:return Iy(),n=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==n&&(t.flags|=8192),n&&t.mode&1?tn&1073741824&&(ir(t),t.subtreeFlags&6&&(t.flags|=8192)):ir(t),null;case 24:return null;case 25:return null}throw Error(H(156,t.tag))}function i9(e,t){switch(gy(t),t.tag){case 1:return $r(t.type)&&Wp(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Bl(),tt(Dr),tt(pr),Cy(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 5:return Ey(t),null;case 13:if(tt(at),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(H(340));$l()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return tt(at),null;case 4:return Bl(),null;case 10:return xy(t.type._context),null;case 22:case 23:return Iy(),null;case 24:return null;default:return null}}var bf=!1,ur=!1,s9=typeof WeakSet=="function"?WeakSet:Set,X=null;function ll(e,t){var r=e.ref;if(r!==null)if(typeof r=="function")try{r(null)}catch(n){mt(e,t,n)}else r.current=null}function L0(e,t,r){try{r()}catch(n){mt(e,t,n)}}var pw=!1;function a9(e,t){if(y0=Fp,e=G5(),hy(e)){if("selectionStart"in e)var r={start:e.selectionStart,end:e.selectionEnd};else e:{r=(r=e.ownerDocument)&&r.defaultView||window;var n=r.getSelection&&r.getSelection();if(n&&n.rangeCount!==0){r=n.anchorNode;var o=n.anchorOffset,i=n.focusNode;n=n.focusOffset;try{r.nodeType,i.nodeType}catch{r=null;break e}var s=0,a=-1,l=-1,c=0,u=0,d=e,f=null;t:for(;;){for(var p;d!==r||o!==0&&d.nodeType!==3||(a=s+o),d!==i||n!==0&&d.nodeType!==3||(l=s+n),d.nodeType===3&&(s+=d.nodeValue.length),(p=d.firstChild)!==null;)f=d,d=p;for(;;){if(d===e)break t;if(f===r&&++c===o&&(a=s),f===i&&++u===n&&(l=s),(p=d.nextSibling)!==null)break;d=f,f=d.parentNode}d=p}r=a===-1||l===-1?null:{start:a,end:l}}else r=null}r=r||{start:0,end:0}}else r=null;for(b0={focusedElem:e,selectionRange:r},Fp=!1,X=t;X!==null;)if(t=X,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,X=e;else for(;X!==null;){t=X;try{var h=t.alternate;if(t.flags&1024)switch(t.tag){case 0:case 11:case 15:break;case 1:if(h!==null){var m=h.memoizedProps,b=h.memoizedState,v=t.stateNode,g=v.getSnapshotBeforeUpdate(t.elementType===t.type?m:Gn(t.type,m),b);v.__reactInternalSnapshotBeforeUpdate=g}break;case 3:var y=t.stateNode.containerInfo;y.nodeType===1?y.textContent="":y.nodeType===9&&y.documentElement&&y.removeChild(y.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(H(163))}}catch(x){mt(t,t.return,x)}if(e=t.sibling,e!==null){e.return=t.return,X=e;break}X=t.return}return h=pw,pw=!1,h}function Mu(e,t,r){var n=t.updateQueue;if(n=n!==null?n.lastEffect:null,n!==null){var o=n=n.next;do{if((o.tag&e)===e){var i=o.destroy;o.destroy=void 0,i!==void 0&&L0(t,r,i)}o=o.next}while(o!==n)}}function tm(e,t){if(t=t.updateQueue,t=t!==null?t.lastEffect:null,t!==null){var r=t=t.next;do{if((r.tag&e)===e){var n=r.create;r.destroy=n()}r=r.next}while(r!==t)}}function I0(e){var t=e.ref;if(t!==null){var r=e.stateNode;switch(e.tag){case 5:e=r;break;default:e=r}typeof t=="function"?t(e):t.current=e}}function WM(e){var t=e.alternate;t!==null&&(e.alternate=null,WM(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&(delete t[bo],delete t[ed],delete t[w0],delete t[j8],delete t[U8])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function KM(e){return e.tag===5||e.tag===3||e.tag===4}function hw(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||KM(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function D0(e,t,r){var n=e.tag;if(n===5||n===6)e=e.stateNode,t?r.nodeType===8?r.parentNode.insertBefore(e,t):r.insertBefore(e,t):(r.nodeType===8?(t=r.parentNode,t.insertBefore(e,r)):(t=r,t.appendChild(e)),r=r._reactRootContainer,r!=null||t.onclick!==null||(t.onclick=Up));else if(n!==4&&(e=e.child,e!==null))for(D0(e,t,r),e=e.sibling;e!==null;)D0(e,t,r),e=e.sibling}function $0(e,t,r){var n=e.tag;if(n===5||n===6)e=e.stateNode,t?r.insertBefore(e,t):r.appendChild(e);else if(n!==4&&(e=e.child,e!==null))for($0(e,t,r),e=e.sibling;e!==null;)$0(e,t,r),e=e.sibling}var qt=null,Yn=!1;function yi(e,t,r){for(r=r.child;r!==null;)qM(e,t,r),r=r.sibling}function qM(e,t,r){if(ko&&typeof ko.onCommitFiberUnmount=="function")try{ko.onCommitFiberUnmount(qh,r)}catch{}switch(r.tag){case 5:ur||ll(r,t);case 6:var n=qt,o=Yn;qt=null,yi(e,t,r),qt=n,Yn=o,qt!==null&&(Yn?(e=qt,r=r.stateNode,e.nodeType===8?e.parentNode.removeChild(r):e.removeChild(r)):qt.removeChild(r.stateNode));break;case 18:qt!==null&&(Yn?(e=qt,r=r.stateNode,e.nodeType===8?Fg(e.parentNode,r):e.nodeType===1&&Fg(e,r),Yu(e)):Fg(qt,r.stateNode));break;case 4:n=qt,o=Yn,qt=r.stateNode.containerInfo,Yn=!0,yi(e,t,r),qt=n,Yn=o;break;case 0:case 11:case 14:case 15:if(!ur&&(n=r.updateQueue,n!==null&&(n=n.lastEffect,n!==null))){o=n=n.next;do{var i=o,s=i.destroy;i=i.tag,s!==void 0&&(i&2||i&4)&&L0(r,t,s),o=o.next}while(o!==n)}yi(e,t,r);break;case 1:if(!ur&&(ll(r,t),n=r.stateNode,typeof n.componentWillUnmount=="function"))try{n.props=r.memoizedProps,n.state=r.memoizedState,n.componentWillUnmount()}catch(a){mt(r,t,a)}yi(e,t,r);break;case 21:yi(e,t,r);break;case 22:r.mode&1?(ur=(n=ur)||r.memoizedState!==null,yi(e,t,r),ur=n):yi(e,t,r);break;default:yi(e,t,r)}}function mw(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var r=e.stateNode;r===null&&(r=e.stateNode=new s9),t.forEach(function(n){var o=g9.bind(null,e,n);r.has(n)||(r.add(n),n.then(o,o))})}}function Un(e,t){var r=t.deletions;if(r!==null)for(var n=0;no&&(o=s),n&=~i}if(n=o,n=vt()-n,n=(120>n?120:480>n?480:1080>n?1080:1920>n?1920:3e3>n?3e3:4320>n?4320:1960*c9(n/1960))-n,10e?16:e,Hi===null)var n=!1;else{if(e=Hi,Hi=null,nh=0,Oe&6)throw Error(H(331));var o=Oe;for(Oe|=4,X=e.current;X!==null;){var i=X,s=i.child;if(X.flags&16){var a=i.deletions;if(a!==null){for(var l=0;lvt()-zy?Qs(e,0):Py|=r),Hr(e,t)}function tT(e,t){t===0&&(e.mode&1?(t=uf,uf<<=1,!(uf&130023424)&&(uf=4194304)):t=1);var r=wr();e=oi(e,t),e!==null&&(Fd(e,t,r),Hr(e,r))}function m9(e){var t=e.memoizedState,r=0;t!==null&&(r=t.retryLane),tT(e,r)}function g9(e,t){var r=0;switch(e.tag){case 13:var n=e.stateNode,o=e.memoizedState;o!==null&&(r=o.retryLane);break;case 19:n=e.stateNode;break;default:throw Error(H(314))}n!==null&&n.delete(t),tT(e,r)}var rT;rT=function(e,t,r){if(e!==null)if(e.memoizedProps!==t.pendingProps||Dr.current)zr=!0;else{if(!(e.lanes&r)&&!(t.flags&128))return zr=!1,n9(e,t,r);zr=!!(e.flags&131072)}else zr=!1,ot&&t.flags&1048576&&iM(t,Gp,t.index);switch(t.lanes=0,t.tag){case 2:var n=t.type;Qf(e,t),e=t.pendingProps;var o=Dl(t,pr.current);bl(t,r),o=Ty(null,t,n,e,o,r);var i=Oy();return t.flags|=1,typeof o=="object"&&o!==null&&typeof o.render=="function"&&o.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,$r(n)?(i=!0,Kp(t)):i=!1,t.memoizedState=o.state!==null&&o.state!==void 0?o.state:null,wy(t),o.updater=Zh,t.stateNode=o,o._reactInternals=t,O0(t,n,e,r),t=N0(null,t,n,!0,i,r)):(t.tag=0,ot&&i&&my(t),yr(null,t,o,r),t=t.child),t;case 16:n=t.elementType;e:{switch(Qf(e,t),e=t.pendingProps,o=n._init,n=o(n._payload),t.type=n,o=t.tag=y9(n),e=Gn(n,e),o){case 0:t=A0(null,t,n,e,r);break e;case 1:t=uw(null,t,n,e,r);break e;case 11:t=lw(null,t,n,e,r);break e;case 14:t=cw(null,t,n,Gn(n.type,e),r);break e}throw Error(H(306,n,""))}return t;case 0:return n=t.type,o=t.pendingProps,o=t.elementType===n?o:Gn(n,o),A0(e,t,n,o,r);case 1:return n=t.type,o=t.pendingProps,o=t.elementType===n?o:Gn(n,o),uw(e,t,n,o,r);case 3:e:{if(HM(t),e===null)throw Error(H(387));n=t.pendingProps,i=t.memoizedState,o=i.element,cM(e,t),Xp(t,n,null,r);var s=t.memoizedState;if(n=s.element,i.isDehydrated)if(i={element:n,isDehydrated:!1,cache:s.cache,pendingSuspenseBoundaries:s.pendingSuspenseBoundaries,transitions:s.transitions},t.updateQueue.baseState=i,t.memoizedState=i,t.flags&256){o=Fl(Error(H(423)),t),t=dw(e,t,n,r,o);break e}else if(n!==o){o=Fl(Error(H(424)),t),t=dw(e,t,n,r,o);break e}else for(ln=Gi(t.stateNode.containerInfo.firstChild),cn=t,ot=!0,Xn=null,r=pM(t,null,n,r),t.child=r;r;)r.flags=r.flags&-3|4096,r=r.sibling;else{if($l(),n===o){t=ii(e,t,r);break e}yr(e,t,n,r)}t=t.child}return t;case 5:return hM(t),e===null&&C0(t),n=t.type,o=t.pendingProps,i=e!==null?e.memoizedProps:null,s=o.children,x0(n,o)?s=null:i!==null&&x0(n,i)&&(t.flags|=32),$M(e,t),yr(e,t,s,r),t.child;case 6:return e===null&&C0(t),null;case 13:return BM(e,t,r);case 4:return Sy(t,t.stateNode.containerInfo),n=t.pendingProps,e===null?t.child=Hl(t,null,n,r):yr(e,t,n,r),t.child;case 11:return n=t.type,o=t.pendingProps,o=t.elementType===n?o:Gn(n,o),lw(e,t,n,o,r);case 7:return yr(e,t,t.pendingProps,r),t.child;case 8:return yr(e,t,t.pendingProps.children,r),t.child;case 12:return yr(e,t,t.pendingProps.children,r),t.child;case 10:e:{if(n=t.type._context,o=t.pendingProps,i=t.memoizedProps,s=o.value,Ye(Yp,n._currentValue),n._currentValue=s,i!==null)if(so(i.value,s)){if(i.children===o.children&&!Dr.current){t=ii(e,t,r);break e}}else for(i=t.child,i!==null&&(i.return=t);i!==null;){var a=i.dependencies;if(a!==null){s=i.child;for(var l=a.firstContext;l!==null;){if(l.context===n){if(i.tag===1){l=ei(-1,r&-r),l.tag=2;var c=i.updateQueue;if(c!==null){c=c.shared;var u=c.pending;u===null?l.next=l:(l.next=u.next,u.next=l),c.pending=l}}i.lanes|=r,l=i.alternate,l!==null&&(l.lanes|=r),M0(i.return,r,t),a.lanes|=r;break}l=l.next}}else if(i.tag===10)s=i.type===t.type?null:i.child;else if(i.tag===18){if(s=i.return,s===null)throw Error(H(341));s.lanes|=r,a=s.alternate,a!==null&&(a.lanes|=r),M0(s,r,t),s=i.sibling}else s=i.child;if(s!==null)s.return=i;else for(s=i;s!==null;){if(s===t){s=null;break}if(i=s.sibling,i!==null){i.return=s.return,s=i;break}s=s.return}i=s}yr(e,t,o.children,r),t=t.child}return t;case 9:return o=t.type,n=t.pendingProps.children,bl(t,r),o=Pn(o),n=n(o),t.flags|=1,yr(e,t,n,r),t.child;case 14:return n=t.type,o=Gn(n,t.pendingProps),o=Gn(n.type,o),cw(e,t,n,o,r);case 15:return IM(e,t,t.type,t.pendingProps,r);case 17:return n=t.type,o=t.pendingProps,o=t.elementType===n?o:Gn(n,o),Qf(e,t),t.tag=1,$r(n)?(e=!0,Kp(t)):e=!1,bl(t,r),dM(t,n,o),O0(t,n,o,r),N0(null,t,n,!0,e,r);case 19:return FM(e,t,r);case 22:return DM(e,t,r)}throw Error(H(156,t.tag))};function nT(e,t){return _5(e,t)}function v9(e,t,r,n){this.tag=e,this.key=r,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=n,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function On(e,t,r,n){return new v9(e,t,r,n)}function $y(e){return e=e.prototype,!(!e||!e.isReactComponent)}function y9(e){if(typeof e=="function")return $y(e)?1:0;if(e!=null){if(e=e.$$typeof,e===ny)return 11;if(e===oy)return 14}return 2}function Qi(e,t){var r=e.alternate;return r===null?(r=On(e.tag,t,e.key,e.mode),r.elementType=e.elementType,r.type=e.type,r.stateNode=e.stateNode,r.alternate=e,e.alternate=r):(r.pendingProps=t,r.type=e.type,r.flags=0,r.subtreeFlags=0,r.deletions=null),r.flags=e.flags&14680064,r.childLanes=e.childLanes,r.lanes=e.lanes,r.child=e.child,r.memoizedProps=e.memoizedProps,r.memoizedState=e.memoizedState,r.updateQueue=e.updateQueue,t=e.dependencies,r.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},r.sibling=e.sibling,r.index=e.index,r.ref=e.ref,r}function tp(e,t,r,n,o,i){var s=2;if(n=e,typeof e=="function")$y(e)&&(s=1);else if(typeof e=="string")s=5;else e:switch(e){case Za:return Zs(r.children,o,i,t);case ry:s=8,o|=8;break;case Q1:return e=On(12,r,t,o|2),e.elementType=Q1,e.lanes=i,e;case Z1:return e=On(13,r,t,o),e.elementType=Z1,e.lanes=i,e;case e0:return e=On(19,r,t,o),e.elementType=e0,e.lanes=i,e;case f5:return nm(r,o,i,t);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case u5:s=10;break e;case d5:s=9;break e;case ny:s=11;break e;case oy:s=14;break e;case _i:s=16,n=null;break e}throw Error(H(130,e==null?e:typeof e,""))}return t=On(s,r,t,o),t.elementType=e,t.type=n,t.lanes=i,t}function Zs(e,t,r,n){return e=On(7,e,n,t),e.lanes=r,e}function nm(e,t,r,n){return e=On(22,e,n,t),e.elementType=f5,e.lanes=r,e.stateNode={isHidden:!1},e}function Yg(e,t,r){return e=On(6,e,null,t),e.lanes=r,e}function Jg(e,t,r){return t=On(4,e.children!==null?e.children:[],e.key,t),t.lanes=r,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function b9(e,t,r,n,o){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=Ag(0),this.expirationTimes=Ag(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Ag(0),this.identifierPrefix=n,this.onRecoverableError=o,this.mutableSourceEagerHydrationData=null}function Hy(e,t,r,n,o,i,s,a,l){return e=new b9(e,t,r,a,l),t===1?(t=1,i===!0&&(t|=8)):t=0,i=On(3,null,null,t),e.current=i,i.stateNode=e,i.memoizedState={element:n,isDehydrated:r,cache:null,transitions:null,pendingSuspenseBoundaries:null},wy(i),e}function x9(e,t,r){var n=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(aT)}catch(e){console.error(e)}}aT(),i5.exports=hn;var lm=i5.exports;const wf=Dn(lm);var C9=Object.defineProperty,M9=Object.getOwnPropertyDescriptor,T9=(e,t,r,n)=>{for(var o=n>1?void 0:n?M9(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&C9(t,r,o),o},lT=(e,t,r)=>{if(!t.has(e))throw TypeError("Cannot "+r)},ne=(e,t,r)=>(lT(e,t,"read from private field"),r?r.call(e):t.get(e)),en=(e,t,r)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,r)},Qr=(e,t,r,n)=>(lT(e,t,"write to private field"),n?n.call(e,r):t.set(e,r),r),Gc,O9=class{constructor(){this.portals=new Map,en(this,Gc,Uh()),this.on=e=>ne(this,Gc).on("update",e),this.once=e=>{const t=ne(this,Gc).on("update",r=>{t(),e(r)});return t}}update(){ne(this,Gc).emit("update",this.portals)}render({Component:e,container:t}){const r=this.portals.get(t);this.portals.set(t,{Component:e,key:(r==null?void 0:r.key)??Cl()}),this.update()}forceUpdate(){for(const[e,{Component:t}]of this.portals)this.portals.set(e,{Component:t,key:Cl()})}remove(e){this.portals.delete(e),this.update()}};Gc=new WeakMap;var _9=e=>{const{portals:t}=e;return I.createElement(I.Fragment,null,t.map(([r,{Component:n,key:o}])=>lm.createPortal(I.createElement(n,null),r,o)))};function A9(e){const[t,r]=S.useState(()=>Array.from(e.portals.entries()));return S.useEffect(()=>e.on(n=>{r(Array.from(n.entries()))}),[e]),S.useMemo(()=>t,[t])}var st,Yc,_s,Jc,rp,Xc,Ka,Qc,np,Ho,vr,j0,cT=class{constructor({getPosition:e,node:t,portalContainer:r,view:n,ReactComponent:o,options:i}){en(this,st,void 0),en(this,Yc,[]),en(this,_s,void 0),en(this,Jc,void 0),en(this,rp,void 0),en(this,Xc,void 0),en(this,Ka,void 0),en(this,Qc,!1),en(this,np,void 0),en(this,Ho,void 0),en(this,vr,void 0),en(this,j0,l=>{l&&(re(ne(this,Ho),{code:B.REACT_NODE_VIEW,message:`You have applied a ref to a node view provided for '${ne(this,st).type.name}' which doesn't support content.`}),l.append(ne(this,Ho)))}),this.Component=()=>{const l=ne(this,rp);return re(l,{code:B.REACT_NODE_VIEW,message:`The custom react node view provided for ${ne(this,st).type.name} doesn't have a valid ReactComponent`}),I.createElement(l,{updateAttributes:this.updateAttributes,selected:this.selected,view:ne(this,_s),getPosition:ne(this,Xc),node:ne(this,st),forwardRef:ne(this,j0),decorations:ne(this,Yc)})},this.updateAttributes=l=>{if(!ne(this,_s).editable)return;const c=ne(this,Xc).call(this);if(c==null)return;const u=ne(this,_s).state.tr.setNodeMarkup(c,void 0,{...ne(this,st).attrs,...l});ne(this,_s).dispatch(u)},re(_e(e),{message:"You are attempting to use a node view for a mark type. This is not supported yet. Please check your configuration."}),Qr(this,st,t),Qr(this,_s,n),Qr(this,Jc,r),Qr(this,rp,o),Qr(this,Xc,e),Qr(this,Ka,i),Qr(this,vr,this.createDom());const{contentDOM:s,wrapper:a}=this.createContentDom()??{};Qr(this,np,s??void 0),Qr(this,Ho,a),ne(this,Ho)&&ne(this,vr).append(ne(this,Ho)),this.setDomAttributes(ne(this,st),ne(this,vr)),this.Component.displayName=j4(`${ne(this,st).type.name}NodeView`),this.renderComponent()}static create(e){const{portalContainer:t,ReactComponent:r,options:n}=e;return(o,i,s)=>new cT({options:n,node:o,view:i,getPosition:s,portalContainer:t,ReactComponent:r})}get selected(){return ne(this,Qc)}get contentDOM(){return ne(this,np)}get dom(){return ne(this,vr)}renderComponent(){ne(this,Jc).render({Component:this.Component,container:ne(this,vr)})}createDom(){const{defaultBlockNode:e,defaultInlineNode:t}=ne(this,Ka),r=ne(this,st).isInline?document.createElement(t):document.createElement(e);return r.classList.add(`${Qx(ne(this,st).type.name)}-node-view-wrapper`),r}createContentDom(){var e,t;if(ne(this,st).isLeaf)return;const r=(t=(e=ne(this,st).type.spec).toDOM)==null?void 0:t.call(e,ne(this,st));if(!r)return;const{contentDOM:n,dom:o}=an.renderSpec(document,r);let i;if(et(o))return i=o,o===n&&(i=document.createElement("span"),i.classList.add(`${Qx(ne(this,st).type.name)}-node-view-content-wrapper`),i.append(n)),et(n),{wrapper:i,contentDOM:n}}update(e,t){return Hh({types:ne(this,st).type,node:e})?(ne(this,st)===e&&ne(this,Yc)===t||(ne(this,st).sameMarkup(e)||this.setDomAttributes(e,ne(this,vr)),Qr(this,st,e),Qr(this,Yc,t),this.renderComponent()),!0):!1}setDomAttributes(e,t){const{toDOM:r}=ne(this,st).type.spec;let n=e.attrs;if(r){const o=r(e);if(oe(o)||N9(o))return;ps(o[1])&&(n=o[1])}for(const[o,i]of At(n))t.setAttribute(o,i)}selectNode(){Qr(this,Qc,!0),ne(this,vr)&&ne(this,vr).classList.add(Gx),this.renderComponent()}deselectNode(){Qr(this,Qc,!1),ne(this,vr)&&ne(this,vr).classList.remove(Gx),this.renderComponent()}destroy(){ne(this,Jc).remove(ne(this,vr))}ignoreMutation(e){return e.type==="selection"?!ne(this,st).type.spec.selectable:ne(this,Ho)?!ne(this,Ho).contains(e.target):!0}stopEvent(e){var t;if(!ne(this,vr))return!1;if(_e(ne(this,Ka).stopEvent))return ne(this,Ka).stopEvent({event:e});const r=e.target;if(!(ne(this,vr).contains(r)&&!((t=this.contentDOM)!=null&&t.contains(r))))return!1;const o=e.type==="drop";if((["INPUT","BUTTON","SELECT","TEXTAREA"].includes(r.tagName)||r.isContentEditable)&&!o)return!0;const s=!!ne(this,st).type.spec.draggable,a=ce.isSelectable(ne(this,st)),l=e.type==="copy",c=e.type==="paste",u=e.type==="cut",d=e.type==="mousedown",f=e.type.startsWith("drag");return!s&&a&&f&&e.preventDefault(),!(f||o||l||c||u||d&&a)}},Sw=cT;st=new WeakMap;Yc=new WeakMap;_s=new WeakMap;Jc=new WeakMap;rp=new WeakMap;Xc=new WeakMap;Ka=new WeakMap;Qc=new WeakMap;np=new WeakMap;Ho=new WeakMap;vr=new WeakMap;j0=new WeakMap;function N9(e){return Np(e)||ps(e)&&Np(e.dom)}var ad=class extends Ve{constructor(){super(...arguments),this.portalContainer=new O9}get name(){return"reactComponent"}onCreate(){this.store.setStoreKey("portalContainer",this.portalContainer)}createNodeViews(){const e=ee(),t=this.store.managerSettings.nodeViewComponents??{};for(const n of this.store.extensions)!n.ReactComponent||!Hd(n)||n.reactComponentEnvironment==="ssr"||(e[n.name]=Sw.create({options:this.options,ReactComponent:n.ReactComponent,portalContainer:this.portalContainer}));const r=At({...this.options.nodeViewComponents,...t});for(const[n,o]of r)e[n]=Sw.create({options:this.options,ReactComponent:o,portalContainer:this.portalContainer});return e}};ad=T9([pe({defaultOptions:{defaultBlockNode:"div",defaultInlineNode:"span",defaultContentNode:"span",defaultEnvironment:"both",nodeViewComponents:{},stopEvent:null},staticKeys:["defaultBlockNode","defaultInlineNode","defaultContentNode","defaultEnvironment"]})],ad);function R9(e){const t=S.createContext(null),r=P9(t);return[o=>{const i=e(o);return I.createElement(t.Provider,{value:i},o.children)},r,t]}function P9(e){return(t,r)=>{const n=S.useContext(e),o=z9(n);if(!n)throw new Error("`useContextHook` must be placed inside the `Provider` returned by the `createContextState` method");if(!t)return n;if(typeof t!="function")throw new TypeError("invalid arguments passed to `useContextHook`. This hook must be called with zero arguments, a getter function or a path string.");const i=t(n);if(!o||!r)return i;const s=t(o);return r(s,i)?s:i}}function z9(e){const t=S.useRef();return L9(()=>{t.current=e}),t.current}var L9=typeof document<"u"?S.useLayoutEffect:S.useEffect;function I9(e,t){return R9(r=>{const n=S.useRef(null),o=S.useRef(),i=t==null?void 0:t(r),[s,a]=S.useState(()=>e({get:Ew(n),set:Cw(o),previousContext:void 0,props:r,state:i})),l=[...Object.values(r),i];return S.useEffect(()=>{l.length!==0&&a(c=>e({get:Ew(n),set:Cw(o),previousContext:c,props:r,state:i}))},l),n.current=s,o.current=a,s})}function Ew(e){return t=>{if(!e.current)throw new Error("`get` called outside of function scope. `get` can only be called within a function.");if(!t)return e.current;if(typeof t!="function")throw new TypeError("Invalid arguments passed to `useContextHook`. The hook must be called with zero arguments, a getter function or a path string.");return t(e.current)}}function Cw(e){return t=>{if(!e.current)throw new Error("`set` called outside of function scope. `set` can only be called within a function.");e.current(r=>({...r,...typeof t=="function"?t(r):t}))}}var uT={},dT={};(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.errorMessages=e.ErrorType=void 0;var t;(function(r){r.MalformedUnicode="MALFORMED_UNICODE",r.MalformedHexadecimal="MALFORMED_HEXADECIMAL",r.CodePointLimit="CODE_POINT_LIMIT",r.OctalDeprecation="OCTAL_DEPRECATION",r.EndOfString="END_OF_STRING"})(t=e.ErrorType||(e.ErrorType={})),e.errorMessages=new Map([[t.MalformedUnicode,"malformed Unicode character escape sequence"],[t.MalformedHexadecimal,"malformed hexadecimal character escape sequence"],[t.CodePointLimit,"Unicode codepoint must not be greater than 0x10FFFF in escape sequence"],[t.OctalDeprecation,'"0"-prefixed octal literals and octal escape sequences are deprecated; for octal literals use the "0o" prefix instead'],[t.EndOfString,"malformed escape sequence at end of string"]])})(dT);(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.unraw=e.errorMessages=e.ErrorType=void 0;const t=dT;Object.defineProperty(e,"ErrorType",{enumerable:!0,get:function(){return t.ErrorType}}),Object.defineProperty(e,"errorMessages",{enumerable:!0,get:function(){return t.errorMessages}});function r(p){return!p.match(/[^a-f0-9]/i)?parseInt(p,16):NaN}function n(p,h,m){const b=r(p);if(Number.isNaN(b)||m!==void 0&&m!==p.length)throw new SyntaxError(t.errorMessages.get(h));return b}function o(p){const h=n(p,t.ErrorType.MalformedHexadecimal,2);return String.fromCharCode(h)}function i(p,h){const m=n(p,t.ErrorType.MalformedUnicode,4);if(h!==void 0){const b=n(h,t.ErrorType.MalformedUnicode,4);return String.fromCharCode(m,b)}return String.fromCharCode(m)}function s(p){return p.charAt(0)==="{"&&p.charAt(p.length-1)==="}"}function a(p){if(!s(p))throw new SyntaxError(t.errorMessages.get(t.ErrorType.MalformedUnicode));const h=p.slice(1,-1),m=n(h,t.ErrorType.MalformedUnicode);try{return String.fromCodePoint(m)}catch(b){throw b instanceof RangeError?new SyntaxError(t.errorMessages.get(t.ErrorType.CodePointLimit)):b}}function l(p,h=!1){if(h)throw new SyntaxError(t.errorMessages.get(t.ErrorType.OctalDeprecation));const m=parseInt(p,8);return String.fromCharCode(m)}const c=new Map([["b","\b"],["f","\f"],["n",` +`],["r","\r"],["t"," "],["v","\v"],["0","\0"]]);function u(p){return c.get(p)||p}const d=/\\(?:(\\)|x([\s\S]{0,2})|u(\{[^}]*\}?)|u([\s\S]{4})\\u([^{][\s\S]{0,3})|u([\s\S]{0,4})|([0-3]?[0-7]{1,2})|([\s\S])|$)/g;function f(p,h=!1){return p.replace(d,function(m,b,v,g,y,x,k,w,E){if(b!==void 0)return"\\";if(v!==void 0)return o(v);if(g!==void 0)return a(g);if(y!==void 0)return i(y,x);if(k!==void 0)return i(k);if(w==="0")return"\0";if(w!==void 0)return l(w,!h);if(E!==void 0)return u(E);throw new SyntaxError(t.errorMessages.get(t.ErrorType.EndOfString))})}e.unraw=f,e.default=f})(uT);const D9=Dn(uT),Yo=e=>typeof e=="string",$9=e=>typeof e=="function",Mw=new Map;function jy(e){return[...Array.isArray(e)?e:[e],"en"]}function fT(e,t,r){const n=jy(e);return sh(()=>ah("date",n,r),()=>new Intl.DateTimeFormat(n,r)).format(Yo(t)?new Date(t):t)}function U0(e,t,r){const n=jy(e);return sh(()=>ah("number",n,r),()=>new Intl.NumberFormat(n,r)).format(t)}function Tw(e,t,r,{offset:n=0,...o}){const i=jy(e),s=t?sh(()=>ah("plural-ordinal",i),()=>new Intl.PluralRules(i,{type:"ordinal"})):sh(()=>ah("plural-cardinal",i),()=>new Intl.PluralRules(i,{type:"cardinal"}));return o[r]??o[s.select(r-n)]??o.other}function sh(e,t){const r=e();let n=Mw.get(r);return n||(n=t(),Mw.set(r,n)),n}function ah(e,t,r){const n=t.join("-");return`${e}-${n}-${JSON.stringify(r)}`}const pT=/\\u[a-fA-F0-9]{4}|\\x[a-fA-F0-9]{2}/g,H9=(e,t,r={})=>{t=t||e;const n=i=>Yo(i)?r[i]||{style:i}:i,o=(i,s)=>{const a=Object.keys(r).length?n("number"):{},l=U0(t,i,a);return s.replace("#",l)};return{plural:(i,s)=>{const{offset:a=0}=s,l=Tw(t,!1,i,s);return o(i-a,l)},selectordinal:(i,s)=>{const{offset:a=0}=s,l=Tw(t,!0,i,s);return o(i-a,l)},select:(i,s)=>s[i]??s.other,number:(i,s)=>U0(t,i,n(s)),date:(i,s)=>fT(t,i,n(s)),undefined:i=>i}};function B9(e,t,r){return(n,o={})=>{const i=H9(t,r,o),s=l=>Array.isArray(l)?l.reduce((c,u)=>{if(Yo(u))return c+u;const[d,f,p]=u;let h={};p!=null&&!Yo(p)?Object.keys(p).forEach(b=>{h[b]=s(p[b])}):h=p;const m=i[f](n[d],h);return m==null?c:c+m},""):l,a=s(e);return Yo(a)&&pT.test(a)?D9(a.trim()):Yo(a)?a.trim():a}}var F9=Object.defineProperty,V9=(e,t,r)=>t in e?F9(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,j9=(e,t,r)=>(V9(e,typeof t!="symbol"?t+"":t,r),r);class U9{constructor(){j9(this,"_events",{})}on(t,r){return this._hasEvent(t)||(this._events[t]=[]),this._events[t].push(r),()=>this.removeListener(t,r)}removeListener(t,r){if(!this._hasEvent(t))return;const n=this._events[t].indexOf(r);~n&&this._events[t].splice(n,1)}emit(t,...r){this._hasEvent(t)&&this._events[t].map(n=>n.apply(this,r))}_hasEvent(t){return Array.isArray(this._events[t])}}var W9=Object.defineProperty,K9=(e,t,r)=>t in e?W9(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,Pa=(e,t,r)=>(K9(e,typeof t!="symbol"?t+"":t,r),r);class q9 extends U9{constructor(t){super(),Pa(this,"_locale"),Pa(this,"_locales"),Pa(this,"_localeData"),Pa(this,"_messages"),Pa(this,"_missing"),Pa(this,"t",this._.bind(this)),this._messages={},this._localeData={},t.missing!=null&&(this._missing=t.missing),t.messages!=null&&this.load(t.messages),t.localeData!=null&&this.loadLocaleData(t.localeData),(t.locale!=null||t.locales!=null)&&this.activate(t.locale,t.locales)}get locale(){return this._locale}get locales(){return this._locales}get messages(){return this._messages[this._locale]??{}}get localeData(){return this._localeData[this._locale]??{}}_loadLocaleData(t,r){this._localeData[t]==null?this._localeData[t]=r:Object.assign(this._localeData[t],r)}loadLocaleData(t,r){r!=null?this._loadLocaleData(t,r):Object.keys(t).forEach(n=>this._loadLocaleData(n,t[n])),this.emit("change")}_load(t,r){this._messages[t]==null?this._messages[t]=r:Object.assign(this._messages[t],r)}load(t,r){r!=null?this._load(t,r):Object.keys(t).forEach(n=>this._load(n,t[n])),this.emit("change")}loadAndActivate({locale:t,locales:r,messages:n}){this._locale=t,this._locales=r||void 0,this._messages[this._locale]=n,this.emit("change")}activate(t,r){this._locale=t,this._locales=r,this.emit("change")}_(t,r={},{message:n,formats:o}={}){Yo(t)||(r=t.values||r,n=t.message,t=t.id);const i=!this.messages[t],s=this._missing;if(s&&i)return $9(s)?s(this._locale,t):s;i&&this.emit("missing",{id:t,locale:this._locale});let a=this.messages[t]||n||t;return Yo(a)&&pT.test(a)?JSON.parse(`"${a}"`):Yo(a)?a:B9(a,this._locale,this._locales)(r,o)}date(t,r){return fT(this._locales||this._locale,t,r)}number(t,r){return U0(this._locales||this._locale,t,r)}}function G9(e={}){return new q9(e)}const cm=G9();function W(e,t){return t?"other":e==1?"one":"other"}function di(e,t){return t?"other":e==0||e==1?"one":"other"}function Kr(e,t){var r=String(e).split("."),n=!r[1];return t?"other":e==1&&n?"one":"other"}function Le(e,t){return"other"}function bs(e,t){return t?"other":e==1?"one":e==2?"two":"other"}const Y9=Le,J9=W,X9=di;function Q9(e,t){return t?"other":e>=0&&e<=1?"one":"other"}const Z9=W;function eD(e,t){var r=String(e).split("."),n=Number(r[0])==e,o=n&&r[0].slice(-2);return t?"other":e==0?"zero":e==1?"one":e==2?"two":o>=3&&o<=10?"few":o>=11&&o<=99?"many":"other"}function tD(e,t){var r=String(e).split("."),n=Number(r[0])==e,o=n&&r[0].slice(-2);return t?"other":e==0?"zero":e==1?"one":e==2?"two":o>=3&&o<=10?"few":o>=11&&o<=99?"many":"other"}function rD(e,t){return t?e==1||e==5||e==7||e==8||e==9||e==10?"one":e==2||e==3?"two":e==4?"few":e==6?"many":"other":e>=0&&e<=1?"one":"other"}const nD=W,oD=Kr;function iD(e,t){var r=String(e).split("."),n=r[0],o=n.slice(-1),i=n.slice(-2),s=n.slice(-3);return t?o==1||o==2||o==5||o==7||o==8||i==20||i==50||i==70||i==80?"one":o==3||o==4||s==100||s==200||s==300||s==400||s==500||s==600||s==700||s==800||s==900?"few":n==0||o==6||i==40||i==60||i==90?"many":"other":e==1?"one":"other"}function sD(e,t){var r=String(e).split("."),n=Number(r[0])==e,o=n&&r[0].slice(-1),i=n&&r[0].slice(-2);return t?(o==2||o==3)&&i!=12&&i!=13?"few":"other":o==1&&i!=11?"one":o>=2&&o<=4&&(i<12||i>14)?"few":n&&o==0||o>=5&&o<=9||i>=11&&i<=14?"many":"other"}const aD=W,lD=W,cD=W,uD=di,dD=Le;function fD(e,t){return t?e==1||e==5||e==7||e==8||e==9||e==10?"one":e==2||e==3?"two":e==4?"few":e==6?"many":"other":e>=0&&e<=1?"one":"other"}const pD=Le;function hD(e,t){var r=String(e).split("."),n=Number(r[0])==e,o=n&&r[0].slice(-1),i=n&&r[0].slice(-2),s=n&&r[0].slice(-6);return t?"other":o==1&&i!=11&&i!=71&&i!=91?"one":o==2&&i!=12&&i!=72&&i!=92?"two":(o==3||o==4||o==9)&&(i<10||i>19)&&(i<70||i>79)&&(i<90||i>99)?"few":e!=0&&n&&s==0?"many":"other"}const mD=W;function gD(e,t){var r=String(e).split("."),n=r[0],o=r[1]||"",i=!r[1],s=n.slice(-1),a=n.slice(-2),l=o.slice(-1),c=o.slice(-2);return t?"other":i&&s==1&&a!=11||l==1&&c!=11?"one":i&&s>=2&&s<=4&&(a<12||a>14)||l>=2&&l<=4&&(c<12||c>14)?"few":"other"}function vD(e,t){var r=String(e).split("."),n=!r[1];return t?e==1||e==3?"one":e==2?"two":e==4?"few":"other":e==1&&n?"one":"other"}const yD=W;function bD(e,t){var r=String(e).split("."),n=r[0],o=r[1]||"",i=!r[1],s=n.slice(-1),a=o.slice(-1);return t?"other":i&&(n==1||n==2||n==3)||i&&s!=4&&s!=6&&s!=9||!i&&a!=4&&a!=6&&a!=9?"one":"other"}const xD=W,kD=W,wD=W;function SD(e,t){var r=String(e).split("."),n=r[0],o=!r[1];return t?"other":e==1&&o?"one":n>=2&&n<=4&&o?"few":o?"other":"many"}function ED(e,t){return t?e==0||e==7||e==8||e==9?"zero":e==1?"one":e==2?"two":e==3||e==4?"few":e==5||e==6?"many":"other":e==0?"zero":e==1?"one":e==2?"two":e==3?"few":e==6?"many":"other"}function CD(e,t){var r=String(e).split("."),n=r[0],o=Number(r[0])==e;return t?"other":e==1||!o&&(n==0||n==1)?"one":"other"}const MD=Kr;function TD(e,t){var r=String(e).split("."),n=r[0],o=r[1]||"",i=!r[1],s=n.slice(-2),a=o.slice(-2);return t?"other":i&&s==1||a==1?"one":i&&s==2||a==2?"two":i&&(s==3||s==4)||a==3||a==4?"few":"other"}const OD=W,_D=Le,AD=W,ND=W;function RD(e,t){var r=String(e).split("."),n=!r[1],o=Number(r[0])==e,i=o&&r[0].slice(-1),s=o&&r[0].slice(-2);return t?i==1&&s!=11?"one":i==2&&s!=12?"two":i==3&&s!=13?"few":"other":e==1&&n?"one":"other"}const PD=W,zD=W,LD=Kr,ID=W;function DD(e,t){return t?"other":e>=0&&e<=1?"one":"other"}function $D(e,t){return t?"other":e>=0&&e<2?"one":"other"}const HD=Kr;function BD(e,t){var r=String(e).split("."),n=r[0],o=r[1]||"",i=!r[1],s=n.slice(-1),a=o.slice(-1);return t?e==1?"one":"other":i&&(n==1||n==2||n==3)||i&&s!=4&&s!=6&&s!=9||!i&&a!=4&&a!=6&&a!=9?"one":"other"}const FD=W;function VD(e,t){return t?e==1?"one":"other":e>=0&&e<2?"one":"other"}const jD=W,UD=Kr;function WD(e,t){var r=String(e).split("."),n=Number(r[0])==e;return t?e==1?"one":"other":e==1?"one":e==2?"two":n&&e>=3&&e<=6?"few":n&&e>=7&&e<=10?"many":"other"}function KD(e,t){var r=String(e).split("."),n=Number(r[0])==e;return t?e==1||e==11?"one":e==2||e==12?"two":e==3||e==13?"few":"other":e==1||e==11?"one":e==2||e==12?"two":n&&e>=3&&e<=10||n&&e>=13&&e<=19?"few":"other"}const qD=Kr,GD=W;function YD(e,t){return t?e==1?"one":e==2||e==3?"two":e==4?"few":e==6?"many":"other":e>=0&&e<=1?"one":"other"}const JD=di;function XD(e,t){var r=String(e).split("."),n=r[0],o=!r[1],i=n.slice(-1),s=n.slice(-2);return t?"other":o&&i==1?"one":o&&i==2?"two":o&&(s==0||s==20||s==40||s==60||s==80)?"few":o?"other":"many"}const QD=W,ZD=W;function e7(e,t){var r=String(e).split("."),n=r[0],o=!r[1],i=Number(r[0])==e,s=i&&r[0].slice(-1);return t?"other":e==1&&o?"one":n==2&&o?"two":o&&(e<0||e>10)&&i&&s==0?"many":"other"}function t7(e,t){return t?e==1?"one":e==2||e==3?"two":e==4?"few":e==6?"many":"other":e>=0&&e<=1?"one":"other"}function r7(e,t){var r=String(e).split("."),n=r[0],o=r[1]||"",i=!r[1],s=n.slice(-1),a=n.slice(-2),l=o.slice(-1),c=o.slice(-2);return t?"other":i&&s==1&&a!=11||l==1&&c!=11?"one":i&&s>=2&&s<=4&&(a<12||a>14)||l>=2&&l<=4&&(c<12||c>14)?"few":"other"}function n7(e,t){var r=String(e).split("."),n=r[0],o=r[1]||"",i=!r[1],s=n.slice(-2),a=o.slice(-2);return t?"other":i&&s==1||a==1?"one":i&&s==2||a==2?"two":i&&(s==3||s==4)||a==3||a==4?"few":"other"}function o7(e,t){return t?e==1||e==5?"one":"other":e==1?"one":"other"}function i7(e,t){return t?e==1?"one":"other":e>=0&&e<2?"one":"other"}const s7=Kr,a7=Le,l7=Le,c7=Le,u7=Kr;function d7(e,t){var r=String(e).split("."),n=r[0],o=Number(r[0])==e,i=n.slice(-1),s=n.slice(-2);return t?"other":o&&i==1&&s!=11||!o?"one":"other"}function f7(e,t){var r=String(e).split("."),n=!r[1];return t?e==11||e==8||e==80||e==800?"many":"other":e==1&&n?"one":"other"}const p7=bs;function h7(e,t){var r=String(e).split("."),n=r[0],o=!r[1],i=Number(r[0])==e,s=i&&r[0].slice(-1);return t?"other":e==1&&o?"one":n==2&&o?"two":o&&(e<0||e>10)&&i&&s==0?"many":"other"}const m7=Le,g7=Le,v7=W,y7=Kr,b7=W,x7=Le,k7=Le;function w7(e,t){var r=String(e).split("."),n=r[0],o=n.slice(-2);return t?n==1?"one":n==0||o>=2&&o<=20||o==40||o==60||o==80?"many":"other":e==1?"one":"other"}function S7(e,t){return t?"other":e>=0&&e<2?"one":"other"}const E7=W,C7=W,M7=Le,T7=Le;function O7(e,t){var r=String(e).split("."),n=Number(r[0])==e,o=n&&r[0].slice(-1);return t?o==6||o==9||n&&o==0&&e!=0?"many":"other":e==1?"one":"other"}const _7=W,A7=W,N7=Le;function R7(e,t){return t?"other":e>=0&&e<=1?"one":"other"}const P7=Le,z7=W,L7=W;function I7(e,t){return t?"other":e==0?"zero":e==1?"one":"other"}const D7=W;function $7(e,t){var r=String(e).split("."),n=Number(r[0])==e,o=n&&r[0].slice(-2),i=n&&r[0].slice(-3),s=n&&r[0].slice(-5),a=n&&r[0].slice(-6);return t?n&&e>=1&&e<=4||o>=1&&o<=4||o>=21&&o<=24||o>=41&&o<=44||o>=61&&o<=64||o>=81&&o<=84?"one":e==5||o==5?"many":"other":e==0?"zero":e==1?"one":o==2||o==22||o==42||o==62||o==82||n&&i==0&&(s>=1e3&&s<=2e4||s==4e4||s==6e4||s==8e4)||e!=0&&a==1e5?"two":o==3||o==23||o==43||o==63||o==83?"few":e!=1&&(o==1||o==21||o==41||o==61||o==81)?"many":"other"}const H7=W;function B7(e,t){var r=String(e).split("."),n=r[0];return t?"other":e==0?"zero":(n==0||n==1)&&e!=0?"one":"other"}const F7=W,V7=W,j7=Le,U7=di;function W7(e,t){return t&&e==1?"one":"other"}function K7(e,t){var r=String(e).split("."),n=r[1]||"",o=Number(r[0])==e,i=o&&r[0].slice(-1),s=o&&r[0].slice(-2);return t?"other":i==1&&(s<11||s>19)?"one":i>=2&&i<=9&&(s<11||s>19)?"few":n!=0?"many":"other"}function q7(e,t){var r=String(e).split("."),n=r[1]||"",o=n.length,i=Number(r[0])==e,s=i&&r[0].slice(-1),a=i&&r[0].slice(-2),l=n.slice(-2),c=n.slice(-1);return t?"other":i&&s==0||a>=11&&a<=19||o==2&&l>=11&&l<=19?"zero":s==1&&a!=11||o==2&&c==1&&l!=11||o!=2&&c==1?"one":"other"}const G7=W,Y7=di,J7=W;function X7(e,t){var r=String(e).split("."),n=r[0],o=r[1]||"",i=!r[1],s=n.slice(-1),a=n.slice(-2),l=o.slice(-1),c=o.slice(-2);return t?s==1&&a!=11?"one":s==2&&a!=12?"two":(s==7||s==8)&&a!=17&&a!=18?"many":"other":i&&s==1&&a!=11||l==1&&c!=11?"one":"other"}const Q7=W,Z7=W;function e$(e,t){var r=String(e).split("."),n=!r[1],o=Number(r[0])==e,i=o&&r[0].slice(-2);return t?e==1?"one":"other":e==1&&n?"one":!n||e==0||i>=2&&i<=19?"few":"other"}function t$(e,t){return t?e==1?"one":e==2||e==3?"two":e==4?"few":"other":e==1?"one":"other"}function r$(e,t){return t&&e==1?"one":"other"}function n$(e,t){var r=String(e).split("."),n=Number(r[0])==e,o=n&&r[0].slice(-2);return t?"other":e==1?"one":e==0||o>=2&&o<=10?"few":o>=11&&o<=19?"many":"other"}const o$=Le,i$=W,s$=bs,a$=W,l$=W;function c$(e,t){var r=String(e).split("."),n=Number(r[0])==e;return t?n&&e>=1&&e<=4?"one":"other":e==1?"one":"other"}const u$=Kr,d$=W,f$=W,p$=W,h$=Le,m$=W,g$=di,v$=W,y$=W,b$=W;function x$(e,t){var r=String(e).split("."),n=Number(r[0])==e;return t?e==1||e==5||n&&e>=7&&e<=9?"one":e==2||e==3?"two":e==4?"few":e==6?"many":"other":e==1?"one":"other"}const k$=W,w$=Le,S$=di,E$=W;function C$(e,t){var r=String(e).split("."),n=r[0],o=!r[1],i=n.slice(-1),s=n.slice(-2);return t?"other":e==1&&o?"one":o&&i>=2&&i<=4&&(s<12||s>14)?"few":o&&n!=1&&(i==0||i==1)||o&&i>=5&&i<=9||o&&s>=12&&s<=14?"many":"other"}function M$(e,t){var r=String(e).split("."),n=r[1]||"",o=n.length,i=Number(r[0])==e,s=i&&r[0].slice(-1),a=i&&r[0].slice(-2),l=n.slice(-2),c=n.slice(-1);return t?"other":i&&s==0||a>=11&&a<=19||o==2&&l>=11&&l<=19?"zero":s==1&&a!=11||o==2&&c==1&&l!=11||o!=2&&c==1?"one":"other"}const T$=W;function O$(e,t){var r=String(e).split("."),n=r[0];return t?"other":n==0||n==1?"one":"other"}const _$=Kr,A$=W;function N$(e,t){var r=String(e).split("."),n=!r[1],o=Number(r[0])==e,i=o&&r[0].slice(-2);return t?e==1?"one":"other":e==1&&n?"one":!n||e==0||i>=2&&i<=19?"few":"other"}const R$=W,P$=Le;function z$(e,t){var r=String(e).split("."),n=r[0],o=!r[1],i=n.slice(-1),s=n.slice(-2);return t?"other":o&&i==1&&s!=11?"one":o&&i>=2&&i<=4&&(s<12||s>14)?"few":o&&i==0||o&&i>=5&&i<=9||o&&s>=11&&s<=14?"many":"other"}const L$=W,I$=Le,D$=W;function $$(e,t){var r=String(e).split("."),n=!r[1];return t?e==11||e==8||e==80||e==800?"many":"other":e==1&&n?"one":"other"}function H$(e,t){var r=String(e).split("."),n=!r[1];return t?e==11||e==8||e==80||e==800?"many":"other":e==1&&n?"one":"other"}const B$=W,F$=W,V$=bs,j$=W,U$=Le,W$=Le;function K$(e,t){var r=String(e).split("."),n=r[0],o=r[1]||"",i=!r[1],s=n.slice(-1),a=n.slice(-2),l=o.slice(-1),c=o.slice(-2);return t?"other":i&&s==1&&a!=11||l==1&&c!=11?"one":i&&s>=2&&s<=4&&(a<12||a>14)||l>=2&&l<=4&&(c<12||c>14)?"few":"other"}function q$(e,t){var r=String(e).split("."),n=Number(r[0])==e;return t?"other":e>=0&&e<=1?"one":n&&e>=2&&e<=10?"few":"other"}function G$(e,t){var r=String(e).split("."),n=r[0],o=r[1]||"";return t?"other":e==0||e==1||n==0&&o==1?"one":"other"}function Y$(e,t){var r=String(e).split("."),n=r[0],o=!r[1];return t?"other":e==1&&o?"one":n>=2&&n<=4&&o?"few":o?"other":"many"}function J$(e,t){var r=String(e).split("."),n=r[0],o=!r[1],i=n.slice(-2);return t?"other":o&&i==1?"one":o&&i==2?"two":o&&(i==3||i==4)||!o?"few":"other"}const X$=bs,Q$=bs,Z$=bs,eH=bs,tH=bs,rH=W,nH=W;function oH(e,t){var r=String(e).split("."),n=Number(r[0])==e,o=n&&r[0].slice(-1),i=n&&r[0].slice(-2);return t?e==1?"one":o==4&&i!=14?"many":"other":e==1?"one":"other"}function iH(e,t){var r=String(e).split("."),n=r[0],o=r[1]||"",i=!r[1],s=n.slice(-1),a=n.slice(-2),l=o.slice(-1),c=o.slice(-2);return t?"other":i&&s==1&&a!=11||l==1&&c!=11?"one":i&&s>=2&&s<=4&&(a<12||a>14)||l>=2&&l<=4&&(c<12||c>14)?"few":"other"}const sH=W,aH=W,lH=W,cH=Le;function uH(e,t){var r=String(e).split("."),n=!r[1],o=Number(r[0])==e,i=o&&r[0].slice(-1),s=o&&r[0].slice(-2);return t?(i==1||i==2)&&s!=11&&s!=12?"one":"other":e==1&&n?"one":"other"}const dH=Kr,fH=W,pH=W,hH=W,mH=W,gH=Le,vH=di,yH=W;function bH(e,t){var r=String(e).split("."),n=Number(r[0])==e,o=n&&r[0].slice(-1);return t?o==6||o==9||e==10?"few":"other":e==1?"one":"other"}function xH(e,t){var r=String(e).split("."),n=r[0],o=r[1]||"",i=!r[1],s=n.slice(-1),a=o.slice(-1);return t?e==1?"one":"other":i&&(n==1||n==2||n==3)||i&&s!=4&&s!=6&&s!=9||!i&&a!=4&&a!=6&&a!=9?"one":"other"}const kH=W,wH=Le,SH=W,EH=W;function CH(e,t){var r=String(e).split("."),n=Number(r[0])==e;return t?"other":e==0||e==1||n&&e>=11&&e<=99?"one":"other"}const MH=W;function TH(e,t){var r=String(e).split("."),n=r[0],o=!r[1],i=Number(r[0])==e,s=i&&r[0].slice(-1),a=i&&r[0].slice(-2),l=n.slice(-1),c=n.slice(-2);return t?s==3&&a!=13?"few":"other":o&&l==1&&c!=11?"one":o&&l>=2&&l<=4&&(c<12||c>14)?"few":o&&l==0||o&&l>=5&&l<=9||o&&c>=11&&c<=14?"many":"other"}const OH=Kr,_H=W,AH=W;function NH(e,t){return t&&e==1?"one":"other"}const RH=W,PH=W,zH=di,LH=W,IH=Le,DH=W,$H=W,HH=Kr,BH=Le,FH=Le,VH=Le;function jH(e,t){return t?"other":e>=0&&e<=1?"one":"other"}const UH=Object.freeze(Object.defineProperty({__proto__:null,_in:Y9,af:J9,ak:X9,am:Q9,an:Z9,ar:eD,ars:tD,as:rD,asa:nD,ast:oD,az:iD,be:sD,bem:aD,bez:lD,bg:cD,bho:uD,bm:dD,bn:fD,bo:pD,br:hD,brx:mD,bs:gD,ca:vD,ce:yD,ceb:bD,cgg:xD,chr:kD,ckb:wD,cs:SD,cy:ED,da:CD,de:MD,dsb:TD,dv:OD,dz:_D,ee:AD,el:ND,en:RD,eo:PD,es:zD,et:LD,eu:ID,fa:DD,ff:$D,fi:HD,fil:BD,fo:FD,fr:VD,fur:jD,fy:UD,ga:WD,gd:KD,gl:qD,gsw:GD,gu:YD,guw:JD,gv:XD,ha:QD,haw:ZD,he:e7,hi:t7,hr:r7,hsb:n7,hu:o7,hy:i7,ia:s7,id:a7,ig:l7,ii:c7,io:u7,is:d7,it:f7,iu:p7,iw:h7,ja:m7,jbo:g7,jgo:v7,ji:y7,jmc:b7,jv:x7,jw:k7,ka:w7,kab:S7,kaj:E7,kcg:C7,kde:M7,kea:T7,kk:O7,kkj:_7,kl:A7,km:N7,kn:R7,ko:P7,ks:z7,ksb:L7,ksh:I7,ku:D7,kw:$7,ky:H7,lag:B7,lb:F7,lg:V7,lkt:j7,ln:U7,lo:W7,lt:K7,lv:q7,mas:G7,mg:Y7,mgo:J7,mk:X7,ml:Q7,mn:Z7,mo:e$,mr:t$,ms:r$,mt:n$,my:o$,nah:i$,naq:s$,nb:a$,nd:l$,ne:c$,nl:u$,nn:d$,nnh:f$,no:p$,nqo:h$,nr:m$,nso:g$,ny:v$,nyn:y$,om:b$,or:x$,os:k$,osa:w$,pa:S$,pap:E$,pl:C$,prg:M$,ps:T$,pt:O$,pt_PT:_$,rm:A$,ro:N$,rof:R$,root:P$,ru:z$,rwk:L$,sah:I$,saq:D$,sc:$$,scn:H$,sd:B$,sdh:F$,se:V$,seh:j$,ses:U$,sg:W$,sh:K$,shi:q$,si:G$,sk:Y$,sl:J$,sma:X$,smi:Q$,smj:Z$,smn:eH,sms:tH,sn:rH,so:nH,sq:oH,sr:iH,ss:sH,ssy:aH,st:lH,su:cH,sv:uH,sw:dH,syr:fH,ta:pH,te:hH,teo:mH,th:gH,ti:vH,tig:yH,tk:bH,tl:xH,tn:kH,to:wH,tr:SH,ts:EH,tzm:CH,ug:MH,uk:TH,ur:OH,uz:_H,ve:AH,vi:NH,vo:RH,vun:PH,wa:zH,wae:LH,wo:IH,xh:DH,xog:$H,yi:HH,yo:BH,yue:FH,zh:VH,zu:jH},Symbol.toStringTag,{value:"Module"}));var WH=Object.defineProperty,KH=Object.getOwnPropertyDescriptor,qH=Object.getOwnPropertyNames,GH=Object.prototype.hasOwnProperty,Ow=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of qH(t))!GH.call(e,o)&&o!==r&&WH(e,o,{get:()=>t[o],enumerable:!(n=KH(t,o))||n.enumerable});return e},YH=(e,t,r)=>(Ow(e,t,"default"),r&&Ow(r,t,"default")),JH=JSON.parse('{"extension.command.toggle-upper-case.label":[["case","select",{"upper":"Uppercase","lower":"Lowercase","capitalize":"Sentence case","smallCaps":"Small caps","other":"Text case"}]],"extension.table.column_count":[["count","plural",{"one":["#"," column"],"other":["#"," columns"]}]],"extension.table.row_count":[["count","plural",{"one":["#"," row"],"other":["#"," rows"]}]],"extension.command.toggle-columns.description":[["count","select",{"2":"Split the block into two columns","3":"Split the current block into three columns","4":"Split the current block into four columns","other":"Split the current block into multiple columns"}]],"extension.command.toggle-columns.label":[["count","select",{"2":"Two Column Block","3":"Three Column Block","4":"Four Column Block","other":"Multi Column Block"}]],"extension.command.set-text-direction.label":[["dir","select",{"ltr":"Left-To-Right","rtl":"Right-To-Left","other":"Reset Direction"}]],"extension.command.set-text-direction.description":[["dir","select",{"ltr":"Set the text direction from left to right","rtl":"Set the text direction from right to left","other":"Reset text direction"}]],"extension.command.toggle-heading.label":[["level","select",{"1":"Heading 1","2":"Heading 2","3":"Heading 3","4":"Heading 4","5":"Heading 5","6":"Heading 6","other":"Heading"}]],"extension.command.toggle-callout.description":[["type","select",{"info":"Create an information callout block","warning":"Create a warning callout block","error":"Create an error callout block","success":"Create a success callout block","other":"Create a callout block"}]],"extension.command.toggle-callout.label":[["type","select",{"info":"Information Callout","warning":"Warning Callout","error":"Error Callout","success":"Success Callout","other":"Callout"}]],"extension.command.toggle-code-block.description":"Add a code block","extension.command.add-annotation.label":"Add annotation","extension.command.toggle-blockquote.description":"Add blockquote formatting to the selected text","extension.command.toggle-bold.description":"Add bold formatting to the selected text","extension.command.toggle-code.description":"Add inline code formatting to the selected text","keyboard.shortcut.alt":"Alt","keyboard.shortcut.arrowDown":"Arrow Down","keyboard.shortcut.arrowLeft":"Arrow Left","keyboard.shortcut.arrowRight":"Arrow Right","keyboard.shortcut.arrowUp":"Arrow Up","keyboard.shortcut.backspace":"Backspace","ui.text-color.black":"Black","extension.command.toggle-blockquote.label":"Blockquote","ui.text-color.blue":"Blue","ui.text-color.blue.hue":["Blue ",["hue"]],"extension.command.toggle-bold.label":"Bold","extension.command.toggle-bullet-list.description":"Bulleted list","keyboard.shortcut.capsLock":"Caps Lock","extension.command.center-align.label":"Center align","extension.command.toggle-code.label":"Code","extension.command.toggle-code-block.label":"Codeblock","keyboard.shortcut.command":"Command","QcPNd6":"Image description","ogrUzJ":"Add a short description here.","yqdyzr":"Image","6/02F4":"Image source","X8H91v":"Image","zhQ7Zt":"Italic","ZL7E7l":"Underline","keyboard.shortcut.control":"Control","extension.command.convert-paragraph.description":"Convert current block into a paragraph block.","extension.command.convert-paragraph.label":"Convert Paragraph","extension.command.copy.label":"Copy","extension.command.copy.description":"Copy the selected text","extension.command.create-table.description":"Create a table with set number of rows and columns.","extension.command.create-table.label":"Create table","extension.command.cut.label":"Cut","extension.command.cut.description":"Cut the selected text","ui.text-color.cyan":"Cyan","ui.text-color.cyan.hue":["Cyan ",["hue"]],"extension.command.decrease-font-size.label":"Decrease","extension.command.decrease-indent.label":"Decrease indentation","extension.command.decrease-font-size.description":"Decrease the font size.","keyboard.shortcut.delete":"Delete","extension.command.insert-horizontal-rule.label":"Divider","keyboard.shortcut.end":"End","keyboard.shortcut.escape":"Enter","keyboard.shortcut.enter":"Enter","6PjrOF":"Add annotation","OTq5WC":"Center align","oeZ3ox":"Convert current block into a paragraph block.","m1khs+":"Convert Paragraph","w/1U+3":"Copy the selected text","kdodi0":"Copy","k0KR/u":"Create a table with set number of rows and columns.","zrwMyD":"Create table","D/nWxh":"Cut the selected text","jHPv5m":"Cut","5cNgRx":"Decrease the font size.","vyRNWx":"Decrease","Jgiol4":"Decrease indentation","1gJSHH":"Increase the font size","OQXJXz":"Increase","72TLhr":"Increase indentation","HFlfzJ":"Insert Emoji","RPq9fY":"Separate content with a diving horizontal line","OKQF+e":"Divider","zjYb9C":"Insert a new paragraph","4M4sXC":"Insert Paragraph","1Q+eVc":"Justify","ejWWtP":"Left align","wVqrpS":"Paste content into the editor","07v9aw":"Paste","zUYfou":"Redo the most recent action","9Nq9zr":"Redo","0uxaZe":"Remove annotation","iJWZAz":"Right align","g5WpPn":"Select all content within the editor","2+pZDT":"Select all","yChCR1":"Set text case","GMzAC/":"Set the font size for the selected text.","vzEyrv":"Font size","7VCkJ8":"Set the text color for the selected text.","qjWFaR":"Text color","LVWgFu":[["dir","select",{"ltr":"Set the text direction from left to right","rtl":"Set the text direction from right to left","other":"Reset text direction"}]],"WXwRy1":[["dir","select",{"ltr":"Left-To-Right","rtl":"Right-To-Left","other":"Reset Direction"}]],"G/o315":"Set the text highlight color for the selected text.","xtHg6d":"Text highlight","1p1W/p":"Add blockquote formatting to the selected text","6+rh6I":"Blockquote","0yB3LV":"Add bold formatting to the selected text","sFMo4Z":"Bold","SMKG/s":"Bulleted list","/BYCMi":[["type","select",{"info":"Create an information callout block","warning":"Create a warning callout block","error":"Create an error callout block","success":"Create a success callout block","other":"Create a callout block"}]],"V+3IBe":[["type","select",{"info":"Information Callout","warning":"Warning Callout","error":"Error Callout","success":"Success Callout","other":"Callout"}]],"hbIo4L":"Add a code block","7GkMcx":"Codeblock","2r4JYl":"Add inline code formatting to the selected text","Up8Tpe":"Code","ATHSPS":[["count","select",{"2":"Split the block into two columns","3":"Split the current block into three columns","4":"Split the current block into four columns","other":"Split the current block into multiple columns"}]],"7DC1VE":[["count","select",{"2":"Two Column Block","3":"Three Column Block","4":"Four Column Block","other":"Multi Column Block"}]],"hnrBeo":[["level","select",{"1":"Heading 1","2":"Heading 2","3":"Heading 3","4":"Heading 4","5":"Heading 5","6":"Heading 6","other":"Heading"}]],"NkZAcw":"Italicize the selected text","2fTW9e":"Italic","c759Ra":"Ordered list","uQwrZu":"Strikethrough the selected text","pT3qly":"Strikethrough","BHk+zu":"Subscript","18BVwM":"Superscript","tOIVCV":"Tasked list","4Janx3":"Underline the selected text","dCHt+D":"Underline","YYAprs":[["case","select",{"upper":"Uppercase","lower":"Lowercase","capitalize":"Sentence case","smallCaps":"Small caps","other":"Text case"}]],"tczyZL":"Show hidden whitespace characters in your editor.","0qAX23":"Toggle Whitespace","ezMADU":"Undo the most recent action","N3P7EC":"Undo","2nj/+s":"Update annotation","dWD7u4":[["count","plural",{"one":["#"," column"],"other":["#"," columns"]}]],"qXqgVT":[["count","plural",{"one":["#"," row"],"other":["#"," rows"]}]],"extension.command.set-font-size.label":"Font size","ui.text-color.grape":"Grape","ui.text-color.grape.hue":["Grape ",["hue"]],"ui.text-color.gray":"Gray","ui.text-color.gray.hue":["Gray ",["hue"]],"ui.text-color.green":"Green","ui.text-color.green.hue":["Green ",["hue"]],"keyboard.shortcut.home":"Home","extension.command.increase-font-size.label":"Increase","extension.command.increase-indent.label":"Increase indentation","extension.command.increase-font-size.description":"Increase the font size","ui.text-color.indigo":"Indigo","ui.text-color.indigo.hue":["Indigo ",["hue"]],"extension.command.insert-paragraph.description":"Insert a new paragraph","extension.command.insert-emoji.label":"Insert Emoji","extension.command.insert-paragraph.label":"Insert Paragraph","extension.command.toggle-italic.label":"Italic","extension.command.toggle-italic.description":"Italicize the selected text","extension.command.justify-align.label":"Justify","R7NlCw":"Alt","RbDiK5":"Arrow Down","Dgyd+E":"Arrow Left","8pdCk4":"Arrow Right","Gp/343":"Arrow Up","PFPV0A":"Backspace","0IRYvp":"Caps Lock","X7HX0D":"Command","zq0AdD":"Control","8SfToN":"Delete","Ys/uah":"End","3K5hww":"Enter","veQt1j":"Enter","ySv7i+":"Home","e6RUI1":"Page Down","EEJk31":"Page Up","7sbhAU":"Shift","Q4eplT":"Space","SUhVVC":"Tab","extension.command.left-align.label":"Left align","ui.text-color.lime":"Lime","ui.text-color.lime.hue":["Lime ",["hue"]],"react-components.mention-atom-component.zero-items":"No items available","ui.text-color.orange":"Orange","ui.text-color.orange.hue":["Orange ",["hue"]],"extension.command.toggle-ordered-list.label":"Ordered list","keyboard.shortcut.pageDown":"Page Down","keyboard.shortcut.pageUp":"Page Up","extension.command.paste.label":"Paste","extension.command.paste.description":"Paste content into the editor","ui.text-color.pink":"Pink","ui.text-color.pink.hue":["Pink ",["hue"]],"zvMfIA":"No items available","pEjhti":"Static Menu","ui.text-color.red":"Red","ui.text-color.red.hue":["Red ",["hue"]],"extension.command.redo.label":"Redo","extension.command.redo.description":"Redo the most recent action","extension.command.remove-annotation.label":"Remove annotation","extension.command.right-align.label":"Right align","extension.command.select-all.label":"Select all","extension.command.select-all.description":"Select all content within the editor","extension.command.insert-horizontal-rule.description":"Separate content with a diving horizontal line","extension.command.set-casing.label":"Set text case","extension.command.set-font-size.description":"Set the font size for the selected text.","extension.command.set-text-color.description":"Set the text color for the selected text.","extension.command.set-text-highlight.description":"Set the text highlight color for the selected text.","keyboard.shortcut.shift":"Shift","extension.command.toggle-whitespace.description":"Show hidden whitespace characters in your editor.","keyboard.shortcut.space":"Space","extension.command.toggle-strike.label":"Strikethrough","extension.command.toggle-strike.description":"Strikethrough the selected text","extension.command.toggle-subscript.label":"Subscript","extension.command.toggle-superscript.label":"Superscript","keyboard.shortcut.tab":"Tab","extension.command.toggle-task-list.description":"Tasked list","ui.text-color.teal":"Teal","ui.text-color.teal.hue":["Teal ",["hue"]],"extension.command.set-text-color.label":"Text color","extension.command.set-text-highlight.label":"Text highlight","extension.command.toggle-whitespace.label":"Toggle Whitespace","ui.text-color.transparent":"Transparent","slrB1c":"Black","6QML30":"Blue","xw+keN":["Blue ",["hue"]],"38RHqP":"Cyan","D89yPf":["Cyan ",["hue"]],"VjBLnd":"Grape","Rp40yv":["Grape ",["hue"]],"5Dm9D1":"Gray","HGjXjC":["Gray ",["hue"]],"b9fz+n":"Green","18jo3M":["Green ",["hue"]],"CFzqCV":"Indigo","aVlDku":["Indigo ",["hue"]],"04PfLc":"Lime","KRTK6Y":["Lime ",["hue"]],"pSnXFd":"Orange","ve/MJZ":["Orange ",["hue"]],"OvCgDa":"Pink","l7NqyT":["Pink ",["hue"]],"IT9k0j":"Red","AdyJ7/":["Red ",["hue"]],"3D2UWc":"Teal","Dcq0Y1":["Teal ",["hue"]],"bsi2ik":"Transparent","Tj3PRR":"Violet","xxMH5N":["Violet ",["hue"]],"Rum0ah":"White","4gaw/Q":"Yellow","hhauc3":["Yellow ",["hue"]],"extension.command.toggle-underline.label":"Underline","extension.command.toggle-underline.description":"Underline the selected text","extension.command.undo.label":"Undo","extension.command.undo.description":"Undo the most recent action","extension.command.update-annotation.label":"Update annotation","ui.text-color.violet":"Violet","ui.text-color.violet.hue":["Violet ",["hue"]],"ui.text-color.white":"White","ui.text-color.yellow":"Yellow","ui.text-color.yellow.hue":["Yellow ",["hue"]]}'),hT={};YH(hT,UH);cm.loadLocaleData("en",{plurals:hT.en});cm.load("en",JH);cm.activate("en");var XH=Object.defineProperty,QH=Object.getOwnPropertyDescriptor,Uy=(e,t,r,n)=>{for(var o=n>1?void 0:n?QH(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&XH(t,r,o),o},jl=class extends er{get name(){return"doc"}createNodeSpec(e,t){const{docAttributes:r,content:n}=this.options,o=ee();if(ps(r))for(const[i,s]of At(r))o[i]={default:s};else for(const i of r)o[i]={default:null};return{attrs:o,content:n,...t}}setDocAttributes(e){return({tr:t,dispatch:r})=>{if(r){for(const[n,o]of Object.entries(e))t.step(new ld(n,o));r(t)}return!0}}isDefaultDocNode({state:e=this.store.getState(),options:t}={}){return qv(e.doc,t)}};Uy([U()],jl.prototype,"setDocAttributes",1);Uy([He()],jl.prototype,"isDefaultDocNode",1);jl=Uy([pe({defaultOptions:{content:"block+",docAttributes:[]},defaultPriority:Ae.Medium,staticKeys:["content","docAttributes"],disableExtraAttributes:!0})],jl);var mT="SetDocAttribute",gT="RevertSetDocAttribute",ld=class extends Rt{constructor(e,t,r=mT){super(),this.stepType=r,this.key=e,this.value=t}static fromJSON(e,t){return new ld(t.key,t.value,t.stepType)}apply(e){this.previous=e.attrs[this.key];const t={...e.attrs,[this.key]:this.value};return yt.ok(e.type.create(t,e.content,e.marks))}invert(){return new ld(this.key,this.previous,gT)}map(){return this}toJSON(){return{stepType:this.stepType,key:this.key,value:this.value}}};try{Rt.jsonID(mT,ld),Rt.jsonID(gT,ld)}catch(e){if(!e.message.startsWith("Duplicate use of step JSON ID"))throw e}var ZH=Object.defineProperty,eB=Object.getOwnPropertyDescriptor,vT=(e,t,r,n)=>{for(var o=n>1?void 0:n?eB(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&ZH(t,r,o),o};function tB(e,t,r,n){const o=e.docView.posFromDOM(t,r,n);return o===null||o<0?null:o}function rB(e,t){const r=t.target;if(r){const n=tB(e,r,0);if(n!==null){const o=e.state.doc.resolve(n),i=o.node().isLeaf?0:1,s=o.start()-i;return{pos:n,inside:s}}}return e.posAtCoords({left:t.clientX,top:t.clientY})??void 0}var lh=class extends Ve{constructor(){super(...arguments),this.mousedown=!1,this.mouseover=!1,this.createMouseEventHandler=e=>(t,r)=>{const n=r,o=rB(t,n);if(!o)return!1;const i=[],s=[],{inside:a,pos:l}=o;if(a===-1)return!1;const c=t.state.doc.resolve(l),u=c.depth+1;for(const d of Cv(u,1))i.push({node:d>c.depth&&c.nodeAfter?c.nodeAfter:c.node(d),pos:c.before(d)});for(const{type:d}of c.marksAcross(c)??[]){const f=_o(c,d);f&&s.push(f)}return e(n,{view:t,nodes:i,marks:s,getMark:d=>{const f=oe(d)?t.state.schema.marks[d]:d;return re(f,{code:B.EXTENSION,message:`The mark ${d} being checked does not exist within the editor schema.`}),s.find(p=>p.mark.type===f)},getNode:d=>{var f;const p=oe(d)?t.state.schema.nodes[d]:d;re(p,{code:B.EXTENSION,message:"The node being checked does not exist"});const h=i.find(({node:m})=>m.type===p);if(h)return{...h,isRoot:!!((f=i[0])!=null&&f.node.eq(h.node))}}})}}get name(){return"events"}onView(){var e,t;if(!((e=this.store.managerSettings.exclude)!=null&&e.clickHandler))for(const r of this.store.extensions){if(!r.createEventHandlers||(t=r.options.exclude)!=null&&t.clickHandler)continue;const n=r.createEventHandlers();for(const[o,i]of At(n))this.addHandler(o,i)}}createPlugin(){const e=new WeakMap,t=(r,n,o,i,s,a,l,c)=>{const u=this.store.currentState,{schema:d,doc:f}=u,p=f.resolve(i),h=e.has(l),m=nB({$pos:p,handled:h,view:o,state:u});let b=!1;h||(b=r(l,m)||b);const v={...m,pos:i,direct:c,nodeWithPosition:{node:s,pos:a},getNode:g=>{const y=oe(g)?d.nodes[g]:g;return re(y,{code:B.EXTENSION,message:"The node being checked does not exist"}),y===s.type?{node:s,pos:a}:void 0}};return e.set(l,!0),n(l,v)||b};return{props:{handleKeyPress:(r,n)=>this.options.keypress(n)||!1,handleKeyDown:(r,n)=>this.options.keydown(n)||!1,handleTextInput:(r,n,o,i)=>this.options.textInput({from:n,to:o,text:i})||!1,handleClickOn:(r,n,o,i,s,a)=>t(this.options.clickMark,this.options.click,r,n,o,i,s,a),handleDoubleClickOn:(r,n,o,i,s,a)=>t(this.options.doubleClickMark,this.options.doubleClick,r,n,o,i,s,a),handleTripleClickOn:(r,n,o,i,s,a)=>t(this.options.tripleClickMark,this.options.tripleClick,r,n,o,i,s,a),handleDOMEvents:{focus:(r,n)=>this.options.focus(n)||!1,blur:(r,n)=>this.options.blur(n)||!1,mousedown:(r,n)=>(this.startMouseover(),this.options.mousedown(n)||!1),mouseup:(r,n)=>(this.endMouseover(),this.options.mouseup(n)||!1),mouseleave:(r,n)=>(this.mouseover=!1,this.options.mouseleave(n)||!1),mouseenter:(r,n)=>(this.mouseover=!0,this.options.mouseenter(n)||!1),keyup:(r,n)=>this.options.keyup(n)||!1,mouseout:this.createMouseEventHandler((r,n)=>{const o={...n,hovering:!1};return this.options.hover(r,o)||!1}),mouseover:this.createMouseEventHandler((r,n)=>{const o={...n,hovering:!0};return this.options.hover(r,o)||!1}),contextmenu:this.createMouseEventHandler((r,n)=>this.options.contextmenu(r,n)||!1),scroll:(r,n)=>this.options.scroll(n)||!1,copy:(r,n)=>this.options.copy(n)||!1,cut:(r,n)=>this.options.cut(n)||!1,paste:(r,n)=>this.options.paste(n)||!1}},view:r=>{let n=r.editable;const o=this.options;return{update(i){const s=i.editable;s!==n&&(o.editable(s),n=s)}}}}}isInteracting(){return this.mousedown&&this.mouseover}startMouseover(){this.mouseover=!0,!this.mousedown&&(this.mousedown=!0,this.store.document.documentElement.addEventListener("mouseup",()=>{this.endMouseover()},{once:!0}))}endMouseover(){this.mousedown&&(this.mousedown=!1,this.store.commands.emptyUpdate())}};vT([He()],lh.prototype,"isInteracting",1);lh=vT([pe({handlerKeys:["blur","focus","mousedown","mouseup","mouseenter","mouseleave","textInput","keypress","keyup","keydown","click","clickMark","doubleClick","doubleClickMark","tripleClick","tripleClickMark","contextmenu","hover","scroll","copy","cut","paste","editable"],handlerKeyOptions:{blur:{earlyReturnValue:!0},focus:{earlyReturnValue:!0},mousedown:{earlyReturnValue:!0},mouseleave:{earlyReturnValue:!0},mouseup:{earlyReturnValue:!0},click:{earlyReturnValue:!0},doubleClick:{earlyReturnValue:!0},tripleClick:{earlyReturnValue:!0},hover:{earlyReturnValue:!0},contextmenu:{earlyReturnValue:!0},scroll:{earlyReturnValue:!0},copy:{earlyReturnValue:!0},cut:{earlyReturnValue:!0},paste:{earlyReturnValue:!0}},defaultPriority:Ae.High})],lh);function nB(e){const{handled:t,view:r,$pos:n,state:o}=e,i={getMark:X4,markRanges:[],view:r,state:o};if(t)return i;for(const{type:s}of n.marksAcross(n)??[]){const a=_o(n,s);a&&i.markRanges.push(a)}return i.getMark=s=>{const a=oe(s)?o.schema.marks[s]:s;return re(a,{code:B.EXTENSION,message:`The mark ${s} being checked does not exist within the editor schema.`}),i.markRanges.find(l=>l.mark.type===a)},i}class gt extends be{constructor(t){super(t,t)}map(t,r){let n=t.resolve(r.map(this.head));return gt.valid(n)?new gt(n):be.near(n)}content(){return K.empty}eq(t){return t instanceof gt&&t.head==this.head}toJSON(){return{type:"gapcursor",pos:this.head}}static fromJSON(t,r){if(typeof r.pos!="number")throw new RangeError("Invalid input for GapCursor.fromJSON");return new gt(t.resolve(r.pos))}getBookmark(){return new Wy(this.anchor)}static valid(t){let r=t.parent;if(r.isTextblock||!oB(t)||!iB(t))return!1;let n=r.type.spec.allowGapCursor;if(n!=null)return n;let o=r.contentMatchAt(t.index()).defaultType;return o&&o.isTextblock}static findGapCursorFrom(t,r,n=!1){e:for(;;){if(!n&>.valid(t))return t;let o=t.pos,i=null;for(let s=t.depth;;s--){let a=t.node(s);if(r>0?t.indexAfter(s)0){i=a.child(r>0?t.indexAfter(s):t.index(s)-1);break}else if(s==0)return null;o+=r;let l=t.doc.resolve(o);if(gt.valid(l))return l}for(;;){let s=r>0?i.firstChild:i.lastChild;if(!s){if(i.isAtom&&!i.isText&&!ce.isSelectable(i)){t=t.doc.resolve(o+i.nodeSize*r),n=!1;continue e}break}i=s,o+=r;let a=t.doc.resolve(o);if(gt.valid(a))return a}return null}}}gt.prototype.visible=!1;gt.findFrom=gt.findGapCursorFrom;be.jsonID("gapcursor",gt);class Wy{constructor(t){this.pos=t}map(t){return new Wy(t.map(this.pos))}resolve(t){let r=t.resolve(this.pos);return gt.valid(r)?new gt(r):be.near(r)}}function oB(e){for(let t=e.depth;t>=0;t--){let r=e.index(t),n=e.node(t);if(r==0){if(n.type.spec.isolating)return!0;continue}for(let o=n.child(r-1);;o=o.lastChild){if(o.childCount==0&&!o.inlineContent||o.isAtom||o.type.spec.isolating)return!0;if(o.inlineContent)return!1}}return!0}function iB(e){for(let t=e.depth;t>=0;t--){let r=e.indexAfter(t),n=e.node(t);if(r==n.childCount){if(n.type.spec.isolating)return!0;continue}for(let o=n.child(r);;o=o.firstChild){if(o.childCount==0&&!o.inlineContent||o.isAtom||o.type.spec.isolating)return!0;if(o.inlineContent)return!1}}return!0}function sB(){return new Ro({props:{decorations:uB,createSelectionBetween(e,t,r){return t.pos==r.pos&>.valid(r)?new gt(r):null},handleClick:lB,handleKeyDown:aB,handleDOMEvents:{beforeinput:cB}}})}const aB=Xv({ArrowLeft:Sf("horiz",-1),ArrowRight:Sf("horiz",1),ArrowUp:Sf("vert",-1),ArrowDown:Sf("vert",1)});function Sf(e,t){const r=e=="vert"?t>0?"down":"up":t>0?"right":"left";return function(n,o,i){let s=n.selection,a=t>0?s.$to:s.$from,l=s.empty;if(s instanceof le){if(!i.endOfTextblock(r)||a.depth==0)return!1;l=!1,a=n.doc.resolve(t>0?a.after():a.before())}let c=gt.findGapCursorFrom(a,t,l);return c?(o&&o(n.tr.setSelection(new gt(c))),!0):!1}}function lB(e,t,r){if(!e||!e.editable)return!1;let n=e.state.doc.resolve(t);if(!gt.valid(n))return!1;let o=e.posAtCoords({left:r.clientX,top:r.clientY});return o&&o.inside>-1&&ce.isSelectable(e.state.doc.nodeAt(o.inside))?!1:(e.dispatch(e.state.tr.setSelection(new gt(n))),!0)}function cB(e,t){if(t.inputType!="insertCompositionText"||!(e.state.selection instanceof gt))return!1;let{$from:r}=e.state.selection,n=r.parent.contentMatchAt(r.index()).findWrapping(e.state.schema.nodes.text);if(!n)return!1;let o=R.empty;for(let s=n.length-1;s>=0;s--)o=R.from(n[s].createAndFill(null,o));let i=e.state.tr.replace(r.pos,r.pos,new K(o,0,0));return i.setSelection(le.near(i.doc.resolve(r.pos+1))),e.dispatch(i),!1}function uB(e){if(!(e.selection instanceof gt))return null;let t=document.createElement("div");return t.className="ProseMirror-gapcursor",Ee.create(e.doc,[Ge.widget(e.selection.head,t,{key:"gapcursor"})])}var dB=Object.defineProperty,fB=Object.getOwnPropertyDescriptor,pB=(e,t,r,n)=>{for(var o=n>1?void 0:n?fB(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&dB(t,r,o),o},W0=class extends Ve{get name(){return"gapCursor"}createExternalPlugins(){return[sB()]}};W0=pB([pe({})],W0);var ch=200,Bt=function(){};Bt.prototype.append=function(t){return t.length?(t=Bt.from(t),!this.length&&t||t.length=r?Bt.empty:this.sliceInner(Math.max(0,t),Math.min(this.length,r))};Bt.prototype.get=function(t){if(!(t<0||t>=this.length))return this.getInner(t)};Bt.prototype.forEach=function(t,r,n){r===void 0&&(r=0),n===void 0&&(n=this.length),r<=n?this.forEachInner(t,r,n,0):this.forEachInvertedInner(t,r,n,0)};Bt.prototype.map=function(t,r,n){r===void 0&&(r=0),n===void 0&&(n=this.length);var o=[];return this.forEach(function(i,s){return o.push(t(i,s))},r,n),o};Bt.from=function(t){return t instanceof Bt?t:t&&t.length?new yT(t):Bt.empty};var yT=function(e){function t(n){e.call(this),this.values=n}e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t;var r={length:{configurable:!0},depth:{configurable:!0}};return t.prototype.flatten=function(){return this.values},t.prototype.sliceInner=function(o,i){return o==0&&i==this.length?this:new t(this.values.slice(o,i))},t.prototype.getInner=function(o){return this.values[o]},t.prototype.forEachInner=function(o,i,s,a){for(var l=i;l=s;l--)if(o(this.values[l],a+l)===!1)return!1},t.prototype.leafAppend=function(o){if(this.length+o.length<=ch)return new t(this.values.concat(o.flatten()))},t.prototype.leafPrepend=function(o){if(this.length+o.length<=ch)return new t(o.flatten().concat(this.values))},r.length.get=function(){return this.values.length},r.depth.get=function(){return 0},Object.defineProperties(t.prototype,r),t}(Bt);Bt.empty=new yT([]);var hB=function(e){function t(r,n){e.call(this),this.left=r,this.right=n,this.length=r.length+n.length,this.depth=Math.max(r.depth,n.depth)+1}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.flatten=function(){return this.left.flatten().concat(this.right.flatten())},t.prototype.getInner=function(n){return na&&this.right.forEachInner(n,Math.max(o-a,0),Math.min(this.length,i)-a,s+a)===!1)return!1},t.prototype.forEachInvertedInner=function(n,o,i,s){var a=this.left.length;if(o>a&&this.right.forEachInvertedInner(n,o-a,Math.max(i,a)-a,s+a)===!1||i=i?this.right.slice(n-i,o-i):this.left.slice(n,i).append(this.right.slice(0,o-i))},t.prototype.leafAppend=function(n){var o=this.right.leafAppend(n);if(o)return new t(this.left,o)},t.prototype.leafPrepend=function(n){var o=this.left.leafPrepend(n);if(o)return new t(o,this.right)},t.prototype.appendInner=function(n){return this.left.depth>=Math.max(this.right.depth,n.depth)+1?new t(this.left,new t(this.right,n)):new t(this,n)},t}(Bt);const mB=500;class Zn{constructor(t,r){this.items=t,this.eventCount=r}popEvent(t,r){if(this.eventCount==0)return null;let n=this.items.length;for(;;n--)if(this.items.get(n-1).selection){--n;break}let o,i;r&&(o=this.remapping(n,this.items.length),i=o.maps.length);let s=t.tr,a,l,c=[],u=[];return this.items.forEach((d,f)=>{if(!d.step){o||(o=this.remapping(n,f+1),i=o.maps.length),i--,u.push(d);return}if(o){u.push(new mo(d.map));let p=d.step.map(o.slice(i)),h;p&&s.maybeStep(p).doc&&(h=s.mapping.maps[s.mapping.maps.length-1],c.push(new mo(h,void 0,void 0,c.length+u.length))),i--,h&&o.appendMap(h,i)}else s.maybeStep(d.step);if(d.selection)return a=o?d.selection.map(o.slice(i)):d.selection,l=new Zn(this.items.slice(0,n).append(u.reverse().concat(c)),this.eventCount-1),!1},this.items.length,0),{remaining:l,transform:s,selection:a}}addTransform(t,r,n,o){let i=[],s=this.eventCount,a=this.items,l=!o&&a.length?a.get(a.length-1):null;for(let u=0;uvB&&(a=gB(a,c),s-=c),new Zn(a.append(i),s)}remapping(t,r){let n=new ul;return this.items.forEach((o,i)=>{let s=o.mirrorOffset!=null&&i-o.mirrorOffset>=t?n.maps.length-o.mirrorOffset:void 0;n.appendMap(o.map,s)},t,r),n}addMaps(t){return this.eventCount==0?this:new Zn(this.items.append(t.map(r=>new mo(r))),this.eventCount)}rebased(t,r){if(!this.eventCount)return this;let n=[],o=Math.max(0,this.items.length-r),i=t.mapping,s=t.steps.length,a=this.eventCount;this.items.forEach(f=>{f.selection&&a--},o);let l=r;this.items.forEach(f=>{let p=i.getMirror(--l);if(p==null)return;s=Math.min(s,p);let h=i.maps[p];if(f.step){let m=t.steps[p].invert(t.docs[p]),b=f.selection&&f.selection.map(i.slice(l+1,p));b&&a++,n.push(new mo(h,m,b))}else n.push(new mo(h))},o);let c=[];for(let f=r;fmB&&(d=d.compress(this.items.length-n.length)),d}emptyItemCount(){let t=0;return this.items.forEach(r=>{r.step||t++}),t}compress(t=this.items.length){let r=this.remapping(0,t),n=r.maps.length,o=[],i=0;return this.items.forEach((s,a)=>{if(a>=t)o.push(s),s.selection&&i++;else if(s.step){let l=s.step.map(r.slice(n)),c=l&&l.getMap();if(n--,c&&r.appendMap(c,n),l){let u=s.selection&&s.selection.map(r.slice(n));u&&i++;let d=new mo(c.invert(),l,u),f,p=o.length-1;(f=o.length&&o[p].merge(d))?o[p]=f:o.push(d)}}else s.map&&n--},this.items.length,0),new Zn(Bt.from(o.reverse()),i)}}Zn.empty=new Zn(Bt.empty,0);function gB(e,t){let r;return e.forEach((n,o)=>{if(n.selection&&t--==0)return r=o,!1}),e.slice(r)}class mo{constructor(t,r,n,o){this.map=t,this.step=r,this.selection=n,this.mirrorOffset=o}merge(t){if(this.step&&t.step&&!t.selection){let r=t.step.merge(this.step);if(r)return new mo(r.getMap().invert(),r,this.selection)}}}class Ni{constructor(t,r,n,o,i){this.done=t,this.undone=r,this.prevRanges=n,this.prevTime=o,this.prevComposition=i}}const vB=20;function yB(e,t,r,n){let o=r.getMeta(So),i;if(o)return o.historyState;r.getMeta(xB)&&(e=new Ni(e.done,e.undone,null,0,-1));let s=r.getMeta("appendedTransaction");if(r.steps.length==0)return e;if(s&&s.getMeta(So))return s.getMeta(So).redo?new Ni(e.done.addTransform(r,void 0,n,op(t)),e.undone,_w(r.mapping.maps[r.steps.length-1]),e.prevTime,e.prevComposition):new Ni(e.done,e.undone.addTransform(r,void 0,n,op(t)),null,e.prevTime,e.prevComposition);if(r.getMeta("addToHistory")!==!1&&!(s&&s.getMeta("addToHistory")===!1)){let a=r.getMeta("composition"),l=e.prevTime==0||!s&&e.prevComposition!=a&&(e.prevTime<(r.time||0)-n.newGroupDelay||!bB(r,e.prevRanges)),c=s?Xg(e.prevRanges,r.mapping):_w(r.mapping.maps[r.steps.length-1]);return new Ni(e.done.addTransform(r,l?t.selection.getBookmark():void 0,n,op(t)),Zn.empty,c,r.time,a??e.prevComposition)}else return(i=r.getMeta("rebased"))?new Ni(e.done.rebased(r,i),e.undone.rebased(r,i),Xg(e.prevRanges,r.mapping),e.prevTime,e.prevComposition):new Ni(e.done.addMaps(r.mapping.maps),e.undone.addMaps(r.mapping.maps),Xg(e.prevRanges,r.mapping),e.prevTime,e.prevComposition)}function bB(e,t){if(!t)return!1;if(!e.docChanged)return!0;let r=!1;return e.mapping.maps[0].forEach((n,o)=>{for(let i=0;i=t[i]&&(r=!0)}),r}function _w(e){let t=[];return e.forEach((r,n,o,i)=>t.push(o,i)),t}function Xg(e,t){if(!e)return null;let r=[];for(let n=0;n{let r=So.getState(e);return!r||r.done.eventCount==0?!1:(t&&bT(r,e,t,!1),!0)},Zc=(e,t)=>{let r=So.getState(e);return!r||r.undone.eventCount==0?!1:(t&&bT(r,e,t,!0),!0)};function K0(e){let t=So.getState(e);return t?t.done.eventCount:0}function wB(e){let t=So.getState(e);return t?t.undone.eventCount:0}var SB=Object.defineProperty,EB=Object.getOwnPropertyDescriptor,Ca=(e,t,r,n)=>{for(var o=n>1?void 0:n?EB(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&SB(t,r,o),o},Ao=class extends Ve{constructor(){super(...arguments),this.wrapMethod=(e,t)=>({state:r,dispatch:n,view:o})=>{const{getState:i,getDispatch:s}=this.options,a=_e(i)?i():r,l=_e(s)&&n?s():n,c=e(a,l,o);return t==null||t(c),c}}get name(){return"history"}createKeymap(){return{"Mod-y":on.isMac?()=>!1:this.wrapMethod(Zc,this.options.onRedo),"Mod-z":this.wrapMethod(ip,this.options.onUndo),"Shift-Mod-z":this.wrapMethod(Zc,this.options.onRedo)}}undoShortcut(e){return this.wrapMethod(ip,this.options.onUndo)(e)}redoShortcut(e){return this.wrapMethod(Zc,this.options.onRedo)(e)}createExternalPlugins(){const{depth:e,newGroupDelay:t}=this.options;return[kB({depth:e,newGroupDelay:t})]}undo(){return l2(this.wrapMethod(ip,this.options.onUndo))}redo(){return l2(this.wrapMethod(Zc,this.options.onRedo))}undoDepth(e=this.store.getState()){return K0(e)}redoDepth(e=this.store.getState()){return wB(e)}};Ca([je({shortcut:$.Undo,command:"undo"})],Ao.prototype,"undoShortcut",1);Ca([je({shortcut:$.Redo,command:"redo"})],Ao.prototype,"redoShortcut",1);Ca([U({disableChaining:!0,description:({t:e})=>e(Cp.UNDO_DESCRIPTION),label:({t:e})=>e(Cp.UNDO_LABEL),icon:"arrowGoBackFill"})],Ao.prototype,"undo",1);Ca([U({disableChaining:!0,description:({t:e})=>e(Cp.REDO_DESCRIPTION),label:({t:e})=>e(Cp.REDO_LABEL),icon:"arrowGoForwardFill"})],Ao.prototype,"redo",1);Ca([He()],Ao.prototype,"undoDepth",1);Ca([He()],Ao.prototype,"redoDepth",1);Ao=Ca([pe({defaultOptions:{depth:100,newGroupDelay:500,getDispatch:void 0,getState:void 0},staticKeys:["depth","newGroupDelay"],handlerKeys:["onUndo","onRedo"]})],Ao);var CB=Object.defineProperty,MB=Object.getOwnPropertyDescriptor,um=(e,t,r,n)=>{for(var o=n>1?void 0:n?MB(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&CB(t,r,o),o},TB={icon:"paragraph",label:({t:e})=>e(Mp.INSERT_LABEL),description:({t:e})=>e(Mp.INSERT_DESCRIPTION)},OB={icon:"paragraph",label:({t:e})=>e(Mp.CONVERT_LABEL),description:({t:e})=>e(Mp.CONVERT_DESCRIPTION)},da=class extends er{get name(){return"paragraph"}createTags(){return[te.LastNodeCompatible,te.TextBlock,te.Block,te.FormattingNode]}createNodeSpec(e,t){return{content:"inline*",draggable:!1,...t,attrs:{...e.defaults()},parseDOM:[{tag:"p",getAttrs:r=>({...e.parse(r)})},...t.parseDOM??[]],toDOM:r=>["p",e.dom(r),0]}}convertParagraph(e={}){const{attrs:t,selection:r,preserveAttrs:n}=e;return this.store.commands.setBlockNodeType.original(this.type,t,r,n)}insertParagraph(e,t={}){const{selection:r,attrs:n}=t;return this.store.commands.insertNode.original(this.type,{content:e,selection:r,attrs:n})}shortcut(e){return this.convertParagraph()(e)}};um([U(OB)],da.prototype,"convertParagraph",1);um([U(TB)],da.prototype,"insertParagraph",1);um([je({shortcut:$.Paragraph,command:"convertParagraph"})],da.prototype,"shortcut",1);da=um([pe({defaultPriority:Ae.Medium})],da);function Jo(e,t,r){return Math.min(Math.max(e,r),t)}class _B extends Error{constructor(t){super(`Failed to parse color: "${t}"`)}}var eu=_B;function Ky(e){if(typeof e!="string")throw new eu(e);if(e.trim().toLowerCase()==="transparent")return[0,0,0,0];let t=e.trim();t=DB.test(e)?RB(e):e;const r=PB.exec(t);if(r){const s=Array.from(r).slice(1);return[...s.slice(0,3).map(a=>parseInt(cd(a,2),16)),parseInt(cd(s[3]||"f",2),16)/255]}const n=zB.exec(t);if(n){const s=Array.from(n).slice(1);return[...s.slice(0,3).map(a=>parseInt(a,16)),parseInt(s[3]||"ff",16)/255]}const o=LB.exec(t);if(o){const s=Array.from(o).slice(1);return[...s.slice(0,3).map(a=>parseInt(a,10)),parseFloat(s[3]||"1")]}const i=IB.exec(t);if(i){const[s,a,l,c]=Array.from(i).slice(1).map(parseFloat);if(Jo(0,100,a)!==a)throw new eu(e);if(Jo(0,100,l)!==l)throw new eu(e);return[...$B(s,a,l),Number.isNaN(c)?1:c]}throw new eu(e)}function AB(e){let t=5381,r=e.length;for(;r;)t=t*33^e.charCodeAt(--r);return(t>>>0)%2341}const Nw=e=>parseInt(e.replace(/_/g,""),36),NB="1q29ehhb 1n09sgk7 1kl1ekf_ _yl4zsno 16z9eiv3 1p29lhp8 _bd9zg04 17u0____ _iw9zhe5 _to73___ _r45e31e _7l6g016 _jh8ouiv _zn3qba8 1jy4zshs 11u87k0u 1ro9yvyo 1aj3xael 1gz9zjz0 _3w8l4xo 1bf1ekf_ _ke3v___ _4rrkb__ 13j776yz _646mbhl _nrjr4__ _le6mbhl 1n37ehkb _m75f91n _qj3bzfz 1939yygw 11i5z6x8 _1k5f8xs 1509441m 15t5lwgf _ae2th1n _tg1ugcv 1lp1ugcv 16e14up_ _h55rw7n _ny9yavn _7a11xb_ 1ih442g9 _pv442g9 1mv16xof 14e6y7tu 1oo9zkds 17d1cisi _4v9y70f _y98m8kc 1019pq0v 12o9zda8 _348j4f4 1et50i2o _8epa8__ _ts6senj 1o350i2o 1mi9eiuo 1259yrp0 1ln80gnw _632xcoy 1cn9zldc _f29edu4 1n490c8q _9f9ziet 1b94vk74 _m49zkct 1kz6s73a 1eu9dtog _q58s1rz 1dy9sjiq __u89jo3 _aj5nkwg _ld89jo3 13h9z6wx _qa9z2ii _l119xgq _bs5arju 1hj4nwk9 1qt4nwk9 1ge6wau6 14j9zlcw 11p1edc_ _ms1zcxe _439shk6 _jt9y70f _754zsow 1la40eju _oq5p___ _x279qkz 1fa5r3rv _yd2d9ip _424tcku _8y1di2_ _zi2uabw _yy7rn9h 12yz980_ __39ljp6 1b59zg0x _n39zfzp 1fy9zest _b33k___ _hp9wq92 1il50hz4 _io472ub _lj9z3eo 19z9ykg0 _8t8iu3a 12b9bl4a 1ak5yw0o _896v4ku _tb8k8lv _s59zi6t _c09ze0p 1lg80oqn 1id9z8wb _238nba5 1kq6wgdi _154zssg _tn3zk49 _da9y6tc 1sg7cv4f _r12jvtt 1gq5fmkz 1cs9rvci _lp9jn1c _xw1tdnb 13f9zje6 16f6973h _vo7ir40 _bt5arjf _rc45e4t _hr4e100 10v4e100 _hc9zke2 _w91egv_ _sj2r1kk 13c87yx8 _vqpds__ _ni8ggk8 _tj9yqfb 1ia2j4r4 _7x9b10u 1fc9ld4j 1eq9zldr _5j9lhpx _ez9zl6o _md61fzm".split(" ").reduce((e,t)=>{const r=Nw(t.substring(0,3)),n=Nw(t.substring(3)).toString(16);let o="";for(let i=0;i<6-n.length;i++)o+="0";return e[r]=`${o}${n}`,e},{});function RB(e){const t=e.toLowerCase().trim(),r=NB[AB(t)];if(!r)throw new eu(e);return`#${r}`}const cd=(e,t)=>Array.from(Array(t)).map(()=>e).join(""),PB=new RegExp(`^#${cd("([a-f0-9])",3)}([a-f0-9])?$`,"i"),zB=new RegExp(`^#${cd("([a-f0-9]{2})",3)}([a-f0-9]{2})?$`,"i"),LB=new RegExp(`^rgba?\\(\\s*(\\d+)\\s*${cd(",\\s*(\\d+)\\s*",2)}(?:,\\s*([\\d.]+))?\\s*\\)$`,"i"),IB=/^hsla?\(\s*([\d.]+)\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%(?:\s*,\s*([\d.]+))?\s*\)$/i,DB=/^[a-z]+$/i,Rw=e=>Math.round(e*255),$B=(e,t,r)=>{let n=r/100;if(t===0)return[n,n,n].map(Rw);const o=(e%360+360)%360/60,i=(1-Math.abs(2*n-1))*(t/100),s=i*(1-Math.abs(o%2-1));let a=0,l=0,c=0;o>=0&&o<1?(a=i,l=s):o>=1&&o<2?(a=s,l=i):o>=2&&o<3?(l=i,c=s):o>=3&&o<4?(l=s,c=i):o>=4&&o<5?(a=s,c=i):o>=5&&o<6&&(a=i,c=s);const u=n-i/2,d=a+u,f=l+u,p=c+u;return[d,f,p].map(Rw)};function HB(e){const[t,r,n,o]=Ky(e).map((d,f)=>f===3?d:d/255),i=Math.max(t,r,n),s=Math.min(t,r,n),a=(i+s)/2;if(i===s)return[0,0,a,o];const l=i-s,c=a>.5?l/(2-i-s):l/(i+s);return[60*(t===i?(r-n)/l+(r.179}function kl(e){return jB(e)?"#000":"#fff"}const UB="remirror-editor-wrapper",WB="remirror-button-active",KB="remirror-button",qB="remirror-composite",GB="remirror-dialog",YB="remirror-dialog-backdrop",JB="remirror-form",XB="remirror-form-message",QB="remirror-form-label",ZB="remirror-form-group",eF="remirror-group",tF="remirror-input",rF="remirror-menu",nF="remirror-menu-pane",oF="remirror-menu-pane-active",iF="remirror-menu-dropdown-label",sF="remirror-menu-pane-icon",aF="remirror-menu-pane-label",lF="remirror-menu-pane-shortcut",cF="remirror-menu-button-left",uF="remirror-menu-button-right",dF="remirror-menu-button-nested-left",fF="remirror-menu-button-nested-right",pF="remirror-menu-button",hF="remirror-menu-bar",mF="remirror-flex-column",gF="remirror-flex-row",vF="remirror-menu-item",yF="remirror-menu-item-row",bF="remirror-menu-item-column",xF="remirror-menu-item-checkbox",kF="remirror-menu-item-radio",wF="remirror-menu-group",SF="remirror-floating-popover",EF="remirror-popover",CF="remirror-animated-popover",MF="remirror-role",TF="remirror-separator",OF="remirror-tab",_F="remirror-tab-list",AF="remirror-tabbable",NF="remirror-toolbar",RF="remirror-tooltip",PF="remirror-table-size-editor",zF="remirror-table-size-editor-body",LF="remirror-table-size-editor-cell",IF="remirror-table-size-editor-cell-selected",DF="remirror-table-size-editor-footer",$F="remirror-color-picker",HF="remirror-color-picker-cell",BF="remirror-color-picker-cell-selected";var FF=Object.freeze({__proto__:null,ANIMATED_POPOVER:CF,BUTTON:KB,BUTTON_ACTIVE:WB,COLOR_PICKER:$F,COLOR_PICKER_CELL:HF,COLOR_PICKER_CELL_SELECTED:BF,COMPOSITE:qB,DIALOG:GB,DIALOG_BACKDROP:YB,EDITOR_WRAPPER:UB,FLEX_COLUMN:mF,FLEX_ROW:gF,FLOATING_POPOVER:SF,FORM:JB,FORM_GROUP:ZB,FORM_LABEL:QB,FORM_MESSAGE:XB,GROUP:eF,INPUT:tF,MENU:rF,MENU_BAR:hF,MENU_BUTTON:pF,MENU_BUTTON_LEFT:cF,MENU_BUTTON_NESTED_LEFT:dF,MENU_BUTTON_NESTED_RIGHT:fF,MENU_BUTTON_RIGHT:uF,MENU_DROPDOWN_LABEL:iF,MENU_GROUP:wF,MENU_ITEM:vF,MENU_ITEM_CHECKBOX:xF,MENU_ITEM_COLUMN:bF,MENU_ITEM_RADIO:kF,MENU_ITEM_ROW:yF,MENU_PANE:nF,MENU_PANE_ACTIVE:oF,MENU_PANE_ICON:sF,MENU_PANE_LABEL:aF,MENU_PANE_SHORTCUT:lF,POPOVER:EF,ROLE:MF,SEPARATOR:TF,TAB:OF,TABBABLE:AF,TABLE_SIZE_EDITOR:PF,TABLE_SIZE_EDITOR_BODY:zF,TABLE_SIZE_EDITOR_CELL:LF,TABLE_SIZE_EDITOR_CELL_SELECTED:IF,TABLE_SIZE_EDITOR_FOOTER:DF,TAB_LIST:_F,TOOLBAR:NF,TOOLTIP:RF});const VF="remirror-wrap",jF="remirror-language-select-positioner",UF="remirror-language-select-width",WF="remirror-a11y-dark",KF="remirror-atom-dark",qF="remirror-base16-ateliersulphurpool-light",GF="remirror-cb",YF="remirror-darcula",JF="remirror-dracula",XF="remirror-duotone-dark",QF="remirror-duotone-earth",ZF="remirror-duotone-forest",eV="remirror-duotone-light",tV="remirror-duotone-sea",rV="remirror-duotone-space",nV="remirror-gh-colors",oV="remirror-hopscotch",iV="remirror-pojoaque",sV="remirror-vs",aV="remirror-xonokai";var lV=Object.freeze({__proto__:null,A11Y_DARK:WF,ATOM_DARK:KF,BASE16_ATELIERSULPHURPOOL_LIGHT:qF,CB:GF,DARCULA:YF,DRACULA:JF,DUOTONE_DARK:XF,DUOTONE_EARTH:QF,DUOTONE_FOREST:ZF,DUOTONE_LIGHT:eV,DUOTONE_SEA:tV,DUOTONE_SPACE:rV,GH_COLORS:nV,HOPSCOTCH:oV,LANGUAGE_SELECT_POSITIONER:jF,LANGUAGE_SELECT_WIDTH:UF,POJOAQUE:iV,VS:sV,WRAP:VF,XONOKAI:aV});const cV="remirror-image-loader";var uV=Object.freeze({__proto__:null,IMAGE_LOADER:cV});const dV="remirror-list-item-with-custom-mark",fV="remirror-ul-list-content",pV="remirror-editor",hV="remirror-list-item-marker-container",mV="remirror-list-item-checkbox",gV="remirror-collapsible-list-item-closed",vV="remirror-collapsible-list-item-button",yV="remirror-list-spine";var cs=Object.freeze({__proto__:null,COLLAPSIBLE_LIST_ITEM_BUTTON:vV,COLLAPSIBLE_LIST_ITEM_CLOSED:gV,EDITOR:pV,LIST_ITEM_CHECKBOX:mV,LIST_ITEM_MARKER_CONTAINER:hV,LIST_ITEM_WITH_CUSTOM_MARKER:dV,LIST_SPINE:yV,UL_LIST_CONTENT:fV});const bV="remirror-is-empty";var xV=Object.freeze({__proto__:null,IS_EMPTY:bV});const kV="remirror-editor",wV="remirror-positioner",SV="remirror-positioner-widget";var EV=Object.freeze({__proto__:null,EDITOR:kV,POSITIONER:wV,POSITIONER_WIDGET:SV});const CV="remirror-theme";function MV(e={}){const t=[],r={};function n(o,i){if(typeof i=="string"||typeof i=="number"){t.push(`${Pw(o)}: ${i};`),r[Pw(o)]=i;return}if(!(typeof i!="object"||!i))for(const[s,a]of Object.entries(i))n([...o,s],a)}for(const[o,i]of Object.entries(e))n([o],i);return{css:t.join(` +`),styles:r}}function TV(e){return e.replace(/([a-z])([\dA-Z])/g,"$1-$2").replace(/[\s_]+/g,"-").toLowerCase()}function Pw(e){return`--rmr-${e.map(TV).join("-")}`}const qn={gray:["#f8f9fa","#f1f3f5","#e9ecef","#dee2e6","#ced4da","#adb5bd","#868e96","#495057","#343a40","#212529"],red:["#fff5f5","#ffe3e3","#ffc9c9","#ffa8a8","#ff8787","#ff6b6b","#fa5252","#f03e3e","#e03131","#c92a2a"],pink:["#fff0f6","#ffdeeb","#fcc2d7","#faa2c1","#f783ac","#f06595","#e64980","#d6336c","#c2255c","#a61e4d"],grape:["#f8f0fc","#f3d9fa","#eebefa","#e599f7","#da77f2","#cc5de8","#be4bdb","#ae3ec9","#9c36b5","#862e9c"],violet:["#f3f0ff","#e5dbff","#d0bfff","#b197fc","#9775fa","#845ef7","#7950f2","#7048e8","#6741d9","#5f3dc4"],indigo:["#edf2ff","#dbe4ff","#bac8ff","#91a7ff","#748ffc","#5c7cfa","#4c6ef5","#4263eb","#3b5bdb","#364fc7"],blue:["#e7f5ff","#d0ebff","#a5d8ff","#74c0fc","#4dabf7","#339af0","#228be6","#1c7ed6","#1971c2","#1864ab"],cyan:["#e3fafc","#c5f6fa","#99e9f2","#66d9e8","#3bc9db","#22b8cf","#15aabf","#1098ad","#0c8599","#0b7285"],teal:["#e6fcf5","#c3fae8","#96f2d7","#63e6be","#38d9a9","#20c997","#12b886","#0ca678","#099268","#087f5b"],green:["#ebfbee","#d3f9d8","#b2f2bb","#8ce99a","#69db7c","#51cf66","#40c057","#37b24d","#2f9e44","#2b8a3e"],lime:["#f4fce3","#e9fac8","#d8f5a2","#c0eb75","#a9e34b","#94d82d","#82c91e","#74b816","#66a80f","#5c940d"],yellow:["#fff9db","#fff3bf","#ffec99","#ffe066","#ffd43b","#fcc419","#fab005","#f59f00","#f08c00","#e67700"],orange:["#fff4e6","#ffe8cc","#ffd8a8","#ffc078","#ffa94d","#ff922b","#fd7e14","#f76707","#e8590c","#d9480f"]},Xo="#000000",qy="#ffffff",OV="#252103",Gy=uh(Xo,.75),dm="#7963d2",Yy="#bcd263",_V="#fff",AV="#fff",Jy=qn.gray[1],zw="rgba(10,31,68,0.08)",Lw="rgba(10,31,68,0.10)",Iw="rgba(10,31,68,0.12)",NV=sp(uh(Xo,.1),.13),Xy={background:qy,border:Gy,foreground:Xo,muted:Jy,primary:dm,secondary:Yy,primaryText:_V,secondaryText:AV,text:OV,faded:NV},RV={...Xy,background:rn(qy,.15),border:rn(Gy,.15),foreground:rn(Xo,.15),muted:rn(Jy,.15),primary:rn(dm,.15),secondary:rn(Yy,.15),get text(){return kl(this.background)},get primaryText(){return kl(this.primary)},get secondaryText(){return kl(this.secondary)}},PV={...Xy,background:rn(qy,.075),border:rn(Gy,.075),foreground:rn(Xo,.075),muted:rn(Jy,.075),primary:rn(dm,.075),secondary:rn(Yy,.075),get text(){return kl(this.background)},get primaryText(){return kl(this.primary)},get secondaryText(){return kl(this.secondary)}},ws={color:{...Xy,active:RV,hover:PV,shadow1:zw,shadow2:Lw,shadow3:Iw,backdrop:uh(Xo,.1),outline:uh(dm,.6),table:{default:{border:sp(Xo,.8),cell:sp(Xo,.4),controller:qn.gray[3]},selected:{border:qn.blue[7],cell:qn.blue[1],controller:qn.blue[5]},preselect:{border:qn.blue[7],cell:sp(Xo,.4),controller:qn.blue[5]},predelete:{border:qn.red[7],cell:qn.red[1],controller:qn.red[5]},mark:"#91919196"}},hue:qn,radius:{border:"0.25rem",extra:"0.5rem",circle:"50%"},fontFamily:{default:'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif',heading:"inherit",mono:"Menlo, monospace"},fontSize:{0:"12px",1:"14px",2:"16px",3:"20px",4:"24px",5:"32px",6:"48px",7:"64px",8:"96px",default:"16px"},space:{1:"4px",2:"8px",3:"16px",4:"32px",5:"64px",6:"128px",7:"256px",8:"512px"},fontWeight:{bold:"700",default:"400",heading:"700"},letterSpacing:{tight:"-1px",default:"normal",loose:"1px",wide:"3px"},lineHeight:{heading:"1.25em",default:"1.5em"},boxShadow:{1:`0 1px 1px ${zw}`,2:`0 1px 1px ${Lw}`,3:`0 1px 1px ${Iw}`}};var zV=Object.defineProperty,LV=Object.getOwnPropertyDescriptor,Qy=(e,t,r,n)=>{for(var o=n>1?void 0:n?LV(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&zV(t,r,o),o},xT=(e,t,r)=>{if(!t.has(e))throw TypeError("Cannot "+r)},Tt=(e,t,r)=>(xT(e,t,"read from private field"),r?r.call(e):t.get(e)),Do=(e,t,r)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,r)},bi=(e,t,r,n)=>(xT(e,t,"write to private field"),n?n.call(e,r):t.set(e,r),r),tu,ru,qa,nu,ap,ou,iu,su,au,lp=class{constructor(e){Do(this,tu,Uh()),Do(this,ru,[]),Do(this,qa,new Map),Do(this,nu,[]),Do(this,ap,!1),Do(this,ou,void 0),Do(this,iu,void 0),Do(this,su,void 0),Do(this,au,void 0),this.addListener=(t,r)=>Tt(this,tu).on(t,r),bi(this,ou,e),bi(this,iu,e.getActive),bi(this,au,e.getPosition),bi(this,su,e.getID),this.hasChanged=e.hasChanged,this.events=e.events??["state","scroll"]}static create(e){return new lp(e)}static fromPositioner(e,t){return lp.create({...e.basePositioner,...t})}get basePositioner(){return{getActive:Tt(this,iu),getPosition:Tt(this,au),hasChanged:this.hasChanged,events:this.events,getID:Tt(this,su)}}onActiveChanged(e){this.recentUpdate=e;const t=Tt(this,iu).call(this,e);bi(this,ru,t),bi(this,qa,new Map),bi(this,ap,!1),bi(this,nu,[]);const r=[];for(const[n,o]of t.entries()){const i=this.getID(o,n);Tt(this,nu).push(i),r.push({setElement:s=>this.addProps({...e,data:o,element:s},n),id:i,data:o})}Tt(this,tu).emit("update",r)}getID(e,t){var r;return((r=Tt(this,su))==null?void 0:r.call(this,e,t))??t.toString()}addProps(e,t){if(Tt(this,ap)||(Tt(this,qa).set(t,e),Tt(this,qa).sizee;return this.clone(r=>({getActive:n=>r.getActive(n).filter(t)}))}},no=lp;tu=new WeakMap;ru=new WeakMap;qa=new WeakMap;nu=new WeakMap;ap=new WeakMap;ou=new WeakMap;iu=new WeakMap;su=new WeakMap;au=new WeakMap;no.EMPTY=[];function IV(e,t=ET){const{key:r}=(e==null?void 0:e.getMeta(ST))??{};return r===t}function kT(e){const{tr:t,state:r,previousState:n}=e;return!n||t&&IV(t)?!0:t?sz(t):!r.doc.eq(n.doc)||!r.selection.eq(n.selection)}function wT(e,t,r={}){const n=t.getBoundingClientRect(),{accountForPadding:o=!1}=r;let i=0,s=0,a=0,l=0;if(et(t)&&o){const u=Number.parseFloat(kn(t,"padding-left").replace("px","")),d=Number.parseFloat(kn(t,"padding-right").replace("px","")),f=Number.parseFloat(kn(t,"padding-top").replace("px","")),p=Number.parseFloat(kn(t,"padding-bottom").replace("px","")),h=Number.parseFloat(kn(t,"border-left").replace("px","")),m=Number.parseFloat(kn(t,"border-right").replace("px","")),b=Number.parseFloat(kn(t,"border-top").replace("px","")),v=Number.parseFloat(kn(t,"border-bottom").replace("px","")),g=t.offsetWidth-t.clientWidth,y=t.offsetHeight-t.clientHeight;i+=u+h+(t.dir==="rtl"?g:0),s+=d+m+(t.dir==="rtl"?0:g),a+=f+b,l+=p+v+y}const c=new DOMRect(n.left+i,n.top+a,n.width-s,n.height-l);for(const[u,d]of[[e.top,e.left],[e.top,e.right],[e.bottom,e.left],[e.bottom,e.right]])if(ek(u,c.top,c.bottom)&&ek(d,c.left,c.right))return!0;return!1}var DV="remirror-positioner-widget",ST="positionerUpdate",ET="__all_positioners__",CT={y:-999999,x:-999999,width:0,height:0},Dw={...CT,left:-999999,top:-999999,bottom:-999999,right:-999999},Zy={...CT,rect:{...Dw,toJSON:()=>Dw},visible:!1},MT=no.create({hasChanged:kT,getActive(e){const{state:t}=e;if(!Uv(t)||t.selection.$anchor.depth>2)return no.EMPTY;const r=Ld({predicate:n=>n.type.isBlock,selection:t});return r?[r]:no.EMPTY},getPosition(e){const{view:t,data:r}=e,n=t.nodeDOM(r.pos);if(!et(n))return Zy;const o=n.getBoundingClientRect(),i=t.dom.getBoundingClientRect(),s=o.height,a=o.width,l=t.dom.scrollLeft+o.left-i.left,c=t.dom.scrollTop+o.top-i.top,u=wT(o,t.dom);return{y:c,x:l,height:s,width:a,rect:o,visible:u}}}),eb=MT.clone(({getActive:e})=>({getActive:t=>{const[r]=e(t);return r&&Fh(r.node)&&r.node.type===Bh(t.state.schema)?[r]:no.EMPTY}})),$V=eb.clone(({getPosition:e})=>({getPosition:t=>({...e(t),width:1})})),HV=eb.clone(({getPosition:e})=>({getPosition:t=>{const{width:r,x:n,y:o,height:i}=e(t);return{...e(t),width:1,x:r+n,rect:new DOMRect(r+n,o,1,i)}}}));function tb(e){return no.create({hasChanged:kT,getActive:t=>{const{state:r,view:n}=t;if(!e(r)||!ms(r.selection))return no.EMPTY;try{const{head:o,anchor:i}=r.selection;return[{from:n.coordsAtPos(i),to:n.coordsAtPos(o)}]}catch{return no.EMPTY}},getPosition(t){const{element:r,data:n,view:o}=t,{from:i,to:s}=n,a=r.offsetParent??o.dom,l=a.getBoundingClientRect(),c=Math.abs(s.bottom-i.top),u=c>i.bottom-i.top,d=Math.min(i.left,s.left),f=Math.min(i.top,s.top),p=a.scrollLeft+(u?s.left-l.left:d-l.left),h=a.scrollTop+f-l.top,m=u?1:Math.abs(i.left-s.right),b=new DOMRect(u?s.left:d,f,m,c),v=wT(b,o.dom);return{rect:b,y:h,x:p,height:c,width:m,visible:v}}})}var TT=tb(e=>!e.selection.empty),BV=tb(e=>e.selection.empty),FV=tb(()=>!0),VV=TT.clone(()=>({getActive:e=>{const{state:t,view:r}=e;if(!t.selection.empty)return no.EMPTY;const n=AC(t);if(!n)return no.EMPTY;try{return[{from:r.coordsAtPos(n.from),to:r.coordsAtPos(n.to)}]}catch{return no.EMPTY}}})),jV={selection:TT,cursor:BV,always:FV,block:MT,emptyBlock:eb,emptyBlockStart:$V,emptyBlockEnd:HV,nearestWord:VV},Ul=class extends Ve{constructor(){super(...arguments),this.positioners=[],this.onAddCustomHandler=({positioner:e})=>{if(e)return this.positioners=[...this.positioners,e],this.store.commands.forceUpdate(),()=>{this.positioners=this.positioners.filter(t=>t!==e)}}}get name(){return"positioner"}createAttributes(){return{class:EV.EDITOR}}init(){this.onScroll=U4(this.options.scrollDebounce,this.onScroll.bind(this))}createEventHandlers(){return{scroll:()=>(this.onScroll(),!1),hover:(e,t)=>(this.positioner(this.getBaseProps("hover",{hover:t})),!1),contextmenu:(e,t)=>(this.positioner(this.getBaseProps("contextmenu",{contextmenu:t})),!1)}}onStateUpdate(e){this.positioner({...e,previousState:e.firstUpdate?void 0:e.previousState,event:"state",helpers:this.store.helpers})}createDecorations(e){if(this.element??(this.element=this.createElement()),!this.element.hasChildNodes())return Ee.empty;const t=Ge.widget(0,this.element,{key:"positioner-widget",side:-1,stopEvent:()=>!0});return Ee.create(e.doc,[t])}forceUpdatePositioners(e=ET){return({tr:t,dispatch:r})=>(r==null||r(t.setMeta(ST,{key:e})),!0)}getPositionerWidget(){return this.element??(this.element=this.createElement())}createElement(){const e=document.createElement("span");return e.dataset.id=DV,e.setAttribute("role","presentation"),e}triggerPositioner(e,t){e.hasChanged(t)&&e.onActiveChanged({...t,view:this.store.view})}positioner(e){for(const t of this.positioners)t.events.includes(e.event)&&this.triggerPositioner(t,e)}getBaseProps(e,t){const r=this.store.getState(),n=this.store.previousState;return{helpers:this.store.helpers,event:e,firstUpdate:!1,previousState:n,state:r,...t}}onScroll(){this.positioner(this.getBaseProps("scroll",{scroll:{scrollTop:this.store.view.dom.scrollTop}}))}};Qy([U()],Ul.prototype,"forceUpdatePositioners",1);Qy([He()],Ul.prototype,"getPositionerWidget",1);Ul=Qy([pe({defaultOptions:{scrollDebounce:100},customHandlerKeys:["positioner"],staticKeys:["scrollDebounce"]})],Ul);function q0(e){return oe(e)?jV[e].clone():_e(e)?e().clone():e.clone()}var UV=Object.defineProperty,WV=Object.getOwnPropertyDescriptor,KV=(e,t,r,n)=>{for(var o=n>1?void 0:n?WV(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&UV(t,r,o),o},G0=class extends er{get name(){return"text"}createTags(){return[te.InlineNode]}createNodeSpec(){return{}}};G0=KV([pe({disableExtraAttributes:!0,defaultPriority:Ae.Medium})],G0);var qV={...jl.defaultOptions,...da.defaultOptions,...Ao.defaultOptions,excludeExtensions:[]};function GV(e={}){e={...qV,...e};const{content:t,depth:r,getDispatch:n,getState:o,newGroupDelay:i,excludeExtensions:s}=e,a={};for(const c of s??[])a[c]=!0;const l=[];if(!a.history){const c=new Ao({depth:r,getDispatch:n,getState:o,newGroupDelay:i});l.push(c)}return a.doc||l.push(new jl({content:t})),a.text||l.push(new G0),a.paragraph||l.push(new da),a.positioner||l.push(new Ul),a.gapCursor||l.push(new W0),a.events||l.push(new lh),l}var YV=Object.defineProperty,JV=Object.getOwnPropertyDescriptor,XV=(e,t,r,n)=>{for(var o=n>1?void 0:n?JV(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&YV(t,r,o),o},fa=class extends Ve{get name(){return"placeholder"}createAttributes(){return{"aria-placeholder":this.options.placeholder}}createPlugin(){return{state:{init:(e,t)=>({...this.options,empty:qv(t.doc,{ignoreAttributes:!0})}),apply:(e,t,r,n)=>QV({pluginState:t,tr:e,extension:this,state:n})},props:{decorations:e=>ZV({state:e,extension:this})}}}onSetOptions(e){const{changes:t}=e;t.placeholder.changed&&this.store.phase>=Nr.EditorView&&this.store.updateAttributes()}};fa=XV([pe({defaultOptions:{emptyNodeClass:xV.IS_EMPTY,placeholder:""}})],fa);function QV(e){const{pluginState:t,extension:r,tr:n,state:o}=e;return n.docChanged?{...r.options,empty:qv(o.doc)}:t}function ZV(e){const{extension:t,state:r}=e,{empty:n}=t.pluginKey.getState(r),{emptyNodeClass:o,placeholder:i}=t.options;if(!n)return null;const s=[];return r.doc.descendants((a,l)=>{const c=Ge.node(l,l+a.nodeSize,{class:o,"data-placeholder":i});s.push(c)}),Ee.create(r.doc,s)}var ej=Object.defineProperty,tj=Object.getOwnPropertyDescriptor,rj=(e,t,r,n)=>{for(var o=n>1?void 0:n?tj(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&ej(t,r,o),o},nj={...fa.defaultOptions,...ad.defaultOptions},oj=[...fa.staticKeys,...ad.staticKeys],ud=class extends Ve{get name(){return"react"}onSetOptions(e){const{pickChanged:t}=e;this.getExtension(fa).setOptions(t(["placeholder"]))}createExtensions(){const{emptyNodeClass:e,placeholder:t,defaultBlockNode:r,defaultContentNode:n,defaultEnvironment:o,defaultInlineNode:i,nodeViewComponents:s}=this.options;return[new fa({emptyNodeClass:e,placeholder:t,priority:Ae.Low}),new ad({defaultBlockNode:r,defaultContentNode:n,defaultEnvironment:o,defaultInlineNode:i,nodeViewComponents:s})]}};ud=rj([pe({defaultOptions:nj,staticKeys:oj})],ud);var OT={};Object.defineProperty(OT,"__esModule",{value:!0});function ij(){for(var e=[],t=0;t{if(!t.has(e))throw TypeError("Cannot "+r)},Zg=(e,t,r)=>(_T(e,t,"read from private field"),r?r.call(e):t.get(e)),sj=(e,t,r)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,r)},aj=(e,t,r,n)=>(_T(e,t,"write to private field"),n?n.call(e,r):t.set(e,r),r);function lj(){const[,e]=S.useState(ee());return S.useCallback(()=>{e(ee())},[])}var AT=S.createContext(null);function fi(e){const t=S.useContext(AT),r=S.useRef(lj());re(t,{code:B.REACT_PROVIDER_CONTEXT});const{addHandler:n}=t;return S.useEffect(()=>{let o=e;if(o){if(ps(o)){const{autoUpdate:i}=o;o=i?()=>r.current():void 0}if(_e(o))return n("updated",o)}},[n,e]),t}function qr(e=!0){return fi({autoUpdate:e}).active}function cj(e=!1){return fi(e?{autoUpdate:!0}:void 0).attrs}function cc(){return fi().chain.new()}function tr(){return fi().commands}function rb(){return fi({autoUpdate:!0}).getState().selection}function Wd(e,t=void 0,r){const{getExtension:n}=fi(),o=S.useMemo(()=>n(e),[e,n]);let i;if(_e(t)?i=r?[o,...r]:[o,t]:i=t?[o,...Object.values(t)]:[],S.useEffect(()=>{_e(t)||!t||o.setOptions(t)},i),S.useEffect(()=>{if(_e(t))return t({addHandler:o.addHandler.bind(o),addCustomHandler:o.addCustomHandler.bind(o),extension:o})},i),!t)return o}function uj(e,t,r){const n=S.useCallback(({addHandler:o})=>o(t,r),[r,t]);return Wd(e,n)}function fm(e=!1){return fi(e?{autoUpdate:!0}:void 0).helpers}var[dj,fj]=I9(({props:e})=>{const t=e.locale??"en",r=e.i18n??cm,n=e.supportedLocales??[t],o=r._.bind(r);return{locale:t,i18n:r,supportedLocales:n,t:o}});function Fw(e,t={}){const{core:r,react:n,...o}=t;return vI(e)?e:gI.create(()=>[...tE(e),new ud(n),...GV(r)],o)}function pj(e,t={}){const r=S.useRef(e),n=S.useRef(t),[o,i]=S.useState(()=>Fw(e,t));return r.current=e,n.current=t,S.useEffect(()=>o.addHandler("destroy",()=>{i(()=>Fw(r.current,n.current))}),[o]),o}var hj=typeof xr=="object"&&xr.__esModule&&xr.default?xr.default:xr,Ga,mj=class extends dI{constructor(e){if(super(e),sj(this,Ga,void 0),this.rootPropsConfig={called:!1,count:0},this.getRootProps=t=>this.internalGetRootProps(t,null),this.internalGetRootProps=(t,r)=>{this.rootPropsConfig.called=!0;const{refKey:n="ref",ref:o,...i}=t??ee();return{[n]:hj(o,this.onRef),key:this.uid,...i,children:r}},this.onRef=t=>{t&&(this.rootPropsConfig.count+=1,re(this.rootPropsConfig.count<=1,{code:B.REACT_GET_ROOT_PROPS,message:`Called ${this.rootPropsConfig.count} times`}),aj(this,Ga,t),this.onRefLoad())},this.manager.view){this.manager.view.setProps({state:this.manager.view.state,dispatchTransaction:this.dispatchTransaction,attributes:()=>this.getAttributes(),editable:()=>this.props.editable??!0});return}this.manager.getExtension(fa).setOptions({placeholder:this.props.placeholder??""})}get name(){return"react"}update(e){return super.update(e),this}createView(e){return new x6(null,{state:e,dispatchTransaction:this.dispatchTransaction,attributes:()=>this.getAttributes(),editable:()=>this.props.editable??!0,plugins:[]})}updateState({state:e,...t}){const{triggerChange:r=!0,tr:n,transactions:o}=t;if(this.props.state){const{onChange:i}=this.props;re(i,{code:B.REACT_CONTROLLED,message:"You are required to provide the `onChange` handler when creating a controlled editor."}),re(r,{code:B.REACT_CONTROLLED,message:"Controlled editors do not support `clearContent` or `setContent` where `triggerChange` is `true`. Update the `state` prop instead."}),this.previousStateOverride||(this.previousStateOverride=this.getState()),this.onChange({state:e,tr:n,transactions:o});return}!n&&!o&&(e=e.apply(e.tr.setMeta(Yx,{}))),this.view.updateState(e),r&&(o==null?void 0:o.length)!==0&&this.onChange({state:e,tr:n,transactions:o}),this.manager.onStateUpdate({previousState:this.previousState,state:e,tr:n,transactions:o})}updateControlledState(e,t){this.previousStateOverride=t,e=e.apply(e.tr.setMeta(Yx,{})),this.view.updateState(e),this.manager.onStateUpdate({previousState:this.previousState,state:e}),this.previousStateOverride=void 0}addProsemirrorViewToDom(e,t){this.props.insertPosition==="start"?e.insertBefore(t,e.firstChild):e.append(t)}onRefLoad(){re(Zg(this,Ga),{code:B.REACT_EDITOR_VIEW,message:"Something went wrong when initializing the text editor. Please check your setup."});const{autoFocus:e}=this.props;this.addProsemirrorViewToDom(Zg(this,Ga),this.view.dom),e&&this.focus(e),this.onChange(),this.addFocusListeners()}onUpdate(){this.view&&Zg(this,Ga)&&this.view.setProps({...this.view.props,editable:()=>this.props.editable??!0})}get frameworkOutput(){return{...this.baseOutput,getRootProps:this.getRootProps,portalContainer:this.manager.store.portalContainer}}resetRender(){this.rootPropsConfig.called=!1,this.rootPropsConfig.count=0}};Ga=new WeakMap;var NT=typeof document<"u"?S.useLayoutEffect:S.useEffect;function gj(e){const t=S.useRef();return NT(()=>{t.current=e}),t.current}function vj(e){const{manager:t,state:r}=e,{placeholder:n,editable:o}=e;S.useRef(!0).current&&!es(n)&&t.getExtension(ud).setOptions({placeholder:n}),S.useEffect(()=>{n!=null&&t.getExtension(ud).setOptions({placeholder:n})},[n,t]);const[s]=S.useState(()=>{if(r)return r;const l=t.createEmptyDoc(),[c,u]=ct(e.initialContent)?e.initialContent:[e.initialContent??l];return t.createState({content:c,selection:u})}),a=yj({initialEditorState:s,getProps:()=>e});return S.useEffect(()=>()=>{a.destroy()},[a]),S.useEffect(()=>{a.onUpdate()},[o,a]),bj(a),a.frameworkOutput}function yj(e){const t=S.useRef(e);t.current=e;const r=S.useMemo(()=>new mj(t.current),[]);return r.update(e),r}function bj(e){const{state:t}=e.props,r=S.useRef(!!t),n=gj(t);NT(()=>{const o=t?r.current===!0:r.current===!1;re(o,{code:B.REACT_CONTROLLED,message:r.current?"You have attempted to switch from a controlled to an uncontrolled editor. Once you set up an editor as a controlled editor it must always provide a `state` prop.":"You have provided a `state` prop to an uncontrolled editor. In order to set up your editor as controlled you must provide the `state` prop from the very first render."}),!(!t||t===n)&&e.updateControlledState(t,n??void 0)},[t,n,e])}function xj(e={}){const{content:t,document:r,selection:n,extensions:o,...i}=e,s=pj(o??(()=>[]),i),[a,l]=S.useState(()=>s.createState({selection:n,content:t??s.createEmptyDoc()})),c=S.useCallback(({state:d})=>{l(d)},[]),u=S.useCallback(()=>s.output,[s]);return S.useMemo(()=>({state:a,setState:l,manager:s,onChange:c,getContext:u}),[u,s,c,a])}var Vw={doc:!1,selection:!1,storedMark:!1};function kj(){const[e,t]=S.useState(Vw);return uj(Lp,"applyState",S.useCallback(({tr:r})=>{const n={...Vw};r.docChanged&&(n.doc=!0),r.selectionSet&&(n.selection=!0),r.storedMarksSet&&(n.storedMark=!0),t(n)},[])),e}var Y0=()=>I.createElement("div",{className:FF.EDITOR_WRAPPER,...fi().getRootProps()}),wj=e=>(e.hook(),null);function Sj(e){const{children:t,autoRender:r,i18n:n,locale:o,supportedLocales:i,hooks:s=[],...a}=e,l=vj(a),c=A9(l.portalContainer),u=r==="start"||r===!0||!t&&es(r),d=r==="end";return I.createElement(dj,{i18n:n,locale:o,supportedLocales:i},I.createElement(AT.Provider,{value:l},I.createElement(_9,{portals:c}),s.map((f,p)=>I.createElement(wj,{hook:f,key:p})),u&&I.createElement(Y0,null),t,d&&I.createElement(Y0,null)))}const Ej={black:"#000",white:"#fff"},dd=Ej,Cj={50:"#ffebee",100:"#ffcdd2",200:"#ef9a9a",300:"#e57373",400:"#ef5350",500:"#f44336",600:"#e53935",700:"#d32f2f",800:"#c62828",900:"#b71c1c",A100:"#ff8a80",A200:"#ff5252",A400:"#ff1744",A700:"#d50000"},za=Cj,Mj={50:"#f3e5f5",100:"#e1bee7",200:"#ce93d8",300:"#ba68c8",400:"#ab47bc",500:"#9c27b0",600:"#8e24aa",700:"#7b1fa2",800:"#6a1b9a",900:"#4a148c",A100:"#ea80fc",A200:"#e040fb",A400:"#d500f9",A700:"#aa00ff"},La=Mj,Tj={50:"#e3f2fd",100:"#bbdefb",200:"#90caf9",300:"#64b5f6",400:"#42a5f5",500:"#2196f3",600:"#1e88e5",700:"#1976d2",800:"#1565c0",900:"#0d47a1",A100:"#82b1ff",A200:"#448aff",A400:"#2979ff",A700:"#2962ff"},Ia=Tj,Oj={50:"#e1f5fe",100:"#b3e5fc",200:"#81d4fa",300:"#4fc3f7",400:"#29b6f6",500:"#03a9f4",600:"#039be5",700:"#0288d1",800:"#0277bd",900:"#01579b",A100:"#80d8ff",A200:"#40c4ff",A400:"#00b0ff",A700:"#0091ea"},Da=Oj,_j={50:"#e8f5e9",100:"#c8e6c9",200:"#a5d6a7",300:"#81c784",400:"#66bb6a",500:"#4caf50",600:"#43a047",700:"#388e3c",800:"#2e7d32",900:"#1b5e20",A100:"#b9f6ca",A200:"#69f0ae",A400:"#00e676",A700:"#00c853"},$a=_j,Aj={50:"#fff3e0",100:"#ffe0b2",200:"#ffcc80",300:"#ffb74d",400:"#ffa726",500:"#ff9800",600:"#fb8c00",700:"#f57c00",800:"#ef6c00",900:"#e65100",A100:"#ffd180",A200:"#ffab40",A400:"#ff9100",A700:"#ff6d00"},Tc=Aj,Nj={50:"#fafafa",100:"#f5f5f5",200:"#eeeeee",300:"#e0e0e0",400:"#bdbdbd",500:"#9e9e9e",600:"#757575",700:"#616161",800:"#424242",900:"#212121",A100:"#f5f5f5",A200:"#eeeeee",A400:"#bdbdbd",A700:"#616161"},Rj=Nj;function _(){return _=Object.assign?Object.assign.bind():function(e){for(var t=1;t{t[r]=RT(e[r])}),t}function un(e,t,r={clone:!0}){const n=r.clone?_({},e):e;return Wo(e)&&Wo(t)&&Object.keys(t).forEach(o=>{o!=="__proto__"&&(Wo(t[o])&&o in e&&Wo(e[o])?n[o]=un(e[o],t[o],r):r.clone?n[o]=Wo(t[o])?RT(t[o]):t[o]:n[o]=t[o])}),n}function Wl(e){let t="https://mui.com/production-error/?code="+e;for(let r=1;rr==null?t:function(...o){t.apply(this,o),r.apply(this,o)},()=>{})}function Lj(e,t=166){let r;function n(...o){const i=()=>{e.apply(this,o)};clearTimeout(r),r=setTimeout(i,t)}return n.clear=()=>{clearTimeout(r)},n}function Br(e){return e&&e.ownerDocument||document}function fd(e){return Br(e).defaultView||window}function J0(e,t){typeof e=="function"?e(t):e&&(e.current=t)}const Ij=typeof window<"u"?S.useLayoutEffect:S.useEffect,pa=Ij;let Uw=0;function Dj(e){const[t,r]=S.useState(e),n=e||t;return S.useEffect(()=>{t==null&&(Uw+=1,r(`mui-${Uw}`))},[t]),n}const Ww=k1["useId".toString()];function $j(e){if(Ww!==void 0){const t=Ww();return e??t}return Dj(e)}function Hj({controlled:e,default:t,name:r,state:n="value"}){const{current:o}=S.useRef(e!==void 0),[i,s]=S.useState(t),a=o?e:i,l=S.useCallback(c=>{o||s(c)},[]);return[a,l]}function Ws(e){const t=S.useRef(e);return pa(()=>{t.current=e}),S.useCallback((...r)=>(0,t.current)(...r),[])}function Ur(...e){return S.useMemo(()=>e.every(t=>t==null)?null:t=>{e.forEach(r=>{J0(r,t)})},e)}let Sm=!0,X0=!1,Kw;const Bj={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function Fj(e){const{type:t,tagName:r}=e;return!!(r==="INPUT"&&Bj[t]&&!e.readOnly||r==="TEXTAREA"&&!e.readOnly||e.isContentEditable)}function Vj(e){e.metaKey||e.altKey||e.ctrlKey||(Sm=!0)}function e1(){Sm=!1}function jj(){this.visibilityState==="hidden"&&X0&&(Sm=!0)}function Uj(e){e.addEventListener("keydown",Vj,!0),e.addEventListener("mousedown",e1,!0),e.addEventListener("pointerdown",e1,!0),e.addEventListener("touchstart",e1,!0),e.addEventListener("visibilitychange",jj,!0)}function Wj(e){const{target:t}=e;try{return t.matches(":focus-visible")}catch{}return Sm||Fj(t)}function zT(){const e=S.useCallback(o=>{o!=null&&Uj(o.ownerDocument)},[]),t=S.useRef(!1);function r(){return t.current?(X0=!0,window.clearTimeout(Kw),Kw=window.setTimeout(()=>{X0=!1},100),t.current=!1,!0):!1}function n(o){return Wj(o)?(t.current=!0,!0):!1}return{isFocusVisibleRef:t,onFocus:n,onBlur:r,ref:e}}function LT(e){const t=e.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}const Kj=e=>{const t=S.useRef({});return S.useEffect(()=>{t.current=e}),t.current},IT=Kj;function DT(e,t){const r=_({},t);return Object.keys(e).forEach(n=>{if(n.toString().match(/^(components|slots)$/))r[n]=_({},e[n],r[n]);else if(n.toString().match(/^(componentsProps|slotProps)$/)){const o=e[n]||{},i=t[n];r[n]={},!i||!Object.keys(i)?r[n]=o:!o||!Object.keys(o)?r[n]=i:(r[n]=_({},i),Object.keys(o).forEach(s=>{r[n][s]=DT(o[s],i[s])}))}else r[n]===void 0&&(r[n]=e[n])}),r}function rr(e,t,r=void 0){const n={};return Object.keys(e).forEach(o=>{n[o]=e[o].reduce((i,s)=>{if(s){const a=t(s);a!==""&&i.push(a),r&&r[s]&&i.push(r[s])}return i},[]).join(" ")}),n}const qw=e=>e,qj=()=>{let e=qw;return{configure(t){e=t},generate(t){return e(t)},reset(){e=qw}}},Gj=qj(),$T=Gj,Yj={active:"active",checked:"checked",completed:"completed",disabled:"disabled",error:"error",expanded:"expanded",focused:"focused",focusVisible:"focusVisible",open:"open",readOnly:"readOnly",required:"required",selected:"selected"};function Vt(e,t,r="Mui"){const n=Yj[t];return n?`${r}-${n}`:`${$T.generate(e)}-${t}`}function jt(e,t,r="Mui"){const n={};return t.forEach(o=>{n[o]=Vt(e,o,r)}),n}const Kl="$$material";function ve(e,t){if(e==null)return{};var r={},n=Object.keys(e),o,i;for(i=0;i=0)&&(r[o]=e[o]);return r}function HT(e){var t=Object.create(null);return function(r){return t[r]===void 0&&(t[r]=e(r)),t[r]}}var Jj=/^((children|dangerouslySetInnerHTML|key|ref|autoFocus|defaultValue|defaultChecked|innerHTML|suppressContentEditableWarning|suppressHydrationWarning|valueLink|abbr|accept|acceptCharset|accessKey|action|allow|allowUserMedia|allowPaymentRequest|allowFullScreen|allowTransparency|alt|async|autoComplete|autoPlay|capture|cellPadding|cellSpacing|challenge|charSet|checked|cite|classID|className|cols|colSpan|content|contentEditable|contextMenu|controls|controlsList|coords|crossOrigin|data|dateTime|decoding|default|defer|dir|disabled|disablePictureInPicture|download|draggable|encType|enterKeyHint|form|formAction|formEncType|formMethod|formNoValidate|formTarget|frameBorder|headers|height|hidden|high|href|hrefLang|htmlFor|httpEquiv|id|inputMode|integrity|is|keyParams|keyType|kind|label|lang|list|loading|loop|low|marginHeight|marginWidth|max|maxLength|media|mediaGroup|method|min|minLength|multiple|muted|name|nonce|noValidate|open|optimum|pattern|placeholder|playsInline|poster|preload|profile|radioGroup|readOnly|referrerPolicy|rel|required|reversed|role|rows|rowSpan|sandbox|scope|scoped|scrolling|seamless|selected|shape|size|sizes|slot|span|spellCheck|src|srcDoc|srcLang|srcSet|start|step|style|summary|tabIndex|target|title|translate|type|useMap|value|width|wmode|wrap|about|datatype|inlist|prefix|property|resource|typeof|vocab|autoCapitalize|autoCorrect|autoSave|color|incremental|fallback|inert|itemProp|itemScope|itemType|itemID|itemRef|on|option|results|security|unselectable|accentHeight|accumulate|additive|alignmentBaseline|allowReorder|alphabetic|amplitude|arabicForm|ascent|attributeName|attributeType|autoReverse|azimuth|baseFrequency|baselineShift|baseProfile|bbox|begin|bias|by|calcMode|capHeight|clip|clipPathUnits|clipPath|clipRule|colorInterpolation|colorInterpolationFilters|colorProfile|colorRendering|contentScriptType|contentStyleType|cursor|cx|cy|d|decelerate|descent|diffuseConstant|direction|display|divisor|dominantBaseline|dur|dx|dy|edgeMode|elevation|enableBackground|end|exponent|externalResourcesRequired|fill|fillOpacity|fillRule|filter|filterRes|filterUnits|floodColor|floodOpacity|focusable|fontFamily|fontSize|fontSizeAdjust|fontStretch|fontStyle|fontVariant|fontWeight|format|from|fr|fx|fy|g1|g2|glyphName|glyphOrientationHorizontal|glyphOrientationVertical|glyphRef|gradientTransform|gradientUnits|hanging|horizAdvX|horizOriginX|ideographic|imageRendering|in|in2|intercept|k|k1|k2|k3|k4|kernelMatrix|kernelUnitLength|kerning|keyPoints|keySplines|keyTimes|lengthAdjust|letterSpacing|lightingColor|limitingConeAngle|local|markerEnd|markerMid|markerStart|markerHeight|markerUnits|markerWidth|mask|maskContentUnits|maskUnits|mathematical|mode|numOctaves|offset|opacity|operator|order|orient|orientation|origin|overflow|overlinePosition|overlineThickness|panose1|paintOrder|pathLength|patternContentUnits|patternTransform|patternUnits|pointerEvents|points|pointsAtX|pointsAtY|pointsAtZ|preserveAlpha|preserveAspectRatio|primitiveUnits|r|radius|refX|refY|renderingIntent|repeatCount|repeatDur|requiredExtensions|requiredFeatures|restart|result|rotate|rx|ry|scale|seed|shapeRendering|slope|spacing|specularConstant|specularExponent|speed|spreadMethod|startOffset|stdDeviation|stemh|stemv|stitchTiles|stopColor|stopOpacity|strikethroughPosition|strikethroughThickness|string|stroke|strokeDasharray|strokeDashoffset|strokeLinecap|strokeLinejoin|strokeMiterlimit|strokeOpacity|strokeWidth|surfaceScale|systemLanguage|tableValues|targetX|targetY|textAnchor|textDecoration|textRendering|textLength|to|transform|u1|u2|underlinePosition|underlineThickness|unicode|unicodeBidi|unicodeRange|unitsPerEm|vAlphabetic|vHanging|vIdeographic|vMathematical|values|vectorEffect|version|vertAdvY|vertOriginX|vertOriginY|viewBox|viewTarget|visibility|widths|wordSpacing|writingMode|x|xHeight|x1|x2|xChannelSelector|xlinkActuate|xlinkArcrole|xlinkHref|xlinkRole|xlinkShow|xlinkTitle|xlinkType|xmlBase|xmlns|xmlnsXlink|xmlLang|xmlSpace|y|y1|y2|yChannelSelector|z|zoomAndPan|for|class|autofocus)|(([Dd][Aa][Tt][Aa]|[Aa][Rr][Ii][Aa]|x)-.*))$/,Xj=HT(function(e){return Jj.test(e)||e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)<91});function Qj(e){if(e.sheet)return e.sheet;for(var t=0;t0?Gt(uc,--Wr):0,ql--,wt===10&&(ql=1,Cm--),wt}function dn(){return wt=Wr2||hd(wt)>3?"":" "}function dU(e,t){for(;--t&&dn()&&!(wt<48||wt>102||wt>57&&wt<65||wt>70&&wt<97););return Kd(e,cp()+(t<6&&Eo()==32&&dn()==32))}function Z0(e){for(;dn();)switch(wt){case e:return Wr;case 34:case 39:e!==34&&e!==39&&Z0(wt);break;case 40:e===41&&Z0(e);break;case 92:dn();break}return Wr}function fU(e,t){for(;dn()&&e+wt!==47+10;)if(e+wt===42+42&&Eo()===47)break;return"/*"+Kd(t,Wr-1)+"*"+Em(e===47?e:dn())}function pU(e){for(;!hd(Eo());)dn();return Kd(e,Wr)}function hU(e){return WT(dp("",null,null,null,[""],e=UT(e),0,[0],e))}function dp(e,t,r,n,o,i,s,a,l){for(var c=0,u=0,d=s,f=0,p=0,h=0,m=1,b=1,v=1,g=0,y="",x=o,k=i,w=n,E=y;b;)switch(h=g,g=dn()){case 40:if(h!=108&&Gt(E,d-1)==58){Q0(E+=Pe(up(g),"&","&\f"),"&\f")!=-1&&(v=-1);break}case 34:case 39:case 91:E+=up(g);break;case 9:case 10:case 13:case 32:E+=uU(h);break;case 92:E+=dU(cp()-1,7);continue;case 47:switch(Eo()){case 42:case 47:Ef(mU(fU(dn(),cp()),t,r),l);break;default:E+="/"}break;case 123*m:a[c++]=go(E)*v;case 125*m:case 59:case 0:switch(g){case 0:case 125:b=0;case 59+u:v==-1&&(E=Pe(E,/\f/g,"")),p>0&&go(E)-d&&Ef(p>32?Yw(E+";",n,r,d-1):Yw(Pe(E," ","")+";",n,r,d-2),l);break;case 59:E+=";";default:if(Ef(w=Gw(E,t,r,c,u,o,a,y,x=[],k=[],d),i),g===123)if(u===0)dp(E,t,w,w,x,i,d,a,k);else switch(f===99&&Gt(E,3)===110?100:f){case 100:case 108:case 109:case 115:dp(e,w,w,n&&Ef(Gw(e,w,w,0,0,o,a,y,o,x=[],d),k),o,k,d,a,n?x:k);break;default:dp(E,w,w,w,[""],k,0,a,k)}}c=u=p=0,m=v=1,y=E="",d=s;break;case 58:d=1+go(E),p=h;default:if(m<1){if(g==123)--m;else if(g==125&&m++==0&&cU()==125)continue}switch(E+=Em(g),g*m){case 38:v=u>0?1:(E+="\f",-1);break;case 44:a[c++]=(go(E)-1)*v,v=1;break;case 64:Eo()===45&&(E+=up(dn())),f=Eo(),u=d=go(y=E+=pU(cp())),g++;break;case 45:h===45&&go(E)==2&&(m=0)}}return i}function Gw(e,t,r,n,o,i,s,a,l,c,u){for(var d=o-1,f=o===0?i:[""],p=ab(f),h=0,m=0,b=0;h0?f[v]+" "+g:Pe(g,/&\f/g,f[v])))&&(l[b++]=y);return Mm(e,t,r,o===0?ib:a,l,c,u)}function mU(e,t,r){return Mm(e,t,r,BT,Em(lU()),pd(e,2,-2),0)}function Yw(e,t,r,n){return Mm(e,t,r,sb,pd(e,0,n),pd(e,n+1,-1),n)}function wl(e,t){for(var r="",n=ab(e),o=0;o6)switch(Gt(e,t+1)){case 109:if(Gt(e,t+4)!==45)break;case 102:return Pe(e,/(.+:)(.+)-([^]+)/,"$1"+Re+"$2-$3$1"+dh+(Gt(e,t+3)==108?"$3":"$2-$3"))+e;case 115:return~Q0(e,"stretch")?KT(Pe(e,"stretch","fill-available"),t)+e:e}break;case 4949:if(Gt(e,t+1)!==115)break;case 6444:switch(Gt(e,go(e)-3-(~Q0(e,"!important")&&10))){case 107:return Pe(e,":",":"+Re)+e;case 101:return Pe(e,/(.+:)([^;!]+)(;|!.+)?/,"$1"+Re+(Gt(e,14)===45?"inline-":"")+"box$3$1"+Re+"$2$3$1"+sr+"$2box$3")+e}break;case 5936:switch(Gt(e,t+11)){case 114:return Re+e+sr+Pe(e,/[svh]\w+-[tblr]{2}/,"tb")+e;case 108:return Re+e+sr+Pe(e,/[svh]\w+-[tblr]{2}/,"tb-rl")+e;case 45:return Re+e+sr+Pe(e,/[svh]\w+-[tblr]{2}/,"lr")+e}return Re+e+sr+e+e}return e}var EU=function(t,r,n,o){if(t.length>-1&&!t.return)switch(t.type){case sb:t.return=KT(t.value,t.length);break;case FT:return wl([Oc(t,{value:Pe(t.value,"@","@"+Re)})],o);case ib:if(t.length)return aU(t.props,function(i){switch(sU(i,/(::plac\w+|:read-\w+)/)){case":read-only":case":read-write":return wl([Oc(t,{props:[Pe(i,/:(read-\w+)/,":"+dh+"$1")]})],o);case"::placeholder":return wl([Oc(t,{props:[Pe(i,/:(plac\w+)/,":"+Re+"input-$1")]}),Oc(t,{props:[Pe(i,/:(plac\w+)/,":"+dh+"$1")]}),Oc(t,{props:[Pe(i,/:(plac\w+)/,sr+"input-$1")]})],o)}return""})}},CU=[EU],MU=function(t){var r=t.key;if(r==="css"){var n=document.querySelectorAll("style[data-emotion]:not([data-s])");Array.prototype.forEach.call(n,function(m){var b=m.getAttribute("data-emotion");b.indexOf(" ")!==-1&&(document.head.appendChild(m),m.setAttribute("data-s",""))})}var o=t.stylisPlugins||CU,i={},s,a=[];s=t.container||document.head,Array.prototype.forEach.call(document.querySelectorAll('style[data-emotion^="'+r+' "]'),function(m){for(var b=m.getAttribute("data-emotion").split(" "),v=1;v=4;++n,o-=4)r=e.charCodeAt(n)&255|(e.charCodeAt(++n)&255)<<8|(e.charCodeAt(++n)&255)<<16|(e.charCodeAt(++n)&255)<<24,r=(r&65535)*1540483477+((r>>>16)*59797<<16),r^=r>>>24,t=(r&65535)*1540483477+((r>>>16)*59797<<16)^(t&65535)*1540483477+((t>>>16)*59797<<16);switch(o){case 3:t^=(e.charCodeAt(n+2)&255)<<16;case 2:t^=(e.charCodeAt(n+1)&255)<<8;case 1:t^=e.charCodeAt(n)&255,t=(t&65535)*1540483477+((t>>>16)*59797<<16)}return t^=t>>>13,t=(t&65535)*1540483477+((t>>>16)*59797<<16),((t^t>>>15)>>>0).toString(36)}var HU={animationIterationCount:1,aspectRatio:1,borderImageOutset:1,borderImageSlice:1,borderImageWidth:1,boxFlex:1,boxFlexGroup:1,boxOrdinalGroup:1,columnCount:1,columns:1,flex:1,flexGrow:1,flexPositive:1,flexShrink:1,flexNegative:1,flexOrder:1,gridRow:1,gridRowEnd:1,gridRowSpan:1,gridRowStart:1,gridColumn:1,gridColumnEnd:1,gridColumnSpan:1,gridColumnStart:1,msGridRow:1,msGridRowSpan:1,msGridColumn:1,msGridColumnSpan:1,fontWeight:1,lineHeight:1,opacity:1,order:1,orphans:1,tabSize:1,widows:1,zIndex:1,zoom:1,WebkitLineClamp:1,fillOpacity:1,floodOpacity:1,stopOpacity:1,strokeDasharray:1,strokeDashoffset:1,strokeMiterlimit:1,strokeOpacity:1,strokeWidth:1},BU=/[A-Z]|^ms/g,FU=/_EMO_([^_]+?)_([^]*?)_EMO_/g,QT=function(t){return t.charCodeAt(1)===45},Xw=function(t){return t!=null&&typeof t!="boolean"},t1=HT(function(e){return QT(e)?e:e.replace(BU,"-$&").toLowerCase()}),Qw=function(t,r){switch(t){case"animation":case"animationName":if(typeof r=="string")return r.replace(FU,function(n,o,i){return vo={name:o,styles:i,next:vo},o})}return HU[t]!==1&&!QT(t)&&typeof r=="number"&&r!==0?r+"px":r};function md(e,t,r){if(r==null)return"";if(r.__emotion_styles!==void 0)return r;switch(typeof r){case"boolean":return"";case"object":{if(r.anim===1)return vo={name:r.name,styles:r.styles,next:vo},r.name;if(r.styles!==void 0){var n=r.next;if(n!==void 0)for(;n!==void 0;)vo={name:n.name,styles:n.styles,next:vo},n=n.next;var o=r.styles+";";return o}return VU(e,t,r)}case"function":{if(e!==void 0){var i=vo,s=r(e);return vo=i,md(e,t,s)}break}}if(t==null)return r;var a=t[r];return a!==void 0?a:r}function VU(e,t,r){var n="";if(Array.isArray(r))for(var o=0;o96?qU:GU},tS=function(t,r,n){var o;if(r){var i=r.shouldForwardProp;o=t.__emotion_forwardProp&&i?function(s){return t.__emotion_forwardProp(s)&&i(s)}:i}return typeof o!="function"&&n&&(o=t.__emotion_forwardProp),o},YU=function(t){var r=t.cache,n=t.serialized,o=t.isStringTag;return XT(r,n,o),WU(function(){return DU(r,n,o)}),null},JU=function e(t,r){var n=t.__emotion_real===t,o=n&&t.__emotion_base||t,i,s;r!==void 0&&(i=r.label,s=r.target);var a=tS(t,r,n),l=a||eS(o),c=!l("as");return function(){var u=arguments,d=n&&t.__emotion_styles!==void 0?t.__emotion_styles.slice(0):[];if(i!==void 0&&d.push("label:"+i+";"),u[0]==null||u[0].raw===void 0)d.push.apply(d,u);else{d.push(u[0][0]);for(var f=u.length,p=1;p{Array.isArray(e.__emotion_styles)&&(e.__emotion_styles=t(e.__emotion_styles))},ZU=["values","unit","step"],eW=e=>{const t=Object.keys(e).map(r=>({key:r,val:e[r]}))||[];return t.sort((r,n)=>r.val-n.val),t.reduce((r,n)=>_({},r,{[n.key]:n.val}),{})};function tW(e){const{values:t={xs:0,sm:600,md:900,lg:1200,xl:1536},unit:r="px",step:n=5}=e,o=ve(e,ZU),i=eW(t),s=Object.keys(i);function a(f){return`@media (min-width:${typeof t[f]=="number"?t[f]:f}${r})`}function l(f){return`@media (max-width:${(typeof t[f]=="number"?t[f]:f)-n/100}${r})`}function c(f,p){const h=s.indexOf(p);return`@media (min-width:${typeof t[f]=="number"?t[f]:f}${r}) and (max-width:${(h!==-1&&typeof t[s[h]]=="number"?t[s[h]]:p)-n/100}${r})`}function u(f){return s.indexOf(f)+1`@media (min-width:${pb[e]}px)`};function ao(e,t,r){const n=e.theme||{};if(Array.isArray(t)){const i=n.breakpoints||rS;return t.reduce((s,a,l)=>(s[i.up(i.keys[l])]=r(t[l]),s),{})}if(typeof t=="object"){const i=n.breakpoints||rS;return Object.keys(t).reduce((s,a)=>{if(Object.keys(i.values||pb).indexOf(a)!==-1){const l=i.up(a);s[l]=r(t[a],a)}else{const l=a;s[l]=t[l]}return s},{})}return r(t)}function r3(e={}){var t;return((t=e.keys)==null?void 0:t.reduce((n,o)=>{const i=e.up(o);return n[i]={},n},{}))||{}}function n3(e,t){return e.reduce((r,n)=>{const o=r[n];return(!o||Object.keys(o).length===0)&&delete r[n],r},t)}function oW(e,...t){const r=r3(e),n=[r,...t].reduce((o,i)=>un(o,i),{});return n3(Object.keys(r),n)}function iW(e,t){if(typeof e!="object")return{};const r={},n=Object.keys(t);return Array.isArray(e)?n.forEach((o,i)=>{i{e[o]!=null&&(r[o]=!0)}),r}function r1({values:e,breakpoints:t,base:r}){const n=r||iW(e,t),o=Object.keys(n);if(o.length===0)return e;let i;return o.reduce((s,a,l)=>(Array.isArray(e)?(s[a]=e[l]!=null?e[l]:e[i],i=l):typeof e=="object"?(s[a]=e[a]!=null?e[a]:e[i],i=a):s[a]=e,s),{})}function Dm(e,t,r=!0){if(!t||typeof t!="string")return null;if(e&&e.vars&&r){const n=`vars.${t}`.split(".").reduce((o,i)=>o&&o[i]?o[i]:null,e);if(n!=null)return n}return t.split(".").reduce((n,o)=>n&&n[o]!=null?n[o]:null,e)}function ph(e,t,r,n=r){let o;return typeof e=="function"?o=e(r):Array.isArray(e)?o=e[r]||n:o=Dm(e,r)||n,t&&(o=t(o,n,e)),o}function Ie(e){const{prop:t,cssProperty:r=e.prop,themeKey:n,transform:o}=e,i=s=>{if(s[t]==null)return null;const a=s[t],l=s.theme,c=Dm(l,n)||{};return ao(s,a,d=>{let f=ph(c,o,d);return d===f&&typeof d=="string"&&(f=ph(c,o,`${t}${d==="default"?"":Fe(d)}`,d)),r===!1?f:{[r]:f}})};return i.propTypes={},i.filterProps=[t],i}function sW(e){const t={};return r=>(t[r]===void 0&&(t[r]=e(r)),t[r])}const aW={m:"margin",p:"padding"},lW={t:"Top",r:"Right",b:"Bottom",l:"Left",x:["Left","Right"],y:["Top","Bottom"]},nS={marginX:"mx",marginY:"my",paddingX:"px",paddingY:"py"},cW=sW(e=>{if(e.length>2)if(nS[e])e=nS[e];else return[e];const[t,r]=e.split(""),n=aW[t],o=lW[r]||"";return Array.isArray(o)?o.map(i=>n+i):[n+o]}),hb=["m","mt","mr","mb","ml","mx","my","margin","marginTop","marginRight","marginBottom","marginLeft","marginX","marginY","marginInline","marginInlineStart","marginInlineEnd","marginBlock","marginBlockStart","marginBlockEnd"],mb=["p","pt","pr","pb","pl","px","py","padding","paddingTop","paddingRight","paddingBottom","paddingLeft","paddingX","paddingY","paddingInline","paddingInlineStart","paddingInlineEnd","paddingBlock","paddingBlockStart","paddingBlockEnd"];[...hb,...mb];function qd(e,t,r,n){var o;const i=(o=Dm(e,t,!1))!=null?o:r;return typeof i=="number"?s=>typeof s=="string"?s:i*s:Array.isArray(i)?s=>typeof s=="string"?s:i[s]:typeof i=="function"?i:()=>{}}function gb(e){return qd(e,"spacing",8)}function ha(e,t){if(typeof t=="string"||t==null)return t;const r=Math.abs(t),n=e(r);return t>=0?n:typeof n=="number"?-n:`-${n}`}function uW(e,t){return r=>e.reduce((n,o)=>(n[o]=ha(t,r),n),{})}function dW(e,t,r,n){if(t.indexOf(r)===-1)return null;const o=cW(r),i=uW(o,n),s=e[r];return ao(e,s,i)}function o3(e,t){const r=gb(e.theme);return Object.keys(e).map(n=>dW(e,t,n,r)).reduce(_u,{})}function pt(e){return o3(e,hb)}pt.propTypes={};pt.filterProps=hb;function ht(e){return o3(e,mb)}ht.propTypes={};ht.filterProps=mb;function fW(e=8){if(e.mui)return e;const t=gb({spacing:e}),r=(...n)=>(n.length===0?[1]:n).map(i=>{const s=t(i);return typeof s=="number"?`${s}px`:s}).join(" ");return r.mui=!0,r}function $m(...e){const t=e.reduce((n,o)=>(o.filterProps.forEach(i=>{n[i]=o}),n),{}),r=n=>Object.keys(n).reduce((o,i)=>t[i]?_u(o,t[i](n)):o,{});return r.propTypes={},r.filterProps=e.reduce((n,o)=>n.concat(o.filterProps),[]),r}function xo(e){return typeof e!="number"?e:`${e}px solid`}const pW=Ie({prop:"border",themeKey:"borders",transform:xo}),hW=Ie({prop:"borderTop",themeKey:"borders",transform:xo}),mW=Ie({prop:"borderRight",themeKey:"borders",transform:xo}),gW=Ie({prop:"borderBottom",themeKey:"borders",transform:xo}),vW=Ie({prop:"borderLeft",themeKey:"borders",transform:xo}),yW=Ie({prop:"borderColor",themeKey:"palette"}),bW=Ie({prop:"borderTopColor",themeKey:"palette"}),xW=Ie({prop:"borderRightColor",themeKey:"palette"}),kW=Ie({prop:"borderBottomColor",themeKey:"palette"}),wW=Ie({prop:"borderLeftColor",themeKey:"palette"}),Hm=e=>{if(e.borderRadius!==void 0&&e.borderRadius!==null){const t=qd(e.theme,"shape.borderRadius",4),r=n=>({borderRadius:ha(t,n)});return ao(e,e.borderRadius,r)}return null};Hm.propTypes={};Hm.filterProps=["borderRadius"];$m(pW,hW,mW,gW,vW,yW,bW,xW,kW,wW,Hm);const Bm=e=>{if(e.gap!==void 0&&e.gap!==null){const t=qd(e.theme,"spacing",8),r=n=>({gap:ha(t,n)});return ao(e,e.gap,r)}return null};Bm.propTypes={};Bm.filterProps=["gap"];const Fm=e=>{if(e.columnGap!==void 0&&e.columnGap!==null){const t=qd(e.theme,"spacing",8),r=n=>({columnGap:ha(t,n)});return ao(e,e.columnGap,r)}return null};Fm.propTypes={};Fm.filterProps=["columnGap"];const Vm=e=>{if(e.rowGap!==void 0&&e.rowGap!==null){const t=qd(e.theme,"spacing",8),r=n=>({rowGap:ha(t,n)});return ao(e,e.rowGap,r)}return null};Vm.propTypes={};Vm.filterProps=["rowGap"];const SW=Ie({prop:"gridColumn"}),EW=Ie({prop:"gridRow"}),CW=Ie({prop:"gridAutoFlow"}),MW=Ie({prop:"gridAutoColumns"}),TW=Ie({prop:"gridAutoRows"}),OW=Ie({prop:"gridTemplateColumns"}),_W=Ie({prop:"gridTemplateRows"}),AW=Ie({prop:"gridTemplateAreas"}),NW=Ie({prop:"gridArea"});$m(Bm,Fm,Vm,SW,EW,CW,MW,TW,OW,_W,AW,NW);function Sl(e,t){return t==="grey"?t:e}const RW=Ie({prop:"color",themeKey:"palette",transform:Sl}),PW=Ie({prop:"bgcolor",cssProperty:"backgroundColor",themeKey:"palette",transform:Sl}),zW=Ie({prop:"backgroundColor",themeKey:"palette",transform:Sl});$m(RW,PW,zW);function sn(e){return e<=1&&e!==0?`${e*100}%`:e}const LW=Ie({prop:"width",transform:sn}),vb=e=>{if(e.maxWidth!==void 0&&e.maxWidth!==null){const t=r=>{var n,o;const i=((n=e.theme)==null||(n=n.breakpoints)==null||(n=n.values)==null?void 0:n[r])||pb[r];return i?((o=e.theme)==null||(o=o.breakpoints)==null?void 0:o.unit)!=="px"?{maxWidth:`${i}${e.theme.breakpoints.unit}`}:{maxWidth:i}:{maxWidth:sn(r)}};return ao(e,e.maxWidth,t)}return null};vb.filterProps=["maxWidth"];const IW=Ie({prop:"minWidth",transform:sn}),DW=Ie({prop:"height",transform:sn}),$W=Ie({prop:"maxHeight",transform:sn}),HW=Ie({prop:"minHeight",transform:sn});Ie({prop:"size",cssProperty:"width",transform:sn});Ie({prop:"size",cssProperty:"height",transform:sn});const BW=Ie({prop:"boxSizing"});$m(LW,vb,IW,DW,$W,HW,BW);const FW={border:{themeKey:"borders",transform:xo},borderTop:{themeKey:"borders",transform:xo},borderRight:{themeKey:"borders",transform:xo},borderBottom:{themeKey:"borders",transform:xo},borderLeft:{themeKey:"borders",transform:xo},borderColor:{themeKey:"palette"},borderTopColor:{themeKey:"palette"},borderRightColor:{themeKey:"palette"},borderBottomColor:{themeKey:"palette"},borderLeftColor:{themeKey:"palette"},borderRadius:{themeKey:"shape.borderRadius",style:Hm},color:{themeKey:"palette",transform:Sl},bgcolor:{themeKey:"palette",cssProperty:"backgroundColor",transform:Sl},backgroundColor:{themeKey:"palette",transform:Sl},p:{style:ht},pt:{style:ht},pr:{style:ht},pb:{style:ht},pl:{style:ht},px:{style:ht},py:{style:ht},padding:{style:ht},paddingTop:{style:ht},paddingRight:{style:ht},paddingBottom:{style:ht},paddingLeft:{style:ht},paddingX:{style:ht},paddingY:{style:ht},paddingInline:{style:ht},paddingInlineStart:{style:ht},paddingInlineEnd:{style:ht},paddingBlock:{style:ht},paddingBlockStart:{style:ht},paddingBlockEnd:{style:ht},m:{style:pt},mt:{style:pt},mr:{style:pt},mb:{style:pt},ml:{style:pt},mx:{style:pt},my:{style:pt},margin:{style:pt},marginTop:{style:pt},marginRight:{style:pt},marginBottom:{style:pt},marginLeft:{style:pt},marginX:{style:pt},marginY:{style:pt},marginInline:{style:pt},marginInlineStart:{style:pt},marginInlineEnd:{style:pt},marginBlock:{style:pt},marginBlockStart:{style:pt},marginBlockEnd:{style:pt},displayPrint:{cssProperty:!1,transform:e=>({"@media print":{display:e}})},display:{},overflow:{},textOverflow:{},visibility:{},whiteSpace:{},flexBasis:{},flexDirection:{},flexWrap:{},justifyContent:{},alignItems:{},alignContent:{},order:{},flex:{},flexGrow:{},flexShrink:{},alignSelf:{},justifyItems:{},justifySelf:{},gap:{style:Bm},rowGap:{style:Vm},columnGap:{style:Fm},gridColumn:{},gridRow:{},gridAutoFlow:{},gridAutoColumns:{},gridAutoRows:{},gridTemplateColumns:{},gridTemplateRows:{},gridTemplateAreas:{},gridArea:{},position:{},zIndex:{themeKey:"zIndex"},top:{},right:{},bottom:{},left:{},boxShadow:{themeKey:"shadows"},width:{transform:sn},maxWidth:{style:vb},minWidth:{transform:sn},height:{transform:sn},maxHeight:{transform:sn},minHeight:{transform:sn},boxSizing:{},fontFamily:{themeKey:"typography"},fontSize:{themeKey:"typography"},fontStyle:{themeKey:"typography"},fontWeight:{themeKey:"typography"},letterSpacing:{},textTransform:{},lineHeight:{},textAlign:{},typography:{cssProperty:!1,themeKey:"typography"}},jm=FW;function VW(...e){const t=e.reduce((n,o)=>n.concat(Object.keys(o)),[]),r=new Set(t);return e.every(n=>r.size===Object.keys(n).length)}function jW(e,t){return typeof e=="function"?e(t):e}function UW(){function e(r,n,o,i){const s={[r]:n,theme:o},a=i[r];if(!a)return{[r]:n};const{cssProperty:l=r,themeKey:c,transform:u,style:d}=a;if(n==null)return null;if(c==="typography"&&n==="inherit")return{[r]:n};const f=Dm(o,c)||{};return d?d(s):ao(s,n,h=>{let m=ph(f,u,h);return h===m&&typeof h=="string"&&(m=ph(f,u,`${r}${h==="default"?"":Fe(h)}`,h)),l===!1?m:{[l]:m}})}function t(r){var n;const{sx:o,theme:i={}}=r||{};if(!o)return null;const s=(n=i.unstable_sxConfig)!=null?n:jm;function a(l){let c=l;if(typeof l=="function")c=l(i);else if(typeof l!="object")return l;if(!c)return null;const u=r3(i.breakpoints),d=Object.keys(u);let f=u;return Object.keys(c).forEach(p=>{const h=jW(c[p],i);if(h!=null)if(typeof h=="object")if(s[p])f=_u(f,e(p,h,i,s));else{const m=ao({theme:i},h,b=>({[p]:b}));VW(m,h)?f[p]=t({sx:h,theme:i}):f=_u(f,m)}else f=_u(f,e(p,h,i,s))}),n3(d,f)}return Array.isArray(o)?o.map(a):a(o)}return t}const i3=UW();i3.filterProps=["sx"];const Um=i3,WW=["breakpoints","palette","spacing","shape"];function Wm(e={},...t){const{breakpoints:r={},palette:n={},spacing:o,shape:i={}}=e,s=ve(e,WW),a=tW(r),l=fW(o);let c=un({breakpoints:a,direction:"ltr",components:{},palette:_({mode:"light"},n),spacing:l,shape:_({},nW,i)},s);return c=t.reduce((u,d)=>un(u,d),c),c.unstable_sxConfig=_({},jm,s==null?void 0:s.unstable_sxConfig),c.unstable_sx=function(d){return Um({sx:d,theme:this})},c}function KW(e){return Object.keys(e).length===0}function yb(e=null){const t=S.useContext(db);return!t||KW(t)?e:t}const qW=Wm();function bb(e=qW){return yb(e)}const GW=["sx"],YW=e=>{var t,r;const n={systemProps:{},otherProps:{}},o=(t=e==null||(r=e.theme)==null?void 0:r.unstable_sxConfig)!=null?t:jm;return Object.keys(e).forEach(i=>{o[i]?n.systemProps[i]=e[i]:n.otherProps[i]=e[i]}),n};function xb(e){const{sx:t}=e,r=ve(e,GW),{systemProps:n,otherProps:o}=YW(r);let i;return Array.isArray(t)?i=[n,...t]:typeof t=="function"?i=(...s)=>{const a=t(...s);return Wo(a)?_({},n,a):n}:i=_({},n,t),_({},o,{sx:i})}function s3(e){var t,r,n="";if(typeof e=="string"||typeof e=="number")n+=e;else if(typeof e=="object")if(Array.isArray(e))for(t=0;ta!=="theme"&&a!=="sx"&&a!=="as"})(Um);return S.forwardRef(function(l,c){const u=bb(r),d=xb(l),{className:f,component:p="div"}=d,h=ve(d,JW);return O.jsx(i,_({as:p,ref:c,className:Ce(f,o?o(n):n),theme:t&&u[t]||u},h))})}const QW=["variant"];function oS(e){return e.length===0}function a3(e){const{variant:t}=e,r=ve(e,QW);let n=t||"";return Object.keys(r).sort().forEach(o=>{o==="color"?n+=oS(n)?e[o]:Fe(e[o]):n+=`${oS(n)?o:Fe(o)}${Fe(e[o].toString())}`}),n}const ZW=["name","slot","skipVariantsResolver","skipSx","overridesResolver"];function eK(e){return Object.keys(e).length===0}function tK(e){return typeof e=="string"&&e.charCodeAt(0)>96}const rK=(e,t)=>t.components&&t.components[e]&&t.components[e].styleOverrides?t.components[e].styleOverrides:null,hh=e=>{const t={};return e&&e.forEach(r=>{const n=a3(r.props);t[n]=r.style}),t},nK=(e,t)=>{let r=[];return t&&t.components&&t.components[e]&&t.components[e].variants&&(r=t.components[e].variants),hh(r)},mh=(e,t,r)=>{const{ownerState:n={}}=e,o=[];return r&&r.forEach(i=>{let s=!0;Object.keys(i.props).forEach(a=>{n[a]!==i.props[a]&&e[a]!==i.props[a]&&(s=!1)}),s&&o.push(t[a3(i.props)])}),o},oK=(e,t,r,n)=>{var o;const i=r==null||(o=r.components)==null||(o=o[n])==null?void 0:o.variants;return mh(e,t,i)};function fp(e){return e!=="ownerState"&&e!=="theme"&&e!=="sx"&&e!=="as"}const iK=Wm(),sK=e=>e&&e.charAt(0).toLowerCase()+e.slice(1);function pp({defaultTheme:e,theme:t,themeId:r}){return eK(t)?e:t[r]||t}function aK(e){return e?(t,r)=>r[e]:null}const iS=({styledArg:e,props:t,defaultTheme:r,themeId:n})=>{const o=e(_({},t,{theme:pp(_({},t,{defaultTheme:r,themeId:n}))}));let i;if(o&&o.variants&&(i=o.variants,delete o.variants),i){const s=mh(t,hh(i),i);return[o,...s]}return o};function l3(e={}){const{themeId:t,defaultTheme:r=iK,rootShouldForwardProp:n=fp,slotShouldForwardProp:o=fp}=e,i=s=>Um(_({},s,{theme:pp(_({},s,{defaultTheme:r,themeId:t}))}));return i.__mui_systemSx=!0,(s,a={})=>{QU(s,x=>x.filter(k=>!(k!=null&&k.__mui_systemSx)));const{name:l,slot:c,skipVariantsResolver:u,skipSx:d,overridesResolver:f=aK(sK(c))}=a,p=ve(a,ZW),h=u!==void 0?u:c&&c!=="Root"&&c!=="root"||!1,m=d||!1;let b,v=fp;c==="Root"||c==="root"?v=n:c?v=o:tK(s)&&(v=void 0);const g=t3(s,_({shouldForwardProp:v,label:b},p)),y=(x,...k)=>{const w=k?k.map(T=>{if(typeof T=="function"&&T.__emotion_real!==T)return N=>iS({styledArg:T,props:N,defaultTheme:r,themeId:t});if(Wo(T)){let N=T,z;return T&&T.variants&&(z=T.variants,delete N.variants,N=D=>{let V=T;return mh(D,hh(z),z).forEach(L=>{V=un(V,L)}),V}),N}return T}):[];let E=x;if(Wo(x)){let T;x&&x.variants&&(T=x.variants,delete E.variants,E=N=>{let z=x;return mh(N,hh(T),T).forEach(V=>{z=un(z,V)}),z})}else typeof x=="function"&&x.__emotion_real!==x&&(E=T=>iS({styledArg:x,props:T,defaultTheme:r,themeId:t}));l&&f&&w.push(T=>{const N=pp(_({},T,{defaultTheme:r,themeId:t})),z=rK(l,N);if(z){const D={};return Object.entries(z).forEach(([V,j])=>{D[V]=typeof j=="function"?j(_({},T,{theme:N})):j}),f(T,D)}return null}),l&&!h&&w.push(T=>{const N=pp(_({},T,{defaultTheme:r,themeId:t}));return oK(T,nK(l,N),N,l)}),m||w.push(i);const M=w.length-k.length;if(Array.isArray(x)&&M>0){const T=new Array(M).fill("");E=[...x,...T],E.raw=[...x.raw,...T]}const C=g(E,...w);return s.muiName&&(C.muiName=s.muiName),C};return g.withConfig&&(y.withConfig=g.withConfig),y}}const lK=l3(),cK=lK;function uK(e){const{theme:t,name:r,props:n}=e;return!t||!t.components||!t.components[r]||!t.components[r].defaultProps?n:DT(t.components[r].defaultProps,n)}function c3({props:e,name:t,defaultTheme:r,themeId:n}){let o=bb(r);return n&&(o=o[n]||o),uK({theme:o,name:t,props:e})}function kb(e,t=0,r=1){return Math.min(Math.max(t,e),r)}function dK(e){e=e.slice(1);const t=new RegExp(`.{1,${e.length>=6?2:1}}`,"g");let r=e.match(t);return r&&r[0].length===1&&(r=r.map(n=>n+n)),r?`rgb${r.length===4?"a":""}(${r.map((n,o)=>o<3?parseInt(n,16):Math.round(parseInt(n,16)/255*1e3)/1e3).join(", ")})`:""}function ma(e){if(e.type)return e;if(e.charAt(0)==="#")return ma(dK(e));const t=e.indexOf("("),r=e.substring(0,t);if(["rgb","rgba","hsl","hsla","color"].indexOf(r)===-1)throw new Error(Wl(9,e));let n=e.substring(t+1,e.length-1),o;if(r==="color"){if(n=n.split(" "),o=n.shift(),n.length===4&&n[3].charAt(0)==="/"&&(n[3]=n[3].slice(1)),["srgb","display-p3","a98-rgb","prophoto-rgb","rec-2020"].indexOf(o)===-1)throw new Error(Wl(10,o))}else n=n.split(",");return n=n.map(i=>parseFloat(i)),{type:r,values:n,colorSpace:o}}function Km(e){const{type:t,colorSpace:r}=e;let{values:n}=e;return t.indexOf("rgb")!==-1?n=n.map((o,i)=>i<3?parseInt(o,10):o):t.indexOf("hsl")!==-1&&(n[1]=`${n[1]}%`,n[2]=`${n[2]}%`),t.indexOf("color")!==-1?n=`${r} ${n.join(" ")}`:n=`${n.join(", ")}`,`${t}(${n})`}function fK(e){e=ma(e);const{values:t}=e,r=t[0],n=t[1]/100,o=t[2]/100,i=n*Math.min(o,1-o),s=(c,u=(c+r/30)%12)=>o-i*Math.max(Math.min(u-3,9-u,1),-1);let a="rgb";const l=[Math.round(s(0)*255),Math.round(s(8)*255),Math.round(s(4)*255)];return e.type==="hsla"&&(a+="a",l.push(t[3])),Km({type:a,values:l})}function sS(e){e=ma(e);let t=e.type==="hsl"||e.type==="hsla"?ma(fK(e)).values:e.values;return t=t.map(r=>(e.type!=="color"&&(r/=255),r<=.03928?r/12.92:((r+.055)/1.055)**2.4)),Number((.2126*t[0]+.7152*t[1]+.0722*t[2]).toFixed(3))}function pK(e,t){const r=sS(e),n=sS(t);return(Math.max(r,n)+.05)/(Math.min(r,n)+.05)}function Lr(e,t){return e=ma(e),t=kb(t),(e.type==="rgb"||e.type==="hsl")&&(e.type+="a"),e.type==="color"?e.values[3]=`/${t}`:e.values[3]=t,Km(e)}function hK(e,t){if(e=ma(e),t=kb(t),e.type.indexOf("hsl")!==-1)e.values[2]*=1-t;else if(e.type.indexOf("rgb")!==-1||e.type.indexOf("color")!==-1)for(let r=0;r<3;r+=1)e.values[r]*=1-t;return Km(e)}function mK(e,t){if(e=ma(e),t=kb(t),e.type.indexOf("hsl")!==-1)e.values[2]+=(100-e.values[2])*t;else if(e.type.indexOf("rgb")!==-1)for(let r=0;r<3;r+=1)e.values[r]+=(255-e.values[r])*t;else if(e.type.indexOf("color")!==-1)for(let r=0;r<3;r+=1)e.values[r]+=(1-e.values[r])*t;return Km(e)}const gK=S.createContext(null),u3=gK;function d3(){return S.useContext(u3)}const vK=typeof Symbol=="function"&&Symbol.for,yK=vK?Symbol.for("mui.nested"):"__THEME_NESTED__";function bK(e,t){return typeof t=="function"?t(e):_({},e,t)}function xK(e){const{children:t,theme:r}=e,n=d3(),o=S.useMemo(()=>{const i=n===null?r:bK(n,r);return i!=null&&(i[yK]=n!==null),i},[r,n]);return O.jsx(u3.Provider,{value:o,children:t})}const aS={};function lS(e,t,r,n=!1){return S.useMemo(()=>{const o=e&&t[e]||t;if(typeof r=="function"){const i=r(o),s=e?_({},t,{[e]:i}):i;return n?()=>s:s}return e?_({},t,{[e]:r}):_({},t,r)},[e,t,r,n])}function kK(e){const{children:t,theme:r,themeId:n}=e,o=yb(aS),i=d3()||aS,s=lS(n,o,r),a=lS(n,i,r,!0);return O.jsx(xK,{theme:a,children:O.jsx(db.Provider,{value:s,children:t})})}const wK=["component","direction","spacing","divider","children","className","useFlexGap"],SK=Wm(),EK=cK("div",{name:"MuiStack",slot:"Root",overridesResolver:(e,t)=>t.root});function CK(e){return c3({props:e,name:"MuiStack",defaultTheme:SK})}function MK(e,t){const r=S.Children.toArray(e).filter(Boolean);return r.reduce((n,o,i)=>(n.push(o),i({row:"Left","row-reverse":"Right",column:"Top","column-reverse":"Bottom"})[e],OK=({ownerState:e,theme:t})=>{let r=_({display:"flex",flexDirection:"column"},ao({theme:t},r1({values:e.direction,breakpoints:t.breakpoints.values}),n=>({flexDirection:n})));if(e.spacing){const n=gb(t),o=Object.keys(t.breakpoints.values).reduce((l,c)=>((typeof e.spacing=="object"&&e.spacing[c]!=null||typeof e.direction=="object"&&e.direction[c]!=null)&&(l[c]=!0),l),{}),i=r1({values:e.direction,base:o}),s=r1({values:e.spacing,base:o});typeof i=="object"&&Object.keys(i).forEach((l,c,u)=>{if(!i[l]){const f=c>0?i[u[c-1]]:"column";i[l]=f}}),r=un(r,ao({theme:t},s,(l,c)=>e.useFlexGap?{gap:ha(n,l)}:{"& > :not(style):not(style)":{margin:0},"& > :not(style) ~ :not(style)":{[`margin${TK(c?i[c]:e.direction)}`]:ha(n,l)}}))}return r=oW(t.breakpoints,r),r};function _K(e={}){const{createStyledComponent:t=EK,useThemeProps:r=CK,componentName:n="MuiStack"}=e,o=()=>rr({root:["root"]},l=>Vt(n,l),{}),i=t(OK);return S.forwardRef(function(l,c){const u=r(l),d=xb(u),{component:f="div",direction:p="column",spacing:h=0,divider:m,children:b,className:v,useFlexGap:g=!1}=d,y=ve(d,wK),x={direction:p,spacing:h,useFlexGap:g},k=o();return O.jsx(i,_({as:f,ownerState:x,ref:c,className:Ce(k.root,v)},y,{children:m?MK(b,m):b}))})}function AK(e,t){return _({toolbar:{minHeight:56,[e.up("xs")]:{"@media (orientation: landscape)":{minHeight:48}},[e.up("sm")]:{minHeight:64}}},t)}const NK=["mode","contrastThreshold","tonalOffset"],cS={text:{primary:"rgba(0, 0, 0, 0.87)",secondary:"rgba(0, 0, 0, 0.6)",disabled:"rgba(0, 0, 0, 0.38)"},divider:"rgba(0, 0, 0, 0.12)",background:{paper:dd.white,default:dd.white},action:{active:"rgba(0, 0, 0, 0.54)",hover:"rgba(0, 0, 0, 0.04)",hoverOpacity:.04,selected:"rgba(0, 0, 0, 0.08)",selectedOpacity:.08,disabled:"rgba(0, 0, 0, 0.26)",disabledBackground:"rgba(0, 0, 0, 0.12)",disabledOpacity:.38,focus:"rgba(0, 0, 0, 0.12)",focusOpacity:.12,activatedOpacity:.12}},n1={text:{primary:dd.white,secondary:"rgba(255, 255, 255, 0.7)",disabled:"rgba(255, 255, 255, 0.5)",icon:"rgba(255, 255, 255, 0.5)"},divider:"rgba(255, 255, 255, 0.12)",background:{paper:"#121212",default:"#121212"},action:{active:dd.white,hover:"rgba(255, 255, 255, 0.08)",hoverOpacity:.08,selected:"rgba(255, 255, 255, 0.16)",selectedOpacity:.16,disabled:"rgba(255, 255, 255, 0.3)",disabledBackground:"rgba(255, 255, 255, 0.12)",disabledOpacity:.38,focus:"rgba(255, 255, 255, 0.12)",focusOpacity:.12,activatedOpacity:.24}};function uS(e,t,r,n){const o=n.light||n,i=n.dark||n*1.5;e[t]||(e.hasOwnProperty(r)?e[t]=e[r]:t==="light"?e.light=mK(e.main,o):t==="dark"&&(e.dark=hK(e.main,i)))}function RK(e="light"){return e==="dark"?{main:Ia[200],light:Ia[50],dark:Ia[400]}:{main:Ia[700],light:Ia[400],dark:Ia[800]}}function PK(e="light"){return e==="dark"?{main:La[200],light:La[50],dark:La[400]}:{main:La[500],light:La[300],dark:La[700]}}function zK(e="light"){return e==="dark"?{main:za[500],light:za[300],dark:za[700]}:{main:za[700],light:za[400],dark:za[800]}}function LK(e="light"){return e==="dark"?{main:Da[400],light:Da[300],dark:Da[700]}:{main:Da[700],light:Da[500],dark:Da[900]}}function IK(e="light"){return e==="dark"?{main:$a[400],light:$a[300],dark:$a[700]}:{main:$a[800],light:$a[500],dark:$a[900]}}function DK(e="light"){return e==="dark"?{main:Tc[400],light:Tc[300],dark:Tc[700]}:{main:"#ed6c02",light:Tc[500],dark:Tc[900]}}function $K(e){const{mode:t="light",contrastThreshold:r=3,tonalOffset:n=.2}=e,o=ve(e,NK),i=e.primary||RK(t),s=e.secondary||PK(t),a=e.error||zK(t),l=e.info||LK(t),c=e.success||IK(t),u=e.warning||DK(t);function d(m){return pK(m,n1.text.primary)>=r?n1.text.primary:cS.text.primary}const f=({color:m,name:b,mainShade:v=500,lightShade:g=300,darkShade:y=700})=>{if(m=_({},m),!m.main&&m[v]&&(m.main=m[v]),!m.hasOwnProperty("main"))throw new Error(Wl(11,b?` (${b})`:"",v));if(typeof m.main!="string")throw new Error(Wl(12,b?` (${b})`:"",JSON.stringify(m.main)));return uS(m,"light",g,n),uS(m,"dark",y,n),m.contrastText||(m.contrastText=d(m.main)),m},p={dark:n1,light:cS};return un(_({common:_({},dd),mode:t,primary:f({color:i,name:"primary"}),secondary:f({color:s,name:"secondary",mainShade:"A400",lightShade:"A200",darkShade:"A700"}),error:f({color:a,name:"error"}),warning:f({color:u,name:"warning"}),info:f({color:l,name:"info"}),success:f({color:c,name:"success"}),grey:Rj,contrastThreshold:r,getContrastText:d,augmentColor:f,tonalOffset:n},p[t]),o)}const HK=["fontFamily","fontSize","fontWeightLight","fontWeightRegular","fontWeightMedium","fontWeightBold","htmlFontSize","allVariants","pxToRem"];function BK(e){return Math.round(e*1e5)/1e5}const dS={textTransform:"uppercase"},fS='"Roboto", "Helvetica", "Arial", sans-serif';function FK(e,t){const r=typeof t=="function"?t(e):t,{fontFamily:n=fS,fontSize:o=14,fontWeightLight:i=300,fontWeightRegular:s=400,fontWeightMedium:a=500,fontWeightBold:l=700,htmlFontSize:c=16,allVariants:u,pxToRem:d}=r,f=ve(r,HK),p=o/14,h=d||(v=>`${v/c*p}rem`),m=(v,g,y,x,k)=>_({fontFamily:n,fontWeight:v,fontSize:h(g),lineHeight:y},n===fS?{letterSpacing:`${BK(x/g)}em`}:{},k,u),b={h1:m(i,96,1.167,-1.5),h2:m(i,60,1.2,-.5),h3:m(s,48,1.167,0),h4:m(s,34,1.235,.25),h5:m(s,24,1.334,0),h6:m(a,20,1.6,.15),subtitle1:m(s,16,1.75,.15),subtitle2:m(a,14,1.57,.1),body1:m(s,16,1.5,.15),body2:m(s,14,1.43,.15),button:m(a,14,1.75,.4,dS),caption:m(s,12,1.66,.4),overline:m(s,12,2.66,1,dS),inherit:{fontFamily:"inherit",fontWeight:"inherit",fontSize:"inherit",lineHeight:"inherit",letterSpacing:"inherit"}};return un(_({htmlFontSize:c,pxToRem:h,fontFamily:n,fontSize:o,fontWeightLight:i,fontWeightRegular:s,fontWeightMedium:a,fontWeightBold:l},b),f,{clone:!1})}const VK=.2,jK=.14,UK=.12;function nt(...e){return[`${e[0]}px ${e[1]}px ${e[2]}px ${e[3]}px rgba(0,0,0,${VK})`,`${e[4]}px ${e[5]}px ${e[6]}px ${e[7]}px rgba(0,0,0,${jK})`,`${e[8]}px ${e[9]}px ${e[10]}px ${e[11]}px rgba(0,0,0,${UK})`].join(",")}const WK=["none",nt(0,2,1,-1,0,1,1,0,0,1,3,0),nt(0,3,1,-2,0,2,2,0,0,1,5,0),nt(0,3,3,-2,0,3,4,0,0,1,8,0),nt(0,2,4,-1,0,4,5,0,0,1,10,0),nt(0,3,5,-1,0,5,8,0,0,1,14,0),nt(0,3,5,-1,0,6,10,0,0,1,18,0),nt(0,4,5,-2,0,7,10,1,0,2,16,1),nt(0,5,5,-3,0,8,10,1,0,3,14,2),nt(0,5,6,-3,0,9,12,1,0,3,16,2),nt(0,6,6,-3,0,10,14,1,0,4,18,3),nt(0,6,7,-4,0,11,15,1,0,4,20,3),nt(0,7,8,-4,0,12,17,2,0,5,22,4),nt(0,7,8,-4,0,13,19,2,0,5,24,4),nt(0,7,9,-4,0,14,21,2,0,5,26,4),nt(0,8,9,-5,0,15,22,2,0,6,28,5),nt(0,8,10,-5,0,16,24,2,0,6,30,5),nt(0,8,11,-5,0,17,26,2,0,6,32,5),nt(0,9,11,-5,0,18,28,2,0,7,34,6),nt(0,9,12,-6,0,19,29,2,0,7,36,6),nt(0,10,13,-6,0,20,31,3,0,8,38,7),nt(0,10,13,-6,0,21,33,3,0,8,40,7),nt(0,10,14,-6,0,22,35,3,0,8,42,7),nt(0,11,14,-7,0,23,36,3,0,9,44,8),nt(0,11,15,-7,0,24,38,3,0,9,46,8)],KK=WK,qK=["duration","easing","delay"],GK={easeInOut:"cubic-bezier(0.4, 0, 0.2, 1)",easeOut:"cubic-bezier(0.0, 0, 0.2, 1)",easeIn:"cubic-bezier(0.4, 0, 1, 1)",sharp:"cubic-bezier(0.4, 0, 0.6, 1)"},YK={shortest:150,shorter:200,short:250,standard:300,complex:375,enteringScreen:225,leavingScreen:195};function pS(e){return`${Math.round(e)}ms`}function JK(e){if(!e)return 0;const t=e/36;return Math.round((4+15*t**.25+t/5)*10)}function XK(e){const t=_({},GK,e.easing),r=_({},YK,e.duration);return _({getAutoHeightDuration:JK,create:(o=["all"],i={})=>{const{duration:s=r.standard,easing:a=t.easeInOut,delay:l=0}=i;return ve(i,qK),(Array.isArray(o)?o:[o]).map(c=>`${c} ${typeof s=="string"?s:pS(s)} ${a} ${typeof l=="string"?l:pS(l)}`).join(",")}},e,{easing:t,duration:r})}const QK={mobileStepper:1e3,fab:1050,speedDial:1050,appBar:1100,drawer:1200,modal:1300,snackbar:1400,tooltip:1500},ZK=QK,eq=["breakpoints","mixins","spacing","palette","transitions","typography","shape"];function wb(e={},...t){const{mixins:r={},palette:n={},transitions:o={},typography:i={}}=e,s=ve(e,eq);if(e.vars)throw new Error(Wl(18));const a=$K(n),l=Wm(e);let c=un(l,{mixins:AK(l.breakpoints,r),palette:a,shadows:KK.slice(),typography:FK(a,i),transitions:XK(o),zIndex:_({},ZK)});return c=un(c,s),c=t.reduce((u,d)=>un(u,d),c),c.unstable_sxConfig=_({},jm,s==null?void 0:s.unstable_sxConfig),c.unstable_sx=function(d){return Um({sx:d,theme:this})},c}const tq=wb(),Sb=tq;function qm(){const e=bb(Sb);return e[Kl]||e}function Wt({props:e,name:t}){return c3({props:e,name:t,defaultTheme:Sb,themeId:Kl})}const Eb=e=>fp(e)&&e!=="classes",rq=l3({themeId:Kl,defaultTheme:Sb,rootShouldForwardProp:Eb}),Je=rq,nq=["theme"];function oq(e){let{theme:t}=e,r=ve(e,nq);const n=t[Kl];return O.jsx(kK,_({},r,{themeId:n?Kl:void 0,theme:n||t}))}const iq=e=>{let t;return e<1?t=5.11916*e**2:t=4.5*Math.log(e+1)+2,(t/100).toFixed(2)},hS=iq;function ev(e,t){return ev=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(n,o){return n.__proto__=o,n},ev(e,t)}function f3(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,ev(e,t)}const mS={disabled:!1},gh=I.createContext(null);var sq=function(t){return t.scrollTop},lu="unmounted",As="exited",Ns="entering",Ya="entered",tv="exiting",pi=function(e){f3(t,e);function t(n,o){var i;i=e.call(this,n,o)||this;var s=o,a=s&&!s.isMounting?n.enter:n.appear,l;return i.appearStatus=null,n.in?a?(l=As,i.appearStatus=Ns):l=Ya:n.unmountOnExit||n.mountOnEnter?l=lu:l=As,i.state={status:l},i.nextCallback=null,i}t.getDerivedStateFromProps=function(o,i){var s=o.in;return s&&i.status===lu?{status:As}:null};var r=t.prototype;return r.componentDidMount=function(){this.updateStatus(!0,this.appearStatus)},r.componentDidUpdate=function(o){var i=null;if(o!==this.props){var s=this.state.status;this.props.in?s!==Ns&&s!==Ya&&(i=Ns):(s===Ns||s===Ya)&&(i=tv)}this.updateStatus(!1,i)},r.componentWillUnmount=function(){this.cancelNextCallback()},r.getTimeouts=function(){var o=this.props.timeout,i,s,a;return i=s=a=o,o!=null&&typeof o!="number"&&(i=o.exit,s=o.enter,a=o.appear!==void 0?o.appear:s),{exit:i,enter:s,appear:a}},r.updateStatus=function(o,i){if(o===void 0&&(o=!1),i!==null)if(this.cancelNextCallback(),i===Ns){if(this.props.unmountOnExit||this.props.mountOnEnter){var s=this.props.nodeRef?this.props.nodeRef.current:wf.findDOMNode(this);s&&sq(s)}this.performEnter(o)}else this.performExit();else this.props.unmountOnExit&&this.state.status===As&&this.setState({status:lu})},r.performEnter=function(o){var i=this,s=this.props.enter,a=this.context?this.context.isMounting:o,l=this.props.nodeRef?[a]:[wf.findDOMNode(this),a],c=l[0],u=l[1],d=this.getTimeouts(),f=a?d.appear:d.enter;if(!o&&!s||mS.disabled){this.safeSetState({status:Ya},function(){i.props.onEntered(c)});return}this.props.onEnter(c,u),this.safeSetState({status:Ns},function(){i.props.onEntering(c,u),i.onTransitionEnd(f,function(){i.safeSetState({status:Ya},function(){i.props.onEntered(c,u)})})})},r.performExit=function(){var o=this,i=this.props.exit,s=this.getTimeouts(),a=this.props.nodeRef?void 0:wf.findDOMNode(this);if(!i||mS.disabled){this.safeSetState({status:As},function(){o.props.onExited(a)});return}this.props.onExit(a),this.safeSetState({status:tv},function(){o.props.onExiting(a),o.onTransitionEnd(s.exit,function(){o.safeSetState({status:As},function(){o.props.onExited(a)})})})},r.cancelNextCallback=function(){this.nextCallback!==null&&(this.nextCallback.cancel(),this.nextCallback=null)},r.safeSetState=function(o,i){i=this.setNextCallback(i),this.setState(o,i)},r.setNextCallback=function(o){var i=this,s=!0;return this.nextCallback=function(a){s&&(s=!1,i.nextCallback=null,o(a))},this.nextCallback.cancel=function(){s=!1},this.nextCallback},r.onTransitionEnd=function(o,i){this.setNextCallback(i);var s=this.props.nodeRef?this.props.nodeRef.current:wf.findDOMNode(this),a=o==null&&!this.props.addEndListener;if(!s||a){setTimeout(this.nextCallback,0);return}if(this.props.addEndListener){var l=this.props.nodeRef?[this.nextCallback]:[s,this.nextCallback],c=l[0],u=l[1];this.props.addEndListener(c,u)}o!=null&&setTimeout(this.nextCallback,o)},r.render=function(){var o=this.state.status;if(o===lu)return null;var i=this.props,s=i.children;i.in,i.mountOnEnter,i.unmountOnExit,i.appear,i.enter,i.exit,i.timeout,i.addEndListener,i.onEnter,i.onEntering,i.onEntered,i.onExit,i.onExiting,i.onExited,i.nodeRef;var a=ve(i,["children","in","mountOnEnter","unmountOnExit","appear","enter","exit","timeout","addEndListener","onEnter","onEntering","onEntered","onExit","onExiting","onExited","nodeRef"]);return I.createElement(gh.Provider,{value:null},typeof s=="function"?s(o,a):I.cloneElement(I.Children.only(s),a))},t}(I.Component);pi.contextType=gh;pi.propTypes={};function Ha(){}pi.defaultProps={in:!1,mountOnEnter:!1,unmountOnExit:!1,appear:!1,enter:!0,exit:!0,onEnter:Ha,onEntering:Ha,onEntered:Ha,onExit:Ha,onExiting:Ha,onExited:Ha};pi.UNMOUNTED=lu;pi.EXITED=As;pi.ENTERING=Ns;pi.ENTERED=Ya;pi.EXITING=tv;const p3=pi;function aq(e){if(e===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function Cb(e,t){var r=function(i){return t&&S.isValidElement(i)?t(i):i},n=Object.create(null);return e&&S.Children.map(e,function(o){return o}).forEach(function(o){n[o.key]=r(o)}),n}function lq(e,t){e=e||{},t=t||{};function r(u){return u in t?t[u]:e[u]}var n=Object.create(null),o=[];for(var i in e)i in t?o.length&&(n[i]=o,o=[]):o.push(i);var s,a={};for(var l in t){if(n[l])for(s=0;se.scrollTop;function vh(e,t){var r,n;const{timeout:o,easing:i,style:s={}}=e;return{duration:(r=s.transitionDuration)!=null?r:typeof o=="number"?o:o[t.mode]||0,easing:(n=s.transitionTimingFunction)!=null?n:typeof i=="object"?i[t.mode]:i,delay:s.transitionDelay}}function hq(e){return Vt("MuiPaper",e)}jt("MuiPaper",["root","rounded","outlined","elevation","elevation0","elevation1","elevation2","elevation3","elevation4","elevation5","elevation6","elevation7","elevation8","elevation9","elevation10","elevation11","elevation12","elevation13","elevation14","elevation15","elevation16","elevation17","elevation18","elevation19","elevation20","elevation21","elevation22","elevation23","elevation24"]);const mq=["className","component","elevation","square","variant"],gq=e=>{const{square:t,elevation:r,variant:n,classes:o}=e,i={root:["root",n,!t&&"rounded",n==="elevation"&&`elevation${r}`]};return rr(i,hq,o)},vq=Je("div",{name:"MuiPaper",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:r}=e;return[t.root,t[r.variant],!r.square&&t.rounded,r.variant==="elevation"&&t[`elevation${r.elevation}`]]}})(({theme:e,ownerState:t})=>{var r;return _({backgroundColor:(e.vars||e).palette.background.paper,color:(e.vars||e).palette.text.primary,transition:e.transitions.create("box-shadow")},!t.square&&{borderRadius:e.shape.borderRadius},t.variant==="outlined"&&{border:`1px solid ${(e.vars||e).palette.divider}`},t.variant==="elevation"&&_({boxShadow:(e.vars||e).shadows[t.elevation]},!e.vars&&e.palette.mode==="dark"&&{backgroundImage:`linear-gradient(${Lr("#fff",hS(t.elevation))}, ${Lr("#fff",hS(t.elevation))})`},e.vars&&{backgroundImage:(r=e.vars.overlays)==null?void 0:r[t.elevation]}))}),yq=S.forwardRef(function(t,r){const n=Wt({props:t,name:"MuiPaper"}),{className:o,component:i="div",elevation:s=1,square:a=!1,variant:l="elevation"}=n,c=ve(n,mq),u=_({},n,{component:i,elevation:s,square:a,variant:l}),d=gq(u);return O.jsx(vq,_({as:i,ownerState:u,className:Ce(d.root,o),ref:r},c))}),bq=yq;function xq(e){const{className:t,classes:r,pulsate:n=!1,rippleX:o,rippleY:i,rippleSize:s,in:a,onExited:l,timeout:c}=e,[u,d]=S.useState(!1),f=Ce(t,r.ripple,r.rippleVisible,n&&r.ripplePulsate),p={width:s,height:s,top:-(s/2)+i,left:-(s/2)+o},h=Ce(r.child,u&&r.childLeaving,n&&r.childPulsate);return!a&&!u&&d(!0),S.useEffect(()=>{if(!a&&l!=null){const m=setTimeout(l,c);return()=>{clearTimeout(m)}}},[l,a,c]),O.jsx("span",{className:f,style:p,children:O.jsx("span",{className:h})})}const kq=jt("MuiTouchRipple",["root","ripple","rippleVisible","ripplePulsate","child","childLeaving","childPulsate"]),Sn=kq,wq=["center","classes","className"];let Gm=e=>e,gS,vS,yS,bS;const rv=550,Sq=80,Eq=fb(gS||(gS=Gm` + 0% { + transform: scale(0); + opacity: 0.1; + } + + 100% { + transform: scale(1); + opacity: 0.3; + } +`)),Cq=fb(vS||(vS=Gm` + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + } +`)),Mq=fb(yS||(yS=Gm` + 0% { + transform: scale(1); + } + + 50% { + transform: scale(0.92); + } + + 100% { + transform: scale(1); + } +`)),Tq=Je("span",{name:"MuiTouchRipple",slot:"Root"})({overflow:"hidden",pointerEvents:"none",position:"absolute",zIndex:0,top:0,right:0,bottom:0,left:0,borderRadius:"inherit"}),Oq=Je(xq,{name:"MuiTouchRipple",slot:"Ripple"})(bS||(bS=Gm` + opacity: 0; + position: absolute; + + &.${0} { + opacity: 0.3; + transform: scale(1); + animation-name: ${0}; + animation-duration: ${0}ms; + animation-timing-function: ${0}; + } + + &.${0} { + animation-duration: ${0}ms; + } + + & .${0} { + opacity: 1; + display: block; + width: 100%; + height: 100%; + border-radius: 50%; + background-color: currentColor; + } + + & .${0} { + opacity: 0; + animation-name: ${0}; + animation-duration: ${0}ms; + animation-timing-function: ${0}; + } + + & .${0} { + position: absolute; + /* @noflip */ + left: 0px; + top: 0; + animation-name: ${0}; + animation-duration: 2500ms; + animation-timing-function: ${0}; + animation-iteration-count: infinite; + animation-delay: 200ms; + } +`),Sn.rippleVisible,Eq,rv,({theme:e})=>e.transitions.easing.easeInOut,Sn.ripplePulsate,({theme:e})=>e.transitions.duration.shorter,Sn.child,Sn.childLeaving,Cq,rv,({theme:e})=>e.transitions.easing.easeInOut,Sn.childPulsate,Mq,({theme:e})=>e.transitions.easing.easeInOut),_q=S.forwardRef(function(t,r){const n=Wt({props:t,name:"MuiTouchRipple"}),{center:o=!1,classes:i={},className:s}=n,a=ve(n,wq),[l,c]=S.useState([]),u=S.useRef(0),d=S.useRef(null);S.useEffect(()=>{d.current&&(d.current(),d.current=null)},[l]);const f=S.useRef(!1),p=S.useRef(0),h=S.useRef(null),m=S.useRef(null);S.useEffect(()=>()=>{p.current&&clearTimeout(p.current)},[]);const b=S.useCallback(x=>{const{pulsate:k,rippleX:w,rippleY:E,rippleSize:M,cb:C}=x;c(T=>[...T,O.jsx(Oq,{classes:{ripple:Ce(i.ripple,Sn.ripple),rippleVisible:Ce(i.rippleVisible,Sn.rippleVisible),ripplePulsate:Ce(i.ripplePulsate,Sn.ripplePulsate),child:Ce(i.child,Sn.child),childLeaving:Ce(i.childLeaving,Sn.childLeaving),childPulsate:Ce(i.childPulsate,Sn.childPulsate)},timeout:rv,pulsate:k,rippleX:w,rippleY:E,rippleSize:M},u.current)]),u.current+=1,d.current=C},[i]),v=S.useCallback((x={},k={},w=()=>{})=>{const{pulsate:E=!1,center:M=o||k.pulsate,fakeElement:C=!1}=k;if((x==null?void 0:x.type)==="mousedown"&&f.current){f.current=!1;return}(x==null?void 0:x.type)==="touchstart"&&(f.current=!0);const T=C?null:m.current,N=T?T.getBoundingClientRect():{width:0,height:0,left:0,top:0};let z,D,V;if(M||x===void 0||x.clientX===0&&x.clientY===0||!x.clientX&&!x.touches)z=Math.round(N.width/2),D=Math.round(N.height/2);else{const{clientX:j,clientY:L}=x.touches&&x.touches.length>0?x.touches[0]:x;z=Math.round(j-N.left),D=Math.round(L-N.top)}if(M)V=Math.sqrt((2*N.width**2+N.height**2)/3),V%2===0&&(V+=1);else{const j=Math.max(Math.abs((T?T.clientWidth:0)-z),z)*2+2,L=Math.max(Math.abs((T?T.clientHeight:0)-D),D)*2+2;V=Math.sqrt(j**2+L**2)}x!=null&&x.touches?h.current===null&&(h.current=()=>{b({pulsate:E,rippleX:z,rippleY:D,rippleSize:V,cb:w})},p.current=setTimeout(()=>{h.current&&(h.current(),h.current=null)},Sq)):b({pulsate:E,rippleX:z,rippleY:D,rippleSize:V,cb:w})},[o,b]),g=S.useCallback(()=>{v({},{pulsate:!0})},[v]),y=S.useCallback((x,k)=>{if(clearTimeout(p.current),(x==null?void 0:x.type)==="touchend"&&h.current){h.current(),h.current=null,p.current=setTimeout(()=>{y(x,k)});return}h.current=null,c(w=>w.length>0?w.slice(1):w),d.current=k},[]);return S.useImperativeHandle(r,()=>({pulsate:g,start:v,stop:y}),[g,v,y]),O.jsx(Tq,_({className:Ce(Sn.root,i.root,s),ref:m},a,{children:O.jsx(pq,{component:null,exit:!0,children:l})}))}),Aq=_q;function Nq(e){return Vt("MuiButtonBase",e)}const Rq=jt("MuiButtonBase",["root","disabled","focusVisible"]),Pq=Rq,zq=["action","centerRipple","children","className","component","disabled","disableRipple","disableTouchRipple","focusRipple","focusVisibleClassName","LinkComponent","onBlur","onClick","onContextMenu","onDragLeave","onFocus","onFocusVisible","onKeyDown","onKeyUp","onMouseDown","onMouseLeave","onMouseUp","onTouchEnd","onTouchMove","onTouchStart","tabIndex","TouchRippleProps","touchRippleRef","type"],Lq=e=>{const{disabled:t,focusVisible:r,focusVisibleClassName:n,classes:o}=e,s=rr({root:["root",t&&"disabled",r&&"focusVisible"]},Nq,o);return r&&n&&(s.root+=` ${n}`),s},Iq=Je("button",{name:"MuiButtonBase",slot:"Root",overridesResolver:(e,t)=>t.root})({display:"inline-flex",alignItems:"center",justifyContent:"center",position:"relative",boxSizing:"border-box",WebkitTapHighlightColor:"transparent",backgroundColor:"transparent",outline:0,border:0,margin:0,borderRadius:0,padding:0,cursor:"pointer",userSelect:"none",verticalAlign:"middle",MozAppearance:"none",WebkitAppearance:"none",textDecoration:"none",color:"inherit","&::-moz-focus-inner":{borderStyle:"none"},[`&.${Pq.disabled}`]:{pointerEvents:"none",cursor:"default"},"@media print":{colorAdjust:"exact"}}),Dq=S.forwardRef(function(t,r){const n=Wt({props:t,name:"MuiButtonBase"}),{action:o,centerRipple:i=!1,children:s,className:a,component:l="button",disabled:c=!1,disableRipple:u=!1,disableTouchRipple:d=!1,focusRipple:f=!1,LinkComponent:p="a",onBlur:h,onClick:m,onContextMenu:b,onDragLeave:v,onFocus:g,onFocusVisible:y,onKeyDown:x,onKeyUp:k,onMouseDown:w,onMouseLeave:E,onMouseUp:M,onTouchEnd:C,onTouchMove:T,onTouchStart:N,tabIndex:z=0,TouchRippleProps:D,touchRippleRef:V,type:j}=n,L=ve(n,zq),q=S.useRef(null),A=S.useRef(null),P=Ur(A,V),{isFocusVisibleRef:F,onFocus:Y,onBlur:J,ref:Ne}=zT(),[ie,ue]=S.useState(!1);c&&ie&&ue(!1),S.useImperativeHandle(o,()=>({focusVisible:()=>{ue(!0),q.current.focus()}}),[]);const[de,me]=S.useState(!1);S.useEffect(()=>{me(!0)},[]);const Me=de&&!u&&!c;S.useEffect(()=>{ie&&f&&!u&&de&&A.current.pulsate()},[u,f,ie,de]);function Se(fe,bn,fc=d){return Ws(vi=>(bn&&bn(vi),!fc&&A.current&&A.current[fe](vi),!0))}const ft=Se("start",w),rt=Se("stop",b),Or=Se("stop",v),he=Se("stop",M),De=Se("stop",fe=>{ie&&fe.preventDefault(),E&&E(fe)}),Ke=Se("start",N),Fn=Se("stop",C),Gr=Se("stop",T),nr=Se("stop",fe=>{J(fe),F.current===!1&&ue(!1),h&&h(fe)},!1),zo=Ws(fe=>{q.current||(q.current=fe.currentTarget),Y(fe),F.current===!0&&(ue(!0),y&&y(fe)),g&&g(fe)}),Pt=()=>{const fe=q.current;return l&&l!=="button"&&!(fe.tagName==="A"&&fe.href)},Yr=S.useRef(!1),vn=Ws(fe=>{f&&!Yr.current&&ie&&A.current&&fe.key===" "&&(Yr.current=!0,A.current.stop(fe,()=>{A.current.start(fe)})),fe.target===fe.currentTarget&&Pt()&&fe.key===" "&&fe.preventDefault(),x&&x(fe),fe.target===fe.currentTarget&&Pt()&&fe.key==="Enter"&&!c&&(fe.preventDefault(),m&&m(fe))}),Vn=Ws(fe=>{f&&fe.key===" "&&A.current&&ie&&!fe.defaultPrevented&&(Yr.current=!1,A.current.stop(fe,()=>{A.current.pulsate(fe)})),k&&k(fe),m&&fe.target===fe.currentTarget&&Pt()&&fe.key===" "&&!fe.defaultPrevented&&m(fe)});let Xe=l;Xe==="button"&&(L.href||L.to)&&(Xe=p);const Jr={};Xe==="button"?(Jr.type=j===void 0?"button":j,Jr.disabled=c):(!L.href&&!L.to&&(Jr.role="button"),c&&(Jr["aria-disabled"]=c));const yn=Ur(r,Ne,q),gi=_({},n,{centerRipple:i,component:l,disabled:c,disableRipple:u,disableTouchRipple:d,focusRipple:f,tabIndex:z,focusVisible:ie}),Oa=Lq(gi);return O.jsxs(Iq,_({as:Xe,className:Ce(Oa.root,a),ownerState:gi,onBlur:nr,onClick:m,onContextMenu:rt,onFocus:zo,onKeyDown:vn,onKeyUp:Vn,onMouseDown:ft,onMouseLeave:De,onMouseUp:he,onDragLeave:Or,onTouchEnd:Fn,onTouchMove:Gr,onTouchStart:Ke,ref:yn,tabIndex:c?-1:z,type:j},Jr,L,{children:[s,Me?O.jsx(Aq,_({ref:P,center:i},D)):null]}))}),Tb=Dq;function $q(e){return Vt("MuiIconButton",e)}const Hq=jt("MuiIconButton",["root","disabled","colorInherit","colorPrimary","colorSecondary","colorError","colorInfo","colorSuccess","colorWarning","edgeStart","edgeEnd","sizeSmall","sizeMedium","sizeLarge"]),Bq=Hq,Fq=["edge","children","className","color","disabled","disableFocusRipple","size"],Vq=e=>{const{classes:t,disabled:r,color:n,edge:o,size:i}=e,s={root:["root",r&&"disabled",n!=="default"&&`color${Fe(n)}`,o&&`edge${Fe(o)}`,`size${Fe(i)}`]};return rr(s,$q,t)},jq=Je(Tb,{name:"MuiIconButton",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:r}=e;return[t.root,r.color!=="default"&&t[`color${Fe(r.color)}`],r.edge&&t[`edge${Fe(r.edge)}`],t[`size${Fe(r.size)}`]]}})(({theme:e,ownerState:t})=>_({textAlign:"center",flex:"0 0 auto",fontSize:e.typography.pxToRem(24),padding:8,borderRadius:"50%",overflow:"visible",color:(e.vars||e).palette.action.active,transition:e.transitions.create("background-color",{duration:e.transitions.duration.shortest})},!t.disableRipple&&{"&:hover":{backgroundColor:e.vars?`rgba(${e.vars.palette.action.activeChannel} / ${e.vars.palette.action.hoverOpacity})`:Lr(e.palette.action.active,e.palette.action.hoverOpacity),"@media (hover: none)":{backgroundColor:"transparent"}}},t.edge==="start"&&{marginLeft:t.size==="small"?-3:-12},t.edge==="end"&&{marginRight:t.size==="small"?-3:-12}),({theme:e,ownerState:t})=>{var r;const n=(r=(e.vars||e).palette)==null?void 0:r[t.color];return _({},t.color==="inherit"&&{color:"inherit"},t.color!=="inherit"&&t.color!=="default"&&_({color:n==null?void 0:n.main},!t.disableRipple&&{"&:hover":_({},n&&{backgroundColor:e.vars?`rgba(${n.mainChannel} / ${e.vars.palette.action.hoverOpacity})`:Lr(n.main,e.palette.action.hoverOpacity)},{"@media (hover: none)":{backgroundColor:"transparent"}})}),t.size==="small"&&{padding:5,fontSize:e.typography.pxToRem(18)},t.size==="large"&&{padding:12,fontSize:e.typography.pxToRem(28)},{[`&.${Bq.disabled}`]:{backgroundColor:"transparent",color:(e.vars||e).palette.action.disabled}})}),Uq=S.forwardRef(function(t,r){const n=Wt({props:t,name:"MuiIconButton"}),{edge:o=!1,children:i,className:s,color:a="default",disabled:l=!1,disableFocusRipple:c=!1,size:u="medium"}=n,d=ve(n,Fq),f=_({},n,{edge:o,color:a,disabled:l,disableFocusRipple:c,size:u}),p=Vq(f);return O.jsx(jq,_({className:Ce(p.root,s),centerRipple:!0,focusRipple:!c,disabled:l,ref:r,ownerState:f},d,{children:i}))}),Wq=Uq;function Kq(e){return Vt("MuiTypography",e)}jt("MuiTypography",["root","h1","h2","h3","h4","h5","h6","subtitle1","subtitle2","body1","body2","inherit","button","caption","overline","alignLeft","alignRight","alignCenter","alignJustify","noWrap","gutterBottom","paragraph"]);const qq=["align","className","component","gutterBottom","noWrap","paragraph","variant","variantMapping"],Gq=e=>{const{align:t,gutterBottom:r,noWrap:n,paragraph:o,variant:i,classes:s}=e,a={root:["root",i,e.align!=="inherit"&&`align${Fe(t)}`,r&&"gutterBottom",n&&"noWrap",o&&"paragraph"]};return rr(a,Kq,s)},Yq=Je("span",{name:"MuiTypography",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:r}=e;return[t.root,r.variant&&t[r.variant],r.align!=="inherit"&&t[`align${Fe(r.align)}`],r.noWrap&&t.noWrap,r.gutterBottom&&t.gutterBottom,r.paragraph&&t.paragraph]}})(({theme:e,ownerState:t})=>_({margin:0},t.variant==="inherit"&&{font:"inherit"},t.variant!=="inherit"&&e.typography[t.variant],t.align!=="inherit"&&{textAlign:t.align},t.noWrap&&{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},t.gutterBottom&&{marginBottom:"0.35em"},t.paragraph&&{marginBottom:16})),xS={h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",h6:"h6",subtitle1:"h6",subtitle2:"h6",body1:"p",body2:"p",inherit:"p"},Jq={primary:"primary.main",textPrimary:"text.primary",secondary:"secondary.main",textSecondary:"text.secondary",error:"error.main"},Xq=e=>Jq[e]||e,Qq=S.forwardRef(function(t,r){const n=Wt({props:t,name:"MuiTypography"}),o=Xq(n.color),i=xb(_({},n,{color:o})),{align:s="inherit",className:a,component:l,gutterBottom:c=!1,noWrap:u=!1,paragraph:d=!1,variant:f="body1",variantMapping:p=xS}=i,h=ve(i,qq),m=_({},i,{align:s,color:o,className:a,component:l,gutterBottom:c,noWrap:u,paragraph:d,variant:f,variantMapping:p}),b=l||(d?"p":p[f]||xS[f])||"span",v=Gq(m);return O.jsx(Yq,_({as:b,ref:r,ownerState:m,className:Ce(v.root,a)},h))}),cu=Qq;function m3(e){return typeof e=="string"}function uu(e,t,r){return e===void 0||m3(e)?t:_({},t,{ownerState:_({},t.ownerState,r)})}const Zq={disableDefaultClasses:!1},eG=S.createContext(Zq);function tG(e){const{disableDefaultClasses:t}=S.useContext(eG);return r=>t?"":e(r)}function g3(e,t=[]){if(e===void 0)return{};const r={};return Object.keys(e).filter(n=>n.match(/^on[A-Z]/)&&typeof e[n]=="function"&&!t.includes(n)).forEach(n=>{r[n]=e[n]}),r}function rG(e,t,r){return typeof e=="function"?e(t,r):e}function kS(e){if(e===void 0)return{};const t={};return Object.keys(e).filter(r=>!(r.match(/^on[A-Z]/)&&typeof e[r]=="function")).forEach(r=>{t[r]=e[r]}),t}function nG(e){const{getSlotProps:t,additionalProps:r,externalSlotProps:n,externalForwardedProps:o,className:i}=e;if(!t){const p=Ce(o==null?void 0:o.className,n==null?void 0:n.className,i,r==null?void 0:r.className),h=_({},r==null?void 0:r.style,o==null?void 0:o.style,n==null?void 0:n.style),m=_({},r,o,n);return p.length>0&&(m.className=p),Object.keys(h).length>0&&(m.style=h),{props:m,internalRef:void 0}}const s=g3(_({},o,n)),a=kS(n),l=kS(o),c=t(s),u=Ce(c==null?void 0:c.className,r==null?void 0:r.className,i,o==null?void 0:o.className,n==null?void 0:n.className),d=_({},c==null?void 0:c.style,r==null?void 0:r.style,o==null?void 0:o.style,n==null?void 0:n.style),f=_({},c,r,l,a);return u.length>0&&(f.className=u),Object.keys(d).length>0&&(f.style=d),{props:f,internalRef:c.ref}}const oG=["elementType","externalSlotProps","ownerState","skipResolvingSlotProps"];function si(e){var t;const{elementType:r,externalSlotProps:n,ownerState:o,skipResolvingSlotProps:i=!1}=e,s=ve(e,oG),a=i?{}:rG(n,o),{props:l,internalRef:c}=nG(_({},s,{externalSlotProps:a})),u=Ur(c,a==null?void 0:a.ref,(t=e.additionalProps)==null?void 0:t.ref);return uu(r,_({},l,{ref:u}),o)}function iG(e){const{badgeContent:t,invisible:r=!1,max:n=99,showZero:o=!1}=e,i=IT({badgeContent:t,max:n});let s=r;r===!1&&t===0&&!o&&(s=!0);const{badgeContent:a,max:l=n}=s?i:e,c=a&&Number(a)>l?`${l}+`:a;return{badgeContent:a,invisible:s,max:l,displayValue:c}}const sG=["input","select","textarea","a[href]","button","[tabindex]","audio[controls]","video[controls]",'[contenteditable]:not([contenteditable="false"])'].join(",");function aG(e){const t=parseInt(e.getAttribute("tabindex")||"",10);return Number.isNaN(t)?e.contentEditable==="true"||(e.nodeName==="AUDIO"||e.nodeName==="VIDEO"||e.nodeName==="DETAILS")&&e.getAttribute("tabindex")===null?0:e.tabIndex:t}function lG(e){if(e.tagName!=="INPUT"||e.type!=="radio"||!e.name)return!1;const t=n=>e.ownerDocument.querySelector(`input[type="radio"]${n}`);let r=t(`[name="${e.name}"]:checked`);return r||(r=t(`[name="${e.name}"]`)),r!==e}function cG(e){return!(e.disabled||e.tagName==="INPUT"&&e.type==="hidden"||lG(e))}function uG(e){const t=[],r=[];return Array.from(e.querySelectorAll(sG)).forEach((n,o)=>{const i=aG(n);i===-1||!cG(n)||(i===0?t.push(n):r.push({documentOrder:o,tabIndex:i,node:n}))}),r.sort((n,o)=>n.tabIndex===o.tabIndex?n.documentOrder-o.documentOrder:n.tabIndex-o.tabIndex).map(n=>n.node).concat(t)}function dG(){return!0}function fG(e){const{children:t,disableAutoFocus:r=!1,disableEnforceFocus:n=!1,disableRestoreFocus:o=!1,getTabbable:i=uG,isEnabled:s=dG,open:a}=e,l=S.useRef(!1),c=S.useRef(null),u=S.useRef(null),d=S.useRef(null),f=S.useRef(null),p=S.useRef(!1),h=S.useRef(null),m=Ur(t.ref,h),b=S.useRef(null);S.useEffect(()=>{!a||!h.current||(p.current=!r)},[r,a]),S.useEffect(()=>{if(!a||!h.current)return;const y=Br(h.current);return h.current.contains(y.activeElement)||(h.current.hasAttribute("tabIndex")||h.current.setAttribute("tabIndex","-1"),p.current&&h.current.focus()),()=>{o||(d.current&&d.current.focus&&(l.current=!0,d.current.focus()),d.current=null)}},[a]),S.useEffect(()=>{if(!a||!h.current)return;const y=Br(h.current),x=E=>{b.current=E,!(n||!s()||E.key!=="Tab")&&y.activeElement===h.current&&E.shiftKey&&(l.current=!0,u.current&&u.current.focus())},k=()=>{const E=h.current;if(E===null)return;if(!y.hasFocus()||!s()||l.current){l.current=!1;return}if(E.contains(y.activeElement)||n&&y.activeElement!==c.current&&y.activeElement!==u.current)return;if(y.activeElement!==f.current)f.current=null;else if(f.current!==null)return;if(!p.current)return;let M=[];if((y.activeElement===c.current||y.activeElement===u.current)&&(M=i(h.current)),M.length>0){var C,T;const N=!!((C=b.current)!=null&&C.shiftKey&&((T=b.current)==null?void 0:T.key)==="Tab"),z=M[0],D=M[M.length-1];typeof z!="string"&&typeof D!="string"&&(N?D.focus():z.focus())}else E.focus()};y.addEventListener("focusin",k),y.addEventListener("keydown",x,!0);const w=setInterval(()=>{y.activeElement&&y.activeElement.tagName==="BODY"&&k()},50);return()=>{clearInterval(w),y.removeEventListener("focusin",k),y.removeEventListener("keydown",x,!0)}},[r,n,o,s,a,i]);const v=y=>{d.current===null&&(d.current=y.relatedTarget),p.current=!0,f.current=y.target;const x=t.props.onFocus;x&&x(y)},g=y=>{d.current===null&&(d.current=y.relatedTarget),p.current=!0};return O.jsxs(S.Fragment,{children:[O.jsx("div",{tabIndex:a?0:-1,onFocus:g,ref:c,"data-testid":"sentinelStart"}),S.cloneElement(t,{ref:m,onFocus:v}),O.jsx("div",{tabIndex:a?0:-1,onFocus:g,ref:u,"data-testid":"sentinelEnd"})]})}var Fr="top",Ln="bottom",In="right",Vr="left",Ob="auto",Gd=[Fr,Ln,In,Vr],Gl="start",gd="end",pG="clippingParents",v3="viewport",_c="popper",hG="reference",wS=Gd.reduce(function(e,t){return e.concat([t+"-"+Gl,t+"-"+gd])},[]),y3=[].concat(Gd,[Ob]).reduce(function(e,t){return e.concat([t,t+"-"+Gl,t+"-"+gd])},[]),mG="beforeRead",gG="read",vG="afterRead",yG="beforeMain",bG="main",xG="afterMain",kG="beforeWrite",wG="write",SG="afterWrite",EG=[mG,gG,vG,yG,bG,xG,kG,wG,SG];function No(e){return e?(e.nodeName||"").toLowerCase():null}function pn(e){if(e==null)return window;if(e.toString()!=="[object Window]"){var t=e.ownerDocument;return t&&t.defaultView||window}return e}function ga(e){var t=pn(e).Element;return e instanceof t||e instanceof Element}function Nn(e){var t=pn(e).HTMLElement;return e instanceof t||e instanceof HTMLElement}function _b(e){if(typeof ShadowRoot>"u")return!1;var t=pn(e).ShadowRoot;return e instanceof t||e instanceof ShadowRoot}function CG(e){var t=e.state;Object.keys(t.elements).forEach(function(r){var n=t.styles[r]||{},o=t.attributes[r]||{},i=t.elements[r];!Nn(i)||!No(i)||(Object.assign(i.style,n),Object.keys(o).forEach(function(s){var a=o[s];a===!1?i.removeAttribute(s):i.setAttribute(s,a===!0?"":a)}))})}function MG(e){var t=e.state,r={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(t.elements.popper.style,r.popper),t.styles=r,t.elements.arrow&&Object.assign(t.elements.arrow.style,r.arrow),function(){Object.keys(t.elements).forEach(function(n){var o=t.elements[n],i=t.attributes[n]||{},s=Object.keys(t.styles.hasOwnProperty(n)?t.styles[n]:r[n]),a=s.reduce(function(l,c){return l[c]="",l},{});!Nn(o)||!No(o)||(Object.assign(o.style,a),Object.keys(i).forEach(function(l){o.removeAttribute(l)}))})}}const TG={name:"applyStyles",enabled:!0,phase:"write",fn:CG,effect:MG,requires:["computeStyles"]};function Co(e){return e.split("-")[0]}var ea=Math.max,yh=Math.min,Yl=Math.round;function nv(){var e=navigator.userAgentData;return e!=null&&e.brands&&Array.isArray(e.brands)?e.brands.map(function(t){return t.brand+"/"+t.version}).join(" "):navigator.userAgent}function b3(){return!/^((?!chrome|android).)*safari/i.test(nv())}function Jl(e,t,r){t===void 0&&(t=!1),r===void 0&&(r=!1);var n=e.getBoundingClientRect(),o=1,i=1;t&&Nn(e)&&(o=e.offsetWidth>0&&Yl(n.width)/e.offsetWidth||1,i=e.offsetHeight>0&&Yl(n.height)/e.offsetHeight||1);var s=ga(e)?pn(e):window,a=s.visualViewport,l=!b3()&&r,c=(n.left+(l&&a?a.offsetLeft:0))/o,u=(n.top+(l&&a?a.offsetTop:0))/i,d=n.width/o,f=n.height/i;return{width:d,height:f,top:u,right:c+d,bottom:u+f,left:c,x:c,y:u}}function Ab(e){var t=Jl(e),r=e.offsetWidth,n=e.offsetHeight;return Math.abs(t.width-r)<=1&&(r=t.width),Math.abs(t.height-n)<=1&&(n=t.height),{x:e.offsetLeft,y:e.offsetTop,width:r,height:n}}function x3(e,t){var r=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(r&&_b(r)){var n=t;do{if(n&&e.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function ai(e){return pn(e).getComputedStyle(e)}function OG(e){return["table","td","th"].indexOf(No(e))>=0}function xs(e){return((ga(e)?e.ownerDocument:e.document)||window.document).documentElement}function Ym(e){return No(e)==="html"?e:e.assignedSlot||e.parentNode||(_b(e)?e.host:null)||xs(e)}function SS(e){return!Nn(e)||ai(e).position==="fixed"?null:e.offsetParent}function _G(e){var t=/firefox/i.test(nv()),r=/Trident/i.test(nv());if(r&&Nn(e)){var n=ai(e);if(n.position==="fixed")return null}var o=Ym(e);for(_b(o)&&(o=o.host);Nn(o)&&["html","body"].indexOf(No(o))<0;){var i=ai(o);if(i.transform!=="none"||i.perspective!=="none"||i.contain==="paint"||["transform","perspective"].indexOf(i.willChange)!==-1||t&&i.willChange==="filter"||t&&i.filter&&i.filter!=="none")return o;o=o.parentNode}return null}function Yd(e){for(var t=pn(e),r=SS(e);r&&OG(r)&&ai(r).position==="static";)r=SS(r);return r&&(No(r)==="html"||No(r)==="body"&&ai(r).position==="static")?t:r||_G(e)||t}function Nb(e){return["top","bottom"].indexOf(e)>=0?"x":"y"}function Au(e,t,r){return ea(e,yh(t,r))}function AG(e,t,r){var n=Au(e,t,r);return n>r?r:n}function k3(){return{top:0,right:0,bottom:0,left:0}}function w3(e){return Object.assign({},k3(),e)}function S3(e,t){return t.reduce(function(r,n){return r[n]=e,r},{})}var NG=function(t,r){return t=typeof t=="function"?t(Object.assign({},r.rects,{placement:r.placement})):t,w3(typeof t!="number"?t:S3(t,Gd))};function RG(e){var t,r=e.state,n=e.name,o=e.options,i=r.elements.arrow,s=r.modifiersData.popperOffsets,a=Co(r.placement),l=Nb(a),c=[Vr,In].indexOf(a)>=0,u=c?"height":"width";if(!(!i||!s)){var d=NG(o.padding,r),f=Ab(i),p=l==="y"?Fr:Vr,h=l==="y"?Ln:In,m=r.rects.reference[u]+r.rects.reference[l]-s[l]-r.rects.popper[u],b=s[l]-r.rects.reference[l],v=Yd(i),g=v?l==="y"?v.clientHeight||0:v.clientWidth||0:0,y=m/2-b/2,x=d[p],k=g-f[u]-d[h],w=g/2-f[u]/2+y,E=Au(x,w,k),M=l;r.modifiersData[n]=(t={},t[M]=E,t.centerOffset=E-w,t)}}function PG(e){var t=e.state,r=e.options,n=r.element,o=n===void 0?"[data-popper-arrow]":n;o!=null&&(typeof o=="string"&&(o=t.elements.popper.querySelector(o),!o)||x3(t.elements.popper,o)&&(t.elements.arrow=o))}const zG={name:"arrow",enabled:!0,phase:"main",fn:RG,effect:PG,requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function Xl(e){return e.split("-")[1]}var LG={top:"auto",right:"auto",bottom:"auto",left:"auto"};function IG(e,t){var r=e.x,n=e.y,o=t.devicePixelRatio||1;return{x:Yl(r*o)/o||0,y:Yl(n*o)/o||0}}function ES(e){var t,r=e.popper,n=e.popperRect,o=e.placement,i=e.variation,s=e.offsets,a=e.position,l=e.gpuAcceleration,c=e.adaptive,u=e.roundOffsets,d=e.isFixed,f=s.x,p=f===void 0?0:f,h=s.y,m=h===void 0?0:h,b=typeof u=="function"?u({x:p,y:m}):{x:p,y:m};p=b.x,m=b.y;var v=s.hasOwnProperty("x"),g=s.hasOwnProperty("y"),y=Vr,x=Fr,k=window;if(c){var w=Yd(r),E="clientHeight",M="clientWidth";if(w===pn(r)&&(w=xs(r),ai(w).position!=="static"&&a==="absolute"&&(E="scrollHeight",M="scrollWidth")),w=w,o===Fr||(o===Vr||o===In)&&i===gd){x=Ln;var C=d&&w===k&&k.visualViewport?k.visualViewport.height:w[E];m-=C-n.height,m*=l?1:-1}if(o===Vr||(o===Fr||o===Ln)&&i===gd){y=In;var T=d&&w===k&&k.visualViewport?k.visualViewport.width:w[M];p-=T-n.width,p*=l?1:-1}}var N=Object.assign({position:a},c&&LG),z=u===!0?IG({x:p,y:m},pn(r)):{x:p,y:m};if(p=z.x,m=z.y,l){var D;return Object.assign({},N,(D={},D[x]=g?"0":"",D[y]=v?"0":"",D.transform=(k.devicePixelRatio||1)<=1?"translate("+p+"px, "+m+"px)":"translate3d("+p+"px, "+m+"px, 0)",D))}return Object.assign({},N,(t={},t[x]=g?m+"px":"",t[y]=v?p+"px":"",t.transform="",t))}function DG(e){var t=e.state,r=e.options,n=r.gpuAcceleration,o=n===void 0?!0:n,i=r.adaptive,s=i===void 0?!0:i,a=r.roundOffsets,l=a===void 0?!0:a,c={placement:Co(t.placement),variation:Xl(t.placement),popper:t.elements.popper,popperRect:t.rects.popper,gpuAcceleration:o,isFixed:t.options.strategy==="fixed"};t.modifiersData.popperOffsets!=null&&(t.styles.popper=Object.assign({},t.styles.popper,ES(Object.assign({},c,{offsets:t.modifiersData.popperOffsets,position:t.options.strategy,adaptive:s,roundOffsets:l})))),t.modifiersData.arrow!=null&&(t.styles.arrow=Object.assign({},t.styles.arrow,ES(Object.assign({},c,{offsets:t.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-placement":t.placement})}const $G={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:DG,data:{}};var Cf={passive:!0};function HG(e){var t=e.state,r=e.instance,n=e.options,o=n.scroll,i=o===void 0?!0:o,s=n.resize,a=s===void 0?!0:s,l=pn(t.elements.popper),c=[].concat(t.scrollParents.reference,t.scrollParents.popper);return i&&c.forEach(function(u){u.addEventListener("scroll",r.update,Cf)}),a&&l.addEventListener("resize",r.update,Cf),function(){i&&c.forEach(function(u){u.removeEventListener("scroll",r.update,Cf)}),a&&l.removeEventListener("resize",r.update,Cf)}}const BG={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:HG,data:{}};var FG={left:"right",right:"left",bottom:"top",top:"bottom"};function hp(e){return e.replace(/left|right|bottom|top/g,function(t){return FG[t]})}var VG={start:"end",end:"start"};function CS(e){return e.replace(/start|end/g,function(t){return VG[t]})}function Rb(e){var t=pn(e),r=t.pageXOffset,n=t.pageYOffset;return{scrollLeft:r,scrollTop:n}}function Pb(e){return Jl(xs(e)).left+Rb(e).scrollLeft}function jG(e,t){var r=pn(e),n=xs(e),o=r.visualViewport,i=n.clientWidth,s=n.clientHeight,a=0,l=0;if(o){i=o.width,s=o.height;var c=b3();(c||!c&&t==="fixed")&&(a=o.offsetLeft,l=o.offsetTop)}return{width:i,height:s,x:a+Pb(e),y:l}}function UG(e){var t,r=xs(e),n=Rb(e),o=(t=e.ownerDocument)==null?void 0:t.body,i=ea(r.scrollWidth,r.clientWidth,o?o.scrollWidth:0,o?o.clientWidth:0),s=ea(r.scrollHeight,r.clientHeight,o?o.scrollHeight:0,o?o.clientHeight:0),a=-n.scrollLeft+Pb(e),l=-n.scrollTop;return ai(o||r).direction==="rtl"&&(a+=ea(r.clientWidth,o?o.clientWidth:0)-i),{width:i,height:s,x:a,y:l}}function zb(e){var t=ai(e),r=t.overflow,n=t.overflowX,o=t.overflowY;return/auto|scroll|overlay|hidden/.test(r+o+n)}function E3(e){return["html","body","#document"].indexOf(No(e))>=0?e.ownerDocument.body:Nn(e)&&zb(e)?e:E3(Ym(e))}function Nu(e,t){var r;t===void 0&&(t=[]);var n=E3(e),o=n===((r=e.ownerDocument)==null?void 0:r.body),i=pn(n),s=o?[i].concat(i.visualViewport||[],zb(n)?n:[]):n,a=t.concat(s);return o?a:a.concat(Nu(Ym(s)))}function ov(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function WG(e,t){var r=Jl(e,!1,t==="fixed");return r.top=r.top+e.clientTop,r.left=r.left+e.clientLeft,r.bottom=r.top+e.clientHeight,r.right=r.left+e.clientWidth,r.width=e.clientWidth,r.height=e.clientHeight,r.x=r.left,r.y=r.top,r}function MS(e,t,r){return t===v3?ov(jG(e,r)):ga(t)?WG(t,r):ov(UG(xs(e)))}function KG(e){var t=Nu(Ym(e)),r=["absolute","fixed"].indexOf(ai(e).position)>=0,n=r&&Nn(e)?Yd(e):e;return ga(n)?t.filter(function(o){return ga(o)&&x3(o,n)&&No(o)!=="body"}):[]}function qG(e,t,r,n){var o=t==="clippingParents"?KG(e):[].concat(t),i=[].concat(o,[r]),s=i[0],a=i.reduce(function(l,c){var u=MS(e,c,n);return l.top=ea(u.top,l.top),l.right=yh(u.right,l.right),l.bottom=yh(u.bottom,l.bottom),l.left=ea(u.left,l.left),l},MS(e,s,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}function C3(e){var t=e.reference,r=e.element,n=e.placement,o=n?Co(n):null,i=n?Xl(n):null,s=t.x+t.width/2-r.width/2,a=t.y+t.height/2-r.height/2,l;switch(o){case Fr:l={x:s,y:t.y-r.height};break;case Ln:l={x:s,y:t.y+t.height};break;case In:l={x:t.x+t.width,y:a};break;case Vr:l={x:t.x-r.width,y:a};break;default:l={x:t.x,y:t.y}}var c=o?Nb(o):null;if(c!=null){var u=c==="y"?"height":"width";switch(i){case Gl:l[c]=l[c]-(t[u]/2-r[u]/2);break;case gd:l[c]=l[c]+(t[u]/2-r[u]/2);break}}return l}function vd(e,t){t===void 0&&(t={});var r=t,n=r.placement,o=n===void 0?e.placement:n,i=r.strategy,s=i===void 0?e.strategy:i,a=r.boundary,l=a===void 0?pG:a,c=r.rootBoundary,u=c===void 0?v3:c,d=r.elementContext,f=d===void 0?_c:d,p=r.altBoundary,h=p===void 0?!1:p,m=r.padding,b=m===void 0?0:m,v=w3(typeof b!="number"?b:S3(b,Gd)),g=f===_c?hG:_c,y=e.rects.popper,x=e.elements[h?g:f],k=qG(ga(x)?x:x.contextElement||xs(e.elements.popper),l,u,s),w=Jl(e.elements.reference),E=C3({reference:w,element:y,strategy:"absolute",placement:o}),M=ov(Object.assign({},y,E)),C=f===_c?M:w,T={top:k.top-C.top+v.top,bottom:C.bottom-k.bottom+v.bottom,left:k.left-C.left+v.left,right:C.right-k.right+v.right},N=e.modifiersData.offset;if(f===_c&&N){var z=N[o];Object.keys(T).forEach(function(D){var V=[In,Ln].indexOf(D)>=0?1:-1,j=[Fr,Ln].indexOf(D)>=0?"y":"x";T[D]+=z[j]*V})}return T}function GG(e,t){t===void 0&&(t={});var r=t,n=r.placement,o=r.boundary,i=r.rootBoundary,s=r.padding,a=r.flipVariations,l=r.allowedAutoPlacements,c=l===void 0?y3:l,u=Xl(n),d=u?a?wS:wS.filter(function(h){return Xl(h)===u}):Gd,f=d.filter(function(h){return c.indexOf(h)>=0});f.length===0&&(f=d);var p=f.reduce(function(h,m){return h[m]=vd(e,{placement:m,boundary:o,rootBoundary:i,padding:s})[Co(m)],h},{});return Object.keys(p).sort(function(h,m){return p[h]-p[m]})}function YG(e){if(Co(e)===Ob)return[];var t=hp(e);return[CS(e),t,CS(t)]}function JG(e){var t=e.state,r=e.options,n=e.name;if(!t.modifiersData[n]._skip){for(var o=r.mainAxis,i=o===void 0?!0:o,s=r.altAxis,a=s===void 0?!0:s,l=r.fallbackPlacements,c=r.padding,u=r.boundary,d=r.rootBoundary,f=r.altBoundary,p=r.flipVariations,h=p===void 0?!0:p,m=r.allowedAutoPlacements,b=t.options.placement,v=Co(b),g=v===b,y=l||(g||!h?[hp(b)]:YG(b)),x=[b].concat(y).reduce(function(ie,ue){return ie.concat(Co(ue)===Ob?GG(t,{placement:ue,boundary:u,rootBoundary:d,padding:c,flipVariations:h,allowedAutoPlacements:m}):ue)},[]),k=t.rects.reference,w=t.rects.popper,E=new Map,M=!0,C=x[0],T=0;T=0,j=V?"width":"height",L=vd(t,{placement:N,boundary:u,rootBoundary:d,altBoundary:f,padding:c}),q=V?D?In:Vr:D?Ln:Fr;k[j]>w[j]&&(q=hp(q));var A=hp(q),P=[];if(i&&P.push(L[z]<=0),a&&P.push(L[q]<=0,L[A]<=0),P.every(function(ie){return ie})){C=N,M=!1;break}E.set(N,P)}if(M)for(var F=h?3:1,Y=function(ue){var de=x.find(function(me){var Me=E.get(me);if(Me)return Me.slice(0,ue).every(function(Se){return Se})});if(de)return C=de,"break"},J=F;J>0;J--){var Ne=Y(J);if(Ne==="break")break}t.placement!==C&&(t.modifiersData[n]._skip=!0,t.placement=C,t.reset=!0)}}const XG={name:"flip",enabled:!0,phase:"main",fn:JG,requiresIfExists:["offset"],data:{_skip:!1}};function TS(e,t,r){return r===void 0&&(r={x:0,y:0}),{top:e.top-t.height-r.y,right:e.right-t.width+r.x,bottom:e.bottom-t.height+r.y,left:e.left-t.width-r.x}}function OS(e){return[Fr,In,Ln,Vr].some(function(t){return e[t]>=0})}function QG(e){var t=e.state,r=e.name,n=t.rects.reference,o=t.rects.popper,i=t.modifiersData.preventOverflow,s=vd(t,{elementContext:"reference"}),a=vd(t,{altBoundary:!0}),l=TS(s,n),c=TS(a,o,i),u=OS(l),d=OS(c);t.modifiersData[r]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:u,hasPopperEscaped:d},t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-reference-hidden":u,"data-popper-escaped":d})}const ZG={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:QG};function eY(e,t,r){var n=Co(e),o=[Vr,Fr].indexOf(n)>=0?-1:1,i=typeof r=="function"?r(Object.assign({},t,{placement:e})):r,s=i[0],a=i[1];return s=s||0,a=(a||0)*o,[Vr,In].indexOf(n)>=0?{x:a,y:s}:{x:s,y:a}}function tY(e){var t=e.state,r=e.options,n=e.name,o=r.offset,i=o===void 0?[0,0]:o,s=y3.reduce(function(u,d){return u[d]=eY(d,t.rects,i),u},{}),a=s[t.placement],l=a.x,c=a.y;t.modifiersData.popperOffsets!=null&&(t.modifiersData.popperOffsets.x+=l,t.modifiersData.popperOffsets.y+=c),t.modifiersData[n]=s}const rY={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:tY};function nY(e){var t=e.state,r=e.name;t.modifiersData[r]=C3({reference:t.rects.reference,element:t.rects.popper,strategy:"absolute",placement:t.placement})}const oY={name:"popperOffsets",enabled:!0,phase:"read",fn:nY,data:{}};function iY(e){return e==="x"?"y":"x"}function sY(e){var t=e.state,r=e.options,n=e.name,o=r.mainAxis,i=o===void 0?!0:o,s=r.altAxis,a=s===void 0?!1:s,l=r.boundary,c=r.rootBoundary,u=r.altBoundary,d=r.padding,f=r.tether,p=f===void 0?!0:f,h=r.tetherOffset,m=h===void 0?0:h,b=vd(t,{boundary:l,rootBoundary:c,padding:d,altBoundary:u}),v=Co(t.placement),g=Xl(t.placement),y=!g,x=Nb(v),k=iY(x),w=t.modifiersData.popperOffsets,E=t.rects.reference,M=t.rects.popper,C=typeof m=="function"?m(Object.assign({},t.rects,{placement:t.placement})):m,T=typeof C=="number"?{mainAxis:C,altAxis:C}:Object.assign({mainAxis:0,altAxis:0},C),N=t.modifiersData.offset?t.modifiersData.offset[t.placement]:null,z={x:0,y:0};if(w){if(i){var D,V=x==="y"?Fr:Vr,j=x==="y"?Ln:In,L=x==="y"?"height":"width",q=w[x],A=q+b[V],P=q-b[j],F=p?-M[L]/2:0,Y=g===Gl?E[L]:M[L],J=g===Gl?-M[L]:-E[L],Ne=t.elements.arrow,ie=p&&Ne?Ab(Ne):{width:0,height:0},ue=t.modifiersData["arrow#persistent"]?t.modifiersData["arrow#persistent"].padding:k3(),de=ue[V],me=ue[j],Me=Au(0,E[L],ie[L]),Se=y?E[L]/2-F-Me-de-T.mainAxis:Y-Me-de-T.mainAxis,ft=y?-E[L]/2+F+Me+me+T.mainAxis:J+Me+me+T.mainAxis,rt=t.elements.arrow&&Yd(t.elements.arrow),Or=rt?x==="y"?rt.clientTop||0:rt.clientLeft||0:0,he=(D=N==null?void 0:N[x])!=null?D:0,De=q+Se-he-Or,Ke=q+ft-he,Fn=Au(p?yh(A,De):A,q,p?ea(P,Ke):P);w[x]=Fn,z[x]=Fn-q}if(a){var Gr,nr=x==="x"?Fr:Vr,zo=x==="x"?Ln:In,Pt=w[k],Yr=k==="y"?"height":"width",vn=Pt+b[nr],Vn=Pt-b[zo],Xe=[Fr,Vr].indexOf(v)!==-1,Jr=(Gr=N==null?void 0:N[k])!=null?Gr:0,yn=Xe?vn:Pt-E[Yr]-M[Yr]-Jr+T.altAxis,gi=Xe?Pt+E[Yr]+M[Yr]-Jr-T.altAxis:Vn,Oa=p&&Xe?AG(yn,Pt,gi):Au(p?yn:vn,Pt,p?gi:Vn);w[k]=Oa,z[k]=Oa-Pt}t.modifiersData[n]=z}}const aY={name:"preventOverflow",enabled:!0,phase:"main",fn:sY,requiresIfExists:["offset"]};function lY(e){return{scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}}function cY(e){return e===pn(e)||!Nn(e)?Rb(e):lY(e)}function uY(e){var t=e.getBoundingClientRect(),r=Yl(t.width)/e.offsetWidth||1,n=Yl(t.height)/e.offsetHeight||1;return r!==1||n!==1}function dY(e,t,r){r===void 0&&(r=!1);var n=Nn(t),o=Nn(t)&&uY(t),i=xs(t),s=Jl(e,o,r),a={scrollLeft:0,scrollTop:0},l={x:0,y:0};return(n||!n&&!r)&&((No(t)!=="body"||zb(i))&&(a=cY(t)),Nn(t)?(l=Jl(t,!0),l.x+=t.clientLeft,l.y+=t.clientTop):i&&(l.x=Pb(i))),{x:s.left+a.scrollLeft-l.x,y:s.top+a.scrollTop-l.y,width:s.width,height:s.height}}function fY(e){var t=new Map,r=new Set,n=[];e.forEach(function(i){t.set(i.name,i)});function o(i){r.add(i.name);var s=[].concat(i.requires||[],i.requiresIfExists||[]);s.forEach(function(a){if(!r.has(a)){var l=t.get(a);l&&o(l)}}),n.push(i)}return e.forEach(function(i){r.has(i.name)||o(i)}),n}function pY(e){var t=fY(e);return EG.reduce(function(r,n){return r.concat(t.filter(function(o){return o.phase===n}))},[])}function hY(e){var t;return function(){return t||(t=new Promise(function(r){Promise.resolve().then(function(){t=void 0,r(e())})})),t}}function mY(e){var t=e.reduce(function(r,n){var o=r[n.name];return r[n.name]=o?Object.assign({},o,n,{options:Object.assign({},o.options,n.options),data:Object.assign({},o.data,n.data)}):n,r},{});return Object.keys(t).map(function(r){return t[r]})}var _S={placement:"bottom",modifiers:[],strategy:"absolute"};function AS(){for(var e=arguments.length,t=new Array(e),r=0;r{i||a(bY(o)||document.body)},[o,i]),pa(()=>{if(s&&!i)return J0(r,s),()=>{J0(r,null)}},[r,s,i]),i){if(S.isValidElement(n)){const c={ref:l};return S.cloneElement(n,c)}return O.jsx(S.Fragment,{children:n})}return O.jsx(S.Fragment,{children:s&&lm.createPortal(n,s)})});function xY(e){return Vt("MuiPopper",e)}jt("MuiPopper",["root"]);const kY=["anchorEl","children","direction","disablePortal","modifiers","open","placement","popperOptions","popperRef","slotProps","slots","TransitionProps","ownerState"],wY=["anchorEl","children","container","direction","disablePortal","keepMounted","modifiers","open","placement","popperOptions","popperRef","style","transition","slotProps","slots"];function SY(e,t){if(t==="ltr")return e;switch(e){case"bottom-end":return"bottom-start";case"bottom-start":return"bottom-end";case"top-end":return"top-start";case"top-start":return"top-end";default:return e}}function iv(e){return typeof e=="function"?e():e}function EY(e){return e.nodeType!==void 0}const CY=()=>rr({root:["root"]},tG(xY)),MY={},TY=S.forwardRef(function(t,r){var n;const{anchorEl:o,children:i,direction:s,disablePortal:a,modifiers:l,open:c,placement:u,popperOptions:d,popperRef:f,slotProps:p={},slots:h={},TransitionProps:m}=t,b=ve(t,kY),v=S.useRef(null),g=Ur(v,r),y=S.useRef(null),x=Ur(y,f),k=S.useRef(x);pa(()=>{k.current=x},[x]),S.useImperativeHandle(f,()=>y.current,[]);const w=SY(u,s),[E,M]=S.useState(w),[C,T]=S.useState(iv(o));S.useEffect(()=>{y.current&&y.current.forceUpdate()}),S.useEffect(()=>{o&&T(iv(o))},[o]),pa(()=>{if(!C||!c)return;const j=A=>{M(A.placement)};let L=[{name:"preventOverflow",options:{altBoundary:a}},{name:"flip",options:{altBoundary:a}},{name:"onUpdate",enabled:!0,phase:"afterWrite",fn:({state:A})=>{j(A)}}];l!=null&&(L=L.concat(l)),d&&d.modifiers!=null&&(L=L.concat(d.modifiers));const q=yY(C,v.current,_({placement:w},d,{modifiers:L}));return k.current(q),()=>{q.destroy(),k.current(null)}},[C,a,l,c,d,w]);const N={placement:E};m!==null&&(N.TransitionProps=m);const z=CY(),D=(n=h.root)!=null?n:"div",V=si({elementType:D,externalSlotProps:p.root,externalForwardedProps:b,additionalProps:{role:"tooltip",ref:g},ownerState:t,className:z.root});return O.jsx(D,_({},V,{children:typeof i=="function"?i(N):i}))}),OY=S.forwardRef(function(t,r){const{anchorEl:n,children:o,container:i,direction:s="ltr",disablePortal:a=!1,keepMounted:l=!1,modifiers:c,open:u,placement:d="bottom",popperOptions:f=MY,popperRef:p,style:h,transition:m=!1,slotProps:b={},slots:v={}}=t,g=ve(t,wY),[y,x]=S.useState(!0),k=()=>{x(!1)},w=()=>{x(!0)};if(!l&&!u&&(!m||y))return null;let E;if(i)E=i;else if(n){const T=iv(n);E=T&&EY(T)?Br(T).body:Br(null).body}const M=!u&&l&&(!m||y)?"none":void 0,C=m?{in:u,onEnter:k,onExited:w}:void 0;return O.jsx(M3,{disablePortal:a,container:E,children:O.jsx(TY,_({anchorEl:n,direction:s,disablePortal:a,modifiers:c,ref:r,open:m?!y:u,placement:d,popperOptions:f,popperRef:p,slotProps:b,slots:v},g,{style:_({position:"fixed",top:0,left:0,display:M},h),TransitionProps:C,children:o}))})});function _Y(e){const t=Br(e);return t.body===e?fd(e).innerWidth>t.documentElement.clientWidth:e.scrollHeight>e.clientHeight}function Ru(e,t){t?e.setAttribute("aria-hidden","true"):e.removeAttribute("aria-hidden")}function NS(e){return parseInt(fd(e).getComputedStyle(e).paddingRight,10)||0}function AY(e){const r=["TEMPLATE","SCRIPT","STYLE","LINK","MAP","META","NOSCRIPT","PICTURE","COL","COLGROUP","PARAM","SLOT","SOURCE","TRACK"].indexOf(e.tagName)!==-1,n=e.tagName==="INPUT"&&e.getAttribute("type")==="hidden";return r||n}function RS(e,t,r,n,o){const i=[t,r,...n];[].forEach.call(e.children,s=>{const a=i.indexOf(s)===-1,l=!AY(s);a&&l&&Ru(s,o)})}function o1(e,t){let r=-1;return e.some((n,o)=>t(n)?(r=o,!0):!1),r}function NY(e,t){const r=[],n=e.container;if(!t.disableScrollLock){if(_Y(n)){const s=LT(Br(n));r.push({value:n.style.paddingRight,property:"padding-right",el:n}),n.style.paddingRight=`${NS(n)+s}px`;const a=Br(n).querySelectorAll(".mui-fixed");[].forEach.call(a,l=>{r.push({value:l.style.paddingRight,property:"padding-right",el:l}),l.style.paddingRight=`${NS(l)+s}px`})}let i;if(n.parentNode instanceof DocumentFragment)i=Br(n).body;else{const s=n.parentElement,a=fd(n);i=(s==null?void 0:s.nodeName)==="HTML"&&a.getComputedStyle(s).overflowY==="scroll"?s:n}r.push({value:i.style.overflow,property:"overflow",el:i},{value:i.style.overflowX,property:"overflow-x",el:i},{value:i.style.overflowY,property:"overflow-y",el:i}),i.style.overflow="hidden"}return()=>{r.forEach(({value:i,el:s,property:a})=>{i?s.style.setProperty(a,i):s.style.removeProperty(a)})}}function RY(e){const t=[];return[].forEach.call(e.children,r=>{r.getAttribute("aria-hidden")==="true"&&t.push(r)}),t}class PY{constructor(){this.containers=void 0,this.modals=void 0,this.modals=[],this.containers=[]}add(t,r){let n=this.modals.indexOf(t);if(n!==-1)return n;n=this.modals.length,this.modals.push(t),t.modalRef&&Ru(t.modalRef,!1);const o=RY(r);RS(r,t.mount,t.modalRef,o,!0);const i=o1(this.containers,s=>s.container===r);return i!==-1?(this.containers[i].modals.push(t),n):(this.containers.push({modals:[t],container:r,restore:null,hiddenSiblings:o}),n)}mount(t,r){const n=o1(this.containers,i=>i.modals.indexOf(t)!==-1),o=this.containers[n];o.restore||(o.restore=NY(o,r))}remove(t,r=!0){const n=this.modals.indexOf(t);if(n===-1)return n;const o=o1(this.containers,s=>s.modals.indexOf(t)!==-1),i=this.containers[o];if(i.modals.splice(i.modals.indexOf(t),1),this.modals.splice(n,1),i.modals.length===0)i.restore&&i.restore(),t.modalRef&&Ru(t.modalRef,r),RS(i.container,t.mount,t.modalRef,i.hiddenSiblings,!1),this.containers.splice(o,1);else{const s=i.modals[i.modals.length-1];s.modalRef&&Ru(s.modalRef,!1)}return n}isTopModal(t){return this.modals.length>0&&this.modals[this.modals.length-1]===t}}function zY(e){return typeof e=="function"?e():e}function LY(e){return e?e.props.hasOwnProperty("in"):!1}const IY=new PY;function DY(e){const{container:t,disableEscapeKeyDown:r=!1,disableScrollLock:n=!1,manager:o=IY,closeAfterTransition:i=!1,onTransitionEnter:s,onTransitionExited:a,children:l,onClose:c,open:u,rootRef:d}=e,f=S.useRef({}),p=S.useRef(null),h=S.useRef(null),m=Ur(h,d),[b,v]=S.useState(!u),g=LY(l);let y=!0;(e["aria-hidden"]==="false"||e["aria-hidden"]===!1)&&(y=!1);const x=()=>Br(p.current),k=()=>(f.current.modalRef=h.current,f.current.mount=p.current,f.current),w=()=>{o.mount(k(),{disableScrollLock:n}),h.current&&(h.current.scrollTop=0)},E=Ws(()=>{const L=zY(t)||x().body;o.add(k(),L),h.current&&w()}),M=S.useCallback(()=>o.isTopModal(k()),[o]),C=Ws(L=>{p.current=L,L&&(u&&M()?w():h.current&&Ru(h.current,y))}),T=S.useCallback(()=>{o.remove(k(),y)},[y,o]);S.useEffect(()=>()=>{T()},[T]),S.useEffect(()=>{u?E():(!g||!i)&&T()},[u,T,g,i,E]);const N=L=>q=>{var A;(A=L.onKeyDown)==null||A.call(L,q),!(q.key!=="Escape"||!M())&&(r||(q.stopPropagation(),c&&c(q,"escapeKeyDown")))},z=L=>q=>{var A;(A=L.onClick)==null||A.call(L,q),q.target===q.currentTarget&&c&&c(q,"backdropClick")};return{getRootProps:(L={})=>{const q=g3(e);delete q.onTransitionEnter,delete q.onTransitionExited;const A=_({},q,L);return _({role:"presentation"},A,{onKeyDown:N(A),ref:m})},getBackdropProps:(L={})=>{const q=L;return _({"aria-hidden":!0},q,{onClick:z(q),open:u})},getTransitionProps:()=>{const L=()=>{v(!1),s&&s()},q=()=>{v(!0),a&&a(),i&&T()};return{onEnter:jw(L,l==null?void 0:l.props.onEnter),onExited:jw(q,l==null?void 0:l.props.onExited)}},rootRef:m,portalRef:C,isTopModal:M,exited:b,hasTransition:g}}const $Y=["anchorEl","component","components","componentsProps","container","disablePortal","keepMounted","modifiers","open","placement","popperOptions","popperRef","transition","slots","slotProps"],HY=Je(OY,{name:"MuiPopper",slot:"Root",overridesResolver:(e,t)=>t.root})({}),BY=S.forwardRef(function(t,r){var n;const o=yb(),i=Wt({props:t,name:"MuiPopper"}),{anchorEl:s,component:a,components:l,componentsProps:c,container:u,disablePortal:d,keepMounted:f,modifiers:p,open:h,placement:m,popperOptions:b,popperRef:v,transition:g,slots:y,slotProps:x}=i,k=ve(i,$Y),w=(n=y==null?void 0:y.root)!=null?n:l==null?void 0:l.Root,E=_({anchorEl:s,container:u,disablePortal:d,keepMounted:f,modifiers:p,open:h,placement:m,popperOptions:b,popperRef:v,transition:g},k);return O.jsx(HY,_({as:a,direction:o==null?void 0:o.direction,slots:{root:w},slotProps:x??c},E,{ref:r}))}),Lb=BY,FY=["addEndListener","appear","children","easing","in","onEnter","onEntered","onEntering","onExit","onExited","onExiting","style","timeout","TransitionComponent"],VY={entering:{opacity:1},entered:{opacity:1}},jY=S.forwardRef(function(t,r){const n=qm(),o={enter:n.transitions.duration.enteringScreen,exit:n.transitions.duration.leavingScreen},{addEndListener:i,appear:s=!0,children:a,easing:l,in:c,onEnter:u,onEntered:d,onEntering:f,onExit:p,onExited:h,onExiting:m,style:b,timeout:v=o,TransitionComponent:g=p3}=t,y=ve(t,FY),x=S.useRef(null),k=Ur(x,a.ref,r),w=V=>j=>{if(V){const L=x.current;j===void 0?V(L):V(L,j)}},E=w(f),M=w((V,j)=>{h3(V);const L=vh({style:b,timeout:v,easing:l},{mode:"enter"});V.style.webkitTransition=n.transitions.create("opacity",L),V.style.transition=n.transitions.create("opacity",L),u&&u(V,j)}),C=w(d),T=w(m),N=w(V=>{const j=vh({style:b,timeout:v,easing:l},{mode:"exit"});V.style.webkitTransition=n.transitions.create("opacity",j),V.style.transition=n.transitions.create("opacity",j),p&&p(V)}),z=w(h),D=V=>{i&&i(x.current,V)};return O.jsx(g,_({appear:s,in:c,nodeRef:x,onEnter:M,onEntered:C,onEntering:E,onExit:N,onExited:z,onExiting:T,addEndListener:D,timeout:v},y,{children:(V,j)=>S.cloneElement(a,_({style:_({opacity:0,visibility:V==="exited"&&!c?"hidden":void 0},VY[V],b,a.props.style),ref:k},j))}))}),UY=jY;function WY(e){return Vt("MuiBackdrop",e)}jt("MuiBackdrop",["root","invisible"]);const KY=["children","className","component","components","componentsProps","invisible","open","slotProps","slots","TransitionComponent","transitionDuration"],qY=e=>{const{classes:t,invisible:r}=e;return rr({root:["root",r&&"invisible"]},WY,t)},GY=Je("div",{name:"MuiBackdrop",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:r}=e;return[t.root,r.invisible&&t.invisible]}})(({ownerState:e})=>_({position:"fixed",display:"flex",alignItems:"center",justifyContent:"center",right:0,bottom:0,top:0,left:0,backgroundColor:"rgba(0, 0, 0, 0.5)",WebkitTapHighlightColor:"transparent"},e.invisible&&{backgroundColor:"transparent"})),YY=S.forwardRef(function(t,r){var n,o,i;const s=Wt({props:t,name:"MuiBackdrop"}),{children:a,className:l,component:c="div",components:u={},componentsProps:d={},invisible:f=!1,open:p,slotProps:h={},slots:m={},TransitionComponent:b=UY,transitionDuration:v}=s,g=ve(s,KY),y=_({},s,{component:c,invisible:f}),x=qY(y),k=(n=h.root)!=null?n:d.root;return O.jsx(b,_({in:p,timeout:v},g,{children:O.jsx(GY,_({"aria-hidden":!0},k,{as:(o=(i=m.root)!=null?i:u.Root)!=null?o:c,className:Ce(x.root,l,k==null?void 0:k.className),ownerState:_({},y,k==null?void 0:k.ownerState),classes:x,ref:r,children:a}))}))}),JY=YY;function XY(e){return Vt("MuiBadge",e)}const QY=jt("MuiBadge",["root","badge","dot","standard","anchorOriginTopRight","anchorOriginBottomRight","anchorOriginTopLeft","anchorOriginBottomLeft","invisible","colorError","colorInfo","colorPrimary","colorSecondary","colorSuccess","colorWarning","overlapRectangular","overlapCircular","anchorOriginTopLeftCircular","anchorOriginTopLeftRectangular","anchorOriginTopRightCircular","anchorOriginTopRightRectangular","anchorOriginBottomLeftCircular","anchorOriginBottomLeftRectangular","anchorOriginBottomRightCircular","anchorOriginBottomRightRectangular"]),xi=QY,ZY=["anchorOrigin","className","classes","component","components","componentsProps","children","overlap","color","invisible","max","badgeContent","slots","slotProps","showZero","variant"],i1=10,s1=4,eJ=e=>{const{color:t,anchorOrigin:r,invisible:n,overlap:o,variant:i,classes:s={}}=e,a={root:["root"],badge:["badge",i,n&&"invisible",`anchorOrigin${Fe(r.vertical)}${Fe(r.horizontal)}`,`anchorOrigin${Fe(r.vertical)}${Fe(r.horizontal)}${Fe(o)}`,`overlap${Fe(o)}`,t!=="default"&&`color${Fe(t)}`]};return rr(a,XY,s)},tJ=Je("span",{name:"MuiBadge",slot:"Root",overridesResolver:(e,t)=>t.root})({position:"relative",display:"inline-flex",verticalAlign:"middle",flexShrink:0}),rJ=Je("span",{name:"MuiBadge",slot:"Badge",overridesResolver:(e,t)=>{const{ownerState:r}=e;return[t.badge,t[r.variant],t[`anchorOrigin${Fe(r.anchorOrigin.vertical)}${Fe(r.anchorOrigin.horizontal)}${Fe(r.overlap)}`],r.color!=="default"&&t[`color${Fe(r.color)}`],r.invisible&&t.invisible]}})(({theme:e,ownerState:t})=>_({display:"flex",flexDirection:"row",flexWrap:"wrap",justifyContent:"center",alignContent:"center",alignItems:"center",position:"absolute",boxSizing:"border-box",fontFamily:e.typography.fontFamily,fontWeight:e.typography.fontWeightMedium,fontSize:e.typography.pxToRem(12),minWidth:i1*2,lineHeight:1,padding:"0 6px",height:i1*2,borderRadius:i1,zIndex:1,transition:e.transitions.create("transform",{easing:e.transitions.easing.easeInOut,duration:e.transitions.duration.enteringScreen})},t.color!=="default"&&{backgroundColor:(e.vars||e).palette[t.color].main,color:(e.vars||e).palette[t.color].contrastText},t.variant==="dot"&&{borderRadius:s1,height:s1*2,minWidth:s1*2,padding:0},t.anchorOrigin.vertical==="top"&&t.anchorOrigin.horizontal==="right"&&t.overlap==="rectangular"&&{top:0,right:0,transform:"scale(1) translate(50%, -50%)",transformOrigin:"100% 0%",[`&.${xi.invisible}`]:{transform:"scale(0) translate(50%, -50%)"}},t.anchorOrigin.vertical==="bottom"&&t.anchorOrigin.horizontal==="right"&&t.overlap==="rectangular"&&{bottom:0,right:0,transform:"scale(1) translate(50%, 50%)",transformOrigin:"100% 100%",[`&.${xi.invisible}`]:{transform:"scale(0) translate(50%, 50%)"}},t.anchorOrigin.vertical==="top"&&t.anchorOrigin.horizontal==="left"&&t.overlap==="rectangular"&&{top:0,left:0,transform:"scale(1) translate(-50%, -50%)",transformOrigin:"0% 0%",[`&.${xi.invisible}`]:{transform:"scale(0) translate(-50%, -50%)"}},t.anchorOrigin.vertical==="bottom"&&t.anchorOrigin.horizontal==="left"&&t.overlap==="rectangular"&&{bottom:0,left:0,transform:"scale(1) translate(-50%, 50%)",transformOrigin:"0% 100%",[`&.${xi.invisible}`]:{transform:"scale(0) translate(-50%, 50%)"}},t.anchorOrigin.vertical==="top"&&t.anchorOrigin.horizontal==="right"&&t.overlap==="circular"&&{top:"14%",right:"14%",transform:"scale(1) translate(50%, -50%)",transformOrigin:"100% 0%",[`&.${xi.invisible}`]:{transform:"scale(0) translate(50%, -50%)"}},t.anchorOrigin.vertical==="bottom"&&t.anchorOrigin.horizontal==="right"&&t.overlap==="circular"&&{bottom:"14%",right:"14%",transform:"scale(1) translate(50%, 50%)",transformOrigin:"100% 100%",[`&.${xi.invisible}`]:{transform:"scale(0) translate(50%, 50%)"}},t.anchorOrigin.vertical==="top"&&t.anchorOrigin.horizontal==="left"&&t.overlap==="circular"&&{top:"14%",left:"14%",transform:"scale(1) translate(-50%, -50%)",transformOrigin:"0% 0%",[`&.${xi.invisible}`]:{transform:"scale(0) translate(-50%, -50%)"}},t.anchorOrigin.vertical==="bottom"&&t.anchorOrigin.horizontal==="left"&&t.overlap==="circular"&&{bottom:"14%",left:"14%",transform:"scale(1) translate(-50%, 50%)",transformOrigin:"0% 100%",[`&.${xi.invisible}`]:{transform:"scale(0) translate(-50%, 50%)"}},t.invisible&&{transition:e.transitions.create("transform",{easing:e.transitions.easing.easeInOut,duration:e.transitions.duration.leavingScreen})})),nJ=S.forwardRef(function(t,r){var n,o,i,s,a,l;const c=Wt({props:t,name:"MuiBadge"}),{anchorOrigin:u={vertical:"top",horizontal:"right"},className:d,component:f,components:p={},componentsProps:h={},children:m,overlap:b="rectangular",color:v="default",invisible:g=!1,max:y=99,badgeContent:x,slots:k,slotProps:w,showZero:E=!1,variant:M="standard"}=c,C=ve(c,ZY),{badgeContent:T,invisible:N,max:z,displayValue:D}=iG({max:y,invisible:g,badgeContent:x,showZero:E}),V=IT({anchorOrigin:u,color:v,overlap:b,variant:M,badgeContent:x}),j=N||T==null&&M!=="dot",{color:L=v,overlap:q=b,anchorOrigin:A=u,variant:P=M}=j?V:c,F=P!=="dot"?D:void 0,Y=_({},c,{badgeContent:T,invisible:j,max:z,displayValue:F,showZero:E,anchorOrigin:A,color:L,overlap:q,variant:P}),J=eJ(Y),Ne=(n=(o=k==null?void 0:k.root)!=null?o:p.Root)!=null?n:tJ,ie=(i=(s=k==null?void 0:k.badge)!=null?s:p.Badge)!=null?i:rJ,ue=(a=w==null?void 0:w.root)!=null?a:h.root,de=(l=w==null?void 0:w.badge)!=null?l:h.badge,me=si({elementType:Ne,externalSlotProps:ue,externalForwardedProps:C,additionalProps:{ref:r,as:f},ownerState:Y,className:Ce(ue==null?void 0:ue.className,J.root,d)}),Me=si({elementType:ie,externalSlotProps:de,ownerState:Y,className:Ce(J.badge,de==null?void 0:de.className)});return O.jsxs(Ne,_({},me,{children:[m,O.jsx(ie,_({},Me,{children:F}))]}))}),oJ=nJ,iJ=wb(),sJ=XW({themeId:Kl,defaultTheme:iJ,defaultClassName:"MuiBox-root",generateClassName:$T.generate}),T3=sJ;function aJ(e){return Vt("MuiModal",e)}jt("MuiModal",["root","hidden","backdrop"]);const lJ=["BackdropComponent","BackdropProps","classes","className","closeAfterTransition","children","container","component","components","componentsProps","disableAutoFocus","disableEnforceFocus","disableEscapeKeyDown","disablePortal","disableRestoreFocus","disableScrollLock","hideBackdrop","keepMounted","onBackdropClick","onClose","onTransitionEnter","onTransitionExited","open","slotProps","slots","theme"],cJ=e=>{const{open:t,exited:r,classes:n}=e;return rr({root:["root",!t&&r&&"hidden"],backdrop:["backdrop"]},aJ,n)},uJ=Je("div",{name:"MuiModal",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:r}=e;return[t.root,!r.open&&r.exited&&t.hidden]}})(({theme:e,ownerState:t})=>_({position:"fixed",zIndex:(e.vars||e).zIndex.modal,right:0,bottom:0,top:0,left:0},!t.open&&t.exited&&{visibility:"hidden"})),dJ=Je(JY,{name:"MuiModal",slot:"Backdrop",overridesResolver:(e,t)=>t.backdrop})({zIndex:-1}),fJ=S.forwardRef(function(t,r){var n,o,i,s,a,l;const c=Wt({name:"MuiModal",props:t}),{BackdropComponent:u=dJ,BackdropProps:d,className:f,closeAfterTransition:p=!1,children:h,container:m,component:b,components:v={},componentsProps:g={},disableAutoFocus:y=!1,disableEnforceFocus:x=!1,disableEscapeKeyDown:k=!1,disablePortal:w=!1,disableRestoreFocus:E=!1,disableScrollLock:M=!1,hideBackdrop:C=!1,keepMounted:T=!1,onBackdropClick:N,open:z,slotProps:D,slots:V}=c,j=ve(c,lJ),L=_({},c,{closeAfterTransition:p,disableAutoFocus:y,disableEnforceFocus:x,disableEscapeKeyDown:k,disablePortal:w,disableRestoreFocus:E,disableScrollLock:M,hideBackdrop:C,keepMounted:T}),{getRootProps:q,getBackdropProps:A,getTransitionProps:P,portalRef:F,isTopModal:Y,exited:J,hasTransition:Ne}=DY(_({},L,{rootRef:r})),ie=_({},L,{exited:J}),ue=cJ(ie),de={};if(h.props.tabIndex===void 0&&(de.tabIndex="-1"),Ne){const{onEnter:he,onExited:De}=P();de.onEnter=he,de.onExited=De}const me=(n=(o=V==null?void 0:V.root)!=null?o:v.Root)!=null?n:uJ,Me=(i=(s=V==null?void 0:V.backdrop)!=null?s:v.Backdrop)!=null?i:u,Se=(a=D==null?void 0:D.root)!=null?a:g.root,ft=(l=D==null?void 0:D.backdrop)!=null?l:g.backdrop,rt=si({elementType:me,externalSlotProps:Se,externalForwardedProps:j,getSlotProps:q,additionalProps:{ref:r,as:b},ownerState:ie,className:Ce(f,Se==null?void 0:Se.className,ue==null?void 0:ue.root,!ie.open&&ie.exited&&(ue==null?void 0:ue.hidden))}),Or=si({elementType:Me,externalSlotProps:ft,additionalProps:d,getSlotProps:he=>A(_({},he,{onClick:De=>{N&&N(De),he!=null&&he.onClick&&he.onClick(De)}})),className:Ce(ft==null?void 0:ft.className,d==null?void 0:d.className,ue==null?void 0:ue.backdrop),ownerState:ie});return!T&&!z&&(!Ne||J)?null:O.jsx(M3,{ref:F,container:m,disablePortal:w,children:O.jsxs(me,_({},rt,{children:[!C&&u?O.jsx(Me,_({},Or)):null,O.jsx(fG,{disableEnforceFocus:x,disableAutoFocus:y,disableRestoreFocus:E,isEnabled:Y,open:z,children:S.cloneElement(h,de)})]}))})}),pJ=fJ,hJ=jt("MuiDivider",["root","absolute","fullWidth","inset","middle","flexItem","light","vertical","withChildren","withChildrenVertical","textAlignRight","textAlignLeft","wrapper","wrapperVertical"]),PS=hJ,mJ=_K({createStyledComponent:Je("div",{name:"MuiStack",slot:"Root",overridesResolver:(e,t)=>t.root}),useThemeProps:e=>Wt({props:e,name:"MuiStack"})}),gJ=mJ,vJ=["addEndListener","appear","children","easing","in","onEnter","onEntered","onEntering","onExit","onExited","onExiting","style","timeout","TransitionComponent"];function sv(e){return`scale(${e}, ${e**2})`}const yJ={entering:{opacity:1,transform:sv(1)},entered:{opacity:1,transform:"none"}},a1=typeof navigator<"u"&&/^((?!chrome|android).)*(safari|mobile)/i.test(navigator.userAgent)&&/(os |version\/)15(.|_)4/i.test(navigator.userAgent),O3=S.forwardRef(function(t,r){const{addEndListener:n,appear:o=!0,children:i,easing:s,in:a,onEnter:l,onEntered:c,onEntering:u,onExit:d,onExited:f,onExiting:p,style:h,timeout:m="auto",TransitionComponent:b=p3}=t,v=ve(t,vJ),g=S.useRef(),y=S.useRef(),x=qm(),k=S.useRef(null),w=Ur(k,i.ref,r),E=j=>L=>{if(j){const q=k.current;L===void 0?j(q):j(q,L)}},M=E(u),C=E((j,L)=>{h3(j);const{duration:q,delay:A,easing:P}=vh({style:h,timeout:m,easing:s},{mode:"enter"});let F;m==="auto"?(F=x.transitions.getAutoHeightDuration(j.clientHeight),y.current=F):F=q,j.style.transition=[x.transitions.create("opacity",{duration:F,delay:A}),x.transitions.create("transform",{duration:a1?F:F*.666,delay:A,easing:P})].join(","),l&&l(j,L)}),T=E(c),N=E(p),z=E(j=>{const{duration:L,delay:q,easing:A}=vh({style:h,timeout:m,easing:s},{mode:"exit"});let P;m==="auto"?(P=x.transitions.getAutoHeightDuration(j.clientHeight),y.current=P):P=L,j.style.transition=[x.transitions.create("opacity",{duration:P,delay:q}),x.transitions.create("transform",{duration:a1?P:P*.666,delay:a1?q:q||P*.333,easing:A})].join(","),j.style.opacity=0,j.style.transform=sv(.75),d&&d(j)}),D=E(f),V=j=>{m==="auto"&&(g.current=setTimeout(j,y.current||0)),n&&n(k.current,j)};return S.useEffect(()=>()=>{clearTimeout(g.current)},[]),O.jsx(b,_({appear:o,in:a,nodeRef:k,onEnter:C,onEntered:T,onEntering:M,onExit:z,onExited:D,onExiting:N,addEndListener:V,timeout:m==="auto"?null:m},v,{children:(j,L)=>S.cloneElement(i,_({style:_({opacity:0,transform:sv(.75),visibility:j==="exited"&&!a?"hidden":void 0},yJ[j],h,i.props.style),ref:w},L))}))});O3.muiSupportAuto=!0;const av=O3,bJ=S.createContext({}),yd=bJ;function xJ(e){return Vt("MuiList",e)}jt("MuiList",["root","padding","dense","subheader"]);const kJ=["children","className","component","dense","disablePadding","subheader"],wJ=e=>{const{classes:t,disablePadding:r,dense:n,subheader:o}=e;return rr({root:["root",!r&&"padding",n&&"dense",o&&"subheader"]},xJ,t)},SJ=Je("ul",{name:"MuiList",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:r}=e;return[t.root,!r.disablePadding&&t.padding,r.dense&&t.dense,r.subheader&&t.subheader]}})(({ownerState:e})=>_({listStyle:"none",margin:0,padding:0,position:"relative"},!e.disablePadding&&{paddingTop:8,paddingBottom:8},e.subheader&&{paddingTop:0})),EJ=S.forwardRef(function(t,r){const n=Wt({props:t,name:"MuiList"}),{children:o,className:i,component:s="ul",dense:a=!1,disablePadding:l=!1,subheader:c}=n,u=ve(n,kJ),d=S.useMemo(()=>({dense:a}),[a]),f=_({},n,{component:s,dense:a,disablePadding:l}),p=wJ(f);return O.jsx(yd.Provider,{value:d,children:O.jsxs(SJ,_({as:s,className:Ce(p.root,i),ref:r,ownerState:f},u,{children:[c,o]}))})}),CJ=EJ;function MJ(e){return Vt("MuiListItemIcon",e)}const TJ=jt("MuiListItemIcon",["root","alignItemsFlexStart"]),zS=TJ,OJ=["className"],_J=e=>{const{alignItems:t,classes:r}=e;return rr({root:["root",t==="flex-start"&&"alignItemsFlexStart"]},MJ,r)},AJ=Je("div",{name:"MuiListItemIcon",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:r}=e;return[t.root,r.alignItems==="flex-start"&&t.alignItemsFlexStart]}})(({theme:e,ownerState:t})=>_({minWidth:56,color:(e.vars||e).palette.action.active,flexShrink:0,display:"inline-flex"},t.alignItems==="flex-start"&&{marginTop:8})),NJ=S.forwardRef(function(t,r){const n=Wt({props:t,name:"MuiListItemIcon"}),{className:o}=n,i=ve(n,OJ),s=S.useContext(yd),a=_({},n,{alignItems:s.alignItems}),l=_J(a);return O.jsx(AJ,_({className:Ce(l.root,o),ownerState:a,ref:r},i))}),RJ=NJ;function PJ(e){return Vt("MuiListItemText",e)}const zJ=jt("MuiListItemText",["root","multiline","dense","inset","primary","secondary"]),bh=zJ,LJ=["children","className","disableTypography","inset","primary","primaryTypographyProps","secondary","secondaryTypographyProps"],IJ=e=>{const{classes:t,inset:r,primary:n,secondary:o,dense:i}=e;return rr({root:["root",r&&"inset",i&&"dense",n&&o&&"multiline"],primary:["primary"],secondary:["secondary"]},PJ,t)},DJ=Je("div",{name:"MuiListItemText",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:r}=e;return[{[`& .${bh.primary}`]:t.primary},{[`& .${bh.secondary}`]:t.secondary},t.root,r.inset&&t.inset,r.primary&&r.secondary&&t.multiline,r.dense&&t.dense]}})(({ownerState:e})=>_({flex:"1 1 auto",minWidth:0,marginTop:4,marginBottom:4},e.primary&&e.secondary&&{marginTop:6,marginBottom:6},e.inset&&{paddingLeft:56})),$J=S.forwardRef(function(t,r){const n=Wt({props:t,name:"MuiListItemText"}),{children:o,className:i,disableTypography:s=!1,inset:a=!1,primary:l,primaryTypographyProps:c,secondary:u,secondaryTypographyProps:d}=n,f=ve(n,LJ),{dense:p}=S.useContext(yd);let h=l??o,m=u;const b=_({},n,{disableTypography:s,inset:a,primary:!!h,secondary:!!m,dense:p}),v=IJ(b);return h!=null&&h.type!==cu&&!s&&(h=O.jsx(cu,_({variant:p?"body2":"body1",className:v.primary,component:c!=null&&c.variant?void 0:"span",display:"block"},c,{children:h}))),m!=null&&m.type!==cu&&!s&&(m=O.jsx(cu,_({variant:"body2",className:v.secondary,color:"text.secondary",display:"block"},d,{children:m}))),O.jsxs(DJ,_({className:Ce(v.root,i),ownerState:b,ref:r},f,{children:[h,m]}))}),HJ=$J,BJ=["actions","autoFocus","autoFocusItem","children","className","disabledItemsFocusable","disableListWrap","onKeyDown","variant"];function l1(e,t,r){return e===t?e.firstChild:t&&t.nextElementSibling?t.nextElementSibling:r?null:e.firstChild}function LS(e,t,r){return e===t?r?e.firstChild:e.lastChild:t&&t.previousElementSibling?t.previousElementSibling:r?null:e.lastChild}function _3(e,t){if(t===void 0)return!0;let r=e.innerText;return r===void 0&&(r=e.textContent),r=r.trim().toLowerCase(),r.length===0?!1:t.repeating?r[0]===t.keys[0]:r.indexOf(t.keys.join(""))===0}function Ac(e,t,r,n,o,i){let s=!1,a=o(e,t,t?r:!1);for(;a;){if(a===e.firstChild){if(s)return!1;s=!0}const l=n?!1:a.disabled||a.getAttribute("aria-disabled")==="true";if(!a.hasAttribute("tabindex")||!_3(a,i)||l)a=o(e,a,r);else return a.focus(),!0}return!1}const FJ=S.forwardRef(function(t,r){const{actions:n,autoFocus:o=!1,autoFocusItem:i=!1,children:s,className:a,disabledItemsFocusable:l=!1,disableListWrap:c=!1,onKeyDown:u,variant:d="selectedMenu"}=t,f=ve(t,BJ),p=S.useRef(null),h=S.useRef({keys:[],repeating:!0,previousKeyMatched:!0,lastTime:null});pa(()=>{o&&p.current.focus()},[o]),S.useImperativeHandle(n,()=>({adjustStyleForScrollbar:(y,x)=>{const k=!p.current.style.width;if(y.clientHeight{const x=p.current,k=y.key,w=Br(x).activeElement;if(k==="ArrowDown")y.preventDefault(),Ac(x,w,c,l,l1);else if(k==="ArrowUp")y.preventDefault(),Ac(x,w,c,l,LS);else if(k==="Home")y.preventDefault(),Ac(x,null,c,l,l1);else if(k==="End")y.preventDefault(),Ac(x,null,c,l,LS);else if(k.length===1){const E=h.current,M=k.toLowerCase(),C=performance.now();E.keys.length>0&&(C-E.lastTime>500?(E.keys=[],E.repeating=!0,E.previousKeyMatched=!0):E.repeating&&M!==E.keys[0]&&(E.repeating=!1)),E.lastTime=C,E.keys.push(M);const T=w&&!E.repeating&&_3(w,E);E.previousKeyMatched&&(T||Ac(x,w,!1,l,l1,E))?y.preventDefault():E.previousKeyMatched=!1}u&&u(y)},b=Ur(p,r);let v=-1;S.Children.forEach(s,(y,x)=>{if(!S.isValidElement(y)){v===x&&(v+=1,v>=s.length&&(v=-1));return}y.props.disabled||(d==="selectedMenu"&&y.props.selected||v===-1)&&(v=x),v===x&&(y.props.disabled||y.props.muiSkipListHighlight||y.type.muiSkipListHighlight)&&(v+=1,v>=s.length&&(v=-1))});const g=S.Children.map(s,(y,x)=>{if(x===v){const k={};return i&&(k.autoFocus=!0),y.props.tabIndex===void 0&&d==="selectedMenu"&&(k.tabIndex=0),S.cloneElement(y,k)}return y});return O.jsx(CJ,_({role:"menu",ref:b,className:a,onKeyDown:m,tabIndex:o?0:-1},f,{children:g}))}),VJ=FJ;function jJ(e){return Vt("MuiPopover",e)}jt("MuiPopover",["root","paper"]);const UJ=["onEntering"],WJ=["action","anchorEl","anchorOrigin","anchorPosition","anchorReference","children","className","container","elevation","marginThreshold","open","PaperProps","slots","slotProps","transformOrigin","TransitionComponent","transitionDuration","TransitionProps","disableScrollLock"],KJ=["slotProps"];function IS(e,t){let r=0;return typeof t=="number"?r=t:t==="center"?r=e.height/2:t==="bottom"&&(r=e.height),r}function DS(e,t){let r=0;return typeof t=="number"?r=t:t==="center"?r=e.width/2:t==="right"&&(r=e.width),r}function $S(e){return[e.horizontal,e.vertical].map(t=>typeof t=="number"?`${t}px`:t).join(" ")}function c1(e){return typeof e=="function"?e():e}const qJ=e=>{const{classes:t}=e;return rr({root:["root"],paper:["paper"]},jJ,t)},GJ=Je(pJ,{name:"MuiPopover",slot:"Root",overridesResolver:(e,t)=>t.root})({}),A3=Je(bq,{name:"MuiPopover",slot:"Paper",overridesResolver:(e,t)=>t.paper})({position:"absolute",overflowY:"auto",overflowX:"hidden",minWidth:16,minHeight:16,maxWidth:"calc(100% - 32px)",maxHeight:"calc(100% - 32px)",outline:0}),YJ=S.forwardRef(function(t,r){var n,o,i;const s=Wt({props:t,name:"MuiPopover"}),{action:a,anchorEl:l,anchorOrigin:c={vertical:"top",horizontal:"left"},anchorPosition:u,anchorReference:d="anchorEl",children:f,className:p,container:h,elevation:m=8,marginThreshold:b=16,open:v,PaperProps:g={},slots:y,slotProps:x,transformOrigin:k={vertical:"top",horizontal:"left"},TransitionComponent:w=av,transitionDuration:E="auto",TransitionProps:{onEntering:M}={},disableScrollLock:C=!1}=s,T=ve(s.TransitionProps,UJ),N=ve(s,WJ),z=(n=x==null?void 0:x.paper)!=null?n:g,D=S.useRef(),V=Ur(D,z.ref),j=_({},s,{anchorOrigin:c,anchorReference:d,elevation:m,marginThreshold:b,externalPaperSlotProps:z,transformOrigin:k,TransitionComponent:w,transitionDuration:E,TransitionProps:T}),L=qJ(j),q=S.useCallback(()=>{if(d==="anchorPosition")return u;const he=c1(l),Ke=(he&&he.nodeType===1?he:Br(D.current).body).getBoundingClientRect();return{top:Ke.top+IS(Ke,c.vertical),left:Ke.left+DS(Ke,c.horizontal)}},[l,c.horizontal,c.vertical,u,d]),A=S.useCallback(he=>({vertical:IS(he,k.vertical),horizontal:DS(he,k.horizontal)}),[k.horizontal,k.vertical]),P=S.useCallback(he=>{const De={width:he.offsetWidth,height:he.offsetHeight},Ke=A(De);if(d==="none")return{top:null,left:null,transformOrigin:$S(Ke)};const Fn=q();let Gr=Fn.top-Ke.vertical,nr=Fn.left-Ke.horizontal;const zo=Gr+De.height,Pt=nr+De.width,Yr=fd(c1(l)),vn=Yr.innerHeight-b,Vn=Yr.innerWidth-b;if(b!==null&&Grvn){const Xe=zo-vn;Gr-=Xe,Ke.vertical+=Xe}if(b!==null&&nrVn){const Xe=Pt-Vn;nr-=Xe,Ke.horizontal+=Xe}return{top:`${Math.round(Gr)}px`,left:`${Math.round(nr)}px`,transformOrigin:$S(Ke)}},[l,d,q,A,b]),[F,Y]=S.useState(v),J=S.useCallback(()=>{const he=D.current;if(!he)return;const De=P(he);De.top!==null&&(he.style.top=De.top),De.left!==null&&(he.style.left=De.left),he.style.transformOrigin=De.transformOrigin,Y(!0)},[P]);S.useEffect(()=>(C&&window.addEventListener("scroll",J),()=>window.removeEventListener("scroll",J)),[l,C,J]);const Ne=(he,De)=>{M&&M(he,De),J()},ie=()=>{Y(!1)};S.useEffect(()=>{v&&J()}),S.useImperativeHandle(a,()=>v?{updatePosition:()=>{J()}}:null,[v,J]),S.useEffect(()=>{if(!v)return;const he=Lj(()=>{J()}),De=fd(l);return De.addEventListener("resize",he),()=>{he.clear(),De.removeEventListener("resize",he)}},[l,v,J]);let ue=E;E==="auto"&&!w.muiSupportAuto&&(ue=void 0);const de=h||(l?Br(c1(l)).body:void 0),me=(o=y==null?void 0:y.root)!=null?o:GJ,Me=(i=y==null?void 0:y.paper)!=null?i:A3,Se=si({elementType:Me,externalSlotProps:_({},z,{style:F?z.style:_({},z.style,{opacity:0})}),additionalProps:{elevation:m,ref:V},ownerState:j,className:Ce(L.paper,z==null?void 0:z.className)}),ft=si({elementType:me,externalSlotProps:(x==null?void 0:x.root)||{},externalForwardedProps:N,additionalProps:{ref:r,slotProps:{backdrop:{invisible:!0}},container:de,open:v},ownerState:j,className:Ce(L.root,p)}),{slotProps:rt}=ft,Or=ve(ft,KJ);return O.jsx(me,_({},Or,!m3(me)&&{slotProps:rt,disableScrollLock:C},{children:O.jsx(w,_({appear:!0,in:v,onEntering:Ne,onExited:ie,timeout:ue},T,{children:O.jsx(Me,_({},Se,{children:f}))}))}))}),JJ=YJ;function XJ(e){return Vt("MuiMenu",e)}jt("MuiMenu",["root","paper","list"]);const QJ=["onEntering"],ZJ=["autoFocus","children","className","disableAutoFocusItem","MenuListProps","onClose","open","PaperProps","PopoverClasses","transitionDuration","TransitionProps","variant","slots","slotProps"],eX={vertical:"top",horizontal:"right"},tX={vertical:"top",horizontal:"left"},rX=e=>{const{classes:t}=e;return rr({root:["root"],paper:["paper"],list:["list"]},XJ,t)},nX=Je(JJ,{shouldForwardProp:e=>Eb(e)||e==="classes",name:"MuiMenu",slot:"Root",overridesResolver:(e,t)=>t.root})({}),oX=Je(A3,{name:"MuiMenu",slot:"Paper",overridesResolver:(e,t)=>t.paper})({maxHeight:"calc(100% - 96px)",WebkitOverflowScrolling:"touch"}),iX=Je(VJ,{name:"MuiMenu",slot:"List",overridesResolver:(e,t)=>t.list})({outline:0}),sX=S.forwardRef(function(t,r){var n,o;const i=Wt({props:t,name:"MuiMenu"}),{autoFocus:s=!0,children:a,className:l,disableAutoFocusItem:c=!1,MenuListProps:u={},onClose:d,open:f,PaperProps:p={},PopoverClasses:h,transitionDuration:m="auto",TransitionProps:{onEntering:b}={},variant:v="selectedMenu",slots:g={},slotProps:y={}}=i,x=ve(i.TransitionProps,QJ),k=ve(i,ZJ),w=qm(),E=w.direction==="rtl",M=_({},i,{autoFocus:s,disableAutoFocusItem:c,MenuListProps:u,onEntering:b,PaperProps:p,transitionDuration:m,TransitionProps:x,variant:v}),C=rX(M),T=s&&!c&&f,N=S.useRef(null),z=(P,F)=>{N.current&&N.current.adjustStyleForScrollbar(P,w),b&&b(P,F)},D=P=>{P.key==="Tab"&&(P.preventDefault(),d&&d(P,"tabKeyDown"))};let V=-1;S.Children.map(a,(P,F)=>{S.isValidElement(P)&&(P.props.disabled||(v==="selectedMenu"&&P.props.selected||V===-1)&&(V=F))});const j=(n=g.paper)!=null?n:oX,L=(o=y.paper)!=null?o:p,q=si({elementType:g.root,externalSlotProps:y.root,ownerState:M,className:[C.root,l]}),A=si({elementType:j,externalSlotProps:L,ownerState:M,className:C.paper});return O.jsx(nX,_({onClose:d,anchorOrigin:{vertical:"bottom",horizontal:E?"right":"left"},transformOrigin:E?eX:tX,slots:{paper:j,root:g.root},slotProps:{root:q,paper:A},open:f,ref:r,transitionDuration:m,TransitionProps:_({onEntering:z},x),ownerState:M},k,{classes:h,children:O.jsx(iX,_({onKeyDown:D,actions:N,autoFocus:s&&(V===-1||c),autoFocusItem:T,variant:v},u,{className:Ce(C.list,u.className),children:a}))}))}),aX=sX;function lX(e){return Vt("MuiMenuItem",e)}const cX=jt("MuiMenuItem",["root","focusVisible","dense","disabled","divider","gutters","selected"]),Nc=cX,uX=["autoFocus","component","dense","divider","disableGutters","focusVisibleClassName","role","tabIndex","className"],dX=(e,t)=>{const{ownerState:r}=e;return[t.root,r.dense&&t.dense,r.divider&&t.divider,!r.disableGutters&&t.gutters]},fX=e=>{const{disabled:t,dense:r,divider:n,disableGutters:o,selected:i,classes:s}=e,l=rr({root:["root",r&&"dense",t&&"disabled",!o&&"gutters",n&&"divider",i&&"selected"]},lX,s);return _({},s,l)},pX=Je(Tb,{shouldForwardProp:e=>Eb(e)||e==="classes",name:"MuiMenuItem",slot:"Root",overridesResolver:dX})(({theme:e,ownerState:t})=>_({},e.typography.body1,{display:"flex",justifyContent:"flex-start",alignItems:"center",position:"relative",textDecoration:"none",minHeight:48,paddingTop:6,paddingBottom:6,boxSizing:"border-box",whiteSpace:"nowrap"},!t.disableGutters&&{paddingLeft:16,paddingRight:16},t.divider&&{borderBottom:`1px solid ${(e.vars||e).palette.divider}`,backgroundClip:"padding-box"},{"&:hover":{textDecoration:"none",backgroundColor:(e.vars||e).palette.action.hover,"@media (hover: none)":{backgroundColor:"transparent"}},[`&.${Nc.selected}`]:{backgroundColor:e.vars?`rgba(${e.vars.palette.primary.mainChannel} / ${e.vars.palette.action.selectedOpacity})`:Lr(e.palette.primary.main,e.palette.action.selectedOpacity),[`&.${Nc.focusVisible}`]:{backgroundColor:e.vars?`rgba(${e.vars.palette.primary.mainChannel} / calc(${e.vars.palette.action.selectedOpacity} + ${e.vars.palette.action.focusOpacity}))`:Lr(e.palette.primary.main,e.palette.action.selectedOpacity+e.palette.action.focusOpacity)}},[`&.${Nc.selected}:hover`]:{backgroundColor:e.vars?`rgba(${e.vars.palette.primary.mainChannel} / calc(${e.vars.palette.action.selectedOpacity} + ${e.vars.palette.action.hoverOpacity}))`:Lr(e.palette.primary.main,e.palette.action.selectedOpacity+e.palette.action.hoverOpacity),"@media (hover: none)":{backgroundColor:e.vars?`rgba(${e.vars.palette.primary.mainChannel} / ${e.vars.palette.action.selectedOpacity})`:Lr(e.palette.primary.main,e.palette.action.selectedOpacity)}},[`&.${Nc.focusVisible}`]:{backgroundColor:(e.vars||e).palette.action.focus},[`&.${Nc.disabled}`]:{opacity:(e.vars||e).palette.action.disabledOpacity},[`& + .${PS.root}`]:{marginTop:e.spacing(1),marginBottom:e.spacing(1)},[`& + .${PS.inset}`]:{marginLeft:52},[`& .${bh.root}`]:{marginTop:0,marginBottom:0},[`& .${bh.inset}`]:{paddingLeft:36},[`& .${zS.root}`]:{minWidth:36}},!t.dense&&{[e.breakpoints.up("sm")]:{minHeight:"auto"}},t.dense&&_({minHeight:32,paddingTop:4,paddingBottom:4},e.typography.body2,{[`& .${zS.root} svg`]:{fontSize:"1.25rem"}}))),hX=S.forwardRef(function(t,r){const n=Wt({props:t,name:"MuiMenuItem"}),{autoFocus:o=!1,component:i="li",dense:s=!1,divider:a=!1,disableGutters:l=!1,focusVisibleClassName:c,role:u="menuitem",tabIndex:d,className:f}=n,p=ve(n,uX),h=S.useContext(yd),m=S.useMemo(()=>({dense:s||h.dense||!1,disableGutters:l}),[h.dense,s,l]),b=S.useRef(null);pa(()=>{o&&b.current&&b.current.focus()},[o]);const v=_({},n,{dense:m.dense,divider:a,disableGutters:l}),g=fX(n),y=Ur(b,r);let x;return n.disabled||(x=d!==void 0?d:-1),O.jsx(yd.Provider,{value:m,children:O.jsx(pX,_({ref:y,role:u,tabIndex:x,component:i,focusVisibleClassName:Ce(g.focusVisible,c),className:Ce(g.root,f)},p,{ownerState:v,classes:g}))})}),mX=hX;function gX(e){return Vt("MuiTooltip",e)}const vX=jt("MuiTooltip",["popper","popperInteractive","popperArrow","popperClose","tooltip","tooltipArrow","touch","tooltipPlacementLeft","tooltipPlacementRight","tooltipPlacementTop","tooltipPlacementBottom","arrow"]),Bi=vX,yX=["arrow","children","classes","components","componentsProps","describeChild","disableFocusListener","disableHoverListener","disableInteractive","disableTouchListener","enterDelay","enterNextDelay","enterTouchDelay","followCursor","id","leaveDelay","leaveTouchDelay","onClose","onOpen","open","placement","PopperComponent","PopperProps","slotProps","slots","title","TransitionComponent","TransitionProps"];function bX(e){return Math.round(e*1e5)/1e5}const xX=e=>{const{classes:t,disableInteractive:r,arrow:n,touch:o,placement:i}=e,s={popper:["popper",!r&&"popperInteractive",n&&"popperArrow"],tooltip:["tooltip",n&&"tooltipArrow",o&&"touch",`tooltipPlacement${Fe(i.split("-")[0])}`],arrow:["arrow"]};return rr(s,gX,t)},kX=Je(Lb,{name:"MuiTooltip",slot:"Popper",overridesResolver:(e,t)=>{const{ownerState:r}=e;return[t.popper,!r.disableInteractive&&t.popperInteractive,r.arrow&&t.popperArrow,!r.open&&t.popperClose]}})(({theme:e,ownerState:t,open:r})=>_({zIndex:(e.vars||e).zIndex.tooltip,pointerEvents:"none"},!t.disableInteractive&&{pointerEvents:"auto"},!r&&{pointerEvents:"none"},t.arrow&&{[`&[data-popper-placement*="bottom"] .${Bi.arrow}`]:{top:0,marginTop:"-0.71em","&::before":{transformOrigin:"0 100%"}},[`&[data-popper-placement*="top"] .${Bi.arrow}`]:{bottom:0,marginBottom:"-0.71em","&::before":{transformOrigin:"100% 0"}},[`&[data-popper-placement*="right"] .${Bi.arrow}`]:_({},t.isRtl?{right:0,marginRight:"-0.71em"}:{left:0,marginLeft:"-0.71em"},{height:"1em",width:"0.71em","&::before":{transformOrigin:"100% 100%"}}),[`&[data-popper-placement*="left"] .${Bi.arrow}`]:_({},t.isRtl?{left:0,marginLeft:"-0.71em"}:{right:0,marginRight:"-0.71em"},{height:"1em",width:"0.71em","&::before":{transformOrigin:"0 0"}})})),wX=Je("div",{name:"MuiTooltip",slot:"Tooltip",overridesResolver:(e,t)=>{const{ownerState:r}=e;return[t.tooltip,r.touch&&t.touch,r.arrow&&t.tooltipArrow,t[`tooltipPlacement${Fe(r.placement.split("-")[0])}`]]}})(({theme:e,ownerState:t})=>_({backgroundColor:e.vars?e.vars.palette.Tooltip.bg:Lr(e.palette.grey[700],.92),borderRadius:(e.vars||e).shape.borderRadius,color:(e.vars||e).palette.common.white,fontFamily:e.typography.fontFamily,padding:"4px 8px",fontSize:e.typography.pxToRem(11),maxWidth:300,margin:2,wordWrap:"break-word",fontWeight:e.typography.fontWeightMedium},t.arrow&&{position:"relative",margin:0},t.touch&&{padding:"8px 16px",fontSize:e.typography.pxToRem(14),lineHeight:`${bX(16/14)}em`,fontWeight:e.typography.fontWeightRegular},{[`.${Bi.popper}[data-popper-placement*="left"] &`]:_({transformOrigin:"right center"},t.isRtl?_({marginLeft:"14px"},t.touch&&{marginLeft:"24px"}):_({marginRight:"14px"},t.touch&&{marginRight:"24px"})),[`.${Bi.popper}[data-popper-placement*="right"] &`]:_({transformOrigin:"left center"},t.isRtl?_({marginRight:"14px"},t.touch&&{marginRight:"24px"}):_({marginLeft:"14px"},t.touch&&{marginLeft:"24px"})),[`.${Bi.popper}[data-popper-placement*="top"] &`]:_({transformOrigin:"center bottom",marginBottom:"14px"},t.touch&&{marginBottom:"24px"}),[`.${Bi.popper}[data-popper-placement*="bottom"] &`]:_({transformOrigin:"center top",marginTop:"14px"},t.touch&&{marginTop:"24px"})})),SX=Je("span",{name:"MuiTooltip",slot:"Arrow",overridesResolver:(e,t)=>t.arrow})(({theme:e})=>({overflow:"hidden",position:"absolute",width:"1em",height:"0.71em",boxSizing:"border-box",color:e.vars?e.vars.palette.Tooltip.bg:Lr(e.palette.grey[700],.9),"&::before":{content:'""',margin:"auto",display:"block",width:"100%",height:"100%",backgroundColor:"currentColor",transform:"rotate(45deg)"}}));let Mf=!1,u1=null,Rc={x:0,y:0};function Tf(e,t){return r=>{t&&t(r),e(r)}}const EX=S.forwardRef(function(t,r){var n,o,i,s,a,l,c,u,d,f,p,h,m,b,v,g,y,x,k;const w=Wt({props:t,name:"MuiTooltip"}),{arrow:E=!1,children:M,components:C={},componentsProps:T={},describeChild:N=!1,disableFocusListener:z=!1,disableHoverListener:D=!1,disableInteractive:V=!1,disableTouchListener:j=!1,enterDelay:L=100,enterNextDelay:q=0,enterTouchDelay:A=700,followCursor:P=!1,id:F,leaveDelay:Y=0,leaveTouchDelay:J=1500,onClose:Ne,onOpen:ie,open:ue,placement:de="bottom",PopperComponent:me,PopperProps:Me={},slotProps:Se={},slots:ft={},title:rt,TransitionComponent:Or=av,TransitionProps:he}=w,De=ve(w,yX),Ke=S.isValidElement(M)?M:O.jsx("span",{children:M}),Fn=qm(),Gr=Fn.direction==="rtl",[nr,zo]=S.useState(),[Pt,Yr]=S.useState(null),vn=S.useRef(!1),Vn=V||P,Xe=S.useRef(),Jr=S.useRef(),yn=S.useRef(),gi=S.useRef(),[Oa,fe]=Hj({controlled:ue,default:!1,name:"Tooltip",state:"open"});let bn=Oa;const fc=$j(F),vi=S.useRef(),pc=S.useCallback(()=>{vi.current!==void 0&&(document.body.style.WebkitUserSelect=vi.current,vi.current=void 0),clearTimeout(gi.current)},[]);S.useEffect(()=>()=>{clearTimeout(Xe.current),clearTimeout(Jr.current),clearTimeout(yn.current),pc()},[pc]);const Rx=ke=>{clearTimeout(u1),Mf=!0,fe(!0),ie&&!bn&&ie(ke)},ef=Ws(ke=>{clearTimeout(u1),u1=setTimeout(()=>{Mf=!1},800+Y),fe(!1),Ne&&bn&&Ne(ke),clearTimeout(Xe.current),Xe.current=setTimeout(()=>{vn.current=!1},Fn.transitions.duration.shortest)}),eg=ke=>{vn.current&&ke.type!=="touchstart"||(nr&&nr.removeAttribute("title"),clearTimeout(Jr.current),clearTimeout(yn.current),L||Mf&&q?Jr.current=setTimeout(()=>{Rx(ke)},Mf?q:L):Rx(ke))},Px=ke=>{clearTimeout(Jr.current),clearTimeout(yn.current),yn.current=setTimeout(()=>{ef(ke)},Y)},{isFocusVisibleRef:zx,onBlur:YO,onFocus:JO,ref:XO}=zT(),[,Lx]=S.useState(!1),Ix=ke=>{YO(ke),zx.current===!1&&(Lx(!1),Px(ke))},Dx=ke=>{nr||zo(ke.currentTarget),JO(ke),zx.current===!0&&(Lx(!0),eg(ke))},$x=ke=>{vn.current=!0;const Xr=Ke.props;Xr.onTouchStart&&Xr.onTouchStart(ke)},Hx=eg,Bx=Px,QO=ke=>{$x(ke),clearTimeout(yn.current),clearTimeout(Xe.current),pc(),vi.current=document.body.style.WebkitUserSelect,document.body.style.WebkitUserSelect="none",gi.current=setTimeout(()=>{document.body.style.WebkitUserSelect=vi.current,eg(ke)},A)},ZO=ke=>{Ke.props.onTouchEnd&&Ke.props.onTouchEnd(ke),pc(),clearTimeout(yn.current),yn.current=setTimeout(()=>{ef(ke)},J)};S.useEffect(()=>{if(!bn)return;function ke(Xr){(Xr.key==="Escape"||Xr.key==="Esc")&&ef(Xr)}return document.addEventListener("keydown",ke),()=>{document.removeEventListener("keydown",ke)}},[ef,bn]);const e_=Ur(Ke.ref,XO,zo,r);!rt&&rt!==0&&(bn=!1);const tg=S.useRef(),t_=ke=>{const Xr=Ke.props;Xr.onMouseMove&&Xr.onMouseMove(ke),Rc={x:ke.clientX,y:ke.clientY},tg.current&&tg.current.update()},hc={},rg=typeof rt=="string";N?(hc.title=!bn&&rg&&!D?rt:null,hc["aria-describedby"]=bn?fc:null):(hc["aria-label"]=rg?rt:null,hc["aria-labelledby"]=bn&&!rg?fc:null);const jn=_({},hc,De,Ke.props,{className:Ce(De.className,Ke.props.className),onTouchStart:$x,ref:e_},P?{onMouseMove:t_}:{}),mc={};j||(jn.onTouchStart=QO,jn.onTouchEnd=ZO),D||(jn.onMouseOver=Tf(Hx,jn.onMouseOver),jn.onMouseLeave=Tf(Bx,jn.onMouseLeave),Vn||(mc.onMouseOver=Hx,mc.onMouseLeave=Bx)),z||(jn.onFocus=Tf(Dx,jn.onFocus),jn.onBlur=Tf(Ix,jn.onBlur),Vn||(mc.onFocus=Dx,mc.onBlur=Ix));const r_=S.useMemo(()=>{var ke;let Xr=[{name:"arrow",enabled:!!Pt,options:{element:Pt,padding:4}}];return(ke=Me.popperOptions)!=null&&ke.modifiers&&(Xr=Xr.concat(Me.popperOptions.modifiers)),_({},Me.popperOptions,{modifiers:Xr})},[Pt,Me]),gc=_({},w,{isRtl:Gr,arrow:E,disableInteractive:Vn,placement:de,PopperComponentProp:me,touch:vn.current}),ng=xX(gc),Fx=(n=(o=ft.popper)!=null?o:C.Popper)!=null?n:kX,Vx=(i=(s=(a=ft.transition)!=null?a:C.Transition)!=null?s:Or)!=null?i:av,jx=(l=(c=ft.tooltip)!=null?c:C.Tooltip)!=null?l:wX,Ux=(u=(d=ft.arrow)!=null?d:C.Arrow)!=null?u:SX,n_=uu(Fx,_({},Me,(f=Se.popper)!=null?f:T.popper,{className:Ce(ng.popper,Me==null?void 0:Me.className,(p=(h=Se.popper)!=null?h:T.popper)==null?void 0:p.className)}),gc),o_=uu(Vx,_({},he,(m=Se.transition)!=null?m:T.transition),gc),i_=uu(jx,_({},(b=Se.tooltip)!=null?b:T.tooltip,{className:Ce(ng.tooltip,(v=(g=Se.tooltip)!=null?g:T.tooltip)==null?void 0:v.className)}),gc),s_=uu(Ux,_({},(y=Se.arrow)!=null?y:T.arrow,{className:Ce(ng.arrow,(x=(k=Se.arrow)!=null?k:T.arrow)==null?void 0:x.className)}),gc);return O.jsxs(S.Fragment,{children:[S.cloneElement(Ke,jn),O.jsx(Fx,_({as:me??Lb,placement:de,anchorEl:P?{getBoundingClientRect:()=>({top:Rc.y,left:Rc.x,right:Rc.x,bottom:Rc.y,width:0,height:0})}:nr,popperRef:tg,open:nr?bn:!1,id:fc,transition:!0},mc,n_,{popperOptions:r_,children:({TransitionProps:ke})=>O.jsx(Vx,_({timeout:Fn.transitions.duration.shorter},ke,o_,{children:O.jsxs(jx,_({},i_,{children:[rt,E?O.jsx(Ux,_({},s_,{ref:Yr})):null]}))}))}))]})}),N3=EX;function CX(e){return Vt("MuiToggleButton",e)}const MX=jt("MuiToggleButton",["root","disabled","selected","standard","primary","secondary","sizeSmall","sizeMedium","sizeLarge"]),HS=MX,TX=["children","className","color","disabled","disableFocusRipple","fullWidth","onChange","onClick","selected","size","value"],OX=e=>{const{classes:t,fullWidth:r,selected:n,disabled:o,size:i,color:s}=e,a={root:["root",n&&"selected",o&&"disabled",r&&"fullWidth",`size${Fe(i)}`,s]};return rr(a,CX,t)},_X=Je(Tb,{name:"MuiToggleButton",slot:"Root",overridesResolver:(e,t)=>{const{ownerState:r}=e;return[t.root,t[`size${Fe(r.size)}`]]}})(({theme:e,ownerState:t})=>{let r=t.color==="standard"?e.palette.text.primary:e.palette[t.color].main,n;return e.vars&&(r=t.color==="standard"?e.vars.palette.text.primary:e.vars.palette[t.color].main,n=t.color==="standard"?e.vars.palette.text.primaryChannel:e.vars.palette[t.color].mainChannel),_({},e.typography.button,{borderRadius:(e.vars||e).shape.borderRadius,padding:11,border:`1px solid ${(e.vars||e).palette.divider}`,color:(e.vars||e).palette.action.active},t.fullWidth&&{width:"100%"},{[`&.${HS.disabled}`]:{color:(e.vars||e).palette.action.disabled,border:`1px solid ${(e.vars||e).palette.action.disabledBackground}`},"&:hover":{textDecoration:"none",backgroundColor:e.vars?`rgba(${e.vars.palette.text.primaryChannel} / ${e.vars.palette.action.hoverOpacity})`:Lr(e.palette.text.primary,e.palette.action.hoverOpacity),"@media (hover: none)":{backgroundColor:"transparent"}},[`&.${HS.selected}`]:{color:r,backgroundColor:e.vars?`rgba(${n} / ${e.vars.palette.action.selectedOpacity})`:Lr(r,e.palette.action.selectedOpacity),"&:hover":{backgroundColor:e.vars?`rgba(${n} / calc(${e.vars.palette.action.selectedOpacity} + ${e.vars.palette.action.hoverOpacity}))`:Lr(r,e.palette.action.selectedOpacity+e.palette.action.hoverOpacity),"@media (hover: none)":{backgroundColor:e.vars?`rgba(${n} / ${e.vars.palette.action.selectedOpacity})`:Lr(r,e.palette.action.selectedOpacity)}}}},t.size==="small"&&{padding:7,fontSize:e.typography.pxToRem(13)},t.size==="large"&&{padding:15,fontSize:e.typography.pxToRem(15)})}),AX=S.forwardRef(function(t,r){const n=Wt({props:t,name:"MuiToggleButton"}),{children:o,className:i,color:s="standard",disabled:a=!1,disableFocusRipple:l=!1,fullWidth:c=!1,onChange:u,onClick:d,selected:f,size:p="medium",value:h}=n,m=ve(n,TX),b=_({},n,{color:s,disabled:a,disableFocusRipple:l,fullWidth:c,size:p}),v=OX(b),g=y=>{d&&(d(y,h),y.defaultPrevented)||u&&u(y,h)};return O.jsx(_X,_({className:Ce(v.root,i),disabled:a,focusRipple:!l,ref:r,onClick:g,onChange:u,value:h,ownerState:b,"aria-pressed":f},m,{children:o}))}),NX=AX;var RX=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M5 15v2c0 1.054.95 2 2 2h3v2H7a4 4 0 0 1-4-4v-2h2zm13-5l4.4 11h-2.155l-1.201-3h-4.09l-1.199 3h-2.154L16 10h2zm-1 2.885L15.753 16h2.492L17 12.885zM3 3h6a3 3 0 0 1 2.235 5A3 3 0 0 1 9 13H3V3zm6 6H5v2h4a1 1 0 0 0 0-2zm8-6a4 4 0 0 1 4 4v2h-2V7a2 2 0 0 0-2-2h-3V3h3zM9 5H5v2h4a1 1 0 1 0 0-2z"}}],PX=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"}}],zX=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"}}],LX=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{fillRule:"nonzero",d:"M12.866 3l9.526 16.5a1 1 0 0 1-.866 1.5H2.474a1 1 0 0 1-.866-1.5L11.134 3a1 1 0 0 1 1.732 0zm-8.66 16h15.588L12 5.5 4.206 19zM11 16h2v2h-2v-2zm0-7h2v5h-2V9z"}}],IX=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M3 19h18v2H3v-2zm5-6h3l-4 4-4-4h3V3h2v10zm10 0h3l-4 4-4-4h3V3h2v10z"}}],DX=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M3 4h18v2H3V4zm2 15h14v2H5v-2zm-2-5h18v2H3v-2zm2-5h14v2H5V9z"}}],$X=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M3 4h18v2H3V4zm0 15h18v2H3v-2zm0-5h18v2H3v-2zm0-5h18v2H3V9z"}}],HX=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M3 4h18v2H3V4zm0 15h14v2H3v-2zm0-5h18v2H3v-2zm0-5h14v2H3V9z"}}],BX=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M3 4h18v2H3V4zm4 15h14v2H7v-2zm-4-5h18v2H3v-2zm4-5h14v2H7V9z"}}],FX=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M3 3h18v2H3V3zm5 8v10H6V11H3l4-4 4 4H8zm10 0v10h-2V11h-3l4-4 4 4h-3z"}}],VX=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M3 11h18v2H3v-2zm15 7v3h-2v-3h-3l4-4 4 4h-3zM8 18v3H6v-3H3l4-4 4 4H8zM18 6h3l-4 4-4-4h3V3h2v3zM8 6h3l-4 4-4-4h3V3h2v3z"}}],jX=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M6.75 2.5A4.25 4.25 0 0 1 11 6.75V11H6.75a4.25 4.25 0 1 1 0-8.5zM9 9V6.75A2.25 2.25 0 1 0 6.75 9H9zm-2.25 4H11v4.25A4.25 4.25 0 1 1 6.75 13zm0 2A2.25 2.25 0 1 0 9 17.25V15H6.75zm10.5-12.5a4.25 4.25 0 1 1 0 8.5H13V6.75a4.25 4.25 0 0 1 4.25-4.25zm0 6.5A2.25 2.25 0 1 0 15 6.75V9h2.25zM13 13h4.25A4.25 4.25 0 1 1 13 17.25V13zm2 2v2.25A2.25 2.25 0 1 0 17.25 15H15z"}}],UX=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M12 16l-6-6h12z"}}],WX=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M8 7v4L2 6l6-5v4h5a8 8 0 1 1 0 16H4v-2h9a6 6 0 1 0 0-12H8z"}}],KX=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M16 7h-5a6 6 0 1 0 0 12h9v2h-9a8 8 0 1 1 0-16h5V1l6 5-6 5V7z"}}],qX=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M8 12l6-6v12z"}}],GX=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M16 12l-6 6V6z"}}],YX=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M12 8l6 6H6z"}}],JX=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M13 3v7.267l6.294-3.633 1 1.732-6.293 3.633 6.293 3.635-1 1.732L13 13.732V21h-2v-7.268l-6.294 3.634-1-1.732L9.999 12 3.706 8.366l1-1.732L11 10.267V3z"}}],XX=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M14.828 7.757l-5.656 5.657a1 1 0 1 0 1.414 1.414l5.657-5.656A3 3 0 1 0 12 4.929l-5.657 5.657a5 5 0 1 0 7.071 7.07L19.071 12l1.414 1.414-5.657 5.657a7 7 0 1 1-9.9-9.9l5.658-5.656a5 5 0 0 1 7.07 7.07L12 16.244A3 3 0 1 1 7.757 12l5.657-5.657 1.414 1.414z"}}],QX=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M8 11h4.5a2.5 2.5 0 1 0 0-5H8v5zm10 4.5a4.5 4.5 0 0 1-4.5 4.5H6V4h6.5a4.5 4.5 0 0 1 3.256 7.606A4.498 4.498 0 0 1 18 15.5zM8 13v5h5.5a2.5 2.5 0 1 0 0-5H8z"}}],ZX=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M4 18v-3.7a1.5 1.5 0 0 0-1.5-1.5H2v-1.6h.5A1.5 1.5 0 0 0 4 9.7V6a3 3 0 0 1 3-3h1v2H7a1 1 0 0 0-1 1v4.1A2 2 0 0 1 4.626 12 2 2 0 0 1 6 13.9V18a1 1 0 0 0 1 1h1v2H7a3 3 0 0 1-3-3zm16-3.7V18a3 3 0 0 1-3 3h-1v-2h1a1 1 0 0 0 1-1v-4.1a2 2 0 0 1 1.374-1.9A2 2 0 0 1 18 10.1V6a1 1 0 0 0-1-1h-1V3h1a3 3 0 0 1 3 3v3.7a1.5 1.5 0 0 0 1.5 1.5h.5v1.6h-.5a1.5 1.5 0 0 0-1.5 1.5z"}}],eQ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M14 3c.552 0 1 .448 1 1v5h5c.552 0 1 .448 1 1v10c0 .552-.448 1-1 1H10c-.552 0-1-.448-1-1v-5H4c-.552 0-1-.448-1-1V4c0-.552.448-1 1-1h10zm-1 2H5v8h8V5z"}}],tQ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M11 3c.552 0 1 .448 1 1v2h5c.552 0 1 .448 1 1v5h2c.552 0 1 .448 1 1v7c0 .552-.448 1-1 1h-7c-.552 0-1-.448-1-1v-2H7c-.552 0-1-.448-1-1v-5H4c-.552 0-1-.448-1-1V4c0-.552.448-1 1-1h7zm5 5H8v8h8V8z"}}],rQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M14 3v2H4v13.385L5.763 17H20v-7h2v8a1 1 0 0 1-1 1H6.455L2 22.5V4a1 1 0 0 1 1-1h11zm5 0V0h2v3h3v2h-3v3h-2V5h-3V3h3z"}}],nQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm-.997-4L6.76 11.757l1.414-1.414 2.829 2.829 5.656-5.657 1.415 1.414L11.003 16z"}}],oQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{fillRule:"nonzero",d:"M7 7V3a1 1 0 0 1 1-1h13a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-4v3.993c0 .556-.449 1.007-1.007 1.007H3.007A1.006 1.006 0 0 1 2 20.993l.003-12.986C2.003 7.451 2.452 7 3.01 7H7zm2 0h6.993C16.549 7 17 7.449 17 8.007V15h3V4H9v3zm6 2H4.003L4 20h11V9zm-6.497 9l-3.536-3.536 1.414-1.414 2.122 2.122 4.242-4.243 1.414 1.414L8.503 18z"}}],iQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M6 4v4h12V4h2.007c.548 0 .993.445.993.993v16.014a.994.994 0 0 1-.993.993H3.993A.994.994 0 0 1 3 21.007V4.993C3 4.445 3.445 4 3.993 4H6zm2-2h8v4H8V2z"}}],sQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M7 4V2h10v2h3.007c.548 0 .993.445.993.993v16.014a.994.994 0 0 1-.993.993H3.993A.994.994 0 0 1 3 21.007V4.993C3 4.445 3.445 4 3.993 4H7zm0 2H5v14h14V6h-2v2H7V6zm2-2v2h6V4H9z"}}],aQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm0-9.414l2.828-2.829 1.415 1.415L13.414 12l2.829 2.828-1.415 1.415L12 13.414l-2.828 2.829-1.415-1.415L10.586 12 7.757 9.172l1.415-1.415L12 10.586z"}}],lQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"}}],cQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"}}],uQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M23 12l-7.071 7.071-1.414-1.414L20.172 12l-5.657-5.657 1.414-1.414L23 12zM3.828 12l5.657 5.657-1.414 1.414L1 12l7.071-7.071 1.414 1.414L3.828 12z"}}],dQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M16.95 8.464l1.414-1.414 4.95 4.95-4.95 4.95-1.414-1.414L20.485 12 16.95 8.464zm-9.9 0L3.515 12l3.535 3.536-1.414 1.414L.686 12l4.95-4.95L7.05 8.464z"}}],fQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M17 6h5v2h-2v13a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V8H2V6h5V3a1 1 0 0 1 1-1h8a1 1 0 0 1 1 1v3zm-8 5v6h2v-6H9zm4 0v6h2v-6h-2zM9 4v2h6V4H9z"}}],pQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M17 6h5v2h-2v13a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V8H2V6h5V3a1 1 0 0 1 1-1h8a1 1 0 0 1 1 1v3zm1 2H6v12h12V8zm-9 3h2v6H9v-6zm4 0h2v6h-2v-6zM9 4v2h6V4H9z"}}],hQ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M12 3c.552 0 1 .448 1 1v8c.835-.628 1.874-1 3-1 2.761 0 5 2.239 5 5s-2.239 5-5 5c-1.032 0-1.99-.313-2.787-.848L13 20c0 .552-.448 1-1 1H6c-.552 0-1-.448-1-1V4c0-.552.448-1 1-1h6zm-1 2H7v14h4V5zm8 10h-6v2h6v-2z"}}],mQ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M20 5c.552 0 1 .448 1 1v6c0 .552-.448 1-1 1 .628.835 1 1.874 1 3 0 2.761-2.239 5-5 5s-5-2.239-5-5c0-1.126.372-2.165 1-3H4c-.552 0-1-.448-1-1V6c0-.552.448-1 1-1h16zm-7 10v2h6v-2h-6zm6-8H5v4h14V7z"}}],gQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M4.583 17.321C3.553 16.227 3 15 3 13.011c0-3.5 2.457-6.637 6.03-8.188l.893 1.378c-3.335 1.804-3.987 4.145-4.247 5.621.537-.278 1.24-.375 1.929-.311 1.804.167 3.226 1.648 3.226 3.489a3.5 3.5 0 0 1-3.5 3.5c-1.073 0-2.099-.49-2.748-1.179zm10 0C13.553 16.227 13 15 13 13.011c0-3.5 2.457-6.637 6.03-8.188l.893 1.378c-3.335 1.804-3.987 4.145-4.247 5.621.537-.278 1.24-.375 1.929-.311 1.804.167 3.226 1.648 3.226 3.489a3.5 3.5 0 0 1-3.5 3.5c-1.073 0-2.099-.49-2.748-1.179z"}}],vQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M19.417 6.679C20.447 7.773 21 9 21 10.989c0 3.5-2.457 6.637-6.03 8.188l-.893-1.378c3.335-1.804 3.987-4.145 4.247-5.621-.537.278-1.24.375-1.929.311-1.804-.167-3.226-1.648-3.226-3.489a3.5 3.5 0 0 1 3.5-3.5c1.073 0 2.099.49 2.748 1.179zm-10 0C10.447 7.773 11 9 11 10.989c0 3.5-2.457 6.637-6.03 8.188l-.893-1.378c3.335-1.804 3.987-4.145 4.247-5.621-.537.278-1.24.375-1.929.311C4.591 12.322 3.17 10.841 3.17 9a3.5 3.5 0 0 1 3.5-3.5c1.073 0 2.099.49 2.748 1.179z"}}],yQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M4 19h16v-7h2v8a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1v-8h2v7zM14 9h5l-7 7-7-7h5V3h4v6z"}}],bQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{fillRule:"nonzero",d:"M16 13l6.964 4.062-2.973.85 2.125 3.681-1.732 1-2.125-3.68-2.223 2.15L16 13zm-2-7h2v2h5a1 1 0 0 1 1 1v4h-2v-3H10v10h4v2H9a1 1 0 0 1-1-1v-5H6v-2h2V9a1 1 0 0 1 1-1h5V6zM4 14v2H2v-2h2zm0-4v2H2v-2h2zm0-4v2H2V6h2zm0-4v2H2V2h2zm4 0v2H6V2h2zm4 0v2h-2V2h2zm4 0v2h-2V2h2z"}}],xQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M12 19a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3zm-5.5 0a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3zm11 0a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3zM13 2v2h6v2h-1.968a18.222 18.222 0 0 1-3.621 6.302 14.685 14.685 0 0 0 5.327 3.042l-.536 1.93A16.685 16.685 0 0 1 12 13.726a16.696 16.696 0 0 1-6.202 3.547l-.536-1.929a14.7 14.7 0 0 0 5.327-3.042 18.077 18.077 0 0 1-2.822-4.3h2.24A16.031 16.031 0 0 0 12 10.876a16.168 16.168 0 0 0 2.91-4.876L5 6V4h6V2h2z"}}],kQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M12 19a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3zm-5.5 0a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3zm11 0a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3zM18 3v2H8v4h9v2H8v4h10v2H6V3h12z"}}],wQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M14 10h2v.757a4.5 4.5 0 0 1 7 3.743V20h-2v-5.5c0-1.43-1.175-2.5-2.5-2.5S16 13.07 16 14.5V20h-2V10zm-2-6v2H4v5h8v2H4v5h8v2H2V4h10z"}}],SQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm-1-5h2v2h-2v-2zm0-8h2v6h-2V7z"}}],EQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M10 6v2H5v11h11v-5h2v6a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1h6zm11-3v9l-3.794-3.793-5.999 6-1.414-1.414 5.999-6L12 3h9z"}}],CQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M7 6V3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1h-3v3c0 .552-.45 1-1.007 1H4.007A1.001 1.001 0 0 1 3 21l.003-14c0-.552.45-1 1.007-1H7zM5.003 8L5 20h10V8H5.003zM9 6h8v10h2V4H9v2z"}}],MQ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M6 21.5c-1.933 0-3.5-1.567-3.5-3.5s1.567-3.5 3.5-3.5c1.585 0 2.924 1.054 3.355 2.5H15v-2h2V9.242L14.757 7H9V9H3V3h6v2h5.757L18 1.756 22.243 6 19 9.241V15L21 15v6h-6v-2H9.355c-.43 1.446-1.77 2.5-3.355 2.5zm0-5c-.828 0-1.5.672-1.5 1.5s.672 1.5 1.5 1.5 1.5-.672 1.5-1.5-.672-1.5-1.5-1.5zm13 .5h-2v2h2v-2zM18 4.586L16.586 6 18 7.414 19.414 6 18 4.586zM7 5H5v2h2V5z"}}],TQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M15.246 14H8.754l-1.6 4H5l6-15h2l6 15h-2.154l-1.6-4zm-.8-2L12 5.885 9.554 12h4.892zM3 20h18v2H3v-2z"}}],OQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M10 6v15H8V6H2V4h14v2h-6zm8 8v7h-2v-7h-3v-2h8v2h-3z"}}],_Q=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M11.246 15H4.754l-2 5H.6L7 4h2l6.4 16h-2.154l-2-5zm-.8-2L8 6.885 5.554 13h4.892zM21 12.535V12h2v8h-2v-.535a4 4 0 1 1 0-6.93zM19 18a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"}}],AQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M12.651 14.065L11.605 20H9.574l1.35-7.661-7.41-7.41L4.93 3.515 20.485 19.07l-1.414 1.414-6.42-6.42zm-.878-6.535l.27-1.53h-1.8l-2-2H20v2h-5.927L13.5 9.257 11.773 7.53z"}}],NQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z"}}],RQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M20 3h2v6h-2V5h-4V3h4zM4 3h4v2H4v4H2V3h2zm16 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z"}}],PQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M5 18l7.68-6L5 6V4h14v2H8.263L16 12l-7.737 6H19v2H5v-2z"}}],zQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M8 1v4H4v14h16V3h1.008c.548 0 .992.445.992.993v16.014a1 1 0 0 1-.992.993H2.992A.993.993 0 0 1 2 20.007V3.993A1 1 0 0 1 2.992 3H6V1h2zm4 7l4 4h-3v4h-2v-4H8l4-4zm6-7v4h-8V3h6V1h2z"}}],LQ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M13 20h-2v-7H4v7H2V4h2v7h7V4h2v16zm8-12v12h-2v-9.796l-2 .536V8.67L19.5 8H21z"}}],IQ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M4 4v7h7V4h2v16h-2v-7H4v7H2V4h2zm14.5 4c2.071 0 3.75 1.679 3.75 3.75 0 .857-.288 1.648-.772 2.28l-.148.18L18.034 18H22v2h-7v-1.556l4.82-5.546c.268-.307.43-.709.43-1.148 0-.966-.784-1.75-1.75-1.75-.918 0-1.671.707-1.744 1.606l-.006.144h-2C14.75 9.679 16.429 8 18.5 8z"}}],DQ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M22 8l-.002 2-2.505 2.883c1.59.435 2.757 1.89 2.757 3.617 0 2.071-1.679 3.75-3.75 3.75-1.826 0-3.347-1.305-3.682-3.033l1.964-.382c.156.806.866 1.415 1.718 1.415.966 0 1.75-.784 1.75-1.75s-.784-1.75-1.75-1.75c-.286 0-.556.069-.794.19l-1.307-1.547L19.35 10H15V8h7zM4 4v7h7V4h2v16h-2v-7H4v7H2V4h2z"}}],$Q=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M13 20h-2v-7H4v7H2V4h2v7h7V4h2v16zm9-12v8h1.5v2H22v2h-2v-2h-5.5v-1.34l5-8.66H22zm-2 3.133L17.19 16H20v-4.867z"}}],HQ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M22 8v2h-4.323l-.464 2.636c.33-.089.678-.136 1.037-.136 2.21 0 4 1.79 4 4s-1.79 4-4 4c-1.827 0-3.367-1.224-3.846-2.897l1.923-.551c.24.836 1.01 1.448 1.923 1.448 1.105 0 2-.895 2-2s-.895-2-2-2c-.63 0-1.193.292-1.56.748l-1.81-.904L16 8h6zM4 4v7h7V4h2v16h-2v-7H4v7H2V4h2z"}}],BQ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M21.097 8l-2.598 4.5c2.21 0 4.001 1.79 4.001 4s-1.79 4-4 4-4-1.79-4-4c0-.736.199-1.426.546-2.019L18.788 8h2.309zM4 4v7h7V4h2v16h-2v-7H4v7H2V4h2zm14.5 10.5c-1.105 0-2 .895-2 2s.895 2 2 2 2-.895 2-2-.895-2-2-2z"}}],FQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M7.784 14l.42-4H4V8h4.415l.525-5h2.011l-.525 5h3.989l.525-5h2.011l-.525 5H20v2h-3.784l-.42 4H20v2h-4.415l-.525 5h-2.011l.525-5H9.585l-.525 5H7.049l.525-5H4v-2h3.784zm2.011 0h3.99l.42-4h-3.99l-.42 4z"}}],VQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M17 11V4h2v17h-2v-8H7v8H5V4h2v7z"}}],jQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M21 15v3h3v2h-3v3h-2v-3h-3v-2h3v-3h2zm.008-12c.548 0 .992.445.992.993V13h-2V5H4v13.999L14 9l3 3v2.829l-3-3L6.827 19H14v2H2.992A.993.993 0 0 1 2 20.007V3.993A1 1 0 0 1 2.992 3h18.016zM8 7a2 2 0 1 1 0 4 2 2 0 0 1 0-4z"}}],UQ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M20 3c.552 0 1 .448 1 1v1.757l-2 2V5H5v8.1l4-4 4.328 4.329-1.415 1.413L9 11.93l-4 3.999V19h10.533l.708.001 1.329-1.33L18.9 19h.1v-2.758l2-2V20c0 .552-.448 1-1 1H4c-.55 0-1-.45-1-1V4c0-.552.448-1 1-1h16zm1.778 4.808l1.414 1.414L15.414 17l-1.416-.002.002-1.412 7.778-7.778zM15.5 7c.828 0 1.5.672 1.5 1.5s-.672 1.5-1.5 1.5S14 9.328 14 8.5 14.672 7 15.5 7z"}}],WQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M4.828 21l-.02.02-.021-.02H2.992A.993.993 0 0 1 2 20.007V3.993A1 1 0 0 1 2.992 3h18.016c.548 0 .992.445.992.993v16.014a1 1 0 0 1-.992.993H4.828zM20 15V5H4v14L14 9l6 6zm0 2.828l-6-6L6.828 19H20v-1.172zM8 11a2 2 0 1 1 0-4 2 2 0 0 1 0 4z"}}],KQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M3 4h18v2H3V4zm0 15h18v2H3v-2zm8-5h10v2H11v-2zm0-5h10v2H11V9zm-8 3.5L7 9v7l-4-3.5z"}}],qQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M3 4h18v2H3V4zm0 15h18v2H3v-2zm8-5h10v2H11v-2zm0-5h10v2H11V9zm-4 3.5L3 16V9l4 3.5z"}}],GQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zM11 7h2v2h-2V7zm0 4h2v6h-2v-6z"}}],YQ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M8 21v-2h3V5H8V3h8v2h-3v14h3v2H8zM18.05 7.05L23 12l-4.95 4.95-1.414-1.414L20.172 12l-3.536-3.536L18.05 7.05zm-12.1 0l1.414 1.414L3.828 12l3.536 3.536L5.95 16.95 1 12l4.95-4.95z"}}],JQ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M20 3c.552 0 1 .448 1 1v16c0 .552-.448 1-1 1h-6c-.552 0-1-.448-1-1V4c0-.552.448-1 1-1h6zm-1 2h-4v14h4V5zM6 7c2.761 0 5 2.239 5 5s-2.239 5-5 5-5-2.239-5-5 2.239-5 5-5zm1 2H5v1.999L3 11v2l2-.001V15h2v-2.001L9 13v-2l-2-.001V9z"}}],XQ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M10 3c.552 0 1 .448 1 1v16c0 .552-.448 1-1 1H4c-.552 0-1-.448-1-1V4c0-.552.448-1 1-1h6zM9 5H5v14h4V5zm9 2c2.761 0 5 2.239 5 5s-2.239 5-5 5-5-2.239-5-5 2.239-5 5-5zm1 2h-2v1.999L15 11v2l2-.001V15h2v-2.001L21 13v-2l-2-.001V9z"}}],QQ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M12 13c2.761 0 5 2.239 5 5s-2.239 5-5 5-5-2.239-5-5 2.239-5 5-5zm1 2h-2v1.999L9 17v2l2-.001V21h2v-2.001L15 19v-2l-2-.001V15zm7-12c.552 0 1 .448 1 1v6c0 .552-.448 1-1 1H4c-.552 0-1-.448-1-1V4c0-.552.448-1 1-1h16zM5 5v4h14V5H5z"}}],ZQ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M20 13c.552 0 1 .448 1 1v6c0 .552-.448 1-1 1H4c-.552 0-1-.448-1-1v-6c0-.552.448-1 1-1h16zm-1 2H5v4h14v-4zM12 1c2.761 0 5 2.239 5 5s-2.239 5-5 5-5-2.239-5-5 2.239-5 5-5zm1 2h-2v1.999L9 5v2l2-.001V9h2V6.999L15 7V5l-2-.001V3z"}}],eZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M15 20H7v-2h2.927l2.116-12H9V4h8v2h-2.927l-2.116 12H15z"}}],tZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{fillRule:"nonzero",d:"M11 5H5v14h6V5zm2 0v14h6V5h-6zM4 3h16a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z"}}],rZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M11 4h10v2H11V4zM6 7v4H4V7H1l4-4 4 4H6zm0 10h3l-4 4-4-4h3v-4h2v4zm5 1h10v2H11v-2zm-2-7h12v2H9v-2z"}}],nZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M17.657 14.828l-1.414-1.414L17.657 12A4 4 0 1 0 12 6.343l-1.414 1.414-1.414-1.414 1.414-1.414a6 6 0 0 1 8.485 8.485l-1.414 1.414zm-2.829 2.829l-1.414 1.414a6 6 0 1 1-8.485-8.485l1.414-1.414 1.414 1.414L6.343 12A4 4 0 1 0 12 17.657l1.414-1.414 1.414 1.414zm0-9.9l1.415 1.415-7.071 7.07-1.415-1.414 7.071-7.07z"}}],oZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M17.657 14.828l-1.414-1.414L17.657 12A4 4 0 1 0 12 6.343l-1.414 1.414-1.414-1.414 1.414-1.414a6 6 0 0 1 8.485 8.485l-1.414 1.414zm-2.829 2.829l-1.414 1.414a6 6 0 1 1-8.485-8.485l1.414-1.414 1.414 1.414L6.343 12A4 4 0 1 0 12 17.657l1.414-1.414 1.414 1.414zm0-9.9l1.415 1.415-7.071 7.07-1.415-1.414 7.071-7.07zM5.775 2.293l1.932-.518L8.742 5.64l-1.931.518-1.036-3.864zm9.483 16.068l1.931-.518 1.036 3.864-1.932.518-1.035-3.864zM2.293 5.775l3.864 1.036-.518 1.931-3.864-1.035.518-1.932zm16.068 9.483l3.864 1.035-.518 1.932-3.864-1.036.518-1.931z"}}],iZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M17 17h5v2h-3v3h-2v-5zM7 7H2V5h3V2h2v5zm11.364 8.536L16.95 14.12l1.414-1.414a5 5 0 1 0-7.071-7.071L9.879 7.05 8.464 5.636 9.88 4.222a7 7 0 0 1 9.9 9.9l-1.415 1.414zm-2.828 2.828l-1.415 1.414a7 7 0 0 1-9.9-9.9l1.415-1.414L7.05 9.88l-1.414 1.414a5 5 0 1 0 7.071 7.071l1.414-1.414 1.415 1.414zm-.708-10.607l1.415 1.415-7.071 7.07-1.415-1.414 7.071-7.07z"}}],sZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M18.364 15.536L16.95 14.12l1.414-1.414a5 5 0 1 0-7.071-7.071L9.879 7.05 8.464 5.636 9.88 4.222a7 7 0 0 1 9.9 9.9l-1.415 1.414zm-2.828 2.828l-1.415 1.414a7 7 0 0 1-9.9-9.9l1.415-1.414L7.05 9.88l-1.414 1.414a5 5 0 1 0 7.071 7.071l1.414-1.414 1.415 1.414zm-.708-10.607l1.415 1.415-7.071 7.07-1.415-1.414 7.071-7.07z"}}],aZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M11 4h10v2H11V4zm0 4h6v2h-6V8zm0 6h10v2H11v-2zm0 4h6v2h-6v-2zM3 4h6v6H3V4zm2 2v2h2V6H5zm-2 8h6v6H3v-6zm2 2v2h2v-2H5z"}}],lZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M8 4h13v2H8V4zm-5-.5h3v3H3v-3zm0 7h3v3H3v-3zm0 7h3v3H3v-3zM8 11h13v2H8v-2zm0 7h13v2H8v-2z"}}],cZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M8 4h13v2H8V4zM5 3v3h1v1H3V6h1V4H3V3h2zM3 14v-2.5h2V11H3v-1h3v2.5H4v.5h2v1H3zm2 5.5H3v-1h2V18H3v-1h3v4H3v-1h2v-.5zM8 11h13v2H8v-2zm0 7h13v2H8v-2z"}}],uZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M8 4h13v2H8V4zM4.5 6.5a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm0 7a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm0 6.9a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zM8 11h13v2H8v-2zm0 7h13v2H8v-2z"}}],dZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M15.243 4.515l-6.738 6.737-.707 2.121-1.04 1.041 2.828 2.829 1.04-1.041 2.122-.707 6.737-6.738-4.242-4.242zm6.364 3.535a1 1 0 0 1 0 1.414l-7.779 7.779-2.12.707-1.415 1.414a1 1 0 0 1-1.414 0l-4.243-4.243a1 1 0 0 1 0-1.414l1.414-1.414.707-2.121 7.779-7.779a1 1 0 0 1 1.414 0l5.657 5.657zm-6.364-.707l1.414 1.414-4.95 4.95-1.414-1.414 4.95-4.95zM4.283 16.89l2.828 2.829-1.414 1.414-4.243-1.414 2.828-2.829z"}}],fZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M3 3h18a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zm4 12.5v-4l2 2 2-2v4h2v-7h-2l-2 2-2-2H5v7h2zm11-3v-4h-2v4h-2l3 3 3-3h-2z"}}],pZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{fillRule:"nonzero",d:"M3 3h18a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zm1 2v14h16V5H4zm3 10.5H5v-7h2l2 2 2-2h2v7h-2v-4l-2 2-2-2v4zm11-3h2l-3 3-3-3h2v-4h2v4z"}}],hZ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M20 3c.552 0 1 .448 1 1v16c0 .552-.448 1-1 1H4c-.552 0-1-.448-1-1V4c0-.552.448-1 1-1h16zm-9 2H5v5.999h2V9l3 3-3 3v-2H5v6h6v-2h2v2h6v-6h-2v2l-3-3 3-3v1.999h2V5h-6v2h-2V5zm2 8v2h-2v-2h2zm0-4v2h-2V9h2z"}}],mZ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M21 20c0 .552-.448 1-1 1H4c-.552 0-1-.448-1-1V4c0-.552.448-1 1-1h16c.552 0 1 .448 1 1v16zm-2-9V5h-5.999v2H15l-3 3-3-3h2V5H5v6h2v2H5v6h6v-2H9l3-3 3 3h-1.999v2H19v-6h-2v-2h2zm-8 2H9v-2h2v2zm4 0h-2v-2h2v2z"}}],gZ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M18 3c1.657 0 3 1.343 3 3s-1.343 3-3 3h-3c-1.306 0-2.417-.834-2.829-2H11c-1.1 0-2 .9-2 2v.171c1.166.412 2 1.523 2 2.829 0 1.306-.834 2.417-2 2.829V15c0 1.1.9 2 2 2h1.17c.412-1.165 1.524-2 2.83-2h3c1.657 0 3 1.343 3 3s-1.343 3-3 3h-3c-1.306 0-2.417-.834-2.829-2H11c-2.21 0-4-1.79-4-4H5c-1.657 0-3-1.343-3-3s1.343-3 3-3h2c0-2.21 1.79-4 4-4h1.17c.412-1.165 1.524-2 2.83-2h3zm0 14h-3c-.552 0-1 .448-1 1s.448 1 1 1h3c.552 0 1-.448 1-1s-.448-1-1-1zM8 11H5c-.552 0-1 .448-1 1s.448 1 1 1h3c.552 0 1-.448 1-1s-.448-1-1-1zm10-6h-3c-.552 0-1 .448-1 1s.448 1 1 1h3c.552 0 1-.448 1-1s-.448-1-1-1z"}}],vZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M5 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm14 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-7 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"}}],yZ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M10 2c.552 0 1 .448 1 1v4c0 .552-.448 1-1 1H8v2h5V9c0-.552.448-1 1-1h6c.552 0 1 .448 1 1v4c0 .552-.448 1-1 1h-6c-.552 0-1-.448-1-1v-1H8v6h5v-1c0-.552.448-1 1-1h6c.552 0 1 .448 1 1v4c0 .552-.448 1-1 1h-6c-.552 0-1-.448-1-1v-1H7c-.552 0-1-.448-1-1V8H4c-.552 0-1-.448-1-1V3c0-.552.448-1 1-1h6zm9 16h-4v2h4v-2zm0-8h-4v2h4v-2zM9 4H5v2h4V4z"}}],bZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M12 1.5c1.321 0 2.484.348 3.447.994.963.645 1.726 1.588 2.249 2.778.522 1.19.804 2.625.804 4.257v4.942c0 1.632-.282 3.068-.804 4.257-.523 1.19-1.286 2.133-2.25 2.778-.962.646-2.125.994-3.446.994-1.321 0-2.484-.348-3.447-.994-.963-.645-1.726-1.588-2.249-2.778-.522-1.19-.804-2.625-.804-4.257V9.529c0-1.632.282-3.068.804-4.257.523-1.19 1.286-2.133 2.25-2.778C9.515 1.848 10.678 1.5 12 1.5zm0 2c-.916 0-1.694.226-2.333.655-.637.427-1.158 1.07-1.532 1.92-.412.94-.635 2.108-.635 3.454v4.942c0 1.346.223 2.514.635 3.453.374.851.895 1.494 1.532 1.921.639.429 1.417.655 2.333.655.916 0 1.694-.226 2.333-.655.637-.427 1.158-1.07 1.532-1.92.412-.94.635-2.108.635-3.454V9.529c0-1.346-.223-2.514-.635-3.453-.374-.851-.895-1.494-1.532-1.921C13.694 3.726 12.916 3.5 12 3.5z"}}],xZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M14 1.5V22h-2V3.704L7.5 4.91V2.839l5-1.339z"}}],kZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M16 7.5a4 4 0 1 0-8 0H6a6 6 0 1 1 10.663 3.776l-7.32 8.723L18 20v2H6v-1.127l9.064-10.802A3.982 3.982 0 0 0 16 7.5z"}}],wZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M18 2v1.362L12.809 9.55a6.501 6.501 0 1 1-7.116 8.028l1.94-.486A4.502 4.502 0 0 0 16.5 16a4.5 4.5 0 0 0-6.505-4.03l-.228.122-.69-1.207L14.855 4 6.5 4V2H18z"}}],SZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M16 1.5V16h3v2h-3v4h-2v-4H4v-1.102L14 1.5h2zM14 16V5.171L6.968 16H14z"}}],EZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M18 2v2H9.3l-.677 6.445a6.5 6.5 0 1 1-2.93 7.133l1.94-.486A4.502 4.502 0 0 0 16.5 16a4.5 4.5 0 0 0-4.5-4.5c-2.022 0-3.278.639-3.96 1.53l-1.575-1.182L7.5 2H18z"}}],CZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M14.886 2l-4.438 7.686A6.5 6.5 0 1 1 6.4 12.7L12.576 2h2.31zM12 11.5a4.5 4.5 0 1 0 0 9 4.5 4.5 0 0 0 0-9z"}}],MZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M19 2v1.5L10.763 22H8.574l8.013-18H6V2z"}}],TZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M12 1.5a5.5 5.5 0 0 1 3.352 9.86C17.24 12.41 18.5 14.32 18.5 16.5c0 3.314-2.91 6-6.5 6s-6.5-2.686-6.5-6c0-2.181 1.261-4.09 3.147-5.141A5.5 5.5 0 0 1 12 1.5zm0 11c-2.52 0-4.5 1.828-4.5 4 0 2.172 1.98 4 4.5 4s4.5-1.828 4.5-4c0-2.172-1.98-4-4.5-4zm0-9a3.5 3.5 0 1 0 0 7 3.5 3.5 0 0 0 0-7z"}}],OZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M12 1.5a6.5 6.5 0 0 1 5.619 9.77l-6.196 10.729H9.114l4.439-7.686A6.5 6.5 0 1 1 12 1.5zm0 2a4.5 4.5 0 1 0 0 9 4.5 4.5 0 0 0 0-9z"}}],_Z=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{fillRule:"nonzero",d:"M14 20v-2.157c1.863-1.192 3.5-3.875 3.5-6.959 0-3.073-2-6.029-5.5-6.029s-5.5 2.956-5.5 6.03c0 3.083 1.637 5.766 3.5 6.958V20H3v-2h4.76C5.666 16.505 4 13.989 4 10.884 4 6.247 7.5 3 12 3s8 3.247 8 7.884c0 3.105-1.666 5.621-3.76 7.116H21v2h-7z"}}],AZ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M15 3c.552 0 1 .448 1 1v4c0 .552-.448 1-1 1h-2v2h4c.552 0 1 .448 1 1v3h2c.552 0 1 .448 1 1v4c0 .552-.448 1-1 1h-6c-.552 0-1-.448-1-1v-4c0-.552.448-1 1-1h2v-2H8v2h2c.552 0 1 .448 1 1v4c0 .552-.448 1-1 1H4c-.552 0-1-.448-1-1v-4c0-.552.448-1 1-1h2v-3c0-.552.448-1 1-1h4V9H9c-.552 0-1-.448-1-1V4c0-.552.448-1 1-1h6zM9 17H5v2h4v-2zm10 0h-4v2h4v-2zM14 5h-4v2h4V5z"}}],NZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M17 21v-4H7v4H5v-5a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v5h-2zM7 3v4h10V3h2v5a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1V3h2zM2 9l4 3-4 3V9zm20 0v6l-4-3 4-3z"}}],RZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M12 6v15h-2v-5a6 6 0 1 1 0-12h10v2h-3v15h-2V6h-3zm-2 0a4 4 0 1 0 0 8V6z"}}],PZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M12.9 6.858l4.242 4.243L7.242 21H3v-4.243l9.9-9.9zm1.414-1.414l2.121-2.122a1 1 0 0 1 1.414 0l2.829 2.829a1 1 0 0 1 0 1.414l-2.122 2.121-4.242-4.242z"}}],zZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M15.728 9.686l-1.414-1.414L5 17.586V19h1.414l9.314-9.314zm1.414-1.414l1.414-1.414-1.414-1.414-1.414 1.414 1.414 1.414zM7.242 21H3v-4.243L16.435 3.322a1 1 0 0 1 1.414 0l2.829 2.829a1 1 0 0 1 0 1.414L7.243 21z"}}],LZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M17.934 3.036l1.732 1L18.531 6H21v2h-2v4h2v2h-2v7h-2v-7h-3.084c-.325 2.862-1.564 5.394-3.37 7.193l-1.562-1.27c1.52-1.438 2.596-3.522 2.917-5.922L10 14v-2l2-.001V8h-2V6h2.467l-1.133-1.964 1.732-1L14.777 6h1.444l1.713-2.964zM5 13.803l-2 .536v-2.071l2-.536V8H3V6h2V3h2v3h2v2H7v3.197l2-.536v2.07l-2 .536V18.5A2.5 2.5 0 0 1 4.5 21H3v-2h1.5a.5.5 0 0 0 .492-.41L5 18.5v-4.697zM17 8h-3v4h3V8z"}}],IZ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M12 19c.828 0 1.5.672 1.5 1.5S12.828 22 12 22s-1.5-.672-1.5-1.5.672-1.5 1.5-1.5zm0-17c3.314 0 6 2.686 6 6 0 2.165-.753 3.29-2.674 4.923C13.399 14.56 13 15.297 13 17h-2c0-2.474.787-3.695 3.031-5.601C15.548 10.11 16 9.434 16 8c0-2.21-1.79-4-4-4S8 5.79 8 8v1H6V8c0-3.314 2.686-6 6-6z"}}],DZ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M21 19v2h-2v-2h2zm-4 0v2h-2v-2h2zm-4 0v2h-2v-2h2zm-4 0v2H7v-2h2zm-4 0v2H3v-2h2zm16-4v2h-2v-2h2zM5 15v2H3v-2h2zm0-4v2H3v-2h2zm11-8c2.687 0 4.882 2.124 4.995 4.783L21 8v5h-2V8c0-1.591-1.255-2.903-2.824-2.995L16 5h-5V3h5zM5 7v2H3V7h2zm0-4v2H3V3h2zm4 0v2H7V3h2z"}}],$Z=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M9.683 7.562L12 9.88l6.374-6.375a2 2 0 0 1 2.829 0l.707.707L9.683 16.438a4 4 0 1 1-2.121-2.121L9.88 12 7.562 9.683a4 4 0 1 1 2.121-2.121zM6 8a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm0 12a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm9.535-6.587l6.375 6.376-.707.707a2 2 0 0 1-2.829 0l-4.96-4.961 2.12-2.122z"}}],HZ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M14 3c.552 0 1 .448 1 1v5h5c.552 0 1 .448 1 1v10c0 .552-.448 1-1 1H10c-.552 0-1-.448-1-1v-5H4c-.552 0-1-.448-1-1V4c0-.552.448-1 1-1h10zm-1 2H5v8h4v-3c0-.552.448-1 1-1h3V5z"}}],BZ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M11 3c.552 0 1 .448 1 1v2h5c.552 0 1 .448 1 1v5h2c.552 0 1 .448 1 1v7c0 .552-.448 1-1 1h-7c-.552 0-1-.448-1-1v-2H7c-.552 0-1-.448-1-1v-5H4c-.552 0-1-.448-1-1V4c0-.552.448-1 1-1h7zm5 5h-4v3c0 .552-.448 1-1 1H8v4h4v-3c0-.552.448-1 1-1h3V8z"}}],FZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M2 11h2v2H2v-2zm4 0h12v2H6v-2zm14 0h2v2h-2v-2z"}}],VZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M9.583 17.321C8.553 16.227 8 15 8 13.011c0-3.5 2.457-6.637 6.03-8.188l.893 1.378c-3.335 1.804-3.987 4.145-4.247 5.621.537-.278 1.24-.375 1.929-.311 1.804.167 3.226 1.648 3.226 3.489a3.5 3.5 0 0 1-3.5 3.5c-1.073 0-2.099-.49-2.748-1.179z"}}],jZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M14.417 6.679C15.447 7.773 16 9 16 10.989c0 3.5-2.457 6.637-6.03 8.188l-.893-1.378c3.335-1.804 3.987-4.145 4.247-5.621-.537.278-1.24.375-1.929.311C9.591 12.322 8.17 10.841 8.17 9a3.5 3.5 0 0 1 3.5-3.5c1.073 0 2.099.49 2.748 1.179z"}}],UZ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M19 3l4 5h-3v12h-2V8h-3l4-5zm-5 15v2H3v-2h11zm0-7v2H3v-2h11zm-2-7v2H3V4h9z"}}],WZ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M20 4v12h3l-4 5-4-5h3V4h2zm-8 14v2H3v-2h9zm2-7v2H3v-2h11zm0-7v2H3V4h11z"}}],KZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M4 9v4h16V9h2v5a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V9h2z"}}],qZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{fillRule:"nonzero",d:"M17.5 2.5L23 12l-5.5 9.5h-11L1 12l5.5-9.5h11zm-1.153 2H7.653L3.311 12l4.342 7.5h8.694l4.342-7.5-4.342-7.5zM11 15h2v2h-2v-2zm0-8h2v6h-2V7z"}}],GZ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M20 3c.552 0 1 .448 1 1v16c0 .552-.448 1-1 1H4c-.552 0-1-.448-1-1V4c0-.552.448-1 1-1h16zm-9 2H5v14h6v-4h2v4h6V5h-6v4h-2V5zm4 4l3 3-3 3v-2H9v2l-3-3 3-3v2h6V9z"}}],YZ=[{tag:"path",attr:{fill:"none",d:"M0 0H24V24H0z"}},{tag:"path",attr:{d:"M20 3c.552 0 1 .448 1 1v16c0 .552-.448 1-1 1H4c-.552 0-1-.448-1-1V4c0-.552.448-1 1-1h16zm-1 2H5v5.999L9 11v2H5v6h14v-6h-4v-2l4-.001V5zm-7 1l3 3h-2v6h2l-3 3-3-3h2V9H9l3-3z"}}],JZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M13 9h-2V6H5V4h14v2h-6v3zm0 6v5h-2v-5h2zM3 11h18v2H3v-2z"}}],XZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M17.154 14c.23.516.346 1.09.346 1.72 0 1.342-.524 2.392-1.571 3.147C14.88 19.622 13.433 20 11.586 20c-1.64 0-3.263-.381-4.87-1.144V16.6c1.52.877 3.075 1.316 4.666 1.316 2.551 0 3.83-.732 3.839-2.197a2.21 2.21 0 0 0-.648-1.603l-.12-.117H3v-2h18v2h-3.846zm-4.078-3H7.629a4.086 4.086 0 0 1-.481-.522C6.716 9.92 6.5 9.246 6.5 8.452c0-1.236.466-2.287 1.397-3.153C8.83 4.433 10.271 4 12.222 4c1.471 0 2.879.328 4.222.984v2.152c-1.2-.687-2.515-1.03-3.946-1.03-2.48 0-3.719.782-3.719 2.346 0 .42.218.786.654 1.099.436.313.974.562 1.613.75.62.18 1.297.414 2.03.699z"}}],QZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M11 6v13H9V6H3V4h14v2h-6zm8.55 10.58a.8.8 0 1 0-1.32-.36l-1.154.33A2.001 2.001 0 0 1 19 14a2 2 0 0 1 1.373 3.454L18.744 19H21v1h-4v-1l2.55-2.42z"}}],ZZ=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M5.596 4L10.5 9.928 15.404 4H18l-6.202 7.497L18 18.994V19h-2.59l-4.91-5.934L5.59 19H3v-.006l6.202-7.497L3 4h2.596zM21.55 16.58a.8.8 0 1 0-1.32-.36l-1.155.33A2.001 2.001 0 0 1 21 14a2 2 0 0 1 1.373 3.454L20.744 19H23v1h-4v-1l2.55-2.42z"}}],eee=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M5 11h14v2H5z"}}],tee=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M11 7v13H9V7H3V5h12v2h-4zm8.55-.42a.8.8 0 1 0-1.32-.36l-1.154.33A2.001 2.001 0 0 1 19 4a2 2 0 0 1 1.373 3.454L18.744 9H21v1h-4V9l2.55-2.42z"}}],ree=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M5.596 5l4.904 5.928L15.404 5H18l-6.202 7.497L18 19.994V20h-2.59l-4.91-5.934L5.59 20H3v-.006l6.202-7.497L3 5h2.596zM21.55 6.58a.8.8 0 1 0-1.32-.36l-1.155.33A2.001 2.001 0 0 1 21 4a2 2 0 0 1 1.373 3.454L20.744 9H23v1h-4V9l2.55-2.42z"}}],nee=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{fillRule:"nonzero",d:"M13 10v4h6v-4h-6zm-2 0H5v4h6v-4zm2 9h6v-3h-6v3zm-2 0v-3H5v3h6zm2-14v3h6V5h-6zm-2 0H5v3h6V5zM4 3h16a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z"}}],oee=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M4 8h16V5H4v3zm10 11v-9h-4v9h4zm2 0h4v-9h-4v9zm-8 0v-9H4v9h4zM3 3h18a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z"}}],iee=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M11 5v10H9v-4a4 4 0 1 1 0-8h8v2h-2v10h-2V5h-2zM9 5a2 2 0 1 0 0 4V5zm8 12v-2.5l4 3.5-4 3.5V19H5v-2h12z"}}],see=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M11 5v10H9v-4a4 4 0 1 1 0-8h8v2h-2v10h-2V5h-2zM9 5a2 2 0 1 0 0 4V5zM7 17h12v2H7v2.5L3 18l4-3.5V17z"}}],aee=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M7 17h10v-2.5l3.5 3.5-3.5 3.5V19H7v2.5L3.5 18 7 14.5V17zm6-11v9h-2V6H5V4h14v2h-6z"}}],lee=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M15 18h1.5a2.5 2.5 0 1 0 0-5H3v-2h13.5a4.5 4.5 0 1 1 0 9H15v2l-4-3 4-3v2zM3 4h18v2H3V4zm6 14v2H3v-2h6z"}}],cee=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M13 6v15h-2V6H5V4h14v2z"}}],uee=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M18.5 10l4.4 11h-2.155l-1.201-3h-4.09l-1.199 3h-2.154L16.5 10h2zM10 2v2h6v2h-1.968a18.222 18.222 0 0 1-3.62 6.301 14.864 14.864 0 0 0 2.336 1.707l-.751 1.878A17.015 17.015 0 0 1 9 13.725a16.676 16.676 0 0 1-6.201 3.548l-.536-1.929a14.7 14.7 0 0 0 5.327-3.042A18.078 18.078 0 0 1 4.767 8h2.24A16.032 16.032 0 0 0 9 10.877a16.165 16.165 0 0 0 2.91-4.876L2 6V4h6V2h2zm7.5 10.885L16.253 16h2.492L17.5 12.885z"}}],dee=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M5 15v2a2 2 0 0 0 1.85 1.995L7 19h3v2H7a4 4 0 0 1-4-4v-2h2zm13-5l4.4 11h-2.155l-1.201-3h-4.09l-1.199 3h-2.154L16 10h2zm-1 2.885L15.753 16h2.492L17 12.885zM8 2v2h4v7H8v3H6v-3H2V4h4V2h2zm9 1a4 4 0 0 1 4 4v2h-2V7a2 2 0 0 0-2-2h-3V3h3zM6 6H4v3h2V6zm4 0H8v3h2V6z"}}],fee=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M8 3v9a4 4 0 1 0 8 0V3h2v9a6 6 0 1 1-12 0V3h2zM4 20h16v2H4v-2z"}}],pee=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M4 19h16v-7h2v8a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1v-8h2v7zM14 9v6h-4V9H5l7-7 7 7h-5z"}}],hee=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M3 3.993C3 3.445 3.445 3 3.993 3h16.014c.548 0 .993.445.993.993v16.014a.994.994 0 0 1-.993.993H3.993A.994.994 0 0 1 3 20.007V3.993zM5 5v14h14V5H5zm5.622 3.415l4.879 3.252a.4.4 0 0 1 0 .666l-4.88 3.252a.4.4 0 0 1-.621-.332V8.747a.4.4 0 0 1 .622-.332z"}}],mee=[{tag:"path",attr:{fill:"none",d:"M0 0h24v24H0z"}},{tag:"path",attr:{d:"M3 21v-2h3.662l1.234-7H5v-2h3.249l.881-5H4V3h16v2h-8.839l-.882 5H18v9h3v2H3zm13-9H9.927l-1.235 7H16v-7z"}}];const gee=Object.freeze(Object.defineProperty({__proto__:null,ab:RX,addFill:PX,addLine:zX,alertLine:LX,alignBottom:IX,alignCenter:DX,alignJustify:$X,alignLeft:HX,alignRight:BX,alignTop:FX,alignVertically:VX,appsLine:jX,arrowDownSFill:UX,arrowGoBackFill:WX,arrowGoForwardFill:KX,arrowLeftSFill:qX,arrowRightSFill:GX,arrowUpSFill:YX,asterisk:JX,attachment2:XX,bold:QX,bracesLine:ZX,bringForward:eQ,bringToFront:tQ,chatNewLine:rQ,checkboxCircleLine:nQ,checkboxMultipleLine:oQ,clipboardFill:iQ,clipboardLine:sQ,closeCircleLine:aQ,closeFill:lQ,closeLine:cQ,codeLine:uQ,codeView:dQ,deleteBinFill:fQ,deleteBinLine:pQ,deleteColumn:hQ,deleteRow:mQ,doubleQuotesL:gQ,doubleQuotesR:vQ,download2Fill:yQ,dragDropLine:bQ,emphasis:kQ,emphasisCn:xQ,englishInput:wQ,errorWarningLine:SQ,externalLinkFill:EQ,fileCopyLine:CQ,flowChart:MQ,fontColor:TQ,fontSize:_Q,fontSize2:OQ,formatClear:AQ,fullscreenExitLine:NQ,fullscreenLine:RQ,functions:PQ,galleryUploadLine:zQ,h1:LQ,h2:IQ,h3:DQ,h4:$Q,h5:HQ,h6:BQ,hashtag:FQ,heading:VQ,imageAddLine:jQ,imageEditLine:UQ,imageLine:WQ,indentDecrease:KQ,indentIncrease:qQ,informationLine:GQ,inputCursorMove:YQ,insertColumnLeft:JQ,insertColumnRight:XQ,insertRowBottom:QQ,insertRowTop:ZQ,italic:eZ,layoutColumnLine:tZ,lineHeight:rZ,link:sZ,linkM:nZ,linkUnlink:iZ,linkUnlinkM:oZ,listCheck:lZ,listCheck2:aZ,listOrdered:cZ,listUnordered:uZ,markPenLine:dZ,markdownFill:fZ,markdownLine:pZ,mergeCellsHorizontal:hZ,mergeCellsVertical:mZ,mindMap:gZ,moreFill:vZ,nodeTree:yZ,number0:bZ,number1:xZ,number2:kZ,number3:wZ,number4:SZ,number5:EZ,number6:CZ,number7:MZ,number8:TZ,number9:OZ,omega:_Z,organizationChart:AZ,pageSeparator:NZ,paragraph:RZ,pencilFill:PZ,pencilLine:zZ,pinyinInput:LZ,questionMark:IZ,roundedCorner:DZ,scissorsFill:$Z,sendBackward:HZ,sendToBack:BZ,separator:FZ,singleQuotesL:VZ,singleQuotesR:jZ,sortAsc:UZ,sortDesc:WZ,space:KZ,spamLine:qZ,splitCellsHorizontal:GZ,splitCellsVertical:YZ,strikethrough:XZ,strikethrough2:JZ,subscript:ZZ,subscript2:QZ,subtractLine:eee,superscript:ree,superscript2:tee,table2:nee,tableLine:oee,text:cee,textDirectionL:iee,textDirectionR:see,textSpacing:aee,textWrap:lee,translate:dee,translate2:uee,underline:fee,upload2Fill:pee,videoLine:hee,wubiInput:mee},Symbol.toStringTag,{value:"Module"}));function vee(e,t=null){return function(r,n){let{$from:o,$to:i}=r.selection,s=o.blockRange(i),a=!1,l=s;if(!s)return!1;if(s.depth>=2&&o.node(s.depth-1).type.compatibleContent(e)&&s.startIndex==0){if(o.index(s.depth-1)==0)return!1;let u=r.doc.resolve(s.start-2);l=new ra(u,u,s.depth),s.endIndex=0;u--)i=R.from(r[u].type.create(r[u].attrs,i));e.step(new bt(t.start-(n?2:0),t.end,t.start,t.end,new K(i,0,0),r.length,!0));let s=0;for(let u=0;us.childCount>0&&s.firstChild.type==e);return i?r?n.node(i.depth-1).type==e?xee(t,r,e,i):kee(t,r,i):!0:!1}}function xee(e,t,r,n){let o=e.tr,i=n.end,s=n.$to.end(n.depth);im;h--)p-=o.child(h).nodeSize,n.delete(p-1,p+1);let i=n.doc.resolve(r.start),s=i.nodeAfter;if(n.mapping.map(r.end)!=r.start+i.nodeAfter.nodeSize)return!1;let a=r.startIndex==0,l=r.endIndex==o.childCount,c=i.node(-1),u=i.index(-1);if(!c.canReplace(u+(a?0:1),u+1,s.content.append(l?R.empty:R.from(o))))return!1;let d=i.pos,f=d+s.nodeSize;return n.step(new bt(d-(a?1:0),f+(l?1:0),d+1,f-1,new K((a?R.empty:R.from(o.copy(R.empty))).append(l?R.empty:R.from(o.copy(R.empty))),a?0:1,l?0:1),a?0:1)),t(n.scrollIntoView()),!0}var wee=Object.defineProperty,See=Object.getOwnPropertyDescriptor,Hn=(e,t,r,n)=>{for(var o=n>1?void 0:n?See(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&wee(t,r,o),o};function lv(e){var t;return!!((t=e.spec.group)!=null&&t.includes(te.ListContainerNode))}function Eee(e){var t;return!!((t=e.spec.group)!=null&&t.includes(te.ListItemNode))}function us(e){return lv(e.type)}function Zi(e){return Eee(e.type)}function Ib(e,t){return r=>{const{dispatch:n,tr:o}=r,i=jv(o,r.state),{$from:s,$to:a}=o.selection,l=s.blockRange(a);if(!l)return!1;const c=Ld({predicate:u=>lv(u.type),selection:o.selection});if(c&&l.depth-c.depth<=1&&l.startIndex===0){if(c.node.type===e)return z3(t)(r);if(lv(c.node.type))return e.validContent(c.node.content)?(n==null||n(o.setNodeMarkup(c.pos,e)),!0):Cee(o,c,e,t)?(n==null||n(o.scrollIntoView()),!0):!1}return vee(e)(i,n)}}function R3(e,t=["checked"]){return function({tr:r,dispatch:n,state:o}){var i,s;const a=dz(e,o.schema),{$from:l,$to:c}=r.selection;if(Dd(r.selection)&&r.selection.node.isBlock||l.depth<2||!l.sameParent(c))return!1;const u=l.node(-1);if(u.type!==a)return!1;if(l.parent.content.size===0&&l.node(-1).childCount===l.indexAfter(-1)){if(l.depth===2||l.node(-3).type!==a||l.index(-2)!==l.node(-2).childCount-1)return!1;if(n){const m=l.index(-1)>0;let b=R.empty;for(let y=l.depth-(m?1:2);y>=l.depth-3;y--)b=R.from(l.node(y).copy(b));const v=((i=a.contentMatch.defaultType)==null?void 0:i.createAndFill())||void 0;b=b.append(R.from(a.createAndFill(null,v)||void 0));const g=l.indexAfter(-1)!t.includes(m))),f=c.pos===l.end()?u.contentMatchAt(0).defaultType:null,p={...l.node().attrs};r.delete(l.pos,c.pos);const h=f?[{type:a,attrs:d},{type:f,attrs:p}]:[{type:a,attrs:d}];return dl(r.doc,l.pos,2)?(n&&n(r.split(l.pos,2,h).scrollIntoView()),!0):!1}}function Cee(e,t,r,n){const o=t.node,i=e.doc.resolve(t.start),s=i.node(-1),a=i.index(-1);if(!s||!s.canReplace(a,a+1,R.from(r.create())))return!1;const l=[];for(let p=0;pb;m--)h-=o.child(m).nodeSize,n.delete(h-1,h+1);const s=n.doc.resolve(r.start),a=s.nodeAfter;if(!a||n.mapping.slice(i).map(r.end)!==r.start+a.nodeSize)return!1;const l=r.startIndex===0,c=r.endIndex===o.childCount,u=s.node(-1),d=s.index(-1);if(!u.canReplace(d+(l?0:1),d+1,a.content.append(c?R.empty:R.from(o))))return!1;const f=s.pos,p=f+a.nodeSize;return n.step(new bt(f-(l?1:0),p+(c?1:0),f+1,p-1,new K((l?R.empty:R.from(o.copy(R.empty))).append(c?R.empty:R.from(o.copy(R.empty))),l?0:1,c?0:1),l?0:1)),t(n.scrollIntoView()),!0}function P3(e,t){const r=t||e.selection.$from;let n=[],o,i,s,a;for(let c=r.depth;c>=0;c--){if(i=r.node(c),o=r.index(c),s=i.maybeChild(o-1),a=i.maybeChild(o),s&&a&&s.type.name===a.type.name&&us(s)){const u=r.before(c+1);n.push(u)}if(o=r.indexAfter(c),s=i.maybeChild(o-1),a=i.maybeChild(o),s&&a&&s.type.name===a.type.name&&us(s)){const u=r.after(c+1);n.push(u)}}n=[...new Set(n)].sort((c,u)=>u-c);let l=!1;for(const c of n)Rd(e.doc,c)&&(e.join(c),l=!0);return l}function z3(e){return t=>{const{dispatch:r,tr:n}=t,o=jv(n,t.state),i=Oee(e,n.selection);return i?(r&&Tee(o,r,i),!0):!1}}function Oee(e,t){const{$from:r,$to:n}=t;return r.blockRange(n,i=>{var s;return((s=i.firstChild)==null?void 0:s.type)===e})}function xh(e){const{$from:t,$to:r}=e;return t.blockRange(r,us)}function _ee(e){const t=e.selection.$from,r=t.blockRange();if(!r||!Zi(r.parent)||r.startIndex!==0)return!1;const n=t.node(r.depth-2),o=t.index(r.depth),i=t.index(r.depth-1),s=t.index(r.depth-2),a=n.maybeChild(s-1),l=a==null?void 0:a.lastChild;if(o!==0||i!==0)return!1;if(a&&us(a)&&l&&Zi(l))return Ql({listType:a.type,itemType:l.type,tr:e});if(Zi(n)){const c=n,u=t.node(r.depth-3);if(us(u))return Ql({listType:u.type,itemType:c.type,tr:e})}return!1}function BS({view:e}){if(!e)return!1;{const t=e.state.selection.$cursor;if(!t||t.parentOffset>0)return!1;const r=t.blockRange();if(!r||!Zi(r.parent)||r.startIndex!==0)return!1}{const t=e.state.tr;_ee(t)&&e.dispatch(t)}{const t=e.state.selection.$cursor;if(!t||t.parentOffset>0)return!1;const r=t.blockRange();if(!r||!Zi(r.parent)||r.startIndex!==0)return!1;const n=t.index(r.depth),o=t.index(r.depth-1),i=t.index(r.depth-2),s=r.depth-2>=1&&Zi(t.node(r.depth-2));n===0&&o===0&&i<=1&&s&&bee(r.parent.type)(e.state,e.dispatch)}return UC(e.state,e.dispatch,e),!0}function L3({node:e,mark:t,updateDOM:r,updateMark:n}){const o=document.createElement("label");o.contentEditable="false",o.classList.add(cs.LIST_ITEM_MARKER_CONTAINER),o.append(t);const i=document.createElement("div"),s=document.createElement("li");s.classList.add(cs.LIST_ITEM_WITH_CUSTOM_MARKER),s.append(o),s.append(i);const a=l=>l.type!==e.type?!1:(e=l,r(e,s),n(e,t),!0);return a(e),{dom:s,contentDOM:i,update:a}}function Aee(e,t){const r=e.node(t.depth-1),n=e.node(t.depth-2);return!Zi(r)||!us(n)?!1:{parentItem:r,parentList:n}}function Nee(e,t){const r=t.parent,n=t.parent.child(t.endIndex-1),o=t.end,i=t.$to.end(t.depth);return ozee(e)?(t==null||t(e.scrollIntoView()),!0):!1;function Iee(e,t,r){let n,o,i,s;const a=t.doc;if(r.startIndex>=1){n=e.child(r.startIndex-1),o=e,s=a.resolve(r.start).start(r.depth),i=s+1;for(let l=0;l=1){const c=t.node(r.depth-1),u=t.start(r.depth-1);if(o=c.child(l-1),!us(o))return!1;s=u+1;for(let d=0;d=r.depth+2?t.end(r.depth+2):r.end-1,a=r.end;return s+1>=a?(n=e.slice(i,a),o=null):(n=e.slice(i,s),o=e.slice(s+1,a-1)),{selectedSlice:n,unselectedSlice:o}}function $ee(e){const{$from:t,$to:r}=e.selection,n=xh(e.selection);if(!n)return!1;const o=e.doc.resolve(n.start).node();if(!us(o))return!1;const i=Iee(o,t,n);if(!i)return!1;const{previousItem:s,previousList:a,previousItemStart:l}=i,{selectedSlice:c,unselectedSlice:u}=Dee(e.doc,r,n),d=s.content.append(R.fromArray([o.copy(c.content)])).append(u?u.content:R.empty);e.deleteRange(n.start,n.end);const f=l+s.nodeSize-2,p=s.copy(d);return p.check(),e.replaceRangeWith(l-1,f+1,p),e.setSelection(a===o?le.between(e.doc.resolve(t.pos),e.doc.resolve(r.pos)):le.between(e.doc.resolve(t.pos-2),e.doc.resolve(r.pos-2))),!0}var Hee=({tr:e,dispatch:t})=>$ee(e)?(t==null||t(e.scrollIntoView()),!0):!1,I3=class extends Ve{get name(){return"listItemShared"}createKeymap(){const e={Tab:Hee,"Shift-Tab":Lee,Backspace:BS,"Mod-Backspace":BS};if(on.isMac){const t={"Ctrl-h":e.Backspace,"Alt-Backspace":e["Mod-Backspace"]};return{...e,...t}}return e}createPlugin(){return{appendTransaction:(e,t,r)=>{const n=r.tr;return P3(n)?n:null}}}},va=class extends er{get name(){return"listItem"}createTags(){return[te.ListItemNode]}createNodeSpec(e,t){return{content:"paragraph block*",defining:!0,draggable:!1,...t,attrs:{...e.defaults(),closed:{default:!1},nested:{default:!1}},parseDOM:[{tag:"li",getAttrs:e.parse,priority:Ae.Lowest},...t.parseDOM??[]],toDOM:r=>["li",e.dom(r),0]}}createNodeViews(){return this.options.enableCollapsible?(e,t,r)=>{const n=document.createElement("div");return n.classList.add(cs.COLLAPSIBLE_LIST_ITEM_BUTTON),n.contentEditable="false",n.addEventListener("click",()=>{if(n.classList.contains("disabled"))return;const o=r(),i=ce.create(t.state.doc,o);return t.dispatch(t.state.tr.setSelection(i)),this.store.commands.toggleListItemClosed(),!0}),L3({mark:n,node:e,updateDOM:Bee,updateMark:Fee})}:{}}createKeymap(){return{Enter:R3(this.type)}}createExtensions(){return[new I3]}toggleListItemClosed(e){return({state:{tr:t,selection:r},dispatch:n})=>{if(!Dd(r)||r.node.type.name!==this.name)return!1;const{node:o,from:i}=r;return e=C1(e)?e:!o.attrs.closed,n==null||n(t.setNodeMarkup(i,void 0,{...o.attrs,closed:e})),!0}}liftListItemOutOfList(e){return z3(e??this.type)}};Hn([U()],va.prototype,"toggleListItemClosed",1);Hn([U()],va.prototype,"liftListItemOutOfList",1);va=Hn([pe({defaultOptions:{enableCollapsible:!1},staticKeys:["enableCollapsible"]})],va);function Bee(e,t){e.attrs.closed?t.classList.add(cs.COLLAPSIBLE_LIST_ITEM_CLOSED):t.classList.remove(cs.COLLAPSIBLE_LIST_ITEM_CLOSED)}function Fee(e,t){e.childCount<=1?t.classList.add("disabled"):t.classList.remove("disabled")}var bd=class extends er{get name(){return"bulletList"}createTags(){return[te.Block,te.ListContainerNode]}createNodeSpec(e,t){return{content:"listItem+",...t,attrs:e.defaults(),parseDOM:[{tag:"ul",getAttrs:e.parse},...t.parseDOM??[]],toDOM:r=>["ul",e.dom(r),0]}}createNodeViews(){return this.options.enableSpine?(e,t,r)=>{var n;const o=document.createElement("div");o.style.position="relative";const i=r(),s=t.state.doc.resolve(i+1),a=s.node(s.depth-1);if(!(((n=a==null?void 0:a.type)==null?void 0:n.name)!=="listItem")){const u=document.createElement("div");u.contentEditable="false",u.classList.add(cs.LIST_SPINE),u.addEventListener("click",d=>{const f=r(),p=t.state.doc.resolve(f+1),h=p.start(p.depth-1),m=ce.create(t.state.doc,h-1);t.dispatch(t.state.tr.setSelection(m)),this.store.commands.toggleListItemClosed(),d.preventDefault(),d.stopPropagation()}),o.append(u)}const c=document.createElement("ul");return c.classList.add(cs.UL_LIST_CONTENT),o.append(c),{dom:o,contentDOM:c}}:{}}createExtensions(){return[new va({priority:Ae.Low,enableCollapsible:this.options.enableSpine})]}toggleBulletList(){return Ib(this.type,it(this.store.schema.nodes,"listItem"))}listShortcut(e){return this.toggleBulletList()(e)}createInputRules(){const e=/^\s*([*+-])\s$/;return[Lh(e,this.type),new wa(e,(t,r,n,o)=>{const i=t.tr;return i.deleteRange(n,o),Ql({listType:this.type,itemType:it(this.store.schema.nodes,"listItem"),tr:i})?i:null})]}};Hn([U({icon:"listUnordered",label:({t:e})=>e(Rv.BULLET_LIST_LABEL)})],bd.prototype,"toggleBulletList",1);Hn([je({shortcut:$.BulletList,command:"toggleBulletList"})],bd.prototype,"listShortcut",1);bd=Hn([pe({defaultOptions:{enableSpine:!1},staticKeys:["enableSpine"]})],bd);var xd=class extends er{get name(){return"orderedList"}createTags(){return[te.Block,te.ListContainerNode]}createNodeSpec(e,t){return{content:"listItem+",...t,attrs:{...e.defaults(),order:{default:1}},parseDOM:[{tag:"ol",getAttrs:r=>et(r)?{...e.parse(r),order:+(r.getAttribute("start")??1)}:{}},...t.parseDOM??[]],toDOM:r=>{const n=e.dom(r);return r.attrs.order===1?["ol",n,0]:["ol",{...n,start:r.attrs.order},0]}}}createExtensions(){return[new va({priority:Ae.Low})]}toggleOrderedList(){return Ib(this.type,it(this.store.schema.nodes,"listItem"))}listShortcut(e){return this.toggleOrderedList()(e)}createInputRules(){const e=/^(\d+)\.\s$/;return[Lh(e,this.type,t=>({order:+it(t,1)}),(t,r)=>r.childCount+r.attrs.order===+it(t,1)),new wa(e,(t,r,n,o)=>{const i=t.tr;if(i.deleteRange(n,o),!Ql({listType:this.type,itemType:it(this.store.schema.nodes,"listItem"),tr:i}))return null;const a=+it(r,1);if(a!==1){const l=rs({selection:i.selection,types:this.type});l&&i.setNodeMarkup(l.pos,void 0,{order:a})}return i})]}};Hn([U({icon:"listOrdered",label:({t:e})=>e(Rv.ORDERED_LIST_LABEL)})],xd.prototype,"toggleOrderedList",1);Hn([je({shortcut:$.OrderedList,command:"toggleOrderedList"})],xd.prototype,"listShortcut",1);xd=Hn([pe({})],xd);var D3=class extends er{get name(){return"taskListItem"}createTags(){return[te.ListItemNode]}createNodeSpec(e,t){return{content:"paragraph block*",defining:!0,draggable:!1,...t,attrs:{...e.defaults(),checked:{default:!1}},parseDOM:[{tag:"li[data-task-list-item]",getAttrs:r=>{let n=!1;return et(r)&&r.getAttribute("data-checked")!==null&&(n=!0),{checked:n,...e.parse(r)}},priority:Ae.Medium},...t.parseDOM??[]],toDOM:r=>["li",{...e.dom(r),"data-task-list-item":"","data-checked":r.attrs.checked?"":void 0},0]}}createNodeViews(){return(e,t,r)=>{const n=document.createElement("input");return n.type="checkbox",n.classList.add(cs.LIST_ITEM_CHECKBOX),n.contentEditable="false",n.addEventListener("click",o=>{t.editable||o.preventDefault()}),n.addEventListener("change",()=>{const o=r(),i=t.state.doc.resolve(o+1);this.store.commands.toggleCheckboxChecked({$pos:i})}),n.checked=e.attrs.checked,L3({node:e,mark:n,updateDOM:Vee,updateMark:jee})}}createKeymap(){return{Enter:R3(this.type)}}createExtensions(){return[new I3]}toggleCheckboxChecked(e){let t,r;return typeof e=="boolean"?t=e:e&&(t=e.checked,r=e.$pos),({tr:n,dispatch:o})=>{const i=rs({selection:r??n.selection.$from,types:this.type});if(!i)return!1;const{node:s,pos:a}=i,l={...s.attrs,checked:t??!s.attrs.checked};return o==null||o(n.setNodeMarkup(a,void 0,l)),!0}}createInputRules(){const e=/^\s*(\[( ?|x|X)]\s)$/;return[Lh(e,this.type,t=>({checked:["x","X"].includes(Zo(t,2))})),new wa(e,(t,r,n,o)=>{const i=t.tr;if(i.deleteRange(n,o),!Ql({listType:it(this.store.schema.nodes,"taskList"),itemType:this.type,tr:i}))return null;const a=["x","X"].includes(Zo(r,2));if(a){const l=rs({selection:i.selection,types:this.type});l&&i.setNodeMarkup(l.pos,void 0,{checked:a})}return i})]}};Hn([U()],D3.prototype,"toggleCheckboxChecked",1);function Vee(e,t){e.attrs.checked?t.setAttribute("data-checked",""):t.removeAttribute("data-checked"),t.setAttribute("data-task-list-item","")}function jee(e,t){t.checked=!!e.attrs.checked}var $3=class extends er{get name(){return"taskList"}createTags(){return[te.Block,te.ListContainerNode]}createNodeSpec(e,t){return{content:"taskListItem+",...t,attrs:e.defaults(),parseDOM:[{tag:"ul[data-task-list]",getAttrs:e.parse,priority:Ae.Medium},...t.parseDOM??[]],toDOM:r=>["ul",{...e.dom(r),"data-task-list":""},0]}}createExtensions(){return[new D3({})]}toggleTaskList(){return Ib(this.type,it(this.store.schema.nodes,"taskListItem"))}listShortcut(e){return this.toggleTaskList()(e)}};Hn([U({icon:"checkboxMultipleLine",label:({t:e})=>e(Rv.TASK_LIST_LABEL)})],$3.prototype,"toggleTaskList",1);Hn([je({shortcut:$.TaskList,command:"toggleTaskList"})],$3.prototype,"listShortcut",1);var fo,Uee=(e=document)=>fo||(fo=e.createElement("div"),fo.setAttribute("id","a11y-status-message"),fo.setAttribute("role","status"),fo.setAttribute("aria-live","polite"),fo.setAttribute("aria-relevant","additions text"),Object.assign(fo.style,{border:"0",clip:"rect(0 0 0 0)",height:"1px",margin:"-1px",overflow:"hidden",padding:"0",position:"absolute",width:"1px"}),e.body.append(fo),fo);U4(500,()=>{Uee().textContent=""});function FS(e){return typeof e=="object"&&e!=null&&e.nodeType===1}function VS(e,t){return(!t||e!=="hidden")&&e!=="visible"&&e!=="clip"}function d1(e,t){if(e.clientHeightt||i>e&&s=t&&a>=r?i-e-n:s>t&&ar?s-t+o:0}var Wee=function(e,t){var r=window,n=t.scrollMode,o=t.block,i=t.inline,s=t.boundary,a=t.skipOverflowHiddenElements,l=typeof s=="function"?s:function(De){return De!==s};if(!FS(e))throw new TypeError("Invalid target");for(var c,u,d=document.scrollingElement||document.documentElement,f=[],p=e;FS(p)&&l(p);){if((p=(u=(c=p).parentElement)==null?c.getRootNode().host||null:u)===d){f.push(p);break}p!=null&&p===document.body&&d1(p)&&!d1(document.documentElement)||p!=null&&d1(p,a)&&f.push(p)}for(var h=r.visualViewport?r.visualViewport.width:innerWidth,m=r.visualViewport?r.visualViewport.height:innerHeight,b=window.scrollX||pageXOffset,v=window.scrollY||pageYOffset,g=e.getBoundingClientRect(),y=g.height,x=g.width,k=g.top,w=g.right,E=g.bottom,M=g.left,C=o==="start"||o==="nearest"?k:o==="end"?E:k+y/2,T=i==="center"?M+x/2:i==="end"?w:M,N=[],z=0;z=0&&M>=0&&E<=m&&w<=h&&k>=q&&E<=P&&M>=F&&w<=A)return N;var Y=getComputedStyle(D),J=parseInt(Y.borderLeftWidth,10),Ne=parseInt(Y.borderTopWidth,10),ie=parseInt(Y.borderRightWidth,10),ue=parseInt(Y.borderBottomWidth,10),de=0,me=0,Me="offsetWidth"in D?D.offsetWidth-D.clientWidth-J-ie:0,Se="offsetHeight"in D?D.offsetHeight-D.clientHeight-Ne-ue:0,ft="offsetWidth"in D?D.offsetWidth===0?0:L/D.offsetWidth:0,rt="offsetHeight"in D?D.offsetHeight===0?0:j/D.offsetHeight:0;if(d===D)de=o==="start"?C:o==="end"?C-m:o==="nearest"?Of(v,v+m,m,Ne,ue,v+C,v+C+y,y):C-m/2,me=i==="start"?T:i==="center"?T-h/2:i==="end"?T-h:Of(b,b+h,h,J,ie,b+T,b+T+x,x),de=Math.max(0,de+v),me=Math.max(0,me+b);else{de=o==="start"?C-q-Ne:o==="end"?C-P+ue+Se:o==="nearest"?Of(q,P,j,Ne,ue+Se,C,C+y,y):C-(q+j/2)+Se/2,me=i==="start"?T-F-J:i==="center"?T-(F+L/2)+Me/2:i==="end"?T-A+ie+Me:Of(F,A,L,J,ie+Me,T,T+x,x);var Or=D.scrollLeft,he=D.scrollTop;C+=he-(de=Math.max(0,Math.min(he+de/rt,D.scrollHeight-j/rt+Se))),T+=Or-(me=Math.max(0,Math.min(Or+me/ft,D.scrollWidth-L/ft+Me)))}N.push({el:D,top:de,left:me})}return N};typeof xr=="object"&&xr.__esModule&&xr.default&&xr.default;Ph(Wee);var Kee=typeof document<"u"?S.useLayoutEffect:S.useEffect;function qee(e){const t=S.useRef();return Kee(()=>{t.current=e}),t.current}function Gee(e,t){const[r,n]=S.useState([]),[o,i]=S.useState(()=>q0(e)),[s,a]=S.useState([]),l=S.useRef(e),c=qee(o);return l.current=e,Wd(Ul,({addCustomHandler:u})=>{const d=q0(l.current),f=u("positioner",d);return i(d),f},t),S.useLayoutEffect(()=>{const u=o.addListener("update",f=>{const p=[];for(const{id:h,data:m,setElement:b}of f){const v=g=>{g&&b(g)};p.push({id:h,data:m,ref:v})}a(p)}),d=o.addListener("done",f=>{n(f)});return c!=null&&c.recentUpdate&&o.onActiveChanged(c==null?void 0:c.recentUpdate),()=>{u(),d()}},[o,c]),S.useMemo(()=>{const u=[];for(const[d,{ref:f,data:p,id:h}]of s.entries()){const m=r[d],{element:b,position:v={}}=m??{},g={...Zy,...G4(v)};u.push({ref:f,element:b,data:p,key:h,...g})}return u},[s,r])}function Yee(e,t){const r=t==null||C1(t)?[e]:t,n=C1(t)?t:!0,o=S.useRef(Cl()),s=Gee(e,r)[0];return S.useMemo(()=>s&&n?{...s,active:!0}:{...Zy,ref:void 0,data:{},active:!1,key:o.current},[n,s])}function f1(e,t){return _e(e)?e(t):e}function Jee(e){return oe(e[0])}function Xee(e,t){var r;return oe(e)?e:ct(e)?Jee(e)?e[0]??"":((r=e.find(n=>Y4(n.attrs,t))??e[0])==null?void 0:r.shortcut)??"":e.shortcut}var Qee={title:e=>fA(e),upper:e=>e.toLocaleUpperCase(),lower:e=>e.toLocaleLowerCase()};function Zee(e,t){const{casing:r="title",namedAsSymbol:n=!1,modifierAsSymbol:o=!0,separator:i=" ",t:s}=t,a=Fz(e),l=[],c=Qee[r];for(const u of a){if(u.type==="char"){l.push(c(u.key));continue}if(u.type==="named"){const f=n===!0||ct(n)&&fr(n,u.key)?u.symbol??s(u.i18n):s(u.i18n);l.push(c(f));continue}const d=o===!0||ct(o)&&fr(o,u.key)?u.symbol:s(u.i18n);l.push(c(d))}return l.join(i)}var H3=({commandName:e,active:t,enabled:r,attrs:n})=>{const{t:o}=fj(),{getCommandOptions:i}=fm(),s=i(e),{description:a,label:l,icon:c,shortcut:u}=s||{},d=S.useMemo(()=>({active:t,attrs:n,enabled:r,t:o}),[t,n,r,o]),f=S.useMemo(()=>{if(u)return Zee(Xee(u,n??{}),{t:o,separator:""})},[u,n,o]);return S.useMemo(()=>({description:f1(a,d),label:f1(l,d),icon:f1(c,d),shortcut:f}),[d,a,l,c,f])},ete={color:void 0,size:void 0,className:void 0,style:void 0,attr:void 0},B3=S.createContext(ete);B3.Provider;function F3(e){return e.map((t,r)=>S.createElement(t.tag,{key:r,...t.attr},F3(t.child??[])))}var Jm=e=>{const{name:t}=e;return I.createElement(tte,{...e},F3(gee[t]))},tte=e=>{const t=r=>{const n=e.size??r.size??"1em";let o;r.className&&(o=r.className),e.className&&(o=(o?`${o} `:"")+e.className);const{title:i,...s}=e;return I.createElement("svg",{stroke:"currentColor",fill:"currentColor",strokeWidth:"0",...r.attr,...s,className:o,style:{color:e.color??r.color,...r.style,...e.style},height:n,width:n,xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24"},i&&I.createElement("title",null,i),e.children)};return I.createElement(B3.Consumer,null,t)},rte=e=>ps(e)?!!e.name:!1,nte=({icon:e})=>oe(e)?I.createElement(Jm,{name:e,size:"1rem"}):e,ote=({icon:e,children:t})=>{if(!rte(e))return I.createElement(I.Fragment,null,t);const{sub:r,sup:n}=e,o=r??n,i=r!==void 0;return o===void 0?I.createElement(I.Fragment,null,t):I.createElement(oJ,{anchorOrigin:{vertical:i?"bottom":"top",horizontal:"right"},badgeContent:o,sx:{"& > .MuiBadge-badge":{bgcolor:"background.paper",color:"text.secondary",minWidth:12,height:12,margin:"2px 0",padding:"1px"}}},t)},dt=({commandName:e,active:t=!1,enabled:r,attrs:n,onSelect:o,onChange:i,icon:s,displayShortcut:a=!0,"aria-label":l,label:c,...u})=>{const d=S.useCallback((g,y)=>{o(),i==null||i(g,y)},[o,i]),f=S.useCallback(g=>{g.preventDefault()},[]),p=H3({commandName:e,active:t,enabled:r,attrs:n});let h=null;p.icon&&(h=oe(p.icon)?p.icon:p.icon.name);const m=l??p.label??"",b=c??m,v=a&&p.shortcut?` (${p.shortcut})`:"";return I.createElement(N3,{title:`${b}${v}`},I.createElement(T3,{component:"span",sx:{"&:not(:first-of-type)":{marginLeft:"-1px"}}},I.createElement(NX,{"aria-label":m,selected:t,disabled:!r,onMouseDown:f,color:"primary",size:"small",sx:{padding:"6px 12px","&.Mui-selected":{backgroundColor:"primary.main",color:"primary.contrastText"},"&.Mui-selected:hover":{backgroundColor:"primary.dark",color:"primary.contrastText"},"&:not(:first-of-type)":{borderLeft:"1px solid transparent",borderTopLeftRadius:0,borderBottomLeftRadius:0},"&:not(:last-of-type)":{borderTopRightRadius:0,borderBottomRightRadius:0}},...u,value:e,onChange:d},I.createElement(ote,{icon:p.icon},I.createElement(nte,{icon:s??h})))))},ite=({icon:e})=>oe(e)?I.createElement(Jm,{name:e,size:"1rem"}):e,V3=({label:e,"aria-label":t,icon:r,children:n,onClose:o,...i})=>{const s=S.useRef(Cl()),[a,l]=S.useState(null),c=!!a,u=S.useCallback(p=>{p.preventDefault()},[]),d=S.useCallback(p=>{l(p.currentTarget)},[]),f=S.useCallback((p,h)=>{l(null),o==null||o(p,h)},[o]);return I.createElement(I.Fragment,null,I.createElement(N3,{title:e??t},I.createElement(Wq,{"aria-label":t,"aria-controls":c?s.current:void 0,"aria-haspopup":!0,"aria-expanded":c?"true":void 0,onMouseDown:u,onClick:d,size:"small",sx:p=>({border:`1px solid ${p.palette.divider}`,borderRadius:`${p.shape.borderRadius}px`,padding:"6px 12px","&:not(:first-of-type)":{marginLeft:"-1px",borderLeft:"1px solid transparent",borderTopLeftRadius:0,borderBottomLeftRadius:0},"&:not(:last-of-type)":{borderTopRightRadius:0,borderBottomRightRadius:0}})},r&&I.createElement(ite,{icon:r}),I.createElement(Jm,{name:"arrowDownSFill",size:"1rem"}))),I.createElement(aX,{...i,id:s.current,anchorEl:a,open:c,onClose:f},n))},ste=e=>{const{insertHorizontalRule:t}=tr();rb();const r=S.useCallback(()=>{t.enabled()&&t()},[t]),n=t.enabled();return I.createElement(dt,{...e,commandName:"insertHorizontalRule",enabled:n,onSelect:r})},ate=e=>{const{redo:t}=tr(),{redoDepth:r}=fm(!0),n=S.useCallback(()=>{t.enabled()&&t()},[t]),o=r()>0;return I.createElement(dt,{...e,commandName:"redo",active:!1,enabled:o,onSelect:n})},lte=e=>{const{toggleBlockquote:t}=tr(),r=S.useCallback(()=>{t.enabled()&&t()},[t]),n=qr().blockquote(),o=t.enabled();return I.createElement(dt,{...e,commandName:"toggleBlockquote",active:n,enabled:o,onSelect:r})},cv=e=>{const{toggleBold:t}=tr(),r=S.useCallback(()=>{t.enabled()&&t()},[t]),n=qr().bold(),o=t.enabled();return I.createElement(dt,{...e,commandName:"toggleBold",active:n,enabled:o,onSelect:r})},cte=e=>{const{toggleBulletList:t}=tr(),r=S.useCallback(()=>{t.enabled()&&t()},[t]),n=qr().bulletList(),o=t.enabled();return I.createElement(dt,{...e,commandName:"toggleBulletList",active:n,enabled:o,onSelect:r})},ute=({attrs:e={},...t})=>{const{toggleCodeBlock:r}=tr(),n=S.useCallback(()=>{r.enabled(e)&&r(e)},[r,e]),o=qr().codeBlock(),i=r.enabled(e);return I.createElement(dt,{...t,commandName:"toggleCodeBlock",active:o,enabled:i,attrs:e,onSelect:n})},uv=e=>{const{toggleCode:t}=tr(),r=S.useCallback(()=>{t.enabled()&&t()},[t]),n=qr().code(),o=t.enabled();return I.createElement(dt,{...e,commandName:"toggleCode",active:n,enabled:o,onSelect:r})},p1=({attrs:e,...t})=>{const{toggleHeading:r}=tr(),n=S.useCallback(()=>{r.enabled(e)&&r(e)},[r,e]),o=qr().heading(e),i=r.enabled(e);return I.createElement(dt,{...t,commandName:"toggleHeading",active:o,enabled:i,attrs:e,onSelect:n})},dv=e=>{const{toggleItalic:t}=tr(),r=S.useCallback(()=>{t.enabled()&&t()},[t]),n=qr().italic(),o=t.enabled();return I.createElement(dt,{...e,commandName:"toggleItalic",active:n,enabled:o,onSelect:r})},dte=e=>{const{toggleOrderedList:t}=tr(),r=S.useCallback(()=>{t.enabled()&&t()},[t]),n=qr().orderedList(),o=t.enabled();return I.createElement(dt,{...e,commandName:"toggleOrderedList",active:n,enabled:o,onSelect:r})},fte=e=>{const{toggleStrike:t}=tr(),r=S.useCallback(()=>{t.enabled()&&t()},[t]),n=qr().strike(),o=t.enabled();return I.createElement(dt,{...e,commandName:"toggleStrike",active:n,enabled:o,onSelect:r})},fv=e=>{const{toggleUnderline:t}=tr(),r=S.useCallback(()=>{t.enabled()&&t()},[t]),n=qr().underline(),o=t.enabled();return I.createElement(dt,{...e,commandName:"toggleUnderline",active:n,enabled:o,onSelect:r})},pte=e=>{const{undo:t}=tr(),{undoDepth:r}=fm(!0),n=S.useCallback(()=>{t.enabled()&&t()},[t]),o=r()>0;return I.createElement(dt,{...e,commandName:"undo",active:!1,enabled:o,onSelect:n})},En=e=>I.createElement(T3,{sx:{display:"flex",alignItems:"center",width:"fit-content",bgcolor:"background.paper",color:"text.secondary"},...e}),hte=({children:e})=>I.createElement(En,null,I.createElement(cv,null),I.createElement(dv,null),I.createElement(fv,null),I.createElement(fte,null),I.createElement(uv,null),e),mte=({icon:e})=>e?I.createElement(RJ,null,oe(e)?I.createElement(Jm,{name:e,size:"1rem"}):I.createElement(I.Fragment,null,e)):null,Db=({commandName:e,active:t=!1,enabled:r,attrs:n,onSelect:o,onClick:i,icon:s,displayShortcut:a=!0,label:l,description:c,displayDescription:u=!0,...d})=>{const f=S.useCallback(g=>{o(),i==null||i(g)},[o,i]),p=S.useCallback(g=>{g.preventDefault()},[]),h=H3({commandName:e,active:t,enabled:r,attrs:n});let m=null;h.icon&&(m=oe(h.icon)?h.icon:h.icon.name);const b=l??h.label??"",v=u&&(c??h.description);return I.createElement(mX,{selected:t,disabled:!r,onMouseDown:p,...d,onClick:f},s!==null&&I.createElement(mte,{icon:s??m}),I.createElement(HJ,{primary:b,secondary:v}),a&&h.shortcut&&I.createElement(cu,{variant:"body2",color:"text.secondary",sx:{ml:2}},h.shortcut))},_f=({attrs:e,...t})=>{const{toggleHeading:r}=tr(),n=S.useCallback(()=>{r.enabled(e)&&r(e)},[r,e]),o=qr().heading(e),i=r.enabled(e);return I.createElement(Db,{...t,commandName:"toggleHeading",active:o,enabled:i,attrs:e,onSelect:n})},gte={level:1},vte={level:2},jS={level:3},yte={level:4},bte={level:5},xte={level:6},kte=({showAll:e=!1,children:t})=>I.createElement(En,null,I.createElement(p1,{attrs:gte}),I.createElement(p1,{attrs:vte}),e?I.createElement(V3,{"aria-label":"More heading options"},I.createElement(_f,{attrs:jS}),I.createElement(_f,{attrs:yte}),I.createElement(_f,{attrs:bte}),I.createElement(_f,{attrs:xte})):I.createElement(p1,{attrs:jS}),t),wte=({children:e})=>I.createElement(En,null,I.createElement(pte,null),I.createElement(ate,null),e);typeof xr=="object"&&xr.__esModule&&xr.default&&xr.default;var j3=S.createContext({});function Ste(e={}){const t=S.useContext(j3),r=S.useMemo(()=>Q4(t,e.theme??{}),[t,e.theme]),n=S.useMemo(()=>MV(r).styles,[r]),o=ju(CV,e.className);return S.useMemo(()=>({style:n,className:o,theme:r}),[n,o,r])}var Ete=e=>{var t,r,n,o,i,s,a,l;const{children:c,as:u="div"}=e,{theme:d,style:f,className:p}=Ste({theme:e.theme??ws}),h=wb({palette:{primary:{main:((t=d.color)==null?void 0:t.primary)??ws.color.primary,dark:((n=(r=d.color)==null?void 0:r.hover)==null?void 0:n.primary)??ws.color.hover.primary,contrastText:((o=d.color)==null?void 0:o.primaryText)??ws.color.primaryText},secondary:{main:((i=d.color)==null?void 0:i.secondary)??ws.color.secondary,dark:((a=(s=d.color)==null?void 0:s.hover)==null?void 0:a.secondary)??ws.color.hover.secondary,contrastText:((l=d.color)==null?void 0:l.secondaryText)??ws.color.secondaryText}}});return I.createElement(oq,{theme:h},I.createElement(j3.Provider,{value:d},I.createElement(u,{style:f,className:p},c)))},U3=e=>I.createElement(gJ,{direction:"row",spacing:1,sx:{backgroundColor:"background.paper",overflowX:"auto"},...e}),Cte=[{name:"offset",options:{offset:[0,8]}}],Mte=({positioner:e="selection",children:t,...r})=>{const{ref:n,x:o,y:i,width:s,height:a,active:l}=Yee(()=>q0(e),[e]),[c,u]=S.useState(null),d=S.useMemo(()=>({position:"absolute",pointerEvents:"none",left:o,top:i,width:s,height:a}),[o,i,s,a]),f=S.useCallback(p=>{u(p),n==null||n(p)},[n]);return I.createElement(I.Fragment,null,I.createElement("div",{ref:f,style:d}),I.createElement(Lb,{placement:"top",modifiers:Cte,...r,open:l,anchorEl:c},I.createElement(U3,null,t?I.createElement(I.Fragment,null,t):I.createElement(hte,null))))},Ct=Ph(fh),$b=xt` + /** + * Styles extracted from: packages/remirror__theme/src/components-theme.ts + */ + .remirror-editor-wrapper { + padding-top: var(--rmr-space-3); + } + + .remirror-button-active { + color: var(--rmr-color-primary-text) !important; + background-color: var(--rmr-color-primary) !important; + } + + .remirror-button { + display: inline-flex; + font-weight: 400; + align-items: center; + justify-content: center; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + padding: 0.375em 0.75em; + line-height: 1.5; + border-radius: var(--rmr-radius-border); + text-decoration: none; + border: 1px solid var(--rmr-color-border); + cursor: pointer; + white-space: nowrap; + color: var(--rmr-color-text); + background-color: var(--rmr-color-background); + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, + border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + font-size: 100%; + } + + .remirror-button[aria-disabled='true'] { + cursor: auto; + } + + .remirror-button:not([aria-disabled='true']):hover { + color: var(--rmr-color-hover-primary-text); + border-color: var(--rmr-color-hover-border); + background-color: var(--rmr-color-hover-primary); + } + + .remirror-button:not([aria-disabled='true']):active, + .remirror-button:not([aria-disabled='true'])[data-active], + .remirror-button:not([aria-disabled='true'])[aria-expanded='true'] { + color: var(--rmr-color-active-primary-text); + border-color: var(--rmr-color-active-border); + background-color: var(--rmr-color-active-primary); + } + + /* Ensure a perceivable button border for users with Windows High Contrast + mode enabled https://moderncss.dev/css-button-styling-guide/ */ + + @media screen and (-ms-high-contrast: active) { + .remirror-button { + border: 2px solid currentcolor; + } + } + + .remirror-composite { + align-items: center; + justify-content: center; + padding: 0.375em 0.75em; + font-size: 100%; + border: 0; + color: inherit; + background-color: inherit; + } + + .remirror-composite:not([aria-selected='true']) { + color: inherit; + background-color: inherit; + } + + [aria-activedescendant='*']:focus .remirror-composite[aria-selected='true'], + [aria-activedescendant='*']:focus ~ * .remirror-composite[aria-selected='true'] { + color: var(--rmr-color-text); + background-color: var(--rmr-color-background); + } + + .remirror-dialog { + position: fixed; + top: 28px; + left: 50%; + transform: translateX(-50%); + border-radius: var(--rmr-radius-border); + padding: 1em; + max-height: calc(100vh - 56px); + outline: 0; + border: 1px solid var(--rmr-color-border); + color: var(--rmr-color-text); + z-index: 999; + } + + .remirror-dialog:focus { + box-shadow: 0 0 0 0.2em var(--rmr-color-shadow-1); + } + + .remirror-dialog-backdrop { + background-color: var(--rmr-color-backdrop); + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 999; + } + + .remirror-form > *:not(:first-child) { + margin-top: 1rem; + } + + .remirror-form-message { + font-size: 0.8em; + margin-top: 0.5rem !important; + } + + .remirror-form-label { + display: block; + margin: 0 0 0.5rem 0 !important; + } + + input[type='checkbox'] + .remirror-form-label, + input[type='radio'] + .remirror-form-label { + display: inline-block; + margin: 0 0 0 0.5rem !important; + } + + .remirror-form-group { + display: block; + color: var(--rmr-color-text); + border: 1px solid var(--rmr-color-border); + border-radius: var(--rmr-radius-border); + padding: 0.5rem 1rem 1rem; + } + + .remirror-form-group > * { + display: block; + } + + .remirror-group { + display: flex; + } + + .remirror-group > :not(:first-child) { + margin-left: -1px; + } + + .remirror-group > :not(:first-child):not(:last-child):not(.first-child):not(.last-child) { + border-radius: 0; + } + + .remirror-group > :first-child:not(:last-child), + .remirror-group > .first-child { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + + .remirror-group > :last-child:not(:first-child), + .remirror-group > .last-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + + .remirror-input { + display: block; + width: 100%; + border-radius: var(--rmr-radius-border); + padding: 0.5em 0.75em; + font-size: 100%; + border: 1px solid var(--rmr-hue-gray-2); + color: var(--rmr-hue-gray-5); + margin: 0 !important; + } + + .remirror-input:focus { + border-color: var(--rmr-hue-gray-3); + } + + .remirror-menu { + display: flex; + border-radius: 0; + } + + .remirror-menu-pane { + position: relative; + display: flex; + justify-content: center; + align-items: flex-start; + padding-top: var(--rmr-space-1); + padding-bottom: var(--rmr-space-1); + padding-right: var(--rmr-space-2); + } + + .remirror-menu-pane-active { + color: var(--rmr-color-primary-text); + background-color: var(--rmr-color-primary); + } + + .remirror-menu-dropdown-label { + padding: 0 var(--rmr-space-2); + } + + .remirror-menu-pane-icon { + position: absolute; + left: 8px; + width: 20px; + color: var(--rmr-hue-gray-7); + } + + button:hover .remirror-menu-pane-icon, + button:active .remirror-menu-pane-icon, + [aria-checked='true'] .remirror-menu-pane-icon { + color: var(--rmr-hue-gray-1); + } + + .remirror-menu-pane-label { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + padding-right: var(--rmr-space-3); + } + + .remirror-menu-pane-shortcut { + align-self: flex-end; + color: var(--rmr-hue-gray-6); + } + + button:hover .remirror-menu-pane-shortcut, + button:active .remirror-menu-pane-shortcut, + [aria-checked='true'] .remirror-menu-pane-shortcut { + color: var(--rmr-hue-gray-1); + } + + [role='menu'] > .remirror-menu-button-left { + left: var(--rmr-space-2); + } + + [role='menu'] > .remirror-menu-button-right { + right: var(--rmr-space-2); + } + + .remirror-menu-button-nested-left svg { + margin-right: var(--rmr-space-2); + } + + [role='menu'] > .remirror-menu-button-nested-right { + padding-right: 2em !important; + } + + .remirror-menu-button-nested-right svg { + margin-left: var(--rmr-space-2); + } + + .remirror-menu-button { + position: relative; + } + + .remirror-menu-button svg { + fill: currentColor; + width: 0.65em; + height: 0.65em; + } + + [role='menu'] > .remirror-menu-button svg { + position: absolute; + top: 50%; + transform: translateY(-50%); + } + + [role='menubar'] > .remirror-menu-button svg { + display: none; + } + + .remirror-menu-bar { + position: relative; + display: flex; + white-space: nowrap; + box-shadow: none !important; + } + + .remirror-menu-bar[aria-orientation='vertical'] { + padding: 0.25em 0; + } + + .remirror-menu-bar[aria-orientation='horizontal'] { + padding: 0; + } + + .remirror-flex-column { + flex-direction: column; + } + + .remirror-flex-row { + flex-direction: row; + } + + .remirror-menu-item { + line-height: 1.5; + text-align: left; + justify-content: flex-start; + border: 0; + border-radius: 0; + font-size: 100%; + background: transparent; + color: var(--rmr-color-foreground); + margin: 0; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: default; + text-decoration: none; + } + + .remirror-menu-item:focus, + .remirror-menu-item[aria-expanded='true'] { + background-color: var(--rmr-color-primary); + color: var(--rmr-color-primary-text); + box-shadow: none !important; + } + + .remirror-menu-item:active, + .remirror-menu-item[data-active] { + background-color: var(--rmr-color-active-primary) !important; + color: var(--rmr-color-active-primary-text) !important; + } + + .remirror-menu-item:disabled { + opacity: 0.5; + } + + .remirror-menu-item-row { + padding: 0 var(--rmr-space-2); + } + + .remirror-menu-item-column { + padding: 0 var(--rmr-space-4); + } + + .remirror-menu-item-checkbox { + position: relative; + outline: 0; + } + + .remirror-menu-item-checkbox[aria-checked='true']:before { + content: '✓'; + position: absolute; + top: 0; + left: 0.4em; + width: 1em; + height: 1em; + } + + .remirror-menu-item-radio { + position: relative; + outline: 0; + } + + .remirror-menu-item-radio[aria-checked='true']:before { + content: '•'; + position: absolute; + font-size: 1.4em; + top: -0.25em; + left: 0.35em; + width: 0.7142857143em; + height: 0.7142857143em; + } + + .remirror-menu-group { + display: inherit; + flex-direction: inherit; + } + + .remirror-floating-popover { + /* padding: var(--rmr-space-2); */ + padding: 0; + border: none; + max-height: calc(100vh - 56px); + } + + .remirror-popover [data-arrow] { + background-color: transparent; + } + + .remirror-popover [data-arrow] .stroke { + fill: var(--rmr-color-border); + } + + .remirror-popover [data-arrow] .fill { + fill: var(--rmr-color-background); + } + + .remirror-animated-popover { + transition: opacity 250ms ease-in-out, transform 250ms ease-in-out; + opacity: 0; + transform-origin: top center; + transform: translate3d(0, -20px, 0); + } + + [data-enter] .remirror-animated-popover { + opacity: 1; + transform: translate3d(0, 0, 0); + } + + .remirror-role { + box-sizing: border-box; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + font-family: var(--rmr-font-family-default); + color: var(--rmr-color-text); + background-color: var(--rmr-color-background); + /* border: 1px solid var(--rmr-color-border); */ + } + + .remirror-separator { + border: 1px solid var(--rmr-color-border); + border-width: 0 1px 0 0; + margin: 0 0.5em; + padding: 0; + width: 0; + height: auto; + } + + .remirror-separator[aria-orientation='horizontal'] { + border-width: 0 0 1px 0; + margin: 0.5em 0; + width: auto; + height: 0; + } + + .remirror-tab { + background-color: transparent; + border: 1px solid transparent; + border-width: 1px 1px 0 1px; + border-radius: var(--rmr-radius-border) var(--rmr-radius-border) 0 0; + font-size: 100%; + padding: 0.5em 1em; + margin: 0 0 -1px 0; + } + + .remirror-tab[aria-selected='true'] { + background-color: var(--rmr-color-background); + border-color: var(--rmr-color-border); + } + + [aria-orientation='vertical'] .remirror-tab { + border-width: 1px 0 1px 1px; + border-radius: 0.2em 0 0 0.2em; + margin: 0 -1px 0 0; + } + + .remirror-tab-list { + display: flex; + flex-direction: row; + border: 1px solid var(--rmr-color-border); + border-width: 0 0 1px 0; + margin: 0 0 1em 0; + } + + .remirror-tab-list[aria-orientation='vertical'] { + flex-direction: column; + border-width: 0 1px 0 0; + margin: 0 1em 0 0; + } + + .remirror-tabbable:not([type='checkbox']):not([type='radio']) { + /* transition: box-shadow 0.15s ease-in-out; */ + outline: 0; + } + + .remirror-tabbable:not([type='checkbox']):not([type='radio']):focus { + box-shadow: var(--rmr-color-outline) 0px 0px 0px 0.2em; + position: relative; + z-index: 2; + } + + .remirror-tabbable:not([type='checkbox']):not([type='radio']):hover { + z-index: 2; + } + + .remirror-tabbable[aria-disabled='true'] { + opacity: 0.5; + } + + .remirror-toolbar { + display: flex; + flex-direction: row; + + overflow-y: auto; + } + + .remirror-toolbar > *:not(:first-child) { + margin: 0 0 0 0.5em; + } + + .remirror-toolbar[aria-orientation='vertical'] { + display: inline-flex; + flex-direction: column; + } + + .remirror-toolbar[aria-orientation='vertical'] > *:not(:first-child) { + margin: 0.5em 0 0; + } + + .remirror-tooltip { + background-color: var(--rmr-color-faded); + color: white; + font-size: 0.8em; + padding: 0.5rem; + border-radius: var(--rmr-radius-border); + z-index: 999; + } + + .remirror-tooltip [data-arrow] { + background-color: transparent; + } + + .remirror-tooltip [data-arrow] .stroke { + fill: transparent; + } + + .remirror-tooltip [data-arrow] .fill { + fill: var(--rmr-hue-gray-8); + } + + .remirror-table-size-editor { + background: var(--rmr-color-background); + box-shadow: var(--rmr-color-shadow-1); + font-family: var(--rmr-font-family-default); + font-size: var(--rmr-font-size-1); + } + + .remirror-table-size-editor-body { + position: relative; + } + + .remirror-table-size-editor-body::after { + background: rgba(0, 0, 0, 0); + bottom: -50px; + content: ''; + left: 0; + position: absolute; + right: -50px; + top: -50px; + } + + .remirror-table-size-editor-cell { + border: var(--rmr-color-border); + position: absolute; + z-index: 2; + } + + .remirror-table-size-editor-cell-selected { + background: var(--rmr-color-table-selected-border); + border-color: var(--rmr-color-border); + } + + .remirror-table-size-editor-footer { + padding-bottom: var(--rmr-space-1); + text-align: center; + } + + .remirror-color-picker { + background: var(--rmr-color-background); + box-shadow: var(--rmr-box-shadow-1); + font-family: var(--rmr-font-family-default); + font-size: var(--rmr-font-size-1); + padding: var(--rmr-space-2) var(--rmr-space-3); + } + + .remirror-color-picker-cell { + } + + .remirror-color-picker-cell-selected { + } +`;Ct.div` + ${$b} +`;var Hb=xt` + /** + * Styles extracted from: packages/remirror__theme/src/core-theme.ts + */ + .remirror-editor.ProseMirror { + word-wrap: break-word; + white-space: pre-wrap; + white-space: break-spaces; + position: relative; + font-variant-ligatures: none; + font-feature-settings: 'liga' 0; + overflow-y: scroll; + } + + .remirror-editor.ProseMirror pre { + white-space: pre-wrap; + } + + .remirror-editor.ProseMirror li { + position: relative; + } + + .remirror-editor.ProseMirror hr { + border-color: #2e2e2e; + } + + /* Protect against generic img rules. See also https://github.com/ProseMirror/prosemirror-view/commit/aaa50d592074c8063fc2ef77907ab6d0373822fb */ + + .remirror-editor.ProseMirror img.ProseMirror-separator { + display: inline !important; + border: none !important; + margin: 0 !important; + } + .remirror-editor.ProseMirror-hideselection *::-moz-selection { + background: transparent; + color: inherit; + } + .remirror-editor.ProseMirror-hideselection *::selection { + background: transparent; + color: inherit; + } + .remirror-editor.ProseMirror-hideselection *::-moz-selection { + background: transparent; + color: inherit; + } + .remirror-editor.ProseMirror-hideselection { + caret-color: transparent; + } + .remirror-editor .ProseMirror-selectednode { + outline: 2px solid #8cf; + } + /* Make sure li selections wrap around markers */ + .remirror-editor li.ProseMirror-selectednode { + outline: none; + } + .remirror-editor li.ProseMirror-selectednode:after { + content: ''; + position: absolute; + left: -32px; + right: -2px; + top: -2px; + bottom: -2px; + border: 2px solid #8cf; + pointer-events: none; + } +`;Ct.div` + ${Hb} +`;var Bb=xt` + /** + * Styles extracted from: packages/remirror__theme/src/extension-blockquote-theme.ts + */ + .remirror-editor.ProseMirror blockquote { + border-left: 3px solid var(--rmr-hue-gray-3); + margin-left: 0; + margin-right: 0; + padding-left: 10px; + font-style: italic; + } + .remirror-editor.ProseMirror blockquote p { + color: #888; + } +`;Ct.div` + ${Bb} +`;var Fb=xt` + /** + * Styles extracted from: packages/remirror__theme/src/extension-callout-theme.ts + */ + .remirror-editor div[data-callout-type] { + display: flex; + margin-left: 0; + margin-right: 0; + padding: 10px; + border-left: 2px solid transparent; + } + + .remirror-editor div[data-callout-type] > :not(.remirror-callout-emoji-wrapper) { + margin-left: 8px; + flex-grow: 1; + } + .remirror-editor div[data-callout-type='info'] { + background: #eef6fc; + border-left-color: #3298dc; + } + .remirror-editor div[data-callout-type='warning'] { + background: #fffbeb; + border-left-color: #ffdd57; + } + .remirror-editor div[data-callout-type='error'] { + background: #feecf0; + border-left-color: #f14668; + } + .remirror-editor div[data-callout-type='success'] { + background: #effaf3; + border-left-color: #48c774; + } + .remirror-editor div[data-callout-type='blank'] { + background: #f8f8f8; + } +`;Ct.div` + ${Fb} +`;var Vb=xt` + /** + * Styles extracted from: packages/remirror__theme/src/extension-code-block-theme.ts + */ + .remirror-wrap { + white-space: pre-wrap !important; + } + + .remirror-language-select-positioner { + position: absolute; + top: var(--y); + left: var(--x); + } + + .remirror-language-select-width { + width: var(--w); + } + + .remirror-a11y-dark code[class*='language-'], + .remirror-a11y-dark pre[class*='language-'] { + color: #f8f8f2; + background: none; + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + -moz-tab-size: 4; + tab-size: 4; + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + } + + /* Code blocks */ + + .remirror-a11y-dark pre[class*='language-'] { + padding: 1em; + margin: 0.5em 0; + overflow: auto; + border-radius: 0.3em; + } + + .remirror-a11y-dark :has(.remirror-language-select-positioner) ~ pre[class*='language-'] { + padding: 2em 1em; + } + + .remirror-a11y-dark :not(pre) > code[class*='language-'], + .remirror-a11y-dark pre[class*='language-'] { + background: #2b2b2b; + } + + /* Inline code */ + + .remirror-a11y-dark :not(pre) > code[class*='language-'] { + padding: 0.1em; + border-radius: 0.3em; + white-space: normal; + } + + .remirror-a11y-dark .token.comment, + .remirror-a11y-dark .token.prolog, + .remirror-a11y-dark .token.doctype, + .remirror-a11y-dark .token.cdata { + color: #d4d0ab; + } + + .remirror-a11y-dark .token.punctuation, + .remirror-a11y-dark .token.punctuation.important { + color: #fefefe; + } + + .remirror-a11y-dark .token.property, + .remirror-a11y-dark .token.tag, + .remirror-a11y-dark .token.constant, + .remirror-a11y-dark .token.symbol, + .remirror-a11y-dark .token.deleted { + color: #ffa07a; + } + + .remirror-a11y-dark .token.boolean, + .remirror-a11y-dark .token.number { + color: #00e0e0; + } + + .remirror-a11y-dark .token.selector, + .remirror-a11y-dark .token.attr-name, + .remirror-a11y-dark .token.string, + .remirror-a11y-dark .token.char, + .remirror-a11y-dark .token.builtin, + .remirror-a11y-dark .token.inserted { + color: #abe338; + } + + .remirror-a11y-dark .token.operator, + .remirror-a11y-dark .token.entity, + .remirror-a11y-dark .token.url, + .remirror-a11y-dark .language-css .token.string, + .remirror-a11y-dark .style .token.string, + .remirror-a11y-dark .token.variable { + color: #00e0e0; + } + + .remirror-a11y-dark .token.atrule, + .remirror-a11y-dark .token.attr-value, + .remirror-a11y-dark .token.function { + color: #ffd700; + } + + .remirror-a11y-dark .token.keyword { + color: #00e0e0; + } + + .remirror-a11y-dark .token.regex, + .remirror-a11y-dark .token.important { + color: #ffd700; + } + + .remirror-a11y-dark .token.important, + .remirror-a11y-dark .token.bold { + font-weight: bold; + } + + .remirror-a11y-dark .token.italic { + font-style: italic; + } + + .remirror-a11y-dark .token.entity { + cursor: help; + } + + @media screen and (-ms-high-contrast: active) { + .remirror-a11y-dark code[class*='language-'], + .remirror-a11y-dark pre[class*='language-'] { + color: windowText; + background: window; + } + .remirror-a11y-dark :not(pre) > code[class*='language-'], + .remirror-a11y-dark pre[class*='language-'] { + background: window; + } + .remirror-a11y-dark .token.important { + background: highlight; + color: window; + font-weight: normal; + } + .remirror-a11y-dark .token.atrule, + .remirror-a11y-dark .token.attr-value, + .remirror-a11y-dark .token.function, + .remirror-a11y-dark .token.keyword, + .remirror-a11y-dark .token.operator, + .remirror-a11y-dark .token.selector { + font-weight: bold; + } + .remirror-a11y-dark .token.attr-value, + .remirror-a11y-dark .token.comment, + .remirror-a11y-dark .token.doctype, + .remirror-a11y-dark .token.function, + .remirror-a11y-dark .token.keyword, + .remirror-a11y-dark .token.operator, + .remirror-a11y-dark .token.property, + .remirror-a11y-dark .token.string { + color: highlight; + } + .remirror-a11y-dark .token.attr-value, + .remirror-a11y-dark .token.url { + font-weight: normal; + } + } + + .remirror-atom-dark code[class*='language-'], + .remirror-atom-dark pre[class*='language-'] { + color: #c5c8c6; + text-shadow: 0 1px rgba(0, 0, 0, 0.3); + font-family: Inconsolata, Monaco, Consolas, 'Courier New', Courier, monospace; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + line-height: 1.5; + -moz-tab-size: 4; + tab-size: 4; + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + } + + /* Code blocks */ + + .remirror-atom-dark pre[class*='language-'] { + padding: 1em; + margin: 0.5em 0; + overflow: auto; + border-radius: 0.3em; + } + + .remirror-atom-dark :has(.remirror-language-select-positioner) ~ pre[class*='language-'] { + padding: 2em 1em; + } + + .remirror-atom-dark :not(pre) > code[class*='language-'], + .remirror-atom-dark pre[class*='language-'] { + background: #1d1f21; + } + + /* Inline code */ + + .remirror-atom-dark :not(pre) > code[class*='language-'] { + padding: 0.1em; + border-radius: 0.3em; + } + + .remirror-atom-dark .token.comment, + .remirror-atom-dark .token.prolog, + .remirror-atom-dark .token.doctype, + .remirror-atom-dark .token.cdata { + color: #7c7c7c; + } + + .remirror-atom-dark .token.punctuation, + .remirror-atom-dark .token.punctuation.important { + color: #c5c8c6; + } + + .remirror-atom-dark .namespace { + opacity: 0.7; + } + + .remirror-atom-dark .token.property, + .remirror-atom-dark .token.keyword, + .remirror-atom-dark .token.tag { + color: #96cbfe; + } + + .remirror-atom-dark .token.class-name { + color: #ffffb6; + text-decoration: underline; + } + + .remirror-atom-dark .token.boolean, + .remirror-atom-dark .token.constant { + color: #99cc99; + } + + .remirror-atom-dark .token.symbol, + .remirror-atom-dark .token.deleted { + color: #f92672; + } + + .remirror-atom-dark .token.number { + color: #ff73fd; + } + + .remirror-atom-dark .token.selector, + .remirror-atom-dark .token.attr-name, + .remirror-atom-dark .token.string, + .remirror-atom-dark .token.char, + .remirror-atom-dark .token.builtin, + .remirror-atom-dark .token.inserted { + color: #a8ff60; + } + + .remirror-atom-dark .token.variable { + color: #c6c5fe; + } + + .remirror-atom-dark .token.operator { + color: #ededed; + } + + .remirror-atom-dark .token.entity { + color: #ffffb6; + /* text-decoration: underline; */ + } + + .remirror-atom-dark .token.url { + color: #96cbfe; + } + + .remirror-atom-dark .language-css .token.string, + .remirror-atom-dark .style .token.string { + color: #87c38a; + } + + .remirror-atom-dark .token.atrule, + .remirror-atom-dark .token.attr-value { + color: #f9ee98; + } + + .remirror-atom-dark .token.function { + color: #dad085; + } + + .remirror-atom-dark .token.regex { + color: #e9c062; + } + + .remirror-atom-dark .token.important { + color: #fd971f; + } + + .remirror-atom-dark .token.important, + .remirror-atom-dark .token.bold { + font-weight: bold; + } + + .remirror-atom-dark .token.italic { + font-style: italic; + } + + .remirror-atom-dark .token.entity { + cursor: help; + } + + .remirror-base16-ateliersulphurpool-light code[class*='language-'], + .remirror-base16-ateliersulphurpool-light pre[class*='language-'] { + font-family: Consolas, Menlo, Monaco, 'Andale Mono WT', 'Andale Mono', 'Lucida Console', + 'Lucida Sans Typewriter', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Liberation Mono', + 'Nimbus Mono L', 'Courier New', Courier, monospace; + font-size: 14px; + line-height: 1.375; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + -moz-tab-size: 4; + tab-size: 4; + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + background: #f5f7ff; + color: #5e6687; + } + + .remirror-base16-ateliersulphurpool-light pre[class*='language-']::-moz-selection, + .remirror-base16-ateliersulphurpool-light pre[class*='language-'] ::-moz-selection, + .remirror-base16-ateliersulphurpool-light code[class*='language-']::-moz-selection, + .remirror-base16-ateliersulphurpool-light code[class*='language-'] ::-moz-selection { + text-shadow: none; + background: #dfe2f1; + } + + .remirror-base16-ateliersulphurpool-light pre[class*='language-']::-moz-selection, + .remirror-base16-ateliersulphurpool-light pre[class*='language-'] ::-moz-selection, + .remirror-base16-ateliersulphurpool-light code[class*='language-']::-moz-selection, + .remirror-base16-ateliersulphurpool-light code[class*='language-'] ::-moz-selection { + text-shadow: none; + background: #dfe2f1; + } + + .remirror-base16-ateliersulphurpool-light pre[class*='language-']::selection, + .remirror-base16-ateliersulphurpool-light pre[class*='language-'] ::selection, + .remirror-base16-ateliersulphurpool-light code[class*='language-']::selection, + .remirror-base16-ateliersulphurpool-light code[class*='language-'] ::selection { + text-shadow: none; + background: #dfe2f1; + } + + /* Code blocks */ + + .remirror-base16-ateliersulphurpool-light pre[class*='language-'] { + padding: 1em; + margin: 0.5em 0; + overflow: auto; + } + + .remirror-base16-ateliersulphurpool-light + :has(.remirror-language-select-positioner) + ~ pre[class*='language-'] { + padding: 2em 1em; + } + + /* Inline code */ + + .remirror-base16-ateliersulphurpool-light :not(pre) > code[class*='language-'] { + padding: 0.1em; + border-radius: 0.3em; + } + + .remirror-base16-ateliersulphurpool-light .token.comment, + .remirror-base16-ateliersulphurpool-light .token.prolog, + .remirror-base16-ateliersulphurpool-light .token.doctype, + .remirror-base16-ateliersulphurpool-light .token.cdata { + color: #898ea4; + } + + .remirror-base16-ateliersulphurpool-light .token.punctuation, + .remirror-base16-ateliersulphurpool-light .token.punctuation.important { + color: #5e6687; + } + + .remirror-base16-ateliersulphurpool-light .token.namespace { + opacity: 0.7; + } + + .remirror-base16-ateliersulphurpool-light .token.operator, + .remirror-base16-ateliersulphurpool-light .token.boolean, + .remirror-base16-ateliersulphurpool-light .token.number { + color: #c76b29; + } + + .remirror-base16-ateliersulphurpool-light .token.property { + color: #c08b30; + } + + .remirror-base16-ateliersulphurpool-light .token.tag { + color: #3d8fd1; + } + + .remirror-base16-ateliersulphurpool-light .token.string { + color: #22a2c9; + } + + .remirror-base16-ateliersulphurpool-light .token.selector { + color: #6679cc; + } + + .remirror-base16-ateliersulphurpool-light .token.attr-name { + color: #c76b29; + } + + .remirror-base16-ateliersulphurpool-light .token.entity, + .remirror-base16-ateliersulphurpool-light .token.url, + .remirror-base16-ateliersulphurpool-light .language-css .token.string, + .remirror-base16-ateliersulphurpool-light .style .token.string { + color: #22a2c9; + } + + .remirror-base16-ateliersulphurpool-light .token.attr-value, + .remirror-base16-ateliersulphurpool-light .token.keyword, + .remirror-base16-ateliersulphurpool-light .token.control, + .remirror-base16-ateliersulphurpool-light .token.directive, + .remirror-base16-ateliersulphurpool-light .token.unit { + color: #ac9739; + } + + .remirror-base16-ateliersulphurpool-light .token.statement, + .remirror-base16-ateliersulphurpool-light .token.regex, + .remirror-base16-ateliersulphurpool-light .token.atrule { + color: #22a2c9; + } + + .remirror-base16-ateliersulphurpool-light .token.placeholder, + .remirror-base16-ateliersulphurpool-light .token.variable { + color: #3d8fd1; + } + + .remirror-base16-ateliersulphurpool-light .token.deleted { + text-decoration: line-through; + } + + .remirror-base16-ateliersulphurpool-light .token.inserted { + border-bottom: 1px dotted #202746; + text-decoration: none; + } + + .remirror-base16-ateliersulphurpool-light .token.italic { + font-style: italic; + } + + .remirror-base16-ateliersulphurpool-light .token.important, + .remirror-base16-ateliersulphurpool-light .token.bold { + font-weight: bold; + } + + .remirror-base16-ateliersulphurpool-light .token.important { + color: #c94922; + } + + .remirror-base16-ateliersulphurpool-light .token.entity { + cursor: help; + } + + .remirror-base16-ateliersulphurpool-light pre > code.highlight { + outline: 0.4em solid #c94922; + outline-offset: 0.4em; + } + + /* overrides color-values for the Line Numbers plugin + * http://prismjs.com/plugins/line-numbers/ + */ + + .remirror-base16-ateliersulphurpool-light .line-numbers .line-numbers-rows { + border-right-color: #dfe2f1; + } + + .remirror-base16-ateliersulphurpool-light .line-numbers-rows > span:before { + color: #979db4; + } + + /* overrides color-values for the Line Highlight plugin + * http://prismjs.com/plugins/line-highlight/ + */ + + .remirror-base16-ateliersulphurpool-light .line-highlight { + background: rgba(107, 115, 148, 0.2); + background: linear-gradient(to right, rgba(107, 115, 148, 0.2) 70%, rgba(107, 115, 148, 0)); + } + + .remirror-cb code[class*='language-'], + .remirror-cb pre[class*='language-'] { + color: #fff; + text-shadow: 0 1px 1px #000; + font-family: Menlo, Monaco, 'Courier New', monospace; + direction: ltr; + text-align: left; + word-spacing: normal; + white-space: pre; + word-wrap: normal; + line-height: 1.4; + background: none; + border: 0; + + -moz-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + } + + .remirror-cb pre[class*='language-'] code { + float: left; + padding: 0 15px 0 0; + } + + .remirror-cb pre[class*='language-'], + .remirror-cb :not(pre) > code[class*='language-'] { + background: #222; + } + + /* Code blocks */ + + .remirror-cb pre[class*='language-'] { + padding: 15px; + margin: 1em 0; + overflow: auto; + border-radius: 8px; + } + + .remirror-cb :has(.remirror-language-select-positioner) ~ pre[class*='language-'] { + padding: 2em 1em; + } + + /* Inline code */ + + .remirror-cb :not(pre) > code[class*='language-'] { + padding: 5px 10px; + line-height: 1; + border-radius: 3px; + } + + .remirror-cb .token.comment, + .remirror-cb .token.prolog, + .remirror-cb .token.doctype, + .remirror-cb .token.cdata { + color: #797979; + } + + .remirror-cb .token.selector, + .remirror-cb .token.operator, + .remirror-cb .token.punctuation, + .remirror-cb .token.punctuation.important { + color: #fff; + } + + .remirror-cb .token.namespace { + opacity: 0.7; + } + + .remirror-cb .token.tag, + .remirror-cb .token.boolean { + color: #ffd893; + } + + .remirror-cb .token.atrule, + .remirror-cb .token.attr-value, + .remirror-cb .token.hex, + .remirror-cb .token.string { + color: #b0c975; + } + + .remirror-cb .token.property, + .remirror-cb .token.entity, + .remirror-cb .token.url, + .remirror-cb .token.attr-name, + .remirror-cb .token.keyword { + color: #c27628; + } + + .remirror-cb .token.regex { + color: #9b71c6; + } + + .remirror-cb .token.entity { + cursor: help; + } + + .remirror-cb .token.function, + .remirror-cb .token.constant { + color: #e5a638; + } + + .remirror-cb .token.variable { + color: #fdfba8; + } + + .remirror-cb .token.number { + color: #8799b0; + } + + .remirror-cb .token.important, + .remirror-cb .token.deliminator { + color: #e45734; + } + + /* Line highlight plugin */ + + .remirror-cb pre[data-line] { + position: relative; + padding: 1em 0 1em 3em; + } + + .remirror-cb .line-highlight { + position: absolute; + left: 0; + right: 0; + margin-top: 1em; /* Same as .prism's padding-top */ + background: rgba(255, 255, 255, 0.2); + pointer-events: none; + line-height: inherit; + white-space: pre; + } + + .remirror-cb .line-highlight:before, + .remirror-cb .line-highlight[data-end]:after { + content: attr(data-start); + position: absolute; + top: 0.3em; + left: 0.6em; + min-width: 1em; + padding: 0 0.5em; + background-color: rgba(255, 255, 255, 0.3); + color: #fff; + font: bold 65%/1.5 sans-serif; + text-align: center; + border-radius: 8px; + text-shadow: none; + } + + .remirror-cb .line-highlight[data-end]:after { + content: attr(data-end); + top: auto; + bottom: 0.4em; + } + + /* for line numbers */ + + .remirror-cb .line-numbers-rows { + margin: 0; + } + + .remirror-cb .line-numbers-rows span { + padding-right: 10px; + border-right: 3px #d9d336 solid; + } + + .remirror-darcula code[class*='language-'], + .remirror-darcula pre[class*='language-'] { + color: #a9b7c6; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + line-height: 1.5; + + -moz-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + } + + .remirror-darcula pre[class*='language-']::-moz-selection, + .remirror-darcula pre[class*='language-'] ::-moz-selection, + .remirror-darcula code[class*='language-']::-moz-selection, + .remirror-darcula code[class*='language-'] ::-moz-selection { + color: inherit; + background: rgba(33, 66, 131, 0.85); + } + + .remirror-darcula pre[class*='language-']::-moz-selection, + .remirror-darcula pre[class*='language-'] ::-moz-selection, + .remirror-darcula code[class*='language-']::-moz-selection, + .remirror-darcula code[class*='language-'] ::-moz-selection { + color: inherit; + background: rgba(33, 66, 131, 0.85); + } + + .remirror-darcula pre[class*='language-']::selection, + .remirror-darcula pre[class*='language-'] ::selection, + .remirror-darcula code[class*='language-']::selection, + .remirror-darcula code[class*='language-'] ::selection { + color: inherit; + background: rgba(33, 66, 131, 0.85); + } + + /* Code blocks */ + + .remirror-darcula pre[class*='language-'] { + padding: 1em; + margin: 0.5em 0; + overflow: auto; + } + + .remirror-darcula :has(.remirror-language-select-positioner) ~ pre[class*='language-'] { + padding: 2em 1em; + } + + .remirror-darcula :not(pre) > code[class*='language-'], + .remirror-darcula pre[class*='language-'] { + background: #2b2b2b; + } + + /* Inline code */ + + .remirror-darcula :not(pre) > code[class*='language-'] { + padding: 0.1em; + border-radius: 0.3em; + } + + .remirror-darcula .token.comment, + .remirror-darcula .token.prolog, + .remirror-darcula .token.cdata { + color: #808080; + } + + .remirror-darcula .token.delimiter, + .remirror-darcula .token.boolean, + .remirror-darcula .token.keyword, + .remirror-darcula .token.selector, + .remirror-darcula .token.important, + .remirror-darcula .token.atrule { + color: #cc7832; + } + + .remirror-darcula .token.operator, + .remirror-darcula .token.punctuation, + .remirror-darcula .token.attr-name { + color: #a9b7c6; + } + + .remirror-darcula .token.tag, + .remirror-darcula .token.tag .punctuation, + .remirror-darcula .token.doctype, + .remirror-darcula .token.builtin { + color: #e8bf6a; + } + + .remirror-darcula .token.entity, + .remirror-darcula .token.number, + .remirror-darcula .token.symbol { + color: #6897bb; + } + + .remirror-darcula .token.property, + .remirror-darcula .token.constant, + .remirror-darcula .token.variable { + color: #9876aa; + } + + .remirror-darcula .token.string, + .remirror-darcula .token.char { + color: #6a8759; + } + + .remirror-darcula .token.attr-value, + .remirror-darcula .token.attr-value .punctuation { + color: #a5c261; + } + + .remirror-darcula .token.attr-value .punctuation:first-of-type { + color: #a9b7c6; + } + + .remirror-darcula .token.url { + color: #287bde; + text-decoration: underline; + } + + .remirror-darcula .token.function { + color: #ffc66d; + } + + .remirror-darcula .token.regex { + background: #364135; + } + + .remirror-darcula .token.bold { + font-weight: bold; + } + + .remirror-darcula .token.italic { + font-style: italic; + } + + .remirror-darcula .token.inserted { + background: #294436; + } + + .remirror-darcula .token.deleted { + background: #484a4a; + } + + /*code.language-css .token.punctuation, .token.punctuation.important {color: + #cc7832; +}*/ + + .remirror-darcula code.language-css .token.property, + .remirror-darcula code.language-css .token.property + .token.punctuation, + .remirror-darcula .token.punctuation.important { + color: #a9b7c6; + } + + .remirror-darcula code.language-css .token.id { + color: #ffc66d; + } + + .remirror-darcula code.language-css .token.selector > .token.class, + .remirror-darcula code.language-css .token.selector > .token.attribute, + .remirror-darcula code.language-css .token.selector > .token.pseudo-class, + .remirror-darcula code.language-css .token.selector > .token.pseudo-element { + color: #ffc66d; + } + + .remirror-dracula code[class*='language-'], + .remirror-dracula pre[class*='language-'] { + color: #f8f8f2; + background: none; + text-shadow: 0 1px rgba(0, 0, 0, 0.3); + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + -moz-tab-size: 4; + tab-size: 4; + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + } + + /* Code blocks */ + + .remirror-dracula pre[class*='language-'] { + padding: 1em; + margin: 0.5em 0; + overflow: auto; + border-radius: 0.3em; + } + + .remirror-dracula :has(.remirror-language-select-positioner) ~ pre[class*='language-'] { + padding: 2em 1em; + } + + .remirror-dracula :not(pre) > code[class*='language-'], + .remirror-dracula pre[class*='language-'] { + background: #282a36; + } + + /* Inline code */ + + .remirror-dracula :not(pre) > code[class*='language-'] { + padding: 0.1em; + border-radius: 0.3em; + white-space: normal; + } + + .remirror-dracula .token.comment, + .remirror-dracula .token.prolog, + .remirror-dracula .token.doctype, + .remirror-dracula .token.cdata { + color: #6272a4; + } + + .remirror-dracula .token.punctuation, + .remirror-dracula .token.punctuation.important { + color: #f8f8f2; + } + + .remirror-dracula .namespace { + opacity: 0.7; + } + + .remirror-dracula .token.property, + .remirror-dracula .token.tag, + .remirror-dracula .token.constant, + .remirror-dracula .token.symbol, + .remirror-dracula .token.deleted { + color: #ff79c6; + } + + .remirror-dracula .token.boolean, + .remirror-dracula .token.number { + color: #bd93f9; + } + + .remirror-dracula .token.selector, + .remirror-dracula .token.attr-name, + .remirror-dracula .token.string, + .remirror-dracula .token.char, + .remirror-dracula .token.builtin, + .remirror-dracula .token.inserted { + color: #50fa7b; + } + + .remirror-dracula .token.operator, + .remirror-dracula .token.entity, + .remirror-dracula .token.url, + .remirror-dracula .language-css .token.string, + .remirror-dracula .style .token.string, + .remirror-dracula .token.variable { + color: #f8f8f2; + } + + .remirror-dracula .token.atrule, + .remirror-dracula .token.attr-value, + .remirror-dracula .token.function, + .remirror-dracula .token.class-name { + color: #f1fa8c; + } + + .remirror-dracula .token.keyword { + color: #8be9fd; + } + + .remirror-dracula .token.regex, + .remirror-dracula .token.important { + color: #ffb86c; + } + + .remirror-dracula .token.important, + .remirror-dracula .token.bold { + font-weight: bold; + } + + .remirror-dracula .token.italic { + font-style: italic; + } + + .remirror-dracula .token.entity { + cursor: help; + } + + .remirror-duotone-dark code[class*='language-'], + .remirror-duotone-dark pre[class*='language-'] { + font-family: Consolas, Menlo, Monaco, 'Andale Mono WT', 'Andale Mono', 'Lucida Console', + 'Lucida Sans Typewriter', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Liberation Mono', + 'Nimbus Mono L', 'Courier New', Courier, monospace; + font-size: 14px; + line-height: 1.375; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + + -moz-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + background: #2a2734; + color: #9a86fd; + } + + .remirror-duotone-dark pre[class*='language-']::-moz-selection, + .remirror-duotone-dark pre[class*='language-'] ::-moz-selection, + .remirror-duotone-dark code[class*='language-']::-moz-selection, + .remirror-duotone-dark code[class*='language-'] ::-moz-selection { + text-shadow: none; + background: #6a51e6; + } + + .remirror-duotone-dark pre[class*='language-']::-moz-selection, + .remirror-duotone-dark pre[class*='language-'] ::-moz-selection, + .remirror-duotone-dark code[class*='language-']::-moz-selection, + .remirror-duotone-dark code[class*='language-'] ::-moz-selection { + text-shadow: none; + background: #6a51e6; + } + + .remirror-duotone-dark pre[class*='language-']::selection, + .remirror-duotone-dark pre[class*='language-'] ::selection, + .remirror-duotone-dark code[class*='language-']::selection, + .remirror-duotone-dark code[class*='language-'] ::selection { + text-shadow: none; + background: #6a51e6; + } + + /* Code blocks */ + + .remirror-duotone-dark pre[class*='language-'] { + padding: 1em; + margin: 0.5em 0; + overflow: auto; + } + + .remirror-duotone-dark :has(.remirror-language-select-positioner) ~ pre[class*='language-'] { + padding: 2em 1em; + } + + /* Inline code */ + + .remirror-duotone-dark :not(pre) > code[class*='language-'] { + padding: 0.1em; + border-radius: 0.3em; + } + + .remirror-duotone-dark .token.comment, + .remirror-duotone-dark .token.prolog, + .remirror-duotone-dark .token.doctype, + .remirror-duotone-dark .token.cdata { + color: #6c6783; + } + + .remirror-duotone-dark .token.punctuation, + .remirror-duotone-dark .token.punctuation.important { + color: #6c6783; + } + + .remirror-duotone-dark .token.namespace { + opacity: 0.7; + } + + .remirror-duotone-dark .token.tag, + .remirror-duotone-dark .token.operator, + .remirror-duotone-dark .token.number { + color: #e09142; + } + + .remirror-duotone-dark .token.property, + .remirror-duotone-dark .token.function { + color: #9a86fd; + } + + .remirror-duotone-dark .token.tag-id, + .remirror-duotone-dark .token.selector, + .remirror-duotone-dark .token.atrule-id { + color: #eeebff; + } + + .remirror-duotone-dark code.language-javascript, + .remirror-duotone-dark .token.attr-name { + color: #c4b9fe; + } + + .remirror-duotone-dark code.language-css, + .remirror-duotone-dark code.language-scss, + .remirror-duotone-dark .token.boolean, + .remirror-duotone-dark .token.string, + .remirror-duotone-dark .token.entity, + .remirror-duotone-dark .token.url, + .remirror-duotone-dark .language-css .token.string, + .remirror-duotone-dark .language-scss .token.string, + .remirror-duotone-dark .style .token.string, + .remirror-duotone-dark .token.attr-value, + .remirror-duotone-dark .token.keyword, + .remirror-duotone-dark .token.control, + .remirror-duotone-dark .token.directive, + .remirror-duotone-dark .token.unit, + .remirror-duotone-dark .token.statement, + .remirror-duotone-dark .token.regex, + .remirror-duotone-dark .token.atrule { + color: #ffcc99; + } + + .remirror-duotone-dark .token.placeholder, + .remirror-duotone-dark .token.variable { + color: #ffcc99; + } + + .remirror-duotone-dark .token.deleted { + text-decoration: line-through; + } + + .remirror-duotone-dark .token.inserted { + border-bottom: 1px dotted #eeebff; + text-decoration: none; + } + + .remirror-duotone-dark .token.italic { + font-style: italic; + } + + .remirror-duotone-dark .token.important, + .remirror-duotone-dark .token.bold { + font-weight: bold; + } + + .remirror-duotone-dark .token.important { + color: #c4b9fe; + } + + .remirror-duotone-dark .token.entity { + cursor: help; + } + + .remirror-duotone-dark pre > code.highlight { + outline: 0.4em solid #8a75f5; + outline-offset: 0.4em; + } + + /* overrides color-values for the Line Numbers plugin + * http://prismjs.com/plugins/line-numbers/ + */ + + .remirror-duotone-dark .line-numbers .line-numbers-rows { + border-right-color: #2c2937; + } + + .remirror-duotone-dark .line-numbers-rows > span:before { + color: #3c3949; + } + + /* overrides color-values for the Line Highlight plugin +* http://prismjs.com/plugins/line-highlight/ +*/ + + .remirror-duotone-dark .line-highlight { + background: rgba(224, 145, 66, 0.2); + background: linear-gradient(to right, rgba(224, 145, 66, 0.2) 70%, rgba(224, 145, 66, 0)); + } + + .remirror-duotone-earth code[class*='language-'], + .remirror-duotone-earth pre[class*='language-'] { + font-family: Consolas, Menlo, Monaco, 'Andale Mono WT', 'Andale Mono', 'Lucida Console', + 'Lucida Sans Typewriter', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Liberation Mono', + 'Nimbus Mono L', 'Courier New', Courier, monospace; + font-size: 14px; + line-height: 1.375; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + + -moz-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + background: #322d29; + color: #88786d; + } + + .remirror-duotone-earth pre[class*='language-']::-moz-selection, + .remirror-duotone-earth pre[class*='language-'] ::-moz-selection, + .remirror-duotone-earth code[class*='language-']::-moz-selection, + .remirror-duotone-earth code[class*='language-'] ::-moz-selection { + text-shadow: none; + background: #6f5849; + } + + .remirror-duotone-earth pre[class*='language-']::-moz-selection, + .remirror-duotone-earth pre[class*='language-'] ::-moz-selection, + .remirror-duotone-earth code[class*='language-']::-moz-selection, + .remirror-duotone-earth code[class*='language-'] ::-moz-selection { + text-shadow: none; + background: #6f5849; + } + + .remirror-duotone-earth pre[class*='language-']::selection, + .remirror-duotone-earth pre[class*='language-'] ::selection, + .remirror-duotone-earth code[class*='language-']::selection, + .remirror-duotone-earth code[class*='language-'] ::selection { + text-shadow: none; + background: #6f5849; + } + + /* Code blocks */ + + .remirror-duotone-earth pre[class*='language-'] { + padding: 1em; + margin: 0.5em 0; + overflow: auto; + } + + .remirror-duotone-earth :has(.remirror-language-select-positioner) ~ pre[class*='language-'] { + padding: 2em 1em; + } + + /* Inline code */ + + .remirror-duotone-earth :not(pre) > code[class*='language-'] { + padding: 0.1em; + border-radius: 0.3em; + } + + .remirror-duotone-earth .token.comment, + .remirror-duotone-earth .token.prolog, + .remirror-duotone-earth .token.doctype, + .remirror-duotone-earth .token.cdata { + color: #6a5f58; + } + + .remirror-duotone-earth .token.punctuation, + .remirror-duotone-earth .token.punctuation.important { + color: #6a5f58; + } + + .remirror-duotone-earth .token.namespace { + opacity: 0.7; + } + + .remirror-duotone-earth .token.tag, + .remirror-duotone-earth .token.operator, + .remirror-duotone-earth .token.number { + color: #bfa05a; + } + + .remirror-duotone-earth .token.property, + .remirror-duotone-earth .token.function { + color: #88786d; + } + + .remirror-duotone-earth .token.tag-id, + .remirror-duotone-earth .token.selector, + .remirror-duotone-earth .token.atrule-id { + color: #fff3eb; + } + + .remirror-duotone-earth code.language-javascript, + .remirror-duotone-earth .token.attr-name { + color: #a48774; + } + + .remirror-duotone-earth code.language-css, + .remirror-duotone-earth code.language-scss, + .remirror-duotone-earth .token.boolean, + .remirror-duotone-earth .token.string, + .remirror-duotone-earth .token.entity, + .remirror-duotone-earth .token.url, + .remirror-duotone-earth .language-css .token.string, + .remirror-duotone-earth .language-scss .token.string, + .remirror-duotone-earth .style .token.string, + .remirror-duotone-earth .token.attr-value, + .remirror-duotone-earth .token.keyword, + .remirror-duotone-earth .token.control, + .remirror-duotone-earth .token.directive, + .remirror-duotone-earth .token.unit, + .remirror-duotone-earth .token.statement, + .remirror-duotone-earth .token.regex, + .remirror-duotone-earth .token.atrule { + color: #fcc440; + } + + .remirror-duotone-earth .token.placeholder, + .remirror-duotone-earth .token.variable { + color: #fcc440; + } + + .remirror-duotone-earth .token.deleted { + text-decoration: line-through; + } + + .remirror-duotone-earth .token.inserted { + border-bottom: 1px dotted #fff3eb; + text-decoration: none; + } + + .remirror-duotone-earth .token.italic { + font-style: italic; + } + + .remirror-duotone-earth .token.important, + .remirror-duotone-earth .token.bold { + font-weight: bold; + } + + .remirror-duotone-earth .token.important { + color: #a48774; + } + + .remirror-duotone-earth .token.entity { + cursor: help; + } + + .remirror-duotone-earth pre > code.highlight { + outline: 0.4em solid #816d5f; + outline-offset: 0.4em; + } + + /* overrides color-values for the Line Numbers plugin + * http://prismjs.com/plugins/line-numbers/ + */ + + .remirror-duotone-earth .line-numbers .line-numbers-rows { + border-right-color: #35302b; + } + + .remirror-duotone-earth .line-numbers-rows > span:before { + color: #46403d; + } + + /* overrides color-values for the Line Highlight plugin +* http://prismjs.com/plugins/line-highlight/ +*/ + + .remirror-duotone-earth .line-highlight { + background: rgba(191, 160, 90, 0.2); + background: linear-gradient(to right, rgba(191, 160, 90, 0.2) 70%, rgba(191, 160, 90, 0)); + } + + .remirror-duotone-forest code[class*='language-'], + .remirror-duotone-forest pre[class*='language-'] { + font-family: Consolas, Menlo, Monaco, 'Andale Mono WT', 'Andale Mono', 'Lucida Console', + 'Lucida Sans Typewriter', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Liberation Mono', + 'Nimbus Mono L', 'Courier New', Courier, monospace; + font-size: 14px; + line-height: 1.375; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + + -moz-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + background: #2a2d2a; + color: #687d68; + } + + .remirror-duotone-forest pre[class*='language-']::-moz-selection, + .remirror-duotone-forest pre[class*='language-'] ::-moz-selection, + .remirror-duotone-forest code[class*='language-']::-moz-selection, + .remirror-duotone-forest code[class*='language-'] ::-moz-selection { + text-shadow: none; + background: #435643; + } + + .remirror-duotone-forest pre[class*='language-']::-moz-selection, + .remirror-duotone-forest pre[class*='language-'] ::-moz-selection, + .remirror-duotone-forest code[class*='language-']::-moz-selection, + .remirror-duotone-forest code[class*='language-'] ::-moz-selection { + text-shadow: none; + background: #435643; + } + + .remirror-duotone-forest pre[class*='language-']::selection, + .remirror-duotone-forest pre[class*='language-'] ::selection, + .remirror-duotone-forest code[class*='language-']::selection, + .remirror-duotone-forest code[class*='language-'] ::selection { + text-shadow: none; + background: #435643; + } + + /* Code blocks */ + + .remirror-duotone-forest pre[class*='language-'] { + padding: 1em; + margin: 0.5em 0; + overflow: auto; + } + + .remirror-duotone-forest :has(.remirror-language-select-positioner) ~ pre[class*='language-'] { + padding: 2em 1em; + } + + /* Inline code */ + + .remirror-duotone-forest :not(pre) > code[class*='language-'] { + padding: 0.1em; + border-radius: 0.3em; + } + + .remirror-duotone-forest .token.comment, + .remirror-duotone-forest .token.prolog, + .remirror-duotone-forest .token.doctype, + .remirror-duotone-forest .token.cdata { + color: #535f53; + } + + .remirror-duotone-forest .token.punctuation, + .remirror-duotone-forest .token.punctuation.important { + color: #535f53; + } + + .remirror-duotone-forest .token.namespace { + opacity: 0.7; + } + + .remirror-duotone-forest .token.tag, + .remirror-duotone-forest .token.operator, + .remirror-duotone-forest .token.number { + color: #a2b34d; + } + + .remirror-duotone-forest .token.property, + .remirror-duotone-forest .token.function { + color: #687d68; + } + + .remirror-duotone-forest .token.tag-id, + .remirror-duotone-forest .token.selector, + .remirror-duotone-forest .token.atrule-id { + color: #f0fff0; + } + + .remirror-duotone-forest code.language-javascript, + .remirror-duotone-forest .token.attr-name { + color: #b3d6b3; + } + + .remirror-duotone-forest code.language-css, + .remirror-duotone-forest code.language-scss, + .remirror-duotone-forest .token.boolean, + .remirror-duotone-forest .token.string, + .remirror-duotone-forest .token.entity, + .remirror-duotone-forest .token.url, + .remirror-duotone-forest .language-css .token.string, + .remirror-duotone-forest .language-scss .token.string, + .remirror-duotone-forest .style .token.string, + .remirror-duotone-forest .token.attr-value, + .remirror-duotone-forest .token.keyword, + .remirror-duotone-forest .token.control, + .remirror-duotone-forest .token.directive, + .remirror-duotone-forest .token.unit, + .remirror-duotone-forest .token.statement, + .remirror-duotone-forest .token.regex, + .remirror-duotone-forest .token.atrule { + color: #e5fb79; + } + + .remirror-duotone-forest .token.placeholder, + .remirror-duotone-forest .token.variable { + color: #e5fb79; + } + + .remirror-duotone-forest .token.deleted { + text-decoration: line-through; + } + + .remirror-duotone-forest .token.inserted { + border-bottom: 1px dotted #f0fff0; + text-decoration: none; + } + + .remirror-duotone-forest .token.italic { + font-style: italic; + } + + .remirror-duotone-forest .token.important, + .remirror-duotone-forest .token.bold { + font-weight: bold; + } + + .remirror-duotone-forest .token.important { + color: #b3d6b3; + } + + .remirror-duotone-forest .token.entity { + cursor: help; + } + + .remirror-duotone-forest pre > code.highlight { + outline: 0.4em solid #5c705c; + outline-offset: 0.4em; + } + + /* overrides color-values for the Line Numbers plugin + * http://prismjs.com/plugins/line-numbers/ + */ + + .remirror-duotone-forest .line-numbers .line-numbers-rows { + border-right-color: #2c302c; + } + + .remirror-duotone-forest .line-numbers-rows > span:before { + color: #3b423b; + } + + /* overrides color-values for the Line Highlight plugin +* http://prismjs.com/plugins/line-highlight/ +*/ + + .remirror-duotone-forest .line-highlight { + background: rgba(162, 179, 77, 0.2); + background: linear-gradient(to right, rgba(162, 179, 77, 0.2) 70%, rgba(162, 179, 77, 0)); + } + + .remirror-duotone-light code[class*='language-'], + .remirror-duotone-light pre[class*='language-'] { + font-family: Consolas, Menlo, Monaco, 'Andale Mono WT', 'Andale Mono', 'Lucida Console', + 'Lucida Sans Typewriter', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Liberation Mono', + 'Nimbus Mono L', 'Courier New', Courier, monospace; + font-size: 14px; + line-height: 1.375; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + + -moz-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + background: #faf8f5; + color: #728fcb; + } + + .remirror-duotone-light pre[class*='language-']::-moz-selection, + .remirror-duotone-light pre[class*='language-'] ::-moz-selection, + .remirror-duotone-light code[class*='language-']::-moz-selection, + .remirror-duotone-light code[class*='language-'] ::-moz-selection { + text-shadow: none; + background: #faf8f5; + } + + .remirror-duotone-light pre[class*='language-']::-moz-selection, + .remirror-duotone-light pre[class*='language-'] ::-moz-selection, + .remirror-duotone-light code[class*='language-']::-moz-selection, + .remirror-duotone-light code[class*='language-'] ::-moz-selection { + text-shadow: none; + background: #faf8f5; + } + + .remirror-duotone-light pre[class*='language-']::selection, + .remirror-duotone-light pre[class*='language-'] ::selection, + .remirror-duotone-light code[class*='language-']::selection, + .remirror-duotone-light code[class*='language-'] ::selection { + text-shadow: none; + background: #faf8f5; + } + + /* Code blocks */ + + .remirror-duotone-light pre[class*='language-'] { + padding: 1em; + margin: 0.5em 0; + overflow: auto; + } + + .remirror-duotone-light :has(.remirror-language-select-positioner) ~ pre[class*='language-'] { + padding: 2em 1em; + } + + /* Inline code */ + + .remirror-duotone-light :not(pre) > code[class*='language-'] { + padding: 0.1em; + border-radius: 0.3em; + } + + .remirror-duotone-light .token.comment, + .remirror-duotone-light .token.prolog, + .remirror-duotone-light .token.doctype, + .remirror-duotone-light .token.cdata { + color: #b6ad9a; + } + + .remirror-duotone-light .token.punctuation, + .remirror-duotone-light .token.punctuation.important { + color: #b6ad9a; + } + + .remirror-duotone-light .token.namespace { + opacity: 0.7; + } + + .remirror-duotone-light .token.tag, + .remirror-duotone-light .token.operator, + .remirror-duotone-light .token.number { + color: #063289; + } + + .remirror-duotone-light .token.property, + .remirror-duotone-light .token.function { + color: #b29762; + } + + .remirror-duotone-light .token.tag-id, + .remirror-duotone-light .token.selector, + .remirror-duotone-light .token.atrule-id { + color: #2d2006; + } + + .remirror-duotone-light code.language-javascript, + .remirror-duotone-light .token.attr-name { + color: #896724; + } + + .remirror-duotone-light code.language-css, + .remirror-duotone-light code.language-scss, + .remirror-duotone-light .token.boolean, + .remirror-duotone-light .token.string, + .remirror-duotone-light .token.entity, + .remirror-duotone-light .token.url, + .remirror-duotone-light .language-css .token.string, + .remirror-duotone-light .language-scss .token.string, + .remirror-duotone-light .style .token.string, + .remirror-duotone-light .token.attr-value, + .remirror-duotone-light .token.keyword, + .remirror-duotone-light .token.control, + .remirror-duotone-light .token.directive, + .remirror-duotone-light .token.unit, + .remirror-duotone-light .token.statement, + .remirror-duotone-light .token.regex, + .remirror-duotone-light .token.atrule { + color: #728fcb; + } + + .remirror-duotone-light .token.placeholder, + .remirror-duotone-light .token.variable { + color: #93abdc; + } + + .remirror-duotone-light .token.deleted { + text-decoration: line-through; + } + + .remirror-duotone-light .token.inserted { + border-bottom: 1px dotted #2d2006; + text-decoration: none; + } + + .remirror-duotone-light .token.italic { + font-style: italic; + } + + .remirror-duotone-light .token.important, + .remirror-duotone-light .token.bold { + font-weight: bold; + } + + .remirror-duotone-light .token.important { + color: #896724; + } + + .remirror-duotone-light .token.entity { + cursor: help; + } + + .remirror-duotone-light pre > code.highlight { + outline: 0.4em solid #896724; + outline-offset: 0.4em; + } + + /* overrides color-values for the Line Numbers plugin + * http://prismjs.com/plugins/line-numbers/ + */ + + .remirror-duotone-light .line-numbers .line-numbers-rows { + border-right-color: #ece8de; + } + + .remirror-duotone-light .line-numbers-rows > span:before { + color: #cdc4b1; + } + + /* overrides color-values for the Line Highlight plugin + * http://prismjs.com/plugins/line-highlight/ + */ + + .remirror-duotone-light .line-highlight { + background: rgba(45, 32, 6, 0.2); + background: linear-gradient(to right, rgba(45, 32, 6, 0.2) 70%, rgba(45, 32, 6, 0)); + } + + .remirror-duotone-sea code[class*='language-'], + .remirror-duotone-sea pre[class*='language-'] { + font-family: Consolas, Menlo, Monaco, 'Andale Mono WT', 'Andale Mono', 'Lucida Console', + 'Lucida Sans Typewriter', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Liberation Mono', + 'Nimbus Mono L', 'Courier New', Courier, monospace; + font-size: 14px; + line-height: 1.375; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + + -moz-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + background: #1d262f; + color: #57718e; + } + + .remirror-duotone-sea pre[class*='language-']::-moz-selection, + .remirror-duotone-sea pre[class*='language-'] ::-moz-selection, + .remirror-duotone-sea code[class*='language-']::-moz-selection, + .remirror-duotone-sea code[class*='language-'] ::-moz-selection { + text-shadow: none; + background: #004a9e; + } + + .remirror-duotone-sea pre[class*='language-']::-moz-selection, + .remirror-duotone-sea pre[class*='language-'] ::-moz-selection, + .remirror-duotone-sea code[class*='language-']::-moz-selection, + .remirror-duotone-sea code[class*='language-'] ::-moz-selection { + text-shadow: none; + background: #004a9e; + } + + .remirror-duotone-sea pre[class*='language-']::selection, + .remirror-duotone-sea pre[class*='language-'] ::selection, + .remirror-duotone-sea code[class*='language-']::selection, + .remirror-duotone-sea code[class*='language-'] ::selection { + text-shadow: none; + background: #004a9e; + } + + /* Code blocks */ + + .remirror-duotone-sea pre[class*='language-'] { + padding: 1em; + margin: 0.5em 0; + overflow: auto; + } + + .remirror-duotone-sea :has(.remirror-language-select-positioner) ~ pre[class*='language-'] { + padding: 2em 1em; + } + + /* Inline code */ + + .remirror-duotone-sea :not(pre) > code[class*='language-'] { + padding: 0.1em; + border-radius: 0.3em; + } + + .remirror-duotone-sea .token.comment, + .remirror-duotone-sea .token.prolog, + .remirror-duotone-sea .token.doctype, + .remirror-duotone-sea .token.cdata { + color: #4a5f78; + } + + .remirror-duotone-sea .token.punctuation, + .remirror-duotone-sea .token.punctuation.important { + color: #4a5f78; + } + + .remirror-duotone-sea .token.namespace { + opacity: 0.7; + } + + .remirror-duotone-sea .token.tag, + .remirror-duotone-sea .token.operator, + .remirror-duotone-sea .token.number { + color: #0aa370; + } + + .remirror-duotone-sea .token.property, + .remirror-duotone-sea .token.function { + color: #57718e; + } + + .remirror-duotone-sea .token.tag-id, + .remirror-duotone-sea .token.selector, + .remirror-duotone-sea .token.atrule-id { + color: #ebf4ff; + } + + .remirror-duotone-sea code.language-javascript, + .remirror-duotone-sea .token.attr-name { + color: #7eb6f6; + } + + .remirror-duotone-sea code.language-css, + .remirror-duotone-sea code.language-scss, + .remirror-duotone-sea .token.boolean, + .remirror-duotone-sea .token.string, + .remirror-duotone-sea .token.entity, + .remirror-duotone-sea .token.url, + .remirror-duotone-sea .language-css .token.string, + .remirror-duotone-sea .language-scss .token.string, + .remirror-duotone-sea .style .token.string, + .remirror-duotone-sea .token.attr-value, + .remirror-duotone-sea .token.keyword, + .remirror-duotone-sea .token.control, + .remirror-duotone-sea .token.directive, + .remirror-duotone-sea .token.unit, + .remirror-duotone-sea .token.statement, + .remirror-duotone-sea .token.regex, + .remirror-duotone-sea .token.atrule { + color: #47ebb4; + } + + .remirror-duotone-sea .token.placeholder, + .remirror-duotone-sea .token.variable { + color: #47ebb4; + } + + .remirror-duotone-sea .token.deleted { + text-decoration: line-through; + } + + .remirror-duotone-sea .token.inserted { + border-bottom: 1px dotted #ebf4ff; + text-decoration: none; + } + + .remirror-duotone-sea .token.italic { + font-style: italic; + } + + .remirror-duotone-sea .token.important, + .remirror-duotone-sea .token.bold { + font-weight: bold; + } + + .remirror-duotone-sea .token.important { + color: #7eb6f6; + } + + .remirror-duotone-sea .token.entity { + cursor: help; + } + + .remirror-duotone-sea pre > code.highlight { + outline: 0.4em solid #34659d; + outline-offset: 0.4em; + } + + /* overrides color-values for the Line Numbers plugin + * http://prismjs.com/plugins/line-numbers/ + */ + + .remirror-duotone-sea .line-numbers .line-numbers-rows { + border-right-color: #1f2932; + } + + .remirror-duotone-sea .line-numbers-rows > span:before { + color: #2c3847; + } + + /* overrides color-values for the Line Highlight plugin +* http://prismjs.com/plugins/line-highlight/ +*/ + + .remirror-duotone-sea .line-highlight { + background: rgba(10, 163, 112, 0.2); + background: linear-gradient(to right, rgba(10, 163, 112, 0.2) 70%, rgba(10, 163, 112, 0)); + } + + .remirror-duotone-space code[class*='language-'], + .remirror-duotone-space pre[class*='language-'] { + font-family: Consolas, Menlo, Monaco, 'Andale Mono WT', 'Andale Mono', 'Lucida Console', + 'Lucida Sans Typewriter', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Liberation Mono', + 'Nimbus Mono L', 'Courier New', Courier, monospace; + font-size: 14px; + line-height: 1.375; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + + -moz-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + background: #24242e; + color: #767693; + } + + .remirror-duotone-space pre[class*='language-']::-moz-selection, + .remirror-duotone-space pre[class*='language-'] ::-moz-selection, + .remirror-duotone-space code[class*='language-']::-moz-selection, + .remirror-duotone-space code[class*='language-'] ::-moz-selection { + text-shadow: none; + background: #5151e6; + } + + .remirror-duotone-space pre[class*='language-']::-moz-selection, + .remirror-duotone-space pre[class*='language-'] ::-moz-selection, + .remirror-duotone-space code[class*='language-']::-moz-selection, + .remirror-duotone-space code[class*='language-'] ::-moz-selection { + text-shadow: none; + background: #5151e6; + } + + .remirror-duotone-space pre[class*='language-']::selection, + .remirror-duotone-space pre[class*='language-'] ::selection, + .remirror-duotone-space code[class*='language-']::selection, + .remirror-duotone-space code[class*='language-'] ::selection { + text-shadow: none; + background: #5151e6; + } + + /* Code blocks */ + + .remirror-duotone-space pre[class*='language-'] { + padding: 1em; + margin: 0.5em 0; + overflow: auto; + } + + .remirror-duotone-space :has(.remirror-language-select-positioner) ~ pre[class*='language-'] { + padding: 2em 1em; + } + + /* Inline code */ + + .remirror-duotone-space :not(pre) > code[class*='language-'] { + padding: 0.1em; + border-radius: 0.3em; + } + + .remirror-duotone-space .token.comment, + .remirror-duotone-space .token.prolog, + .remirror-duotone-space .token.doctype, + .remirror-duotone-space .token.cdata { + color: #5b5b76; + } + + .remirror-duotone-space .token.punctuation, + .remirror-duotone-space .token.punctuation.important { + color: #5b5b76; + } + + .remirror-duotone-space .token.namespace { + opacity: 0.7; + } + + .remirror-duotone-space .token.tag, + .remirror-duotone-space .token.operator, + .remirror-duotone-space .token.number { + color: #dd672c; + } + + .remirror-duotone-space .token.property, + .remirror-duotone-space .token.function { + color: #767693; + } + + .remirror-duotone-space .token.tag-id, + .remirror-duotone-space .token.selector, + .remirror-duotone-space .token.atrule-id { + color: #ebebff; + } + + .remirror-duotone-space code.language-javascript, + .remirror-duotone-space .token.attr-name { + color: #aaaaca; + } + + .remirror-duotone-space code.language-css, + .remirror-duotone-space code.language-scss, + .remirror-duotone-space .token.boolean, + .remirror-duotone-space .token.string, + .remirror-duotone-space .token.entity, + .remirror-duotone-space .token.url, + .remirror-duotone-space .language-css .token.string, + .remirror-duotone-space .language-scss .token.string, + .remirror-duotone-space .style .token.string, + .remirror-duotone-space .token.attr-value, + .remirror-duotone-space .token.keyword, + .remirror-duotone-space .token.control, + .remirror-duotone-space .token.directive, + .remirror-duotone-space .token.unit, + .remirror-duotone-space .token.statement, + .remirror-duotone-space .token.regex, + .remirror-duotone-space .token.atrule { + color: #fe8c52; + } + + .remirror-duotone-space .token.placeholder, + .remirror-duotone-space .token.variable { + color: #fe8c52; + } + + .remirror-duotone-space .token.deleted { + text-decoration: line-through; + } + + .remirror-duotone-space .token.inserted { + border-bottom: 1px dotted #ebebff; + text-decoration: none; + } + + .remirror-duotone-space .token.italic { + font-style: italic; + } + + .remirror-duotone-space .token.important, + .remirror-duotone-space .token.bold { + font-weight: bold; + } + + .remirror-duotone-space .token.important { + color: #aaaaca; + } + + .remirror-duotone-space .token.entity { + cursor: help; + } + + .remirror-duotone-space pre > code.highlight { + outline: 0.4em solid #7676f4; + outline-offset: 0.4em; + } + + /* overrides color-values for the Line Numbers plugin + * http://prismjs.com/plugins/line-numbers/ + */ + + .remirror-duotone-space .line-numbers .line-numbers-rows { + border-right-color: #262631; + } + + .remirror-duotone-space .line-numbers-rows > span:before { + color: #393949; + } + + /* overrides color-values for the Line Highlight plugin +* http://prismjs.com/plugins/line-highlight/ +*/ + + .remirror-duotone-space .line-highlight { + background: rgba(221, 103, 44, 0.2); + background: linear-gradient(to right, rgba(221, 103, 44, 0.2) 70%, rgba(221, 103, 44, 0)); + } + + .remirror-gh-colors code[class*='language-'], + .remirror-gh-colors pre[class*='language-'] { + color: #393a34; + font-family: 'Consolas', 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + font-size: 0.95em; + line-height: 1.2em; + + -moz-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + } + + .remirror-gh-colors pre[class*='language-']::-moz-selection, + .remirror-gh-colors pre[class*='language-'] ::-moz-selection, + .remirror-gh-colors code[class*='language-']::-moz-selection, + .remirror-gh-colors code[class*='language-'] ::-moz-selection { + background: #b3d4fc; + } + + .remirror-gh-colors pre[class*='language-']::-moz-selection, + .remirror-gh-colors pre[class*='language-'] ::-moz-selection, + .remirror-gh-colors code[class*='language-']::-moz-selection, + .remirror-gh-colors code[class*='language-'] ::-moz-selection { + background: #b3d4fc; + } + + .remirror-gh-colors pre[class*='language-']::selection, + .remirror-gh-colors pre[class*='language-'] ::selection, + .remirror-gh-colors code[class*='language-']::selection, + .remirror-gh-colors code[class*='language-'] ::selection { + background: #b3d4fc; + } + + /* Code blocks */ + + .remirror-gh-colors pre[class*='language-'] { + padding: 1em; + margin: 0.5em 0; + overflow: auto; + border: 1px solid #dddddd; + background-color: white; + } + + .remirror-gh-colors :has(.remirror-language-select-positioner) ~ pre[class*='language-'] { + padding: 2em 1em; + } + + .remirror-gh-colors :not(pre) > code[class*='language-'], + .remirror-gh-colors pre[class*='language-'] { + } + + /* Inline code */ + + .remirror-gh-colors :not(pre) > code[class*='language-'] { + padding: 0.2em; + padding-top: 1px; + padding-bottom: 1px; + background: #f8f8f8; + border: 1px solid #dddddd; + } + + .remirror-gh-colors .token.comment, + .remirror-gh-colors .token.prolog, + .remirror-gh-colors .token.doctype, + .remirror-gh-colors .token.cdata { + color: #999988; + font-style: italic; + } + + .remirror-gh-colors .token.namespace { + opacity: 0.7; + } + + .remirror-gh-colors .token.string, + .remirror-gh-colors .token.attr-value { + color: #e3116c; + } + + .remirror-gh-colors .token.punctuation, + .remirror-gh-colors .token.operator { + color: #393a34; /* no highlight */ + } + + .remirror-gh-colors .token.entity, + .remirror-gh-colors .token.url, + .remirror-gh-colors .token.symbol, + .remirror-gh-colors .token.number, + .remirror-gh-colors .token.boolean, + .remirror-gh-colors .token.variable, + .remirror-gh-colors .token.constant, + .remirror-gh-colors .token.property, + .remirror-gh-colors .token.regex, + .remirror-gh-colors .token.inserted { + color: #36acaa; + } + + .remirror-gh-colors .token.atrule, + .remirror-gh-colors .token.keyword, + .remirror-gh-colors .token.attr-name, + .remirror-gh-colors .language-autohotkey .token.selector { + color: #00a4db; + } + + .remirror-gh-colors .token.function, + .remirror-gh-colors .token.deleted, + .remirror-gh-colors .language-autohotkey .token.tag { + color: #9a050f; + } + + .remirror-gh-colors .token.tag, + .remirror-gh-colors .token.selector, + .remirror-gh-colors .language-autohotkey .token.keyword { + color: #00009f; + } + + .remirror-gh-colors .token.important, + .remirror-gh-colors .token.function, + .remirror-gh-colors .token.bold { + font-weight: bold; + } + + .remirror-gh-colors .token.italic { + font-style: italic; + } + + .remirror-hopscotch code[class*='language-'], + .remirror-hopscotch pre[class*='language-'] { + color: #ffffff; + font-family: 'Fira Mono', Menlo, Monaco, 'Lucida Console', 'Courier New', Courier, monospace; + font-size: 16px; + line-height: 1.375; + direction: ltr; + text-align: left; + word-spacing: normal; + + -moz-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + white-space: pre; + white-space: pre-wrap; + word-break: break-all; + word-wrap: break-word; + background: #322931; + color: #b9b5b8; + } + + /* Code blocks */ + + .remirror-hopscotch pre[class*='language-'] { + padding: 1em; + margin: 0.5em 0; + overflow: auto; + } + + .remirror-hopscotch :has(.remirror-language-select-positioner) ~ pre[class*='language-'] { + padding: 2em 1em; + } + + /* Inline code */ + + .remirror-hopscotch :not(pre) > code[class*='language-'] { + padding: 0.1em; + border-radius: 0.3em; + } + + .remirror-hopscotch .token.comment, + .remirror-hopscotch .token.prolog, + .remirror-hopscotch .token.doctype, + .remirror-hopscotch .token.cdata { + color: #797379; + } + + .remirror-hopscotch .token.punctuation, + .remirror-hopscotch .token.punctuation.important { + color: #b9b5b8; + } + + .remirror-hopscotch .namespace { + opacity: 0.7; + } + + .remirror-hopscotch .token.null, + .remirror-hopscotch .token.operator, + .remirror-hopscotch .token.boolean, + .remirror-hopscotch .token.number { + color: #fd8b19; + } + + .remirror-hopscotch .token.property { + color: #fdcc59; + } + + .remirror-hopscotch .token.tag { + color: #1290bf; + } + + .remirror-hopscotch .token.string { + color: #149b93; + } + + .remirror-hopscotch .token.selector { + color: #c85e7c; + } + + .remirror-hopscotch .token.attr-name { + color: #fd8b19; + } + + .remirror-hopscotch .token.entity, + .remirror-hopscotch .token.url, + .remirror-hopscotch .language-css .token.string, + .remirror-hopscotch .style .token.string { + color: #149b93; + } + + .remirror-hopscotch .token.attr-value, + .remirror-hopscotch .token.keyword, + .remirror-hopscotch .token.control, + .remirror-hopscotch .token.directive, + .remirror-hopscotch .token.unit { + color: #8fc13e; + } + + .remirror-hopscotch .token.statement, + .remirror-hopscotch .token.regex, + .remirror-hopscotch .token.atrule { + color: #149b93; + } + + .remirror-hopscotch .token.placeholder, + .remirror-hopscotch .token.variable { + color: #1290bf; + } + + .remirror-hopscotch .token.important { + color: #dd464c; + font-weight: bold; + } + + .remirror-hopscotch .token.entity { + cursor: help; + } + + .remirror-hopscotch pre > code.highlight { + outline: 0.4em solid red; + outline-offset: 0.4em; + } + + .remirror-pojoaque code[class*='language-'], + .remirror-pojoaque pre[class*='language-'] { + -moz-tab-size: 4; + tab-size: 4; + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + white-space: pre; + white-space: pre-wrap; + word-break: break-all; + word-wrap: break-word; + font-family: Menlo, Monaco, 'Courier New', monospace; + font-size: 15px; + line-height: 1.5; + color: #dccf8f; + text-shadow: 0; + } + + .remirror-pojoaque pre[class*='language-'], + .remirror-pojoaque :not(pre) > code[class*='language-'] { + border-radius: 5px; + border: 1px solid #000; + color: #dccf8f; + background: #181914 + url('data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAMAAA/+4ADkFkb2JlAGTAAAAAAf/bAIQACQYGBgcGCQcHCQ0IBwgNDwsJCQsPEQ4ODw4OERENDg4ODg0RERQUFhQUERoaHBwaGiYmJiYmKysrKysrKysrKwEJCAgJCgkMCgoMDwwODA8TDg4ODhMVDg4PDg4VGhMRERERExoXGhYWFhoXHR0aGh0dJCQjJCQrKysrKysrKysr/8AAEQgAjACMAwEiAAIRAQMRAf/EAF4AAQEBAAAAAAAAAAAAAAAAAAABBwEBAQAAAAAAAAAAAAAAAAAAAAIQAAEDAwIHAQEAAAAAAAAAAADwAREhYaExkUFRcYGxwdHh8REBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AyGFEjHaBS2fDDs2zkhKmBKktb7km+ZwwCnXPkLVmCTMItj6AXFxRS465/BTnkAJvkLkJe+7AKKoi2AtRS2zuAWsCb5GOlBN8gKfmuGHZ8MFqIth3ALmFoFwbwKWyAlTAp17uKqBvgBD8sM4fTjhvAhkzhaRkBMKBrfs7jGPIpzy7gFrAqnC0C0gB0EWwBDW2cBVQwm+QtPpa3wBO3sVvszCnLAhkzgL5/RLf13cLQd8/AGlu0Cb5HTx9KuAEieGJEdcehS3eRTp2ATdt3CpIm+QtZwAhROXFeb7swp/ahaM3kBE/jSIUBc/AWrgBN8uNFAl+b7sAXFxFn2YLUU5Ns7gFX8C4ib+hN8gFWXwK3bZglxEJm+gKdciLPsFV/TClsgJUwKJ5FVA7tvIFrfZhVfGJDcsCKaYgAqv6YRbE+RWOWBtu7+AL3yRalXLyKqAIIfk+zARbDgFyEsncYwJvlgFRW+GEWntIi2P0BooyFxcNr8Ep3+ANLbMO+QyhvbiqdgC0kVvgUUiLYgBS2QtPbiVI1/sgOmG9uO+Y8DW+7jS2zAOnj6O2BndwuIAUtkdRN8gFoK3wwXMQyZwHVbClsuNLd4E3yAUR6FVDBR+BafQGt93LVMxJTv8ABts4CVLhcfYWsCb5kC9/BHdU8CLYFY5bMAd+eX9MGthhpbA1vu4B7+RKkaW2Yq4AQtVBBFsAJU/AuIXBhN8gGWnstefhiZyWvLAEnbYS1uzSFP6Jvn4Baxx70JKkQojLib5AVTey1jjgkKJGO0AKWyOm7N7cSpgSpAdPH0Tfd/gp1z5C1ZgKqN9J2wFxcUUuAFLZAm+QC0Fb4YUVRFsAOvj4KW2dwtYE3yAWk/wS/PLMKfmuGHZ8MAXF/Ja32Yi5haAKWz4Ydm2cSpgU693Atb7km+Zwwh+WGcPpxw3gAkzCLY+iYUDW/Z3Adc/gpzyFrAqnALkJe+7DoItgAtRS2zuKqGE3yAx0oJvkdvYrfZmALURbDuL5/RLf13cAuDeBS2RpbtAm+QFVA3wR+3fUtFHoBDJnC0jIXH0HWsgMY8inPLuOkd9chp4z20ALQLSA8cI9jYAIa2zjzjBd8gRafS1vgiUho/kAKcsCGTOGWvoOpkAtB3z8Hm8x2Ff5ADp4+lXAlIvcmwH/2Q==') + repeat left top; + } + + .remirror-pojoaque pre[class*='language-'] { + padding: 12px; + overflow: auto; + } + + .remirror-pojoaque :has(.remirror-language-select-positioner) ~ pre[class*='language-'] { + padding: 2em 1em; + } + + .remirror-pojoaque :not(pre) > code[class*='language-'] { + padding: 2px 6px; + } + + .remirror-pojoaque .token.namespace { + opacity: 0.7; + } + + .remirror-pojoaque .token.comment, + .remirror-pojoaque .token.prolog, + .remirror-pojoaque .token.doctype, + .remirror-pojoaque .token.cdata { + color: #586e75; + font-style: italic; + } + + .remirror-pojoaque .token.number, + .remirror-pojoaque .token.string, + .remirror-pojoaque .token.char, + .remirror-pojoaque .token.builtin, + .remirror-pojoaque .token.inserted { + color: #468966; + } + + .remirror-pojoaque .token.attr-name { + color: #b89859; + } + + .remirror-pojoaque .token.operator, + .remirror-pojoaque .token.entity, + .remirror-pojoaque .token.url, + .remirror-pojoaque .language-css .token.string, + .remirror-pojoaque .style .token.string { + color: #dccf8f; + } + + .remirror-pojoaque .token.selector, + .remirror-pojoaque .token.regex { + color: #859900; + } + + .remirror-pojoaque .token.atrule, + .remirror-pojoaque .token.keyword { + color: #cb4b16; + } + + .remirror-pojoaque .token.attr-value { + color: #468966; + } + + .remirror-pojoaque .token.function, + .remirror-pojoaque .token.variable, + .remirror-pojoaque .token.placeholder { + color: #b58900; + } + + .remirror-pojoaque .token.property, + .remirror-pojoaque .token.tag, + .remirror-pojoaque .token.boolean, + .remirror-pojoaque .token.number, + .remirror-pojoaque .token.constant, + .remirror-pojoaque .token.symbol { + color: #b89859; + } + + .remirror-pojoaque .token.tag { + color: #ffb03b; + } + + .remirror-pojoaque .token.important, + .remirror-pojoaque .token.statement, + .remirror-pojoaque .token.deleted { + color: #dc322f; + } + + .remirror-pojoaque .token.punctuation, + .remirror-pojoaque .token.punctuation.important { + color: #dccf8f; + } + + .remirror-pojoaque .token.entity { + cursor: help; + } + + .remirror-pojoaque .token.bold { + font-weight: bold; + } + + .remirror-pojoaque .token.italic { + font-style: italic; + } + + .remirror-vs code[class*='language-'], + .remirror-vs pre[class*='language-'] { + color: #393a34; + font-family: 'Consolas', 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + font-size: 0.95em; + line-height: 1.2em; + + -moz-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + } + + .remirror-vs pre[class*='language-']::-moz-selection, + .remirror-vs pre[class*='language-'] ::-moz-selection, + .remirror-vs code[class*='language-']::-moz-selection, + .remirror-vs code[class*='language-'] ::-moz-selection { + background: #c1def1; + } + + .remirror-vs pre[class*='language-']::-moz-selection, + .remirror-vs pre[class*='language-'] ::-moz-selection, + .remirror-vs code[class*='language-']::-moz-selection, + .remirror-vs code[class*='language-'] ::-moz-selection { + background: #c1def1; + } + + .remirror-vs pre[class*='language-']::selection, + .remirror-vs pre[class*='language-'] ::selection, + .remirror-vs code[class*='language-']::selection, + .remirror-vs code[class*='language-'] ::selection { + background: #c1def1; + } + + /* Code blocks */ + + .remirror-vs pre[class*='language-'] { + padding: 1em; + margin: 0.5em 0; + overflow: auto; + border: 1px solid #dddddd; + background-color: white; + } + + .remirror-vs :has(.remirror-language-select-positioner) ~ pre[class*='language-'] { + padding: 2em 1em; + } + + /* Inline code */ + + .remirror-vs :not(pre) > code[class*='language-'] { + padding: 0.2em; + padding-top: 1px; + padding-bottom: 1px; + background: #f8f8f8; + border: 1px solid #dddddd; + } + + .remirror-vs .token.comment, + .remirror-vs .token.prolog, + .remirror-vs .token.doctype, + .remirror-vs .token.cdata { + color: #008000; + font-style: italic; + } + + .remirror-vs .token.namespace { + opacity: 0.7; + } + + .remirror-vs .token.string { + color: #a31515; + } + + .remirror-vs .token.punctuation, + .remirror-vs .token.operator { + color: #393a34; /* no highlight */ + } + + .remirror-vs .token.url, + .remirror-vs .token.symbol, + .remirror-vs .token.number, + .remirror-vs .token.boolean, + .remirror-vs .token.variable, + .remirror-vs .token.constant, + .remirror-vs .token.inserted { + color: #36acaa; + } + + .remirror-vs .token.atrule, + .remirror-vs .token.keyword, + .remirror-vs .token.attr-value, + .remirror-vs .language-autohotkey .token.selector, + .remirror-vs .language-json .token.boolean, + .remirror-vs .language-json .token.number, + .remirror-vs code[class*='language-css'] { + color: #0000ff; + } + + .remirror-vs .token.function { + color: #393a34; + } + + .remirror-vs .token.deleted, + .remirror-vs .language-autohotkey .token.tag { + color: #9a050f; + } + + .remirror-vs .token.selector, + .remirror-vs .language-autohotkey .token.keyword { + color: #00009f; + } + + .remirror-vs .token.important, + .remirror-vs .token.bold { + font-weight: bold; + } + + .remirror-vs .token.italic { + font-style: italic; + } + + .remirror-vs .token.class-name, + .remirror-vs .language-json .token.property { + color: #2b91af; + } + + .remirror-vs .token.tag, + .remirror-vs .token.selector { + color: #800000; + } + + .remirror-vs .token.attr-name, + .remirror-vs .token.property, + .remirror-vs .token.regex, + .remirror-vs .token.entity { + color: #ff0000; + } + + .remirror-vs .token.directive.tag .tag { + background: #ffff00; + color: #393a34; + } + + /* overrides color-values for the Line Numbers plugin + * http://prismjs.com/plugins/line-numbers/ + */ + + .remirror-vs .line-numbers .line-numbers-rows { + border-right-color: #a5a5a5; + } + + .remirror-vs .line-numbers-rows > span:before { + color: #2b91af; + } + + /* overrides color-values for the Line Highlight plugin +* http://prismjs.com/plugins/line-highlight/ +*/ + + .remirror-vs .line-highlight { + background: rgba(193, 222, 241, 0.2); + background: linear-gradient(to right, rgba(193, 222, 241, 0.2) 70%, rgba(221, 222, 241, 0)); + } + + .remirror-xonokai code[class*='language-'], + .remirror-xonokai pre[class*='language-'] { + -moz-tab-size: 2; + tab-size: 2; + -webkit-hyphens: none; + -ms-hyphens: none; + hyphens: none; + white-space: pre; + white-space: pre-wrap; + word-wrap: normal; + font-family: Menlo, Monaco, 'Courier New', monospace; + font-size: 14px; + color: #76d9e6; + text-shadow: none; + } + + .remirror-xonokai pre[class*='language-'], + .remirror-xonokai :not(pre) > code[class*='language-'] { + background: #2a2a2a; + } + + .remirror-xonokai pre[class*='language-'] { + padding: 15px; + border-radius: 4px; + border: 1px solid #e1e1e8; + overflow: auto; + } + + .remirror-xonokai :has(.remirror-language-select-positioner) ~ pre[class*='language-'] { + padding: 2em 1em; + } + + .remirror-xonokai pre[class*='language-'] { + position: relative; + } + + .remirror-xonokai pre[class*='language-'] code { + white-space: pre; + display: block; + } + + .remirror-xonokai :not(pre) > code[class*='language-'] { + padding: 0.15em 0.2em 0.05em; + border-radius: 0.3em; + border: 0.13em solid #7a6652; + box-shadow: 1px 1px 0.3em -0.1em #000 inset; + } + + .remirror-xonokai .token.namespace { + opacity: 0.7; + } + + .remirror-xonokai .token.comment, + .remirror-xonokai .token.prolog, + .remirror-xonokai .token.doctype, + .remirror-xonokai .token.cdata { + color: #6f705e; + } + + .remirror-xonokai .token.operator, + .remirror-xonokai .token.boolean, + .remirror-xonokai .token.number { + color: #a77afe; + } + + .remirror-xonokai .token.attr-name, + .remirror-xonokai .token.string { + color: #e6d06c; + } + + .remirror-xonokai .token.entity, + .remirror-xonokai .token.url, + .remirror-xonokai .language-css .token.string, + .remirror-xonokai .style .token.string { + color: #e6d06c; + } + + .remirror-xonokai .token.selector, + .remirror-xonokai .token.inserted { + color: #a6e22d; + } + + .remirror-xonokai .token.atrule, + .remirror-xonokai .token.attr-value, + .remirror-xonokai .token.keyword, + .remirror-xonokai .token.important, + .remirror-xonokai .token.deleted { + color: #ef3b7d; + } + + .remirror-xonokai .token.regex, + .remirror-xonokai .token.statement { + color: #76d9e6; + } + + .remirror-xonokai .token.placeholder, + .remirror-xonokai .token.variable { + color: #fff; + } + + .remirror-xonokai .token.important, + .remirror-xonokai .token.statement, + .remirror-xonokai .token.bold { + font-weight: bold; + } + + .remirror-xonokai .token.punctuation, + .remirror-xonokai .token.punctuation.important { + color: #bebec5; + } + + .remirror-xonokai .token.entity { + cursor: help; + } + + .remirror-xonokai .token.italic { + font-style: italic; + } + + .remirror-xonokai code.language-markup { + color: #f9f9f9; + } + + .remirror-xonokai code.language-markup .token.tag { + color: #ef3b7d; + } + + .remirror-xonokai code.language-markup .token.attr-name { + color: #a6e22d; + } + + .remirror-xonokai code.language-markup .token.attr-value { + color: #e6d06c; + } + + .remirror-xonokai code.language-markup .token.style, + .remirror-xonokai code.language-markup .token.script { + color: #76d9e6; + } + + .remirror-xonokai code.language-markup .token.script .token.keyword { + color: #76d9e6; + } + + /* Line highlight plugin */ + + .remirror-xonokai pre[class*='language-'][data-line] { + position: relative; + padding: 1em 0 1em 3em; + } + + .remirror-xonokai pre[data-line] .line-highlight { + position: absolute; + left: 0; + right: 0; + padding: 0; + margin-top: 1em; + background: rgba(255, 255, 255, 0.08); + pointer-events: none; + line-height: inherit; + white-space: pre; + } + + .remirror-xonokai pre[data-line] .line-highlight:before, + .remirror-xonokai pre[data-line] .line-highlight[data-end]:after { + content: attr(data-start); + position: absolute; + top: 0.4em; + left: 0.6em; + min-width: 1em; + padding: 0.2em 0.5em; + background-color: rgba(255, 255, 255, 0.4); + color: black; + font: bold 65%/1 sans-serif; + height: 1em; + line-height: 1em; + text-align: center; + border-radius: 999px; + text-shadow: none; + box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7); + } + + .remirror-xonokai pre[data-line] .line-highlight[data-end]:after { + content: attr(data-end); + top: auto; + bottom: 0.4em; + } +`;Ct.div` + ${Vb} +`;var jb=xt` + /** + * Styles extracted from: packages/remirror__theme/src/extension-count-theme.ts + */ + .remirror-editor span.remirror-max-count-exceeded { + background-color: var(--rmr-hue-red-4); + } +`;Ct.div` + ${jb} +`;var Ub=xt` + /** + * Styles extracted from: packages/remirror__theme/src/extension-emoji-theme.ts + */ + .remirror-emoji-image { + object-fit: contain; + width: 1.375em; + height: 1.375em; + vertical-align: bottom; + } + + .remirror-emoji-wrapper { + text-indent: -99999px; + } + + .remirror-emoji-popup-item { + padding: 8px; + text-overflow: ellipsis; + max-width: 250px; + width: 250px; + overflow: hidden; + white-space: nowrap; + color: white; + } + + .remirror-emoji-popup-hovered { + background-color: var(--rmr-hue-gray-2); + } + + .remirror-emoji-popup-highlight { + background-color: var(--rmr-hue-gray-3); + } + + .remirror-emoji-popup-wrapper { + position: absolute; + width: -webkit-max-content; + width: -moz-max-content; + width: max-content; + padding-top: 8px; + padding-bottom: 8px; + margin: 0 auto; + border-radius: 8px; + box-shadow: hsla(205, 70%, 15%, 0.25) 0 4px 8px, hsla(205, 70%, 15%, 0.31) 0px 0px 1px; + background-color: white; + z-index: 10; + max-height: 250px; + overflow-y: scroll; + } + + .remirror-emoji-popup-name { + color: rgb(121, 129, 134); + } + + .remirror-emoji-popup-char { + font-size: 1.25em; + padding-right: 5px; + } +`;Ct.div` + ${Ub} +`;var Wb=xt` + /** + * Styles extracted from: packages/remirror__theme/src/extension-file-theme.ts + */ + .remirror-file-root { + border-radius: 4px; + padding: 8px 12px; + background-color: #e8ecf1; + color: #000; + margin: 8px auto; + min-height: 32px; + width: 100%; + max-width: 600px; + display: flex; + align-items: center; + } + + .remirror-file-name { + font-size: 1rem; + margin-left: 8px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .remirror-file-size { + font-size: 0.8rem; + margin-left: 8px; + color: gray; + white-space: nowrap; + } + + .remirror-file-upload-progress { + font-size: 0.8rem; + margin-left: 8px; + margin-right: 8px; + color: gray; + font-family: Menlo, Monaco, 'Courier New', monospace; + } + + .remirror-file-error { + font-size: 0.8rem; + color: red; + } + + .remirror-file-icon-button { + display: flex; + justify-content: center; + align-items: center; + color: #000; + } +`;Ct.div` + ${Wb} +`;var Kb=xt` + /** + * Styles extracted from: packages/remirror__theme/src/extension-gap-cursor-theme.ts + */ + .remirror-editor.ProseMirror .ProseMirror-gapcursor { + display: none; + pointer-events: none; + position: absolute; + } + .remirror-editor.ProseMirror .ProseMirror-gapcursor:after { + content: ''; + display: block; + position: absolute; + top: -2px; + width: 20px; + border-top: 1px solid black; + animation: ProseMirror-cursor-blink 1.1s steps(2, start) infinite; + } + @keyframes ProseMirror-cursor-blink { + to { + visibility: hidden; + } + } + .remirror-editor.ProseMirror .ProseMirror-focused .ProseMirror-gapcursor, + .remirror-editor.ProseMirror.ProseMirror-focused .ProseMirror-gapcursor { + display: block; + } +`;Ct.div` + ${Kb} +`;var qb=xt` + /** + * Styles extracted from: packages/remirror__theme/src/extension-image-theme.ts + */ + .remirror-image-loader { + border: 16px solid #f3f3f3; + border-radius: 50%; + border-top: 16px solid #3498db; + width: 120px; + height: 120px; + animation: spin 2s linear infinite; + } + + @keyframes spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } + } +`;Ct.div` + ${qb} +`;var Gb=xt` + /** + * Styles extracted from: packages/remirror__theme/src/extension-list-theme.ts + */ + /* don't show the custom markers in a ordered list */ + .remirror-editor ol > li > .remirror-list-item-marker-container { + display: none; + } + /* don't show the origin markers when using custom markers (checkbox / collapsible) */ + .remirror-editor ul > li.remirror-list-item-with-custom-mark { + list-style: none; + } + .remirror-editor .remirror-ul-list-content > li.remirror-list-item-with-custom-mark { + list-style: none; + } + /* override the browser's default styles */ + .remirror-editor ul ul + ul { + -webkit-margin-before: 1em; + margin-block-start: 1em; + } + + .remirror-list-item-marker-container { + position: absolute; + left: -32px; + width: 24px; + display: inline-block; + text-align: center; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + } + + .remirror-list-item-checkbox { + /* change the checkbox color from blue (default on Chrome) to purple. */ + -webkit-filter: hue-rotate(60deg); + filter: hue-rotate(60deg); + } + + .remirror-collapsible-list-item-closed li { + display: none; + } + + .remirror-collapsible-list-item-closed .remirror-collapsible-list-item-button { + background-color: var(--rmr-hue-gray-6); + } + + .remirror-collapsible-list-item-button { + width: 8px; + height: 8px; + border-radius: 50%; + cursor: pointer; + display: inline-block; + vertical-align: middle; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + transition: background-color 0.25s ease; + background-color: var(--rmr-color-border); + } + + .remirror-collapsible-list-item-button:hover { + background-color: var(--rmr-color-primary); + } + + .remirror-collapsible-list-item-button.disabled, + .remirror-collapsible-list-item-button.disabled:hover { + background-color: var(--rmr-color-border); + cursor: default; + } + + .remirror-list-spine { + position: absolute; + top: 4px; + bottom: 0px; + left: -20px; + width: 16px; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + transition: border-left-color 0.25s ease; + border-left-color: var(--rmr-color-border); + border-left-style: solid; + border-left-width: 1px; + } + + .remirror-list-spine:hover { + border-left-color: var(--rmr-color-primary); + } +`;Ct.div` + ${Gb} +`;var Yb=xt` + /** + * Styles extracted from: packages/remirror__theme/src/extension-mention-atom-theme.ts + */ + .remirror-mention-atom { + background: var(--rmr-hue-gray-2); + font-weight: bold; + font-size: 0.9em; + font-style: normal; + border-radius: var(--rmr-radius-border); + padding: 0.2rem 0.5rem; + white-space: nowrap; + color: var(--rmr-color-primary); + } + + .remirror-suggest-atom { + color: rgba(0, 0, 0, 0.6); + } + + .remirror-mention-atom-popup-item { + padding: 8px; + text-overflow: ellipsis; + max-width: 250px; + width: 250px; + overflow: hidden; + white-space: nowrap; + color: white; + } + + .remirror-mention-atom-popup-hovered { + background-color: var(--rmr-hue-gray-2); + } + + .remirror-mention-atom-popup-highlight { + background-color: var(--rmr-hue-gray-3); + } + + .remirror-mention-atom-popup-wrapper { + width: -webkit-max-content; + width: -moz-max-content; + width: max-content; + padding-top: 8px; + padding-bottom: 8px; + margin: 0 auto; + border-radius: 8px; + box-shadow: hsla(205, 70%, 15%, 0.25) 0 4px 8px, hsla(205, 70%, 15%, 0.31) 0px 0px 1px; + background-color: white; + z-index: 10; + max-height: 250px; + overflow-y: scroll; + } + + .remirror-mention-atom-popup-name { + color: rgb(121, 129, 134); + } + + .remirror-mention-atom-zero-items { + color: rgb(121, 129, 134); + } + + .remirror-mention-atom-popup-char { + font-size: 1.25em; + padding-right: 5px; + } +`;Ct.div` + ${Yb} +`;var Jb=xt` + /** + * Styles extracted from: packages/remirror__theme/src/extension-node-formatting-theme.ts + */ + .remirror-editor.ProseMirror { + } +`;Ct.div` + ${Jb} +`;var Xb=xt` + /** + * Styles extracted from: packages/remirror__theme/src/extension-placeholder-theme.ts + */ + .remirror-is-empty:first-of-type::before { + position: absolute; + color: #aaa; + pointer-events: none; + height: 0; + font-style: italic; + content: attr(data-placeholder); + } +`;Ct.div` + ${Xb} +`;var Qb=xt` + /** + * Styles extracted from: packages/remirror__theme/src/extension-positioner-theme.ts + */ + .remirror-editor.ProseMirror { + position: relative; + } + + .remirror-positioner { + position: absolute; + min-width: 1px; + min-height: 1px; + pointer-events: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + cursor: none; + z-index: -1; + } + + .remirror-positioner-widget { + width: 0; + height: 0; + position: absolute; + } +`;Ct.div` + ${Qb} +`;var Zb=xt` + /** + * Styles extracted from: packages/remirror__theme/src/extension-tables-theme.ts + */ + .remirror-editor.ProseMirror { + /* Give selected cells a blue overlay */ + /* We don't need this anymore -- 2021-04-03 ocavue */ + } + .remirror-editor.ProseMirror .tableWrapper { + overflow-x: auto; + } + .remirror-editor.ProseMirror table { + border-collapse: collapse; + table-layout: fixed; + width: 100%; + overflow: hidden; + } + .remirror-editor.ProseMirror td, + .remirror-editor.ProseMirror th { + vertical-align: top; + box-sizing: border-box; + position: relative; + border-width: 1px; + border-style: solid; + border-color: var(--rmr-color-table-default-border); + } + .remirror-editor.ProseMirror .column-resize-handle { + position: absolute; + right: -2px; + top: 0; + bottom: 0; + width: 4px; + z-index: 40; + background-color: var(--rmr-hue-blue-7); + pointer-events: none; + } + .remirror-editor.ProseMirror.resize-cursor { + cursor: ew-resize; + cursor: col-resize; + } + /* + .selectedCell:after { + z-index: 2; + position: absolute; + content: ''; + left: 0; + right: 0; + top: 0; + bottom: 0; + background: rgba(200, 200, 255, 0.4); + pointer-events: none; + } + */ + .remirror-editor.ProseMirror th.selectedCell, + .remirror-editor.ProseMirror td.selectedCell { + border-style: double; + border-color: var(--rmr-color-table-selected-border); + background-color: var(--rmr-color-table-selected-cell); + } + + .remirror-table-colgroup > col:first-of-type { + width: 13px; + overflow: visible; + } + + .remirror-controllers-toggle { + visibility: hidden; + } + + .remirror-table-show-controllers .remirror-controllers-toggle { + visibility: visible; + } + + .remirror-table-insert-button { + position: absolute; + width: 18px; + height: 18px; + z-index: 25; + cursor: pointer; + border-radius: 4px; + transition: background-color 150ms ease; + + background-color: #dcdcdc; + } + + .remirror-table-insert-button svg { + fill: #ffffff; + } + + .remirror-table-insert-button:hover { + background-color: #136bda; + } + + .remirror-table-insert-button:hover svg { + fill: #ffffff; + } + + .remirror-table-delete-inner-button { + border: none; + padding: 0; + width: 18px; + height: 18px; + + position: absolute; + z-index: 30; + cursor: pointer; + border-radius: 4px; + background-color: #cecece; + transition: background-color 150ms ease; + } + + .remirror-table-delete-inner-button:hover { + background-color: #ff7884; + } + + .remirror-table-delete-table-inner-button { + top: calc(var(--remirror-table-delete-button-y) - 9px); + left: calc(var(--remirror-table-delete-button-x) - 9px); + } + + .remirror-table-delete-row-column-inner-button { + top: calc(var(--remirror-table-delete-row-column-button-y) - 9px); + left: calc(var(--remirror-table-delete-row-column-button-x) - 9px); + } + + .remirror-table-with-controllers { + /* Space for marks */ + margin-top: 40px; + margin-bottom: 40px; + + /* To make controller's 'height: 100%' works, table must set its own height. */ + height: 1px; + } + + /* To show marks */ + + .ProseMirror table.remirror-table-with-controllers { + overflow: visible; + } + + .remirror-table-waitting-controllers { + /* Hide the table before controllers injected */ + display: none; + } + + /* First row contains one corner controller and multiple column controllers */ + + .remirror-table-tbody-with-controllers > tr:nth-of-type(1) { + height: 12px; + overflow: visible; + } + + /* First controller cell is the corner controller */ + + .remirror-table-tbody-with-controllers > tr:nth-of-type(1) th:nth-of-type(1) { + overflow: visible; + padding: 0; + cursor: pointer; + z-index: 15; + position: relative; + height: 12px; + width: 12px; + } + + .remirror-table-tbody-with-controllers + > tr:nth-of-type(1) + th:nth-of-type(1) + div.remirror-table-controller-wrapper { + overflow: visible; + display: flex; + justify-content: flex-end; + align-items: flex-end; + width: 12px; + height: 12px; + } + + .remirror-table-tbody-with-controllers + > tr:nth-of-type(1) + th:nth-of-type(1) + div.remirror-table-controller-trigger-area { + flex: 1; + position: relative; + z-index: 10; /* Style for debug. Use linear-gradient as background so that we can differentiate two neighbor areas. */ /* background: linear-gradient(to left top, rgba(0, 255, 100, 0.2), rgba(200, 100, 255, 0.2)); */ + display: none; + } + + .remirror-table-tbody-with-controllers + > tr:nth-of-type(1) + th:nth-of-type(1) + div.remirror-table-controller-mark-row-corner { + bottom: -2px; + left: -12px; + position: absolute; + width: 0px; + height: 0px; + border-radius: 50%; + border-style: solid; + border-color: var(--rmr-color-table-mark); + border-width: 2px; + } + + .remirror-table-tbody-with-controllers + > tr:nth-of-type(1) + th:nth-of-type(1) + div.remirror-table-controller-mark-column-corner { + position: absolute; + width: 0px; + height: 0px; + border-radius: 50%; + border-style: solid; + border-color: var(--rmr-color-table-mark); + border-width: 2px; + right: -2px; + top: -12px; + } + + /* Second and more cells are column controllers */ + + .remirror-table-tbody-with-controllers > tr:nth-of-type(1) th:nth-of-type(n + 2) { + overflow: visible; + padding: 0; + cursor: pointer; + z-index: 15; + position: relative; + height: 12px; + } + + .remirror-table-tbody-with-controllers + > tr:nth-of-type(1) + th:nth-of-type(n + 2) + div.remirror-table-controller-wrapper { + overflow: visible; + display: flex; + justify-content: flex-end; + align-items: flex-end; + width: 100%; + height: 12px; + flex-direction: row; + } + + .remirror-table-tbody-with-controllers + > tr:nth-of-type(1) + th:nth-of-type(n + 2) + div.remirror-table-controller-trigger-area { + flex: 1; + position: relative; + z-index: 10; /* Style for debug. Use linear-gradient as background so that we can differentiate two neighbor areas. */ /* background: linear-gradient(to left top, rgba(0, 255, 100, 0.2), rgba(200, 100, 255, 0.2)); */ + height: 36px; + } + + .remirror-table-tbody-with-controllers + > tr:nth-of-type(1) + th:nth-of-type(n + 2) + div.remirror-table-controller-mark-row-corner { + display: none; + } + + .remirror-table-tbody-with-controllers + > tr:nth-of-type(1) + th:nth-of-type(n + 2) + div.remirror-table-controller-mark-column-corner { + position: absolute; + width: 0px; + height: 0px; + border-radius: 50%; + border-style: solid; + border-color: var(--rmr-color-table-mark); + border-width: 2px; + right: -2px; + top: -12px; + } + + /* Second and more rows containes row controllers */ + + /* First controller cell in each row is a row controller */ + + .remirror-table-tbody-with-controllers > tr:nth-of-type(n + 2) th { + overflow: visible; + padding: 0; + cursor: pointer; + z-index: 15; + position: relative; + width: 12px; + } + + .remirror-table-tbody-with-controllers + > tr:nth-of-type(n + 2) + th + div.remirror-table-controller-wrapper { + overflow: visible; + display: flex; + justify-content: flex-end; + align-items: flex-end; + height: 100%; + width: 12px; + flex-direction: column; + } + + .remirror-table-tbody-with-controllers + > tr:nth-of-type(n + 2) + th + div.remirror-table-controller-trigger-area { + flex: 1; + position: relative; + z-index: 10; /* Style for debug. Use linear-gradient as background so that we can differentiate two neighbor areas. */ /* background: linear-gradient(to left top, rgba(0, 255, 100, 0.2), rgba(200, 100, 255, 0.2)); */ + width: 36px; + } + + .remirror-table-tbody-with-controllers + > tr:nth-of-type(n + 2) + th + div.remirror-table-controller-mark-row-corner { + bottom: -2px; + left: -12px; + position: absolute; + width: 0px; + height: 0px; + border-radius: 50%; + border-style: solid; + border-color: var(--rmr-color-table-mark); + border-width: 2px; + } + + .remirror-table-tbody-with-controllers + > tr:nth-of-type(n + 2) + th + div.remirror-table-controller-mark-column-corner { + display: none; + } + + /* Styles for default */ + + .remirror-table-tbody-with-controllers th.remirror-table-controller { + background-color: var(--rmr-color-table-default-controller); + } + + /* Styles for selected */ + + .remirror-table-tbody-with-controllers th.selectedCell.remirror-table-controller { + background-color: var(--rmr-color-table-selected-controller); + } + + .remirror-table-preselect-all { + } + + /* Styles for predelete */ + + .remirror-table-show-predelete th.selectedCell.remirror-table-controller, + .remirror-table-show-predelete td.selectedCell { + border-color: var(--rmr-color-table-predelete-border) !important; + background-color: var(--rmr-color-table-predelete-cell) !important; + } + + .remirror-table-show-predelete th.selectedCell.remirror-table-controller { + background-color: var(--rmr-color-table-predelete-controller) !important; + } + + .remirror-table-show-predelete.remirror-table-preselect-all th.remirror-table-controller, + .remirror-table-show-predelete.remirror-table-preselect-all td { + border-color: var(--rmr-color-table-predelete-border) !important; + background-color: var(--rmr-color-table-predelete-cell) !important; + } + + .remirror-table-show-predelete.remirror-table-preselect-all th.remirror-table-controller { + background-color: var(--rmr-color-table-predelete-controller) !important; + } +`;Ct.div` + ${Zb} +`;var ex=xt` + /** + * Styles extracted from: packages/remirror__theme/src/extension-whitespace-theme.ts + */ + .remirror-editor.ProseMirror .whitespace { + pointer-events: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + } + .remirror-editor.ProseMirror .whitespace:before { + caret-color: inherit; + color: gray; + display: inline-block; + font-weight: 400; + font-style: normal; + line-height: 1em; + width: 0; + } + .remirror-editor.ProseMirror .whitespace--s:before { + content: '·'; + } + .remirror-editor.ProseMirror .whitespace--br:before { + content: '¬'; + } + .remirror-editor.ProseMirror .whitespace--p:before { + content: '¶'; + } +`;Ct.div` + ${ex} +`;var tx=xt` + /** + * Styles extracted from: packages/remirror__theme/src/extension-yjs-theme.ts + */ + .remirror-editor.ProseMirror .ProseMirror-yjs-cursor { + position: absolute; + border-left: black; + border-left-style: solid; + border-left-width: 2px; + border-color: orange; + height: 1em; + word-break: normal; + pointer-events: none; + } + + .remirror-editor.ProseMirror .ProseMirror-yjs-cursor > div { + position: relative; + top: -1.05em; + font-size: 13px; + background-color: rgb(250, 129, 0); + font-family: serif; + font-style: normal; + font-weight: normal; + line-height: normal; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + color: white; + padding-left: 2px; + padding-right: 2px; + } + .remirror-editor.ProseMirror > .ProseMirror-yjs-cursor:first-child { + margin-top: 16px; + } + .remirror-editor #y-functions { + position: absolute; + top: 20px; + right: 20px; + } + .remirror-editor #y-functions > * { + display: inline-block; + } +`;Ct.div` + ${tx} +`;var rx=xt` + /** + * Styles extracted from: packages/remirror__theme/src/theme.ts + */ + .remirror-theme { + /* The following makes it easier to measure components within the editor. */ + box-sizing: border-box; + } + + .remirror-theme *, + .remirror-theme *:before, + .remirror-theme *:after { + /** Preserve box-sizing when override exists: + * https://css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice/ + * */ + box-sizing: inherit; + } + + .remirror-theme { + --rmr-color-background: #ffffff; + --rmr-color-border: rgba(0, 0, 0, 0.25); + --rmr-color-foreground: #000000; + --rmr-color-muted: #f1f3f5; + --rmr-color-primary: #7963d2; + --rmr-color-secondary: #bcd263; + --rmr-color-primary-text: #fff; + --rmr-color-secondary-text: #fff; + --rmr-color-text: #252103; + --rmr-color-faded: hsla(0, 0%, 13%, 0.9); + --rmr-color-active-background: hsla(0, 0%, 85%, 1); + --rmr-color-active-border: hsla(0, 0%, 0%, 0.25); + --rmr-color-active-foreground: hsla(0, 0%, 0%, 1); + --rmr-color-active-muted: hsla(210, 17%, 80%, 1); + --rmr-color-active-primary: hsla(252, 55%, 46%, 1); + --rmr-color-active-secondary: hsla(72, 55%, 46%, 1); + --rmr-color-active-primary-text: #fff; + --rmr-color-active-secondary-text: #000; + --rmr-color-active-text: #000; + --rmr-color-active-faded: hsla(0, 0%, 13%, 0.9); + --rmr-color-hover-background: hsla(0, 0%, 93%, 1); + --rmr-color-hover-border: hsla(0, 0%, 0%, 0.25); + --rmr-color-hover-foreground: hsla(0, 0%, 0%, 1); + --rmr-color-hover-muted: hsla(210, 17%, 88%, 1); + --rmr-color-hover-primary: hsla(252, 55%, 53%, 1); + --rmr-color-hover-secondary: hsla(72, 55%, 53%, 1); + --rmr-color-hover-primary-text: #fff; + --rmr-color-hover-secondary-text: #000; + --rmr-color-hover-text: #000; + --rmr-color-hover-faded: hsla(0, 0%, 13%, 0.9); + --rmr-color-shadow-1: rgba(10, 31, 68, 0.08); + --rmr-color-shadow-2: rgba(10, 31, 68, 0.1); + --rmr-color-shadow-3: rgba(10, 31, 68, 0.12); + --rmr-color-backdrop: rgba(0, 0, 0, 0.9); + --rmr-color-outline: rgba(121, 99, 210, 0.4); + --rmr-color-table-default-border: hsla(0, 0%, 80%, 1); + --rmr-color-table-default-cell: hsla(0, 0%, 40%, 1); + --rmr-color-table-default-controller: #dee2e6; + --rmr-color-table-selected-border: #1c7ed6; + --rmr-color-table-selected-cell: #d0ebff; + --rmr-color-table-selected-controller: #339af0; + --rmr-color-table-preselect-border: #1c7ed6; + --rmr-color-table-preselect-cell: hsla(0, 0%, 40%, 1); + --rmr-color-table-preselect-controller: #339af0; + --rmr-color-table-predelete-border: #f03e3e; + --rmr-color-table-predelete-cell: #ffe3e3; + --rmr-color-table-predelete-controller: #ff6b6b; + --rmr-color-table-mark: #91919196; + --rmr-hue-gray-0: #f8f9fa; + --rmr-hue-gray-1: #f1f3f5; + --rmr-hue-gray-2: #e9ecef; + --rmr-hue-gray-3: #dee2e6; + --rmr-hue-gray-4: #ced4da; + --rmr-hue-gray-5: #adb5bd; + --rmr-hue-gray-6: #868e96; + --rmr-hue-gray-7: #495057; + --rmr-hue-gray-8: #343a40; + --rmr-hue-gray-9: #212529; + --rmr-hue-red-0: #fff5f5; + --rmr-hue-red-1: #ffe3e3; + --rmr-hue-red-2: #ffc9c9; + --rmr-hue-red-3: #ffa8a8; + --rmr-hue-red-4: #ff8787; + --rmr-hue-red-5: #ff6b6b; + --rmr-hue-red-6: #fa5252; + --rmr-hue-red-7: #f03e3e; + --rmr-hue-red-8: #e03131; + --rmr-hue-red-9: #c92a2a; + --rmr-hue-pink-0: #fff0f6; + --rmr-hue-pink-1: #ffdeeb; + --rmr-hue-pink-2: #fcc2d7; + --rmr-hue-pink-3: #faa2c1; + --rmr-hue-pink-4: #f783ac; + --rmr-hue-pink-5: #f06595; + --rmr-hue-pink-6: #e64980; + --rmr-hue-pink-7: #d6336c; + --rmr-hue-pink-8: #c2255c; + --rmr-hue-pink-9: #a61e4d; + --rmr-hue-grape-0: #f8f0fc; + --rmr-hue-grape-1: #f3d9fa; + --rmr-hue-grape-2: #eebefa; + --rmr-hue-grape-3: #e599f7; + --rmr-hue-grape-4: #da77f2; + --rmr-hue-grape-5: #cc5de8; + --rmr-hue-grape-6: #be4bdb; + --rmr-hue-grape-7: #ae3ec9; + --rmr-hue-grape-8: #9c36b5; + --rmr-hue-grape-9: #862e9c; + --rmr-hue-violet-0: #f3f0ff; + --rmr-hue-violet-1: #e5dbff; + --rmr-hue-violet-2: #d0bfff; + --rmr-hue-violet-3: #b197fc; + --rmr-hue-violet-4: #9775fa; + --rmr-hue-violet-5: #845ef7; + --rmr-hue-violet-6: #7950f2; + --rmr-hue-violet-7: #7048e8; + --rmr-hue-violet-8: #6741d9; + --rmr-hue-violet-9: #5f3dc4; + --rmr-hue-indigo-0: #edf2ff; + --rmr-hue-indigo-1: #dbe4ff; + --rmr-hue-indigo-2: #bac8ff; + --rmr-hue-indigo-3: #91a7ff; + --rmr-hue-indigo-4: #748ffc; + --rmr-hue-indigo-5: #5c7cfa; + --rmr-hue-indigo-6: #4c6ef5; + --rmr-hue-indigo-7: #4263eb; + --rmr-hue-indigo-8: #3b5bdb; + --rmr-hue-indigo-9: #364fc7; + --rmr-hue-blue-0: #e7f5ff; + --rmr-hue-blue-1: #d0ebff; + --rmr-hue-blue-2: #a5d8ff; + --rmr-hue-blue-3: #74c0fc; + --rmr-hue-blue-4: #4dabf7; + --rmr-hue-blue-5: #339af0; + --rmr-hue-blue-6: #228be6; + --rmr-hue-blue-7: #1c7ed6; + --rmr-hue-blue-8: #1971c2; + --rmr-hue-blue-9: #1864ab; + --rmr-hue-cyan-0: #e3fafc; + --rmr-hue-cyan-1: #c5f6fa; + --rmr-hue-cyan-2: #99e9f2; + --rmr-hue-cyan-3: #66d9e8; + --rmr-hue-cyan-4: #3bc9db; + --rmr-hue-cyan-5: #22b8cf; + --rmr-hue-cyan-6: #15aabf; + --rmr-hue-cyan-7: #1098ad; + --rmr-hue-cyan-8: #0c8599; + --rmr-hue-cyan-9: #0b7285; + --rmr-hue-teal-0: #e6fcf5; + --rmr-hue-teal-1: #c3fae8; + --rmr-hue-teal-2: #96f2d7; + --rmr-hue-teal-3: #63e6be; + --rmr-hue-teal-4: #38d9a9; + --rmr-hue-teal-5: #20c997; + --rmr-hue-teal-6: #12b886; + --rmr-hue-teal-7: #0ca678; + --rmr-hue-teal-8: #099268; + --rmr-hue-teal-9: #087f5b; + --rmr-hue-green-0: #ebfbee; + --rmr-hue-green-1: #d3f9d8; + --rmr-hue-green-2: #b2f2bb; + --rmr-hue-green-3: #8ce99a; + --rmr-hue-green-4: #69db7c; + --rmr-hue-green-5: #51cf66; + --rmr-hue-green-6: #40c057; + --rmr-hue-green-7: #37b24d; + --rmr-hue-green-8: #2f9e44; + --rmr-hue-green-9: #2b8a3e; + --rmr-hue-lime-0: #f4fce3; + --rmr-hue-lime-1: #e9fac8; + --rmr-hue-lime-2: #d8f5a2; + --rmr-hue-lime-3: #c0eb75; + --rmr-hue-lime-4: #a9e34b; + --rmr-hue-lime-5: #94d82d; + --rmr-hue-lime-6: #82c91e; + --rmr-hue-lime-7: #74b816; + --rmr-hue-lime-8: #66a80f; + --rmr-hue-lime-9: #5c940d; + --rmr-hue-yellow-0: #fff9db; + --rmr-hue-yellow-1: #fff3bf; + --rmr-hue-yellow-2: #ffec99; + --rmr-hue-yellow-3: #ffe066; + --rmr-hue-yellow-4: #ffd43b; + --rmr-hue-yellow-5: #fcc419; + --rmr-hue-yellow-6: #fab005; + --rmr-hue-yellow-7: #f59f00; + --rmr-hue-yellow-8: #f08c00; + --rmr-hue-yellow-9: #e67700; + --rmr-hue-orange-0: #fff4e6; + --rmr-hue-orange-1: #ffe8cc; + --rmr-hue-orange-2: #ffd8a8; + --rmr-hue-orange-3: #ffc078; + --rmr-hue-orange-4: #ffa94d; + --rmr-hue-orange-5: #ff922b; + --rmr-hue-orange-6: #fd7e14; + --rmr-hue-orange-7: #f76707; + --rmr-hue-orange-8: #e8590c; + --rmr-hue-orange-9: #d9480f; + --rmr-radius-border: 0.25rem; + --rmr-radius-extra: 0.5rem; + --rmr-radius-circle: 50%; + --rmr-font-family-default: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, + 'Helvetica Neue', sans-serif; + --rmr-font-family-heading: inherit; + --rmr-font-family-mono: Menlo, monospace; + --rmr-font-size-0: 12px; + --rmr-font-size-1: 14px; + --rmr-font-size-2: 16px; + --rmr-font-size-3: 20px; + --rmr-font-size-4: 24px; + --rmr-font-size-5: 32px; + --rmr-font-size-6: 48px; + --rmr-font-size-7: 64px; + --rmr-font-size-8: 96px; + --rmr-font-size-default: 16px; + --rmr-space-1: 4px; + --rmr-space-2: 8px; + --rmr-space-3: 16px; + --rmr-space-4: 32px; + --rmr-space-5: 64px; + --rmr-space-6: 128px; + --rmr-space-7: 256px; + --rmr-space-8: 512px; + --rmr-font-weight-bold: 700; + --rmr-font-weight-default: 400; + --rmr-font-weight-heading: 700; + --rmr-letter-spacing-tight: -1px; + --rmr-letter-spacing-default: normal; + --rmr-letter-spacing-loose: 1px; + --rmr-letter-spacing-wide: 3px; + --rmr-line-height-heading: 1.25em; + --rmr-line-height-default: 1.5em; + --rmr-box-shadow-1: 0 1px 1px rgba(10, 31, 68, 0.08); + --rmr-box-shadow-2: 0 1px 1px rgba(10, 31, 68, 0.1); + --rmr-box-shadow-3: 0 1px 1px rgba(10, 31, 68, 0.12); + + font-family: var(--rmr-font-family-default); + line-height: var(--rmr-line-height-default); + font-weight: var(--rmr-font-weight-default); + } + + .remirror-theme h1, + .remirror-theme h2, + .remirror-theme h3, + .remirror-theme h4, + .remirror-theme h5, + .remirror-theme h6 { + color: var(--rmr-color-text); + font-family: var(--rmr-font-family-heading); + line-height: var(--rmr-line-height-heading); + font-weight: var(--rmr-font-weight-heading); + } + + .remirror-theme h1 { + font-size: var(--rmr-font-size-5); + } + + .remirror-theme h2 { + font-size: var(--rmr-font-size-4); + } + + .remirror-theme h3 { + font-size: var(--rmr-font-size-3); + } + + .remirror-theme h4 { + font-size: var(--rmr-font-size-2); + } + + .remirror-theme h5 { + font-size: var(--rmr-font-size-1); + } + + .remirror-theme h6 { + font-size: var(--rmr-font-size-0); + } + + .remirror-theme .ProseMirror { + min-height: var(--rmr-space-6); + box-shadow: var(--rmr-color-border) 0px 0px 0px 0.1em; + padding: var(--rmr-space-3); + border-radius: var(--rmr-radius-border); + outline: none; + } + + .remirror-theme .ProseMirror:active, + .remirror-theme .ProseMirror:focus { + box-shadow: var(--rmr-color-outline) 0px 0px 0px 0.2em; + } + + .remirror-theme .ProseMirror p, + .remirror-theme .ProseMirror h1, + .remirror-theme .ProseMirror h2, + .remirror-theme .ProseMirror h3, + .remirror-theme .ProseMirror h4, + .remirror-theme .ProseMirror h4, + .remirror-theme .ProseMirror h5, + .remirror-theme .ProseMirror h6, + .remirror-theme .ProseMirror span { + margin: 0; + /* margin-bottom: var(--rmr-space-2); */ + } +`;Ct.div` + ${rx} +`;xt` + ${$b} + ${Hb} + ${Bb} + ${Fb} + ${Vb} + ${jb} + ${Ub} + ${Wb} + ${Kb} + ${qb} + ${Gb} + ${Yb} + ${Jb} + ${Xb} + ${Qb} + ${Zb} + ${ex} + ${tx} + ${rx} +`;var Tte=Ct.div` + ${$b} + ${Hb} + ${Bb} + ${Fb} + ${Vb} + ${jb} + ${Ub} + ${Wb} + ${Kb} + ${qb} + ${Gb} + ${Yb} + ${Jb} + ${Xb} + ${Qb} + ${Zb} + ${ex} + ${tx} + ${rx} +`,Ote=Object.defineProperty,_te=Object.getOwnPropertyDescriptor,W3=(e,t,r,n)=>{for(var o=n>1?void 0:n?_te(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&Ote(t,r,o),o},nx=class extends er{get name(){return"blockquote"}createTags(){return[te.Block,te.FormattingNode]}createNodeSpec(e,t){return{content:"block+",defining:!0,draggable:!1,...t,attrs:e.defaults(),parseDOM:[{tag:"blockquote",getAttrs:e.parse,priority:100},...t.parseDOM??[]],toDOM:r=>["blockquote",e.dom(r),0]}}toggleBlockquote(){return $C(this.type)}shortcut(e){return this.toggleBlockquote()(e)}createInputRules(){return[Lh(/^\s*>\s$/,this.type)]}createPasteRules(){return{type:"node",nodeType:this.type,regexp:/^\s*>\s$/,startOfTextBlock:!0}}};W3([U({icon:"doubleQuotesL",description:({t:e})=>e(gk.DESCRIPTION),label:({t:e})=>e(gk.LABEL)})],nx.prototype,"toggleBlockquote",1);W3([je({shortcut:"Ctrl->",command:"toggleBlockquote"})],nx.prototype,"shortcut",1);var Ate=Object.defineProperty,Nte=Object.getOwnPropertyDescriptor,Jd=(e,t,r,n)=>{for(var o=n>1?void 0:n?Nte(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&Ate(t,r,o),o},Rte={icon:"bold",label:({t:e})=>e(vk.LABEL),description:({t:e})=>e(vk.DESCRIPTION)},ya=class extends ci{get name(){return"bold"}createTags(){return[te.FormattingMark,te.FontStyle]}createMarkSpec(e,t){return{...t,attrs:e.defaults(),parseDOM:[{tag:"strong",getAttrs:e.parse},{tag:"b",getAttrs:r=>et(r)&&r.style.fontWeight!=="normal"?e.parse(r):!1},{style:"font-weight",getAttrs:r=>oe(r)&&/^(bold(er)?|[5-9]\d{2,})$/.test(r)?null:!1},...t.parseDOM??[]],toDOM:r=>{const{weight:n}=this.options;return n?["strong",{"font-weight":n.toString()},0]:["strong",e.dom(r),0]}}}createInputRules(){return[Vu({regexp:/(?:\*\*|__)([^*_]+)(?:\*\*|__)$/,type:this.type,ignoreWhitespace:!0})]}toggleBold(e){return is({type:this.type,selection:e})}setBold(e){return({tr:t,dispatch:r})=>{const{from:n,to:o}=jr(e??t.selection,t.doc);return r==null||r(t.addMark(n,o,this.type.create())),!0}}removeBold(e){return({tr:t,dispatch:r})=>{const{from:n,to:o}=jr(e??t.selection,t.doc);return t.doc.rangeHasMark(n,o,this.type)?(r==null||r(t.removeMark(n,o,this.type)),!0):!1}}shortcut(e){return this.toggleBold()(e)}};Jd([U(Rte)],ya.prototype,"toggleBold",1);Jd([U()],ya.prototype,"setBold",1);Jd([U()],ya.prototype,"removeBold",1);Jd([je({shortcut:$.Bold,command:"toggleBold"})],ya.prototype,"shortcut",1);ya=Jd([pe({defaultOptions:{weight:void 0},staticKeys:["weight"]})],ya);var Pte=Object.defineProperty,zte=Object.getOwnPropertyDescriptor,ox=(e,t,r,n)=>{for(var o=n>1?void 0:n?zte(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&Pte(t,r,o),o},{DESCRIPTION:Lte,LABEL:Ite}=aR,Dte={icon:"codeLine",description:({t:e})=>e(Lte),label:({t:e})=>e(Ite)},kd=class extends ci{get name(){return"code"}createTags(){return[te.Code,te.ExcludeInputRules]}createMarkSpec(e,t){return{excludes:"_",...t,attrs:e.defaults(),parseDOM:[{tag:"code",getAttrs:e.parse},...t.parseDOM??[]],toDOM:r=>["code",{spellcheck:"false",...e.dom(r)},0]}}createKeymap(){return{"Mod-`":is({type:this.type})}}keyboardShortcut(e){return this.toggleCode()(e)}toggleCode(){return is({type:this.type})}createInputRules(){return[Vu({regexp:new RegExp(`(?:\`)([^\`${wv}]+)(?:\`)$`),type:this.type,ignoreWhitespace:!0})]}createPasteRules(){return[{type:"mark",regexp:/`([^`]+)`/g,markType:this.type}]}};ox([je({shortcut:$.Code,command:"toggleCode"})],kd.prototype,"keyboardShortcut",1);ox([U(Dte)],kd.prototype,"toggleCode",1);kd=ox([pe({})],kd);var $te=Bte,Hte=Object.prototype.hasOwnProperty;function Bte(){for(var e={},t=0;t4&&r.slice(0,4)===cx&&Tre.test(t)&&(t.charAt(4)==="-"?n=Are(t):t=Nre(t),o=Ere),new o(n,t))}function Are(e){var t=e.slice(5).replace(eO,Pre);return cx+t.charAt(0).toUpperCase()+t.slice(1)}function Nre(e){var t=e.slice(4);return eO.test(t)?e:(t=t.replace(Ore,Rre),t.charAt(0)!=="-"&&(t="-"+t),cx+t)}function Rre(e){return"-"+e.toLowerCase()}function Pre(e){return e.charAt(1).toUpperCase()}var zre=Lre,GS=/[#.]/g;function Lre(e,t){for(var r=e||"",n=t||"div",o={},i=0,s,a,l;i=48&&t<=57}var nie=oie;function oie(e){var t=typeof e=="string"?e.charCodeAt(0):e;return t>=97&&t<=102||t>=65&&t<=70||t>=48&&t<=57}var iie=sie;function sie(e){var t=typeof e=="string"?e.charCodeAt(0):e;return t>=97&&t<=122||t>=65&&t<=90}var aie=iie,lie=nO,cie=uie;function uie(e){return aie(e)||lie(e)}var Nf,die=59,fie=pie;function pie(e){var t="&"+e+";",r;return Nf=Nf||document.createElement("i"),Nf.innerHTML=t,r=Nf.textContent,r.charCodeAt(r.length-1)===die&&e!=="semi"||r===t?!1:r}var t4=eie,r4=tie,hie=nO,mie=nie,oO=cie,gie=fie,vie=Aie,yie={}.hasOwnProperty,Ba=String.fromCharCode,bie=Function.prototype,n4={warning:null,reference:null,text:null,warningContext:null,referenceContext:null,textContext:null,position:{},additional:null,attribute:!1,nonTerminated:!0},xie=9,o4=10,kie=12,wie=32,i4=38,Sie=59,Eie=60,Cie=61,Mie=35,Tie=88,Oie=120,_ie=65533,Ja="named",fx="hexadecimal",px="decimal",hx={};hx[fx]=16;hx[px]=10;var Xm={};Xm[Ja]=oO;Xm[px]=hie;Xm[fx]=mie;var iO=1,sO=2,aO=3,lO=4,cO=5,hv=6,uO=7,ks={};ks[iO]="Named character references must be terminated by a semicolon";ks[sO]="Numeric character references must be terminated by a semicolon";ks[aO]="Named character references cannot be empty";ks[lO]="Numeric character references cannot be empty";ks[cO]="Named character references must be known";ks[hv]="Numeric character references cannot be disallowed";ks[uO]="Numeric character references cannot be outside the permissible Unicode range";function Aie(e,t){var r={},n,o;t||(t={});for(o in n4)n=t[o],r[o]=n??n4[o];return(r.position.indent||r.position.start)&&(r.indent=r.position.indent||[],r.position=r.position.start),Nie(e,r)}function Nie(e,t){var r=t.additional,n=t.nonTerminated,o=t.text,i=t.reference,s=t.warning,a=t.textContext,l=t.referenceContext,c=t.warningContext,u=t.position,d=t.indent||[],f=e.length,p=0,h=-1,m=u.column||1,b=u.line||1,v="",g=[],y,x,k,w,E,M,C,T,N,z,D,V,j,L,q,A,P,F,Y;for(typeof r=="string"&&(r=r.charCodeAt(0)),A=J(),T=s?Ne:bie,p--,f++;++p65535&&(M-=65536,z+=Ba(M>>>10|55296),M=56320|M&1023),M=z+Ba(M))):L!==Ja&&T(lO,F)),M?(ie(),A=J(),p=Y-1,m+=Y-j+1,g.push(M),P=J(),P.offset++,i&&i.call(l,M,{start:A,end:P},e.slice(j-1,Y)),A=P):(w=e.slice(j-1,Y),v+=w,m+=w.length,p=Y-1)}else E===10&&(b++,h++,m=0),E===E?(v+=Ba(E),m++):ie();return g.join("");function J(){return{line:b,column:m,offset:p+(u.offset||0)}}function Ne(ue,de){var me=J();me.column+=de,me.offset+=de,s.call(c,ks[ue],me,ue)}function ie(){v&&(g.push(v),o&&o.call(a,v,{start:A,end:J()}),v="")}}function Rie(e){return e>=55296&&e<=57343||e>1114111}function Pie(e){return e>=1&&e<=8||e===11||e>=13&&e<=31||e>=127&&e<=159||e>=64976&&e<=65007||(e&65535)===65535||(e&65535)===65534}var dO={exports:{}};(function(e){var t=typeof window<"u"?window:typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope?self:{};/** + * Prism: Lightweight, robust, elegant syntax highlighting + * + * @license MIT + * @author Lea Verou + * @namespace + * @public + */var r=function(n){var o=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,i=0,s={},a={manual:n.Prism&&n.Prism.manual,disableWorkerMessageHandler:n.Prism&&n.Prism.disableWorkerMessageHandler,util:{encode:function g(y){return y instanceof l?new l(y.type,g(y.content),y.alias):Array.isArray(y)?y.map(g):y.replace(/&/g,"&").replace(/"u")return null;if("currentScript"in document&&1<2)return document.currentScript;try{throw new Error}catch(k){var g=(/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(k.stack)||[])[1];if(g){var y=document.getElementsByTagName("script");for(var x in y)if(y[x].src==g)return y[x]}return null}},isActive:function(g,y,x){for(var k="no-"+y;g;){var w=g.classList;if(w.contains(y))return!0;if(w.contains(k))return!1;g=g.parentElement}return!!x}},languages:{plain:s,plaintext:s,text:s,txt:s,extend:function(g,y){var x=a.util.clone(a.languages[g]);for(var k in y)x[k]=y[k];return x},insertBefore:function(g,y,x,k){k=k||a.languages;var w=k[g],E={};for(var M in w)if(w.hasOwnProperty(M)){if(M==y)for(var C in x)x.hasOwnProperty(C)&&(E[C]=x[C]);x.hasOwnProperty(M)||(E[M]=w[M])}var T=k[g];return k[g]=E,a.languages.DFS(a.languages,function(N,z){z===T&&N!=g&&(this[N]=E)}),E},DFS:function g(y,x,k,w){w=w||{};var E=a.util.objId;for(var M in y)if(y.hasOwnProperty(M)){x.call(y,M,y[M],k||M);var C=y[M],T=a.util.type(C);T==="Object"&&!w[E(C)]?(w[E(C)]=!0,g(C,x,null,w)):T==="Array"&&!w[E(C)]&&(w[E(C)]=!0,g(C,x,M,w))}}},plugins:{},highlightAll:function(g,y){a.highlightAllUnder(document,g,y)},highlightAllUnder:function(g,y,x){var k={callback:x,container:g,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};a.hooks.run("before-highlightall",k),k.elements=Array.prototype.slice.apply(k.container.querySelectorAll(k.selector)),a.hooks.run("before-all-elements-highlight",k);for(var w=0,E;E=k.elements[w++];)a.highlightElement(E,y===!0,k.callback)},highlightElement:function(g,y,x){var k=a.util.getLanguage(g),w=a.languages[k];a.util.setLanguage(g,k);var E=g.parentElement;E&&E.nodeName.toLowerCase()==="pre"&&a.util.setLanguage(E,k);var M=g.textContent,C={element:g,language:k,grammar:w,code:M};function T(z){C.highlightedCode=z,a.hooks.run("before-insert",C),C.element.innerHTML=C.highlightedCode,a.hooks.run("after-highlight",C),a.hooks.run("complete",C),x&&x.call(C.element)}if(a.hooks.run("before-sanity-check",C),E=C.element.parentElement,E&&E.nodeName.toLowerCase()==="pre"&&!E.hasAttribute("tabindex")&&E.setAttribute("tabindex","0"),!C.code){a.hooks.run("complete",C),x&&x.call(C.element);return}if(a.hooks.run("before-highlight",C),!C.grammar){T(a.util.encode(C.code));return}if(y&&n.Worker){var N=new Worker(a.filename);N.onmessage=function(z){T(z.data)},N.postMessage(JSON.stringify({language:C.language,code:C.code,immediateClose:!0}))}else T(a.highlight(C.code,C.grammar,C.language))},highlight:function(g,y,x){var k={code:g,grammar:y,language:x};if(a.hooks.run("before-tokenize",k),!k.grammar)throw new Error('The language "'+k.language+'" has no grammar.');return k.tokens=a.tokenize(k.code,k.grammar),a.hooks.run("after-tokenize",k),l.stringify(a.util.encode(k.tokens),k.language)},tokenize:function(g,y){var x=y.rest;if(x){for(var k in x)y[k]=x[k];delete y.rest}var w=new d;return f(w,w.head,g),u(g,w,y,w.head,0),h(w)},hooks:{all:{},add:function(g,y){var x=a.hooks.all;x[g]=x[g]||[],x[g].push(y)},run:function(g,y){var x=a.hooks.all[g];if(!(!x||!x.length))for(var k=0,w;w=x[k++];)w(y)}},Token:l};n.Prism=a;function l(g,y,x,k){this.type=g,this.content=y,this.alias=x,this.length=(k||"").length|0}l.stringify=function g(y,x){if(typeof y=="string")return y;if(Array.isArray(y)){var k="";return y.forEach(function(T){k+=g(T,x)}),k}var w={type:y.type,content:g(y.content,x),tag:"span",classes:["token",y.type],attributes:{},language:x},E=y.alias;E&&(Array.isArray(E)?Array.prototype.push.apply(w.classes,E):w.classes.push(E)),a.hooks.run("wrap",w);var M="";for(var C in w.attributes)M+=" "+C+'="'+(w.attributes[C]||"").replace(/"/g,""")+'"';return"<"+w.tag+' class="'+w.classes.join(" ")+'"'+M+">"+w.content+""};function c(g,y,x,k){g.lastIndex=y;var w=g.exec(x);if(w&&k&&w[1]){var E=w[1].length;w.index+=E,w[0]=w[0].slice(E)}return w}function u(g,y,x,k,w,E){for(var M in x)if(!(!x.hasOwnProperty(M)||!x[M])){var C=x[M];C=Array.isArray(C)?C:[C];for(var T=0;T=E.reach);P+=A.value.length,A=A.next){var F=A.value;if(y.length>g.length)return;if(!(F instanceof l)){var Y=1,J;if(V){if(J=c(q,P,g,D),!J||J.index>=g.length)break;var de=J.index,Ne=J.index+J[0].length,ie=P;for(ie+=A.value.length;de>=ie;)A=A.next,ie+=A.value.length;if(ie-=A.value.length,P=ie,A.value instanceof l)continue;for(var ue=A;ue!==y.tail&&(ieE.reach&&(E.reach=ft);var rt=A.prev;Me&&(rt=f(y,rt,Me),P+=Me.length),p(y,rt,Y);var Or=new l(M,z?a.tokenize(me,z):me,j,me);if(A=f(y,rt,Or),Se&&f(y,A,Se),Y>1){var he={cause:M+","+T,reach:ft};u(g,y,x,A.prev,P,he),E&&he.reach>E.reach&&(E.reach=he.reach)}}}}}}function d(){var g={value:null,prev:null,next:null},y={value:null,prev:g,next:null};g.next=y,this.head=g,this.tail=y,this.length=0}function f(g,y,x){var k=y.next,w={value:x,prev:y,next:k};return y.next=w,k.prev=w,g.length++,w}function p(g,y,x){for(var k=y.next,w=0;w/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},e.languages.markup.tag.inside["attr-value"].inside.entity=e.languages.markup.entity,e.languages.markup.doctype.inside["internal-subset"].inside=e.languages.markup,e.hooks.add("wrap",function(t){t.type==="entity"&&(t.attributes.title=t.content.value.replace(/&/,"&"))}),Object.defineProperty(e.languages.markup.tag,"addInlined",{value:function(r,n){var o={};o["language-"+n]={pattern:/(^$)/i,lookbehind:!0,inside:e.languages[n]},o.cdata=/^$/i;var i={"included-cdata":{pattern://i,inside:o}};i["language-"+n]={pattern:/[\s\S]+/,inside:e.languages[n]};var s={};s[r]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,function(){return r}),"i"),lookbehind:!0,greedy:!0,inside:i},e.languages.insertBefore("markup","cdata",s)}}),Object.defineProperty(e.languages.markup.tag,"addAttribute",{value:function(t,r){e.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+t+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[r,"language-"+r],inside:e.languages[r]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),e.languages.html=e.languages.markup,e.languages.mathml=e.languages.markup,e.languages.svg=e.languages.markup,e.languages.xml=e.languages.extend("markup",{}),e.languages.ssml=e.languages.xml,e.languages.atom=e.languages.xml,e.languages.rss=e.languages.xml}var Iie=gx;gx.displayName="css";gx.aliases=[];function gx(e){(function(t){var r=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;t.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+r.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+r.source+"$"),alias:"url"}}},selector:{pattern:RegExp(`(^|[{}\\s])[^{}\\s](?:[^{};"'\\s]|\\s+(?![\\s{])|`+r.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:r,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},t.languages.css.atrule.inside.rest=t.languages.css;var n=t.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))})(e)}var Die=vx;vx.displayName="clike";vx.aliases=[];function vx(e){e.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/}}var $ie=yx;yx.displayName="javascript";yx.aliases=["js"];function yx(e){e.languages.javascript=e.languages.extend("clike",{"class-name":[e.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+(/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source)+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),e.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,e.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:e.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:e.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:e.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:e.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:e.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),e.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:e.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),e.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),e.languages.markup&&(e.languages.markup.tag.addInlined("script","javascript"),e.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),e.languages.js=e.languages.javascript}var fu=typeof globalThis=="object"?globalThis:typeof self=="object"?self:typeof window=="object"?window:typeof Pu=="object"?Pu:{},Hie=tse();fu.Prism={manual:!0,disableWorkerMessageHandler:!0};var Bie=tne,Fie=vie,fO=zie,Vie=Lie,jie=Iie,Uie=Die,Wie=$ie;Hie();var bx={}.hasOwnProperty;function pO(){}pO.prototype=fO;var Et=new pO,Kie=Et;Et.highlight=Gie;Et.register=Qd;Et.alias=qie;Et.registered=Yie;Et.listLanguages=Jie;Qd(Vie);Qd(jie);Qd(Uie);Qd(Wie);Et.util.encode=Zie;Et.Token.stringify=Xie;function Qd(e){if(typeof e!="function"||!e.displayName)throw new Error("Expected `function` for `grammar`, got `"+e+"`");Et.languages[e.displayName]===void 0&&e(Et)}function qie(e,t){var r=Et.languages,n=e,o,i,s,a;t&&(n={},n[e]=t);for(o in n)for(i=n[o],i=typeof i=="string"?[i]:i,s=i.length,a=-1;++a{for(var o=n>1?void 0:n?nse(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&rse(t,r,o),o},hO=(e,t,r)=>{if(!t.has(e))throw TypeError("Cannot "+r)},ki=(e,t,r)=>(hO(e,t,"read from private field"),r?r.call(e):t.get(e)),h1=(e,t,r)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,r)},m1=(e,t,r,n)=>(hO(e,t,"write to private field"),n?n.call(e,r):t.set(e,r),r),mO="data-code-block-language";function gO(e,t,r=[]){return e.map(n=>{const o=[...r];return n.type==="element"&&n.properties.className?o.push(...n.properties.className):n.type==="text"&&o.length===0&&t&&o.push(t),n.type==="element"?gO(n.children,t,o):{text:n.value,classes:o}})}function ose(e,t){var r;const{node:n,pos:o}=e,i=kh({language:(r=n.attrs.language)==null?void 0:r.replace("language-",""),fallback:"markup"}),s=xx.highlight(n.textContent??"",i),a=gO(s,t);let l=o+1;function c(u){const d=l,f=d+u.text.length;return l=f,{...u,from:d,to:f}}return J4(a).map(c)}function s4(e){const{blocks:t,skipLast:r,plainTextClassName:n}=e,o=[];for(const i of t){const s=ose(i,n),a=r?s.length-1:s.length;for(const l of Cv(a)){const c=s[l],u=c==null?void 0:c.classes;if(!c||!(u!=null&&u.length))continue;const d=Ge.inline(c.from,c.to,{class:u.join(" ")});o.push(d)}}return o}function ise(e){return!!(e&&Zt(e)&&oe(e.language)&&e.language.length>0)}function sse(e){return t=>({state:{tr:r,selection:n},dispatch:o})=>{if(!ise(t))throw new Error("Invalid attrs passed to the updateAttributes method");const i=rs({types:e,selection:n});return!i||Y4(t,i.node.attrs)?!1:(r.setNodeMarkup(i.pos,e,{...i.node.attrs,...t}),o&&o(r),!0)}}function kh(e){const{language:t,fallback:r}=e;if(!t)return r;const n=xx.listLanguages();for(const o of n)if(o.toLowerCase()===t.toLowerCase())return o;return r}function ase(e,t){const{language:r,wrap:n}=$d(e.attrs,t),{style:o,...i}=t.dom(e);let s=i.style;return n&&(s=Gv({whiteSpace:"pre-wrap",wordBreak:"break-all"},s)),["pre",{spellcheck:"false",...i,class:ju(i.class,`language-${r}`)},["code",{[mO]:r,style:s},0]]}function lse(e){return({pos:t}=ee())=>({tr:r,dispatch:n})=>{const{type:o,formatter:i,defaultLanguage:s}=e,{from:a,to:l}=t?{from:t,to:t}:r.selection,c=rs({types:o,selection:r.selection});if(!c)return!1;const{node:{attrs:u,textContent:d},start:f}=c,p=a-f,h=l-f,m=kh({language:u.language,fallback:s}),b=i({source:d,language:m,cursorOffset:p});let v;if(p!==h&&(v=i({source:d,language:m,cursorOffset:h})),!b)return!1;const{cursorOffset:g,formatted:y}=b;if(y===d)return!1;const x=f+d.length;r.insertText(y,f,x);const k=f+g,w=v?f+v.cursorOffset:void 0;return r.setSelection(le.between(r.doc.resolve(k),r.doc.resolve(w??k))),n&&n(r),!0}}function cse(e){var t;return(t=e.getAttribute(mO)??e.classList[0])==null?void 0:t.replace("language-","")}var{DESCRIPTION:use,LABEL:dse}=oR,fse={icon:"bracesLine",description:({t:e})=>e(use),label:({t:e})=>e(dse)},Rs,pu,hu,pse=class{constructor(e,t){h1(this,Rs,void 0),h1(this,pu,void 0),h1(this,hu,!1),m1(this,pu,e),m1(this,Rs,t)}init(e){const t=jz({node:e.doc,type:ki(this,pu)});return this.refreshDecorationSet(e.doc,t),this}refreshDecorationSet(e,t){const r=s4({blocks:t,skipLast:ki(this,hu),defaultLanguage:ki(this,Rs).options.defaultLanguage,plainTextClassName:ki(this,Rs).options.plainTextClassName??void 0});this.decorationSet=Ee.create(e,r)}apply(e,t){if(!e.docChanged)return this;this.decorationSet=this.decorationSet.map(e.mapping,e.doc);const r=Uz(e,{descend:!0,predicate:n=>n.type===ki(this,pu),StepTypes:[]});return this.updateDecorationSet(e,r),this}updateDecorationSet(e,t){if(t.length===0)return;let r=this.decorationSet;for(const{node:n,pos:o}of t)r=this.decorationSet.remove(this.decorationSet.find(o,o+n.nodeSize));this.decorationSet=r.add(e.doc,s4({blocks:t,skipLast:ki(this,hu),defaultLanguage:ki(this,Rs).options.defaultLanguage,plainTextClassName:ki(this,Rs).options.plainTextClassName??void 0}))}setDeleted(e){m1(this,hu,e)}};Rs=new WeakMap;pu=new WeakMap;hu=new WeakMap;var lo=class extends er{get name(){return"codeBlock"}createTags(){return[te.Block,te.Code]}init(){this.registerLanguages()}createNodeSpec(e,t){const r=/highlight-(?:text|source)-([\da-z]+)/;return{content:"text*",marks:"",defining:!0,draggable:!1,...t,code:!0,attrs:{...e.defaults(),language:{default:this.options.defaultLanguage},wrap:{default:this.options.defaultWrap}},parseDOM:[{tag:"div.highlight",preserveWhitespace:"full",getAttrs:n=>{var o,i;if(!et(n))return!1;const s=n.querySelector("pre.code");if(!et(s))return!1;const a=kn(s,"white-space")==="pre-wrap",l=(i=(o=n.className.match(r))==null?void 0:o[1])==null?void 0:i.replace("language-","");return{...e.parse(n),language:l,wrap:a}}},{tag:"pre",preserveWhitespace:"full",getAttrs:n=>{if(!et(n))return!1;const o=n.querySelector("code");if(!et(o))return!1;const i=kn(o,"white-space")==="pre-wrap",s=this.options.getLanguageFromDom(o,n);return{...e.parse(n),language:s,wrap:i}}},...t.parseDOM??[]],toDOM:n=>ase(n,e)}}createAttributes(){return{class:lV[this.options.syntaxTheme.toUpperCase()]}}createInputRules(){const e=/^```([\dA-Za-z]*) $/,t=r=>({language:kh({language:Zo(r,1),fallback:this.options.defaultLanguage})});return[FC({regexp:e,type:this.type,beforeDispatch:({tr:r,start:n})=>{const o=r.doc.resolve(n);r.setSelection(le.near(o))},getAttributes:t})]}onSetOptions(e){const{changes:t}=e;t.supportedLanguages.changed&&this.registerLanguages(),t.syntaxTheme.changed&&this.store.updateAttributes()}createPlugin(){const e=new pse(this.type,this),t=()=>(e.setDeleted(!0),!1);return{state:{init(r,n){return e.init(n)},apply(r,n,o,i){return e.apply(r,i)}},props:{handleKeyDown:Xv({Backspace:t,"Mod-Backspace":t,Delete:t,"Mod-Delete":t,"Ctrl-h":t,"Alt-Backspace":t,"Ctrl-d":t,"Ctrl-Alt-Backspace":t,"Alt-Delete":t,"Alt-d":t}),decorations(){return e.setDeleted(!1),e.decorationSet}}}}toggleCodeBlock(e={}){return Yv({type:this.type,toggleType:this.options.toggleName,attrs:{language:this.options.defaultLanguage,...e}})}createCodeBlock(e){return Fu(this.type,e)}updateCodeBlock(e){return sse(this.type)(e)}formatCodeBlock(e){return lse({type:this.type,formatter:this.options.formatter,defaultLanguage:this.options.defaultLanguage})(e)}tabKey({state:e,dispatch:t}){const{selection:r,tr:n,schema:o}=e,{node:i}=oz(r);if(!Hh({node:i,types:this.type}))return!1;if(r.empty)n.insertText(" ");else{const{from:s,to:a}=r;n.replaceWith(s,a,o.text(" "))}return t&&t(n),!0}backspaceKey({dispatch:e,tr:t,state:r}){if(!t.selection.empty)return!1;const n=rs({types:this.type,selection:t.selection});if((n==null?void 0:n.start)!==t.selection.from)return!1;const{pos:o,node:i,start:s}=n,a=it(r.schema.nodes,this.options.toggleName);return i.textContent.trim()===""?t.doc.lastChild===i&&t.doc.firstChild===i?rz({pos:o,tr:t,content:a.create()}):tz({pos:o,tr:t}):s>2?t.setSelection(le.near(t.doc.resolve(s-2))):(t.insert(0,a.create()),t.setSelection(le.near(t.doc.resolve(1)))),e&&e(t),!0}enterKey({dispatch:e,tr:t}){if(!(ms(t.selection)&&t.selection.empty))return!1;const{nodeBefore:r,parent:n}=t.selection.$anchor;if(!(r!=null&&r.isText)||!n.type.isTextblock)return!1;const o=/^```([A-Za-z]*)?$/,{text:i,nodeSize:s}=r,{textContent:a}=n;if(!i)return!1;const l=i.match(o),c=a.match(o);if(!l||!c)return!1;const[,u]=l,d=kh({language:u,fallback:this.options.defaultLanguage}),f=t.selection.$from.before(),p=f+s+1;return t.replaceWith(f,p,this.type.create({language:d})),t.setSelection(le.near(t.doc.resolve(f+1))),e&&e(t),!0}formatShortcut({tr:e}){const t=this.store.commands;if(!EC({type:this.type,state:e}))return!1;const r=t.formatCodeBlock.isEnabled();return r&&t.formatCodeBlock(),r}registerLanguages(){for(const e of this.options.supportedLanguages)xx.register(e)}};hi([U(fse)],lo.prototype,"toggleCodeBlock",1);hi([U()],lo.prototype,"createCodeBlock",1);hi([U()],lo.prototype,"updateCodeBlock",1);hi([U()],lo.prototype,"formatCodeBlock",1);hi([je({shortcut:"Tab"})],lo.prototype,"tabKey",1);hi([je({shortcut:"Backspace"})],lo.prototype,"backspaceKey",1);hi([je({shortcut:"Enter"})],lo.prototype,"enterKey",1);hi([je({shortcut:$.Format})],lo.prototype,"formatShortcut",1);lo=hi([pe({defaultOptions:{supportedLanguages:[],toggleName:"paragraph",formatter:({source:e})=>({cursorOffset:0,formatted:e}),syntaxTheme:"a11y_dark",defaultLanguage:"markup",defaultWrap:!1,plainTextClassName:"",getLanguageFromDom:cse},staticKeys:["getLanguageFromDom"]})],lo);var vO=(e,t,r)=>{if(!t.has(e))throw TypeError("Cannot "+r)},ze=(e,t,r)=>(vO(e,t,"read from private field"),r?r.call(e):t.get(e)),Xa=(e,t,r)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,r)},Ti=(e,t,r,n)=>(vO(e,t,"write to private field"),n?n.call(e,r):t.set(e,r),r),hse='',mse='',gse=encodeURIComponent(hse),vse=encodeURIComponent(mse),Ar,yse=class{constructor(e){Xa(this,Ar,void 0);const t=document.createElement("div"),r=document.createElement("div");this.dom=t,Ti(this,Ar,r),this.type=e,this.createHandle(e)}createHandle(e){switch(ar(this.dom,{position:"absolute",pointerEvents:"auto",display:"flex",alignItems:"center",justifyContent:"center",zIndex:"100"}),ar(ze(this,Ar),{opacity:"0",transition:"opacity 300ms ease-in 0s"}),ze(this,Ar).dataset.dragging="",e){case 0:ar(this.dom,{right:"0px",top:"0px",height:"100%",width:"15px",cursor:"col-resize"}),ar(ze(this,Ar),{width:" 4px",height:"36px",maxHeight:"50%",boxSizing:"content-box",background:"rgba(0, 0, 0, 0.65)",border:"1px solid rgba(255, 255, 255, 0.5)",borderRadius:"6px"});break;case 1:ar(this.dom,{left:"0px",top:"0px",height:"100%",width:"15px",cursor:"col-resize"}),ar(ze(this,Ar),{width:" 4px",height:"36px",maxHeight:"50%",boxSizing:"content-box",background:"rgba(0, 0, 0, 0.65)",border:"1px solid rgba(255, 255, 255, 0.5)",borderRadius:"6px"});break;case 2:ar(this.dom,{bottom:"0px",width:"100%",height:"14px",cursor:"row-resize"}),ar(ze(this,Ar),{width:" 42px",height:"4px",boxSizing:"content-box",maxWidth:"50%",background:"rgba(0, 0, 0, 0.65)",border:"1px solid rgba(255, 255, 255, 0.5)",borderRadius:"6px"});break;case 3:ar(this.dom,{right:"-1px",bottom:"-2px",width:"30px",height:"30px",cursor:"nwse-resize",zIndex:"101"}),ar(ze(this,Ar),{height:"22px",width:"22px",backgroundRepeat:"no-repeat",backgroundImage:`url("data:image/svg+xml,${vse}") `});break;case 4:ar(this.dom,{left:"-1px",bottom:"-2px",width:"30px",height:"30px",cursor:"nesw-resize",zIndex:"101"}),ar(ze(this,Ar),{height:"22px",width:"22px",backgroundRepeat:"no-repeat",backgroundImage:`url("data:image/svg+xml,${gse}") `});break}this.dom.append(ze(this,Ar))}setHandleVisibility(e){const t=e||!!ze(this,Ar).dataset.dragging;ze(this,Ar).style.opacity=t?"1":"0"}dataSetDragging(e){ze(this,Ar).dataset.dragging=e?"true":""}};Ar=new WeakMap;var Rf=50,yO=(e=>(e[e.Fixed=0]="Fixed",e[e.Flexible=1]="Flexible",e))(yO||{}),Ps,zs,Ls,Bo,Is,bse=class{constructor({node:e,view:t,getPos:r,aspectRatio:n=0,options:o,initialSize:i}){Xa(this,Ps,void 0),Xa(this,zs,void 0),Xa(this,Ls,[]),Xa(this,Bo,void 0),Xa(this,Is,void 0);const s=this.createWrapper(e,i),a=this.createElement({node:e,view:t,getPos:r,options:o}),c=(n===1?[0,1,2,3,4]:[0,1]).map(f=>new yse(f));for(const f of c){const p=h=>{this.startResizing(h,t,r,f)};f.dom.addEventListener("mousedown",p),ze(this,Ls).push(()=>f.dom.removeEventListener("mousedown",p)),s.append(f.dom)}const u=()=>{c.forEach(f=>f.setHandleVisibility(!0))},d=()=>{c.forEach(f=>f.setHandleVisibility(!1))};s.addEventListener("mouseover",u),s.addEventListener("mouseout",d),ze(this,Ls).push(()=>s.removeEventListener("mouseover",u),()=>s.removeEventListener("mouseout",d)),s.append(a),this.dom=s,Ti(this,zs,e),Ti(this,Ps,a),this.aspectRatio=n}createWrapper(e,t){const r=document.createElement("div");return r.classList.add("remirror-resizable-view"),r.style.position="relative",t?ar(r,{width:a4(t.width),aspectRatio:`${t.width} / ${t.height}`}):ar(r,{width:a4(e.attrs.width),aspectRatio:`${e.attrs.width} / ${e.attrs.height}`}),ar(r,{maxWidth:"100%",minWidth:`${Rf}px`,verticalAlign:"bottom",display:"inline-block",lineHeight:"0",transition:"width 0.15s ease-out, height 0.15s ease-out"}),r}startResizing(e,t,r,n){var o,i;e.preventDefault(),n.dataSetDragging(!0),ze(this,Ps).style.pointerEvents="none";const s=e.pageX,a=e.pageY,l=((o=ze(this,Ps))==null?void 0:o.getBoundingClientRect().width)||0,c=((i=ze(this,Ps))==null?void 0:i.getBoundingClientRect().height)||0,u=E1(100,!1,f=>{const p=f.pageX,h=f.pageY,m=p-s,b=h-a;let v=null,g=null;if(this.aspectRatio===0&&l&&c)switch(n.type){case 0:case 3:v=l+m,g=c/l*v;break;case 1:case 4:v=l-m,g=c/l*v;break;case 2:g=c+b,v=l/c*g;break}else if(this.aspectRatio===1)switch(n.type){case 0:v=l+m;break;case 1:v=l-m;break;case 2:g=c+b;break;case 3:v=l+m,g=c+b;break;case 4:v=l-m,g=c+b;break}typeof v=="number"&&v{f.preventDefault(),n.dataSetDragging(!1),n.setHandleVisibility(!1),ze(this,Ps).style.pointerEvents="auto",document.removeEventListener("mousemove",u),document.removeEventListener("mouseup",d);const p=r(),h=t.state.tr.setNodeMarkup(p,void 0,{...ze(this,zs).attrs,width:ze(this,Bo),height:ze(this,Is)});t.dispatch(h)};document.addEventListener("mousemove",u),document.addEventListener("mouseup",d),ze(this,Ls).push(()=>document.removeEventListener("mousemove",u)),ze(this,Ls).push(()=>document.removeEventListener("mouseup",d))}update(e){return e.type!==ze(this,zs).type||this.aspectRatio===0&&e.attrs.width&&e.attrs.width!==ze(this,Bo)||this.aspectRatio===1&&e.attrs.width&&e.attrs.height&&e.attrs.width!==ze(this,Bo)&&e.attrs.height!==ze(this,Is)||!xse(ze(this,zs),e,["width","height"])?!1:(Ti(this,zs,e),Ti(this,Bo,e.attrs.width),Ti(this,Is,e.attrs.height),!0)}destroy(){ze(this,Ls).forEach(e=>e())}};Ps=new WeakMap;zs=new WeakMap;Ls=new WeakMap;Bo=new WeakMap;Is=new WeakMap;function xse(e,t,r){return e===t||kse(e,t,r)&&e.content.eq(t.content)}function kse(e,t,r){const n=e.attrs,o=t.attrs,i={};for(const a of r)i[a]=null;e.attrs={...n,...i},t.attrs={...o,...i};const s=e.sameMarkup(t);return e.attrs=n,t.attrs=o,s}function a4(e){return typeof e=="number"?`${e}px`:e||void 0}var bO={exports:{}},wse=Number.isNaN||function(e){return e!==e},Sse=wse,kx=Number.isFinite||function(e){return!(typeof e!="number"||Sse(e)||e===1/0||e===-1/0)},Ese=kx,Cse=Number.isInteger||function(e){return typeof e=="number"&&Ese(e)&&Math.floor(e)===e},Mse=kx,Tse=Cse,Ose=function(t,r){if(!Mse(t))throw new Error("Value must be a finite number");if(!Tse(r)||r<0)throw new Error("Precision must be a non-negative integer");return parseFloat(t.toFixed(r))},_se=/^(-?\d?\.?\d+)e([\+\-]\d)+/,Ase=function(t){var r=t.match(_se);if(!r)throw new Error("Invalid exponential");return r.slice(1)},Nse=kx,Rse=Ase,Pse=function(t){if(!Nse(t))throw new Error("Value must be a finite number");var r=Rse(t.toExponential()),n=r[0],o=parseInt(r[1],10),i=(n.split(".")[1]||"").length;return!i&&o>0?0:i+-1*o};(function(e,t){var r=Ose,n=Pse;e.exports=i;var o={down:"floor",up:"ceil"};function i(s,a,l){if(a=a||1,l){if(!o.hasOwnProperty(l))throw new Error("invalid direction");var c=o[l];return r(Math[c](s/a)*a,n(a))}var u=i(s,a,"down"),d=i(s,a,"up");return s-u{for(var o=n>1?void 0:n?Dse(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&Ise(t,r,o),o},$se={icon:"fontSize",description:({t:e})=>e(Al.SET_DESCRIPTION),label:({t:e})=>e(Al.SET_LABEL)},Hse={icon:"addLine",description:({t:e})=>e(Al.INCREASE_DESCRIPTION),label:({t:e})=>e(Al.INCREASE_LABEL)},Bse={icon:"subtractLine",description:({t:e})=>e(Al.DECREASE_DESCRIPTION),label:({t:e})=>e(Al.DECREASE_LABEL)},g1="data-font-size-mark",co=class extends ci{get name(){return"fontSize"}createTags(){return[te.FormattingMark,te.FontStyle]}createMarkSpec(e,t){return{...t,attrs:{...e.defaults(),size:{default:this.options.defaultSize}},parseDOM:[{tag:`span[${g1}]`,getAttrs:r=>{if(!et(r))return null;let n=r.getAttribute(g1);return n?(n=`${xg(n,this.options.unit,r)}${this.options.unit}`,{...e.parse(r),size:n}):null}},{style:"font-size",priority:Ae.Low,getAttrs:r=>oe(r)?(r=this.getFontSize(r),{size:r}):null},...t.parseDOM??[]],toDOM:r=>{const{size:n,...o}=$d(r.attrs,e),i=e.dom(r);let s=i.style,a;return n&&(s=Gv({fontSize:this.getFontSize(n)},s)),["span",{...o,...i,style:s,[g1]:a},0]}}}getFontSize(e){var t;const{unit:r,roundingMultiple:n,max:o,min:i,defaultSize:s}=this.options,a=xg(e,r,(t=this.store.view)==null?void 0:t.dom);return Number.isNaN(a)?s||"1rem":`${Ad({value:Lse(a,n),max:o,min:i})}${r}`}setFontSize(e,t){return this.store.commands.applyMark.original(this.type,{size:String(e)},t==null?void 0:t.selection)}increaseFontSize(e){const{increment:t}=this.options;return r=>{const[n]=this.getFontSizeForSelection(e==null?void 0:e.selection);let[o]=n;return o+=_e(t)?t(n,1):t,this.setFontSize(o,e)(r)}}decreaseFontSize(e){const{increment:t}=this.options;return r=>{const[n]=this.getFontSizeForSelection(e==null?void 0:e.selection);let[o]=n;return o-=_e(t)?t(n,-1):t,this.setFontSize(o,e)(r)}}removeFontSize(e){return this.store.commands.removeMark.original({type:this.type,expand:!1,...e})}increaseFontSizeShortcut(e){return this.increaseFontSize()(e)}decreaseFontSizeShortcut(e){return this.decreaseFontSize()(e)}getFontSizeForSelection(e){const t=this.store.getState(),r=jr(e??t.selection,t.doc),[n,...o]=bz(r,this.type);if(n)return[$f(n.mark.attrs.size),...o.map(l=>$f(l.mark.attrs.size))];const{defaultSize:i,unit:s}=this.options;return[[xg(i,s),s]]}getFontSizeFromDom(e){const t=this.store.getState(),r=jr(e??t.selection,t.doc),n=this.store.view.domAtPos(r.from),o=et(n.node)?n.node:this.store.view.dom;return $f(Pl(o))}};mi([U($se)],co.prototype,"setFontSize",1);mi([U(Hse)],co.prototype,"increaseFontSize",1);mi([U(Bse)],co.prototype,"decreaseFontSize",1);mi([U()],co.prototype,"removeFontSize",1);mi([je({shortcut:$.IncreaseFontSize,command:"increaseFontSize"})],co.prototype,"increaseFontSizeShortcut",1);mi([je({shortcut:$.IncreaseFontSize,command:"decreaseFontSize"})],co.prototype,"decreaseFontSizeShortcut",1);mi([He()],co.prototype,"getFontSizeForSelection",1);mi([He()],co.prototype,"getFontSizeFromDom",1);co=mi([pe({defaultOptions:{defaultSize:"",unit:"pt",increment:1,max:100,min:1,roundingMultiple:.5},staticKeys:["defaultSize"]})],co);var Fse=Object.defineProperty,Vse=Object.getOwnPropertyDescriptor,xO=(e,t,r,n)=>{for(var o=n>1?void 0:n?Vse(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&Fse(t,r,o),o},wh=class extends er{get name(){return"hardBreak"}createTags(){return[te.InlineNode]}createNodeSpec(e,t){return{inline:!0,selectable:!1,atom:!0,leafText:()=>` +`,...t,attrs:e.defaults(),parseDOM:[{tag:"br",getAttrs:e.parse},...t.parseDOM??[]],toDOM:r=>["br",e.dom(r)]}}createKeymap(){const e=Y6(bu(qC),()=>(this.store.commands.insertHardBreak(),!0));return{"Mod-Enter":e,"Shift-Enter":e}}insertHardBreak(){return e=>{const{tr:t,dispatch:r}=e;return r==null||r(t.replaceSelectionWith(this.type.create()).scrollIntoView()),!0}}};xO([U()],wh.prototype,"insertHardBreak",1);wh=xO([pe({defaultPriority:Ae.Low})],wh);var jse=Object.defineProperty,Use=Object.getOwnPropertyDescriptor,kO=(e,t,r,n)=>{for(var o=n>1?void 0:n?Use(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&jse(t,r,o),o},{LABEL:Wse}=mR,Kse={icon:({attrs:e})=>`h${(e==null?void 0:e.level)??"1"}`,label:({t:e,attrs:t})=>e({...Wse,values:{level:t==null?void 0:t.level}})},qse=[$.H1,$.H2,$.H3,$.H4,$.H5,$.H6],Sh=class extends er{get name(){return"heading"}createTags(){return[te.Block,te.TextBlock,te.FormattingNode]}createNodeSpec(e,t){return{content:"inline*",defining:!0,draggable:!1,...t,attrs:{...e.defaults(),level:{default:this.options.defaultLevel}},parseDOM:[...this.options.levels.map(r=>({tag:`h${r}`,getAttrs:n=>({...e.parse(n),level:r})})),...t.parseDOM??[]],toDOM:r=>this.options.levels.includes(r.attrs.level)?[`h${r.attrs.level}`,e.dom(r),0]:[`h${this.options.defaultLevel}`,e.dom(r),0]}}toggleHeading(e={}){return Yv({type:this.type,toggleType:"paragraph",attrs:e})}createKeymap(e){const t=this.store.getExtension(xe),r=ee(),n=[];for(const o of this.options.levels){const i=qse[o-1]??$.H1;r[i]=Fu(this.type,{level:o}),n.push({attrs:{level:o},shortcut:e(i)[0]})}return t.updateDecorated("toggleHeading",{shortcut:n}),r}createInputRules(){return this.options.levels.map(e=>WR(new RegExp(`^(#{1,${e}})\\s$`),this.type,()=>({level:e})))}createPasteRules(){return this.options.levels.map(e=>({type:"node",nodeType:this.type,regexp:new RegExp(`^#{${e}}\\s([\\s\\w]+)$`),getAttributes:()=>({level:e}),startOfTextBlock:!0}))}};kO([U(Kse)],Sh.prototype,"toggleHeading",1);Sh=kO([pe({defaultOptions:{levels:[1,2,3,4,5,6],defaultLevel:1},staticKeys:["defaultLevel","levels"]})],Sh);var Gse=Object.defineProperty,Yse=Object.getOwnPropertyDescriptor,wO=(e,t,r,n)=>{for(var o=n>1?void 0:n?Yse(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&Gse(t,r,o),o},Jse={icon:"separator",label:({t:e})=>e(yk.LABEL),description:({t:e})=>e(yk.DESCRIPTION)},Eh=class extends er{get name(){return"horizontalRule"}createTags(){return[te.Block]}createNodeSpec(e,t){return{...t,attrs:e.defaults(),parseDOM:[{tag:"hr",getAttrs:e.parse},...t.parseDOM??[]],toDOM:r=>["hr",e.dom(r)]}}insertHorizontalRule(){return e=>{const{tr:t,dispatch:r}=e,n=t.selection.$anchor,o=n.parent;return o.type.name==="doc"||o.isAtom||o.isLeaf?!1:(r&&(t.selection.empty&&Fh(o)&&t.insert(n.pos+1,o),t.replaceSelectionWith(this.type.create()),this.updateFromNodeSelection(t),r(t.scrollIntoView())),!0)}}createInputRules(){return[FC({regexp:/^(?:---|—-|___\s|\*\*\*\s)$/,type:this.type,beforeDispatch:({tr:e})=>{this.updateFromNodeSelection(e)}})]}updateFromNodeSelection(e){if(!Dd(e.selection)||e.selection.node.type.name!==this.name)return;const t=e.selection.$from.pos+1,{insertionNode:r}=this.options;if(!r)return;const n=this.store.schema.nodes[r];re(n,{code:B.EXTENSION,message:`'${r}' node provided as the insertionNode to the '${this.constructorName}' does not exist.`});const o=n.create();e.insert(t,o),e.setSelection(le.near(e.doc.resolve(t+1)))}};wO([U(Jse)],Eh.prototype,"insertHorizontalRule",1);Eh=wO([pe({defaultOptions:{insertionNode:"paragraph"}})],Eh);var Xse=Object.defineProperty,Qse=Object.getOwnPropertyDescriptor,wx=(e,t,r,n)=>{for(var o=n>1?void 0:n?Qse(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&Xse(t,r,o),o},Zse=class extends bse{constructor(e,t,r){super({node:e,view:t,getPos:r,aspectRatio:yO.Fixed})}createElement({node:e}){const t=document.createElement("img");return t.setAttribute("src",e.attrs.src),ar(t,{width:"100%",minWidth:"50px",objectFit:"contain"}),t}},wd=class extends er{get name(){return"image"}createTags(){return[te.InlineNode,te.Media]}createNodeSpec(e,t){const{preferPastedTextContent:r}=this.options;return{inline:!0,draggable:!0,selectable:!1,...t,attrs:{...e.defaults(),alt:{default:""},crop:{default:null},height:{default:null},width:{default:null},rotate:{default:null},src:{default:null},title:{default:""},fileName:{default:null},resizable:{default:!1}},parseDOM:[{tag:"img[src]",getAttrs:n=>{var o;if(et(n)){const i=tae({element:n,parse:e.parse});return r&&((o=i.src)!=null&&o.startsWith("file:///"))?!1:i}return{}}},...t.parseDOM??[]],toDOM:n=>{const o=$d(n.attrs,e);return["img",{...e.dom(n),...o}]}}}insertImage(e,t){return({tr:r,dispatch:n})=>{const{from:o,to:i}=jr(t??r.selection,r.doc),s=this.type.create(e);return n==null||n(r.replaceRangeWith(o,i,s)),!0}}uploadImage(e,t){const{updatePlaceholder:r,destroyPlaceholder:n,createPlaceholder:o}=this.options;return i=>{const{tr:s}=i;let a=s.selection.from;return this.store.createPlaceholderCommand({promise:e,placeholder:{type:"widget",get pos(){return a},createElement:(l,c)=>{const u=o(l,c);return t==null||t(u),u},onUpdate:(l,c,u,d)=>{r(l,c,u,d)},onDestroy:(l,c)=>{n(l,c)}},onSuccess:(l,c,u)=>this.insertImage(l,c)(u)}).validate(({tr:l,dispatch:c})=>{const u=CE(l.doc,a,this.type);return u==null?!1:(a=u,l.selection.empty||c==null||c(l.deleteSelection()),!0)},"unshift").generateCommand()(i)}}fileUploadFileHandler(e,t,r){var n;const{preferPastedTextContent:o,uploadHandler:i}=this.options;if(o&&oae(t)&&((n=t.clipboardData)!=null&&n.getData("text/plain")))return!1;const{commands:s,chain:a}=this.store,l=e.map((u,d)=>({file:u,progress:f=>{s.updatePlaceholder(c[d],f)}})),c=i(l);Jt(r)&&a.selectText(r);for(const u of c)a.uploadImage(u);return a.run(),!0}createPasteRules(){return[{type:"file",regexp:/image/i,fileHandler:e=>{const t=e.type==="drop"?e.pos:void 0;return this.fileUploadFileHandler(e.files,e.event,t)}}]}createNodeViews(){return this.options.enableResizing?(e,t,r)=>new Zse(e,t,r):{}}};wx([U()],wd.prototype,"insertImage",1);wx([U()],wd.prototype,"uploadImage",1);wd=wx([pe({defaultOptions:{createPlaceholder:rae,updatePlaceholder:()=>{},destroyPlaceholder:()=>{},uploadHandler:nae,enableResizing:!1,preferPastedTextContent:!0}})],wd);function eae(e){let{width:t,height:r}=e.style;return t=t||e.getAttribute("width")||"",r=r||e.getAttribute("height")||"",{width:t,height:r}}function tae({element:e,parse:t}){const{width:r,height:n}=eae(e);return{...t(e),alt:e.getAttribute("alt")??"",height:Number.parseInt(n||"0",10)||null,src:e.getAttribute("src")??null,title:e.getAttribute("title")??"",width:Number.parseInt(r||"0",10)||null,fileName:e.getAttribute("data-file-name")??null}}function rae(e,t){const r=document.createElement("div");return r.classList.add(uV.IMAGE_LOADER),r}function nae(e){re(e.length>0,{code:B.EXTENSION,message:"The upload handler was applied for the image extension without any valid files"});let t=0;const r=[];for(const{file:n,progress:o}of e)r.push(()=>new Promise(i=>{const s=new FileReader;s.addEventListener("load",a=>{var l;t+=1,o(t/e.length),i({src:(l=a.target)==null?void 0:l.result,fileName:n.name})},{once:!0}),s.readAsDataURL(n)}));return r}function oae(e){return e.clipboardData!==void 0}var iae=Object.defineProperty,sae=Object.getOwnPropertyDescriptor,Sx=(e,t,r,n)=>{for(var o=n>1?void 0:n?sae(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&iae(t,r,o),o},aae={icon:"italic",label:({t:e})=>e(bk.LABEL),description:({t:e})=>e(bk.DESCRIPTION)},Sd=class extends ci{get name(){return"italic"}createTags(){return[te.FontStyle,te.FormattingMark]}createMarkSpec(e,t){return{...t,attrs:e.defaults(),parseDOM:[{tag:"i",getAttrs:e.parse},{tag:"em",getAttrs:e.parse},{style:"font-style=italic"},...t.parseDOM??[]],toDOM:r=>["em",e.dom(r),0]}}createKeymap(){return{"Mod-i":is({type:this.type})}}createInputRules(){return[Vu({regexp:/(?:^|[^*])\*([^*]+)\*$/,type:this.type,ignoreWhitespace:!0,updateCaptured:({fullMatch:e,start:t})=>e.startsWith("*")?{}:{fullMatch:e.slice(1),start:t+1}}),Vu({regexp:/(?:^|\W)_([^_]+)_$/,type:this.type,ignoreWhitespace:!0,updateCaptured:({fullMatch:e,start:t})=>e.startsWith("_")?{}:{fullMatch:e.slice(1),start:t+1}})]}createPasteRules(){return[{type:"mark",markType:this.type,regexp:/(?:^|\W)_([^_]+)_/g},{type:"mark",markType:this.type,regexp:/\*([^*]+)\*/g}]}toggleItalic(e){return is({type:this.type,selection:e})}shortcut(e){return this.toggleItalic()(e)}};Sx([U(aae)],Sd.prototype,"toggleItalic",1);Sx([je({shortcut:$.Italic,command:"toggleItalic"})],Sd.prototype,"shortcut",1);Sd=Sx([pe({})],Sd);var SO={exports:{}};(function(e,t){(function(r,n){e.exports=n()})(typeof self<"u"?self:Pu,function(){return function(r){function n(i){if(o[i])return o[i].exports;var s=o[i]={i,l:!1,exports:{}};return r[i].call(s.exports,s,s.exports,n),s.l=!0,s.exports}var o={};return n.m=r,n.c=o,n.d=function(i,s,a){n.o(i,s)||Object.defineProperty(i,s,{configurable:!1,enumerable:!0,get:a})},n.n=function(i){var s=i&&i.__esModule?function(){return i.default}:function(){return i};return n.d(s,"a",s),s},n.o=function(i,s){return Object.prototype.hasOwnProperty.call(i,s)},n.p="",n(n.s=0)}([function(r,n,o){function i(){throw new TypeError("The given URL is not a string. Please verify your string|array.")}function s(c){typeof c!="string"&&i();for(var u=0,d=0,f=0,p=c.length,h=0;p--&&++h&&!(u&&-1f?"":c.slice(f,u)}var a=["/",":","?","#"],l=[".","/","@"];r.exports=function(c){if(typeof c=="string")return s(c);if(Array.isArray(c)){var u=[],d,f=0;for(d=c.length;f{for(var o=n>1?void 0:n?dae(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&uae(t,r,o),o},fae=["com","de","net","org","uk","cn","ga","nl","cf","ml","tk","ru","br","gq","xyz","fr","eu","info","co","au","ca","it","in","ch","pl","es","online","us","top","be","jp","biz","se","at","dk","cz","za","me","ir","icu","shop","kr","site","mx","hu","io","cc","club","no","cyou"],l4="updateLink",pae=/(?:(?:(?:https?|ftp):)?\/\/)?(?:\S+(?::\S*)?@)?(?:(?:[\da-z\u00A1-\uFFFF][\w\u00A1-\uFFFF-]{0,62})?[\da-z\u00A1-\uFFFF]\.)*(?:(?:\d(?!\.)|[a-z\u00A1-\uFFFF])(?:[\da-z\u00A1-\uFFFF][\w\u00A1-\uFFFF-]{0,62})?[\da-z\u00A1-\uFFFF]\.)+[a-z\u00A1-\uFFFF]{2,}(?::\d{2,5})?(?:[#/?]\S*)?/gi,ba=class extends ci{constructor(){super(...arguments),this._autoLinkRegexNonGlobal=void 0}get name(){return"link"}createTags(){return[te.Link,te.ExcludeInputRules]}createMarkSpec(e,t){const r="data-link-auto",n=o=>{const{defaultTarget:i,supportedTargets:s}=this.options,a=i?[...s,i]:s;return o&&fr(a,o)?{target:o}:void 0};return{inclusive:!1,excludes:"_",...t,attrs:{...e.defaults(),href:{},target:{default:this.options.defaultTarget},auto:{default:!1}},parseDOM:[{tag:"a[href]",getAttrs:o=>{if(!et(o))return!1;const i=o.getAttribute("href"),s=o.textContent,a=this.options.autoLink&&(o.hasAttribute(r)||i===s||(i==null?void 0:i.replace(`${this.options.defaultProtocol}//`,""))===s);return{...e.parse(o),href:i,auto:a,...n(o.getAttribute("target"))}}},...t.parseDOM??[]],toDOM:o=>{const{auto:i,target:s,...a}=$d(o.attrs,e),l=o.attrs.auto?{[r]:""}:{},c="noopener noreferrer nofollow";return["a",{...e.dom(o),...a,rel:c,...l,...n(o.attrs.target)},0]}}}onCreate(){const{autoLinkRegex:e}=this.options;this._autoLinkRegexNonGlobal=new RegExp(`^${e.source}$`,e.flags.replace("g",""))}shortcut({tr:e}){let t="",{from:r,to:n,empty:o,$from:i}=e.selection,s=!1;const a=_o(i,this.type);if(o){const l=a??AC(e);if(!l)return!1;({text:t,from:r,to:n}=l),s=!0}return r===n?!1:(s||(t=e.doc.textBetween(r,n)),this.options.onActivateLink(t),this.options.onShortcut({activeLink:a?{attrs:a.mark.attrs,from:a.from,to:a.to}:void 0,selectedText:t,from:r,to:n}),!0)}updateLink(e,t){return r=>{const{tr:n}=r;return!(ms(n.selection)&&!Uv(n.selection)||mz(n.selection)||Pp({trState:n,type:this.type}))&&!t?!1:(n.setMeta(this.name,{command:l4,attrs:e,range:t}),zz({type:this.type,attrs:e,range:t})(r))}}selectLink(){return this.store.commands.selectMark.original(this.type)}removeLink(e){return t=>{const{tr:r}=t;return Pp({trState:r,type:this.type,...e})?BC({type:this.type,expand:!0,range:e})(t):!1}}createPasteRules(){return[{type:"mark",regexp:this.options.autoLinkRegex,markType:this.type,getAttributes:(e,t)=>({href:this.buildHref(Zo(e)),auto:!t}),transformMatch:e=>{const t=Zo(e);return!t||!this.isValidUrl(t)?!1:t}}]}createEventHandlers(){return{clickMark:(e,t)=>{const r=t.getMark(this.type);if(!r)return;const n=r.mark.attrs,o={...n,...r};if(this.options.onClick(e,o))return!0;if(!this.store.view.editable)return;let i=!1;if(this.options.openLinkOnClick){i=!0;const s=n.href;window.open(s,"_blank")}return this.options.selectTextOnClick&&(i=!0,this.store.commands.selectText(r)),i}}}createPlugin(){return{appendTransaction:(e,t,r)=>{if(e.filter(p=>!!p.getMeta(this.name)).forEach(p=>{const h=p.getMeta(this.name);if(h.command===l4){const{range:m,attrs:b}=h,{selection:v,doc:g}=r,y={range:m,selection:v,doc:g,attrs:b},{from:x,to:k}=m??v;this.options.onUpdateLink(g.textBetween(x,k),y)}}),!this.options.autoLink||K0(t)-K0(r)===1||!e.some(p=>p.docChanged))return;const s=ez(e,t),a=_C(s,[bt,Dt]),{mapping:l}=s,{tr:c,doc:u}=r,{updateLink:d,removeLink:f}=this.store.chain(c);if(a.forEach(({prevFrom:p,prevTo:h,from:m,to:b})=>{const v=[],g=b-m===2,y=this.getLinkMarksInRange(t.doc,p,h,!0).filter(x=>x.mark.type===this.type).map(({from:x,to:k,text:w})=>({mappedFrom:l.map(x),mappedTo:l.map(k),text:w,from:x,to:k}));y.forEach(({mappedFrom:x,mappedTo:k,from:w,to:E},M)=>this.getLinkMarksInRange(u,x,k,!0).filter(C=>C.mark.type===this.type).forEach(C=>{const T=t.doc.textBetween(w,E,void 0," "),N=u.textBetween(C.from,C.to+1,void 0," ").trim(),z=this.isValidUrl(T);this.isValidUrl(N)||(z&&(f({from:C.from,to:C.to}).tr(),y.splice(M,1)),!g&&m===b&&this.findAutoLinks(N).map(V=>this.addLinkProperties({...V,from:x+V.start,to:x+V.end})).forEach(({attrs:V,range:j,text:L})=>{d(V,j).tr(),v.push({attrs:V,range:j,text:L})}))})),this.findTextBlocksInRange(u,{from:m,to:b}).forEach(({text:x,positionStart:k})=>{this.findAutoLinks(x).map(w=>this.addLinkProperties({...w,from:k+w.start+1,to:k+w.end+1})).filter(({range:w})=>{const E=m>=w.from&&m<=w.to,M=b>=w.from&&b<=w.to;return E||M||g}).filter(({range:w})=>this.getLinkMarksInRange(c.doc,w.from,w.to,!1).length===0).filter(({range:{from:w},text:E})=>!y.some(({text:M,mappedFrom:C})=>C===w&&M===E)).forEach(({attrs:w,text:E,range:M})=>{d(w,M).tr(),v.push({attrs:w,range:M,text:E})})}),window.requestAnimationFrame(()=>{v.forEach(({attrs:x,range:k,text:w})=>{const{doc:E,selection:M}=c;this.options.onUpdateLink(w,{attrs:x,doc:E,range:k,selection:M})})})}),c.steps.length!==0)return c}}}buildHref(e){return this.options.extractHref({url:e,defaultProtocol:this.options.defaultProtocol})}getLinkMarksInRange(e,t,r,n){const o=[];if(t===r){const i=Math.max(t-1,0),s=e.resolve(i),a=_o(s,this.type);(a==null?void 0:a.mark.attrs.auto)===n&&o.push(a)}else e.nodesBetween(t,r,(i,s)=>{const l=(i.marks??[]).find(({type:c,attrs:u})=>c===this.type&&u.auto===n);l&&o.push({from:s,to:s+i.nodeSize,mark:l,text:i.textContent})});return o}findTextBlocksInRange(e,t){const r=[];return e.nodesBetween(t.from,t.to,(n,o)=>{!n.isTextblock||!n.type.allowsMarkType(this.type)||r.push({node:n,pos:o})}),r.map(n=>({text:e.textBetween(n.pos,n.pos+n.node.nodeSize,void 0," "),positionStart:n.pos}))}addLinkProperties({from:e,to:t,href:r,...n}){return{...n,range:{from:e,to:t},attrs:{href:r,auto:!0}}}findAutoLinks(e){if(this.options.findAutoLinks)return this.options.findAutoLinks(e,this.options.defaultProtocol);const t=[];for(const r of xa(e,this.options.autoLinkRegex)){const n=Zo(r);if(!n)continue;const o=this.buildHref(n);!this.isValidTLD(o)&&!o.startsWith("tel:")||t.push({text:n,href:o,start:r.index,end:r.index+n.length})}return t}isValidUrl(e){var t;return this.options.isValidUrl?this.options.isValidUrl(e,this.options.defaultProtocol):this.isValidTLD(this.buildHref(e))&&!!((t=this._autoLinkRegexNonGlobal)!=null&&t.test(e))}isValidTLD(e){const{autoLinkAllowedTLDs:t}=this.options;if(t.length===0)return!0;const r=cae(e);if(r==="")return!0;const n=Z4(r.split("."));return t.includes(n)}};Zd([je({shortcut:$.InsertLink})],ba.prototype,"shortcut",1);Zd([U()],ba.prototype,"updateLink",1);Zd([U()],ba.prototype,"selectLink",1);Zd([U()],ba.prototype,"removeLink",1);ba=Zd([pe({defaultOptions:{autoLink:!1,defaultProtocol:"",selectTextOnClick:!1,openLinkOnClick:!1,autoLinkRegex:pae,autoLinkAllowedTLDs:fae,findAutoLinks:void 0,isValidUrl:void 0,defaultTarget:null,supportedTargets:[],extractHref:hae},staticKeys:["autoLinkRegex"],handlerKeyOptions:{onClick:{earlyReturnValue:!0}},handlerKeys:["onActivateLink","onShortcut","onUpdateLink","onClick"],defaultPriority:Ae.Medium})],ba);function hae({url:e,defaultProtocol:t}){const r=/^((?:https?|ftp)?:)\/\//.test(e);return!r&&e.includes("@")?`mailto:${e}`:r?e:`${t}//${e}`}function mae(e){for(var t=1;t0&&e[t-1]===` +`;)t--;return e.substring(0,t)}var yae=["ADDRESS","ARTICLE","ASIDE","AUDIO","BLOCKQUOTE","BODY","CANVAS","CENTER","DD","DIR","DIV","DL","DT","FIELDSET","FIGCAPTION","FIGURE","FOOTER","FORM","FRAMESET","H1","H2","H3","H4","H5","H6","HEADER","HGROUP","HR","HTML","ISINDEX","LI","MAIN","MENU","NAV","NOFRAMES","NOSCRIPT","OL","OUTPUT","P","PRE","SECTION","TABLE","TBODY","TD","TFOOT","TH","THEAD","TR","UL"];function Ex(e){return Cx(e,yae)}var EO=["AREA","BASE","BR","COL","COMMAND","EMBED","HR","IMG","INPUT","KEYGEN","LINK","META","PARAM","SOURCE","TRACK","WBR"];function CO(e){return Cx(e,EO)}function bae(e){return TO(e,EO)}var MO=["A","TABLE","THEAD","TBODY","TFOOT","TH","TD","IFRAME","SCRIPT","AUDIO","VIDEO"];function xae(e){return Cx(e,MO)}function kae(e){return TO(e,MO)}function Cx(e,t){return t.indexOf(e.nodeName)>=0}function TO(e,t){return e.getElementsByTagName&&t.some(function(r){return e.getElementsByTagName(r).length})}var hr={};hr.paragraph={filter:"p",replacement:function(e){return` + +`+e+` + +`}};hr.lineBreak={filter:"br",replacement:function(e,t,r){return r.br+` +`}};hr.heading={filter:["h1","h2","h3","h4","h5","h6"],replacement:function(e,t,r){var n=Number(t.nodeName.charAt(1));if(r.headingStyle==="setext"&&n<3){var o=mv(n===1?"=":"-",e.length);return` + +`+e+` +`+o+` + +`}else return` + +`+mv("#",n)+" "+e+` + +`}};hr.blockquote={filter:"blockquote",replacement:function(e){return e=e.replace(/^\n+|\n+$/g,""),e=e.replace(/^/gm,"> "),` + +`+e+` + +`}};hr.list={filter:["ul","ol"],replacement:function(e,t){var r=t.parentNode;return r.nodeName==="LI"&&r.lastElementChild===t?` +`+e:` + +`+e+` + +`}};hr.listItem={filter:"li",replacement:function(e,t,r){e=e.replace(/^\n+/,"").replace(/\n+$/,` +`).replace(/\n/gm,` + `);var n=r.bulletListMarker+" ",o=t.parentNode;if(o.nodeName==="OL"){var i=o.getAttribute("start"),s=Array.prototype.indexOf.call(o.children,t);n=(i?Number(i)+s:s+1)+". "}return n+e+(t.nextSibling&&!/\n$/.test(e)?` +`:"")}};hr.indentedCodeBlock={filter:function(e,t){return t.codeBlockStyle==="indented"&&e.nodeName==="PRE"&&e.firstChild&&e.firstChild.nodeName==="CODE"},replacement:function(e,t,r){return` + + `+t.firstChild.textContent.replace(/\n/g,` + `)+` + +`}};hr.fencedCodeBlock={filter:function(e,t){return t.codeBlockStyle==="fenced"&&e.nodeName==="PRE"&&e.firstChild&&e.firstChild.nodeName==="CODE"},replacement:function(e,t,r){for(var n=t.firstChild.getAttribute("class")||"",o=(n.match(/language-(\S+)/)||[null,""])[1],i=t.firstChild.textContent,s=r.fence.charAt(0),a=3,l=new RegExp("^"+s+"{3,}","gm"),c;c=l.exec(i);)c[0].length>=a&&(a=c[0].length+1);var u=mv(s,a);return` + +`+u+o+` +`+i.replace(/\n$/,"")+` +`+u+` + +`}};hr.horizontalRule={filter:"hr",replacement:function(e,t,r){return` + +`+r.hr+` + +`}};hr.inlineLink={filter:function(e,t){return t.linkStyle==="inlined"&&e.nodeName==="A"&&e.getAttribute("href")},replacement:function(e,t){var r=t.getAttribute("href"),n=Ch(t.getAttribute("title"));return n&&(n=' "'+n+'"'),"["+e+"]("+r+n+")"}};hr.referenceLink={filter:function(e,t){return t.linkStyle==="referenced"&&e.nodeName==="A"&&e.getAttribute("href")},replacement:function(e,t,r){var n=t.getAttribute("href"),o=Ch(t.getAttribute("title"));o&&(o=' "'+o+'"');var i,s;switch(r.linkReferenceStyle){case"collapsed":i="["+e+"][]",s="["+e+"]: "+n+o;break;case"shortcut":i="["+e+"]",s="["+e+"]: "+n+o;break;default:var a=this.references.length+1;i="["+e+"]["+a+"]",s="["+a+"]: "+n+o}return this.references.push(s),i},references:[],append:function(e){var t="";return this.references.length&&(t=` + +`+this.references.join(` +`)+` + +`,this.references=[]),t}};hr.emphasis={filter:["em","i"],replacement:function(e,t,r){return e.trim()?r.emDelimiter+e+r.emDelimiter:""}};hr.strong={filter:["strong","b"],replacement:function(e,t,r){return e.trim()?r.strongDelimiter+e+r.strongDelimiter:""}};hr.code={filter:function(e){var t=e.previousSibling||e.nextSibling,r=e.parentNode.nodeName==="PRE"&&!t;return e.nodeName==="CODE"&&!r},replacement:function(e){if(!e)return"";e=e.replace(/\r?\n|\r/g," ");for(var t=/^`|^ .*?[^ ].* $|`$/.test(e)?" ":"",r="`",n=e.match(/`+/gm)||[];n.indexOf(r)!==-1;)r=r+"`";return r+t+e+t+r}};hr.image={filter:"img",replacement:function(e,t){var r=Ch(t.getAttribute("alt")),n=t.getAttribute("src")||"",o=Ch(t.getAttribute("title")),i=o?' "'+o+'"':"";return n?"!["+r+"]("+n+i+")":""}};function Ch(e){return e?e.replace(/(\n+\s*)+/g,` +`):""}function OO(e){this.options=e,this._keep=[],this._remove=[],this.blankRule={replacement:e.blankReplacement},this.keepReplacement=e.keepReplacement,this.defaultRule={replacement:e.defaultReplacement},this.array=[];for(var t in e.rules)this.array.push(e.rules[t])}OO.prototype={add:function(e,t){this.array.unshift(t)},keep:function(e){this._keep.unshift({filter:e,replacement:this.keepReplacement})},remove:function(e){this._remove.unshift({filter:e,replacement:function(){return""}})},forNode:function(e){if(e.isBlank)return this.blankRule;var t;return(t=v1(this.array,e,this.options))||(t=v1(this._keep,e,this.options))||(t=v1(this._remove,e,this.options))?t:this.defaultRule},forEach:function(e){for(var t=0;t-1)return!0}else if(typeof n=="function"){if(n.call(e,t,r))return!0}else throw new TypeError("`filter` needs to be a string, array, or function")}function Sae(e){var t=e.element,r=e.isBlock,n=e.isVoid,o=e.isPre||function(d){return d.nodeName==="PRE"};if(!(!t.firstChild||o(t))){for(var i=null,s=!1,a=null,l=c4(a,t,o);l!==t;){if(l.nodeType===3||l.nodeType===4){var c=l.data.replace(/[ \r\n\t]+/g," ");if((!i||/ $/.test(i.data))&&!s&&c[0]===" "&&(c=c.substr(1)),!c){l=y1(l);continue}l.data=c,i=l}else if(l.nodeType===1)r(l)||l.nodeName==="BR"?(i&&(i.data=i.data.replace(/ $/,"")),i=null,s=!1):n(l)||o(l)?(i=null,s=!0):i&&(s=!1);else{l=y1(l);continue}var u=c4(a,l,o);a=l,l=u}i&&(i.data=i.data.replace(/ $/,""),i.data||y1(i))}}function y1(e){var t=e.nextSibling||e.parentNode;return e.parentNode.removeChild(e),t}function c4(e,t,r){return e&&e.parentNode===t||r(t)?t.nextSibling||t.parentNode:t.firstChild||t.nextSibling||t.parentNode}var _O=typeof window<"u"?window:{};function Eae(){var e=_O.DOMParser,t=!1;try{new e().parseFromString("","text/html")&&(t=!0)}catch{}return t}function Cae(){var e=function(){};return Mae()?e.prototype.parseFromString=function(t){var r=new window.ActiveXObject("htmlfile");return r.designMode="on",r.open(),r.write(t),r.close(),r}:e.prototype.parseFromString=function(t){var r=document.implementation.createHTMLDocument("");return r.open(),r.write(t),r.close(),r},e}function Mae(){var e=!1;try{document.implementation.createHTMLDocument("").open()}catch{window.ActiveXObject&&(e=!0)}return e}var Tae=Eae()?_O.DOMParser:Cae();function Oae(e,t){var r;if(typeof e=="string"){var n=_ae().parseFromString(''+e+"","text/html");r=n.getElementById("turndown-root")}else r=e.cloneNode(!0);return Sae({element:r,isBlock:Ex,isVoid:CO,isPre:t.preformattedCode?Aae:null}),r}var b1;function _ae(){return b1=b1||new Tae,b1}function Aae(e){return e.nodeName==="PRE"||e.nodeName==="CODE"}function Nae(e,t){return e.isBlock=Ex(e),e.isCode=e.nodeName==="CODE"||e.parentNode.isCode,e.isBlank=Rae(e),e.flankingWhitespace=Pae(e,t),e}function Rae(e){return!CO(e)&&!xae(e)&&/^\s*$/i.test(e.textContent)&&!bae(e)&&!kae(e)}function Pae(e,t){if(e.isBlock||t.preformattedCode&&e.isCode)return{leading:"",trailing:""};var r=zae(e.textContent);return r.leadingAscii&&u4("left",e,t)&&(r.leading=r.leadingNonAscii),r.trailingAscii&&u4("right",e,t)&&(r.trailing=r.trailingNonAscii),{leading:r.leading,trailing:r.trailing}}function zae(e){var t=e.match(/^(([ \t\r\n]*)(\s*))(?:(?=\S)[\s\S]*\S)?((\s*?)([ \t\r\n]*))$/);return{leading:t[1],leadingAscii:t[2],leadingNonAscii:t[3],trailing:t[4],trailingNonAscii:t[5],trailingAscii:t[6]}}function u4(e,t,r){var n,o,i;return e==="left"?(n=t.previousSibling,o=/ $/):(n=t.nextSibling,o=/^ /),n&&(n.nodeType===3?i=o.test(n.nodeValue):r.preformattedCode&&n.nodeName==="CODE"?i=!1:n.nodeType===1&&!Ex(n)&&(i=o.test(n.textContent))),i}var Lae=Array.prototype.reduce,Iae=[[/\\/g,"\\\\"],[/\*/g,"\\*"],[/^-/g,"\\-"],[/^\+ /g,"\\+ "],[/^(=+)/g,"\\$1"],[/^(#{1,6}) /g,"\\$1 "],[/`/g,"\\`"],[/^~~~/g,"\\~~~"],[/\[/g,"\\["],[/\]/g,"\\]"],[/^>/g,"\\>"],[/_/g,"\\_"],[/^(\d+)\. /g,"$1\\. "]];function Ed(e){if(!(this instanceof Ed))return new Ed(e);var t={rules:hr,headingStyle:"setext",hr:"* * *",bulletListMarker:"*",codeBlockStyle:"indented",fence:"```",emDelimiter:"_",strongDelimiter:"**",linkStyle:"inlined",linkReferenceStyle:"full",br:" ",preformattedCode:!1,blankReplacement:function(r,n){return n.isBlock?` + +`:""},keepReplacement:function(r,n){return n.isBlock?` + +`+n.outerHTML+` + +`:n.outerHTML},defaultReplacement:function(r,n){return n.isBlock?` + +`+r+` + +`:r}};this.options=mae({},t,e),this.rules=new OO(this.options)}Ed.prototype={turndown:function(e){if(!Hae(e))throw new TypeError(e+" is not a string, or an element/document/fragment node.");if(e==="")return"";var t=AO.call(this,new Oae(e,this.options));return Dae.call(this,t)},use:function(e){if(Array.isArray(e))for(var t=0;t"']/,Fae=new RegExp(PO.source,"g"),zO=/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,Vae=new RegExp(zO.source,"g"),jae={"&":"&","<":"<",">":">",'"':""","'":"'"},d4=e=>jae[e];function cr(e,t){if(t){if(PO.test(e))return e.replace(Fae,d4)}else if(zO.test(e))return e.replace(Vae,d4);return e}const Uae=/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig;function LO(e){return e.replace(Uae,(t,r)=>(r=r.toLowerCase(),r==="colon"?":":r.charAt(0)==="#"?r.charAt(1)==="x"?String.fromCharCode(parseInt(r.substring(2),16)):String.fromCharCode(+r.substring(1)):""))}const Wae=/(^|[^\[])\^/g;function We(e,t){e=typeof e=="string"?e:e.source,t=t||"";const r={replace:(n,o)=>(o=o.source||o,o=o.replace(Wae,"$1"),e=e.replace(n,o),r),getRegex:()=>new RegExp(e,t)};return r}const Kae=/[^\w:]/g,qae=/^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;function f4(e,t,r){if(e){let n;try{n=decodeURIComponent(LO(r)).replace(Kae,"").toLowerCase()}catch{return null}if(n.indexOf("javascript:")===0||n.indexOf("vbscript:")===0||n.indexOf("data:")===0)return null}t&&!qae.test(r)&&(r=Xae(t,r));try{r=encodeURI(r).replace(/%25/g,"%")}catch{return null}return r}const Pf={},Gae=/^[^:]+:\/*[^/]*$/,Yae=/^([^:]+:)[\s\S]*$/,Jae=/^([^:]+:\/*[^/]*)[\s\S]*$/;function Xae(e,t){Pf[" "+e]||(Gae.test(e)?Pf[" "+e]=e+"/":Pf[" "+e]=mp(e,"/",!0)),e=Pf[" "+e];const r=e.indexOf(":")===-1;return t.substring(0,2)==="//"?r?t:e.replace(Yae,"$1")+t:t.charAt(0)==="/"?r?t:e.replace(Jae,"$1")+t:e+t}const Mh={exec:function(){}};function p4(e,t){const r=e.replace(/\|/g,(i,s,a)=>{let l=!1,c=s;for(;--c>=0&&a[c]==="\\";)l=!l;return l?"|":" |"}),n=r.split(/ \|/);let o=0;if(n[0].trim()||n.shift(),n.length>0&&!n[n.length-1].trim()&&n.pop(),n.length>t)n.splice(t);else for(;n.length1;)t&1&&(r+=e),t>>=1,e+=e;return r+e}function m4(e,t,r,n){const o=t.href,i=t.title?cr(t.title):null,s=e[1].replace(/\\([\[\]])/g,"$1");if(e[0].charAt(0)!=="!"){n.state.inLink=!0;const a={type:"link",raw:r,href:o,title:i,text:s,tokens:n.inlineTokens(s)};return n.state.inLink=!1,a}return{type:"image",raw:r,href:o,title:i,text:cr(s)}}function ele(e,t){const r=e.match(/^(\s+)(?:```)/);if(r===null)return t;const n=r[1];return t.split(` +`).map(o=>{const i=o.match(/^\s+/);if(i===null)return o;const[s]=i;return s.length>=n.length?o.slice(n.length):o}).join(` +`)}class Mx{constructor(t){this.options=t||Ta}space(t){const r=this.rules.block.newline.exec(t);if(r&&r[0].length>0)return{type:"space",raw:r[0]}}code(t){const r=this.rules.block.code.exec(t);if(r){const n=r[0].replace(/^ {1,4}/gm,"");return{type:"code",raw:r[0],codeBlockStyle:"indented",text:this.options.pedantic?n:mp(n,` +`)}}}fences(t){const r=this.rules.block.fences.exec(t);if(r){const n=r[0],o=ele(n,r[3]||"");return{type:"code",raw:n,lang:r[2]?r[2].trim().replace(this.rules.inline._escapes,"$1"):r[2],text:o}}}heading(t){const r=this.rules.block.heading.exec(t);if(r){let n=r[2].trim();if(/#$/.test(n)){const o=mp(n,"#");(this.options.pedantic||!o||/ $/.test(o))&&(n=o.trim())}return{type:"heading",raw:r[0],depth:r[1].length,text:n,tokens:this.lexer.inline(n)}}}hr(t){const r=this.rules.block.hr.exec(t);if(r)return{type:"hr",raw:r[0]}}blockquote(t){const r=this.rules.block.blockquote.exec(t);if(r){const n=r[0].replace(/^ *>[ \t]?/gm,""),o=this.lexer.state.top;this.lexer.state.top=!0;const i=this.lexer.blockTokens(n);return this.lexer.state.top=o,{type:"blockquote",raw:r[0],tokens:i,text:n}}}list(t){let r=this.rules.block.list.exec(t);if(r){let n,o,i,s,a,l,c,u,d,f,p,h,m=r[1].trim();const b=m.length>1,v={type:"list",raw:"",ordered:b,start:b?+m.slice(0,-1):"",loose:!1,items:[]};m=b?`\\d{1,9}\\${m.slice(-1)}`:`\\${m}`,this.options.pedantic&&(m=b?m:"[*+-]");const g=new RegExp(`^( {0,3}${m})((?:[ ][^\\n]*)?(?:\\n|$))`);for(;t&&(h=!1,!(!(r=g.exec(t))||this.rules.block.hr.test(t)));){if(n=r[0],t=t.substring(n.length),u=r[2].split(` +`,1)[0].replace(/^\t+/,x=>" ".repeat(3*x.length)),d=t.split(` +`,1)[0],this.options.pedantic?(s=2,p=u.trimLeft()):(s=r[2].search(/[^ ]/),s=s>4?1:s,p=u.slice(s),s+=r[1].length),l=!1,!u&&/^ *$/.test(d)&&(n+=d+` +`,t=t.substring(d.length+1),h=!0),!h){const x=new RegExp(`^ {0,${Math.min(3,s-1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`),k=new RegExp(`^ {0,${Math.min(3,s-1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`),w=new RegExp(`^ {0,${Math.min(3,s-1)}}(?:\`\`\`|~~~)`),E=new RegExp(`^ {0,${Math.min(3,s-1)}}#`);for(;t&&(f=t.split(` +`,1)[0],d=f,this.options.pedantic&&(d=d.replace(/^ {1,4}(?=( {4})*[^ ])/g," ")),!(w.test(d)||E.test(d)||x.test(d)||k.test(t)));){if(d.search(/[^ ]/)>=s||!d.trim())p+=` +`+d.slice(s);else{if(l||u.search(/[^ ]/)>=4||w.test(u)||E.test(u)||k.test(u))break;p+=` +`+d}!l&&!d.trim()&&(l=!0),n+=f+` +`,t=t.substring(f.length+1),u=d.slice(s)}}v.loose||(c?v.loose=!0:/\n *\n *$/.test(n)&&(c=!0)),this.options.gfm&&(o=/^\[[ xX]\] /.exec(p),o&&(i=o[0]!=="[ ] ",p=p.replace(/^\[[ xX]\] +/,""))),v.items.push({type:"list_item",raw:n,task:!!o,checked:i,loose:!1,text:p}),v.raw+=n}v.items[v.items.length-1].raw=n.trimRight(),v.items[v.items.length-1].text=p.trimRight(),v.raw=v.raw.trimRight();const y=v.items.length;for(a=0;aw.type==="space"),k=x.length>0&&x.some(w=>/\n.*\n/.test(w.raw));v.loose=k}if(v.loose)for(a=0;a$/,"$1").replace(this.rules.inline._escapes,"$1"):"",i=r[3]?r[3].substring(1,r[3].length-1).replace(this.rules.inline._escapes,"$1"):r[3];return{type:"def",tag:n,raw:r[0],href:o,title:i}}}table(t){const r=this.rules.block.table.exec(t);if(r){const n={type:"table",header:p4(r[1]).map(o=>({text:o})),align:r[2].replace(/^ *|\| *$/g,"").split(/ *\| */),rows:r[3]&&r[3].trim()?r[3].replace(/\n[ \t]*$/,"").split(` +`):[]};if(n.header.length===n.align.length){n.raw=r[0];let o=n.align.length,i,s,a,l;for(i=0;i({text:c}));for(o=n.header.length,s=0;s/i.test(r[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&/^<(pre|code|kbd|script)(\s|>)/i.test(r[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&/^<\/(pre|code|kbd|script)(\s|>)/i.test(r[0])&&(this.lexer.state.inRawBlock=!1),{type:this.options.sanitize?"text":"html",raw:r[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,text:this.options.sanitize?this.options.sanitizer?this.options.sanitizer(r[0]):cr(r[0]):r[0]}}link(t){const r=this.rules.inline.link.exec(t);if(r){const n=r[2].trim();if(!this.options.pedantic&&/^$/.test(n))return;const s=mp(n.slice(0,-1),"\\");if((n.length-s.length)%2===0)return}else{const s=Qae(r[2],"()");if(s>-1){const l=(r[0].indexOf("!")===0?5:4)+r[1].length+s;r[2]=r[2].substring(0,s),r[0]=r[0].substring(0,l).trim(),r[3]=""}}let o=r[2],i="";if(this.options.pedantic){const s=/^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(o);s&&(o=s[1],i=s[3])}else i=r[3]?r[3].slice(1,-1):"";return o=o.trim(),/^$/.test(n)?o=o.slice(1):o=o.slice(1,-1)),m4(r,{href:o&&o.replace(this.rules.inline._escapes,"$1"),title:i&&i.replace(this.rules.inline._escapes,"$1")},r[0],this.lexer)}}reflink(t,r){let n;if((n=this.rules.inline.reflink.exec(t))||(n=this.rules.inline.nolink.exec(t))){let o=(n[2]||n[1]).replace(/\s+/g," ");if(o=r[o.toLowerCase()],!o){const i=n[0].charAt(0);return{type:"text",raw:i,text:i}}return m4(n,o,n[0],this.lexer)}}emStrong(t,r,n=""){let o=this.rules.inline.emStrong.lDelim.exec(t);if(!o||o[3]&&n.match(/[\p{L}\p{N}]/u))return;const i=o[1]||o[2]||"";if(!i||i&&(n===""||this.rules.inline.punctuation.exec(n))){const s=o[0].length-1;let a,l,c=s,u=0;const d=o[0][0]==="*"?this.rules.inline.emStrong.rDelimAst:this.rules.inline.emStrong.rDelimUnd;for(d.lastIndex=0,r=r.slice(-1*t.length+s);(o=d.exec(r))!=null;){if(a=o[1]||o[2]||o[3]||o[4]||o[5]||o[6],!a)continue;if(l=a.length,o[3]||o[4]){c+=l;continue}else if((o[5]||o[6])&&s%3&&!((s+l)%3)){u+=l;continue}if(c-=l,c>0)continue;l=Math.min(l,l+c+u);const f=t.slice(0,s+o.index+(o[0].length-a.length)+l);if(Math.min(s,l)%2){const h=f.slice(1,-1);return{type:"em",raw:f,text:h,tokens:this.lexer.inlineTokens(h)}}const p=f.slice(2,-2);return{type:"strong",raw:f,text:p,tokens:this.lexer.inlineTokens(p)}}}}codespan(t){const r=this.rules.inline.code.exec(t);if(r){let n=r[2].replace(/\n/g," ");const o=/[^ ]/.test(n),i=/^ /.test(n)&&/ $/.test(n);return o&&i&&(n=n.substring(1,n.length-1)),n=cr(n,!0),{type:"codespan",raw:r[0],text:n}}}br(t){const r=this.rules.inline.br.exec(t);if(r)return{type:"br",raw:r[0]}}del(t){const r=this.rules.inline.del.exec(t);if(r)return{type:"del",raw:r[0],text:r[2],tokens:this.lexer.inlineTokens(r[2])}}autolink(t,r){const n=this.rules.inline.autolink.exec(t);if(n){let o,i;return n[2]==="@"?(o=cr(this.options.mangle?r(n[1]):n[1]),i="mailto:"+o):(o=cr(n[1]),i=o),{type:"link",raw:n[0],text:o,href:i,tokens:[{type:"text",raw:o,text:o}]}}}url(t,r){let n;if(n=this.rules.inline.url.exec(t)){let o,i;if(n[2]==="@")o=cr(this.options.mangle?r(n[0]):n[0]),i="mailto:"+o;else{let s;do s=n[0],n[0]=this.rules.inline._backpedal.exec(n[0])[0];while(s!==n[0]);o=cr(n[0]),n[1]==="www."?i="http://"+n[0]:i=n[0]}return{type:"link",raw:n[0],text:o,href:i,tokens:[{type:"text",raw:o,text:o}]}}}inlineText(t,r){const n=this.rules.inline.text.exec(t);if(n){let o;return this.lexer.state.inRawBlock?o=this.options.sanitize?this.options.sanitizer?this.options.sanitizer(n[0]):cr(n[0]):n[0]:o=cr(this.options.smartypants?r(n[0]):n[0]),{type:"text",raw:n[0],text:o}}}}const ae={newline:/^(?: *(?:\n|$))+/,code:/^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,fences:/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,hr:/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,heading:/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,blockquote:/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,list:/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/,html:"^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|)[\\s\\S]*?(?:(?:\\n *)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$))",def:/^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,table:Mh,lheading:/^((?:.|\n(?!\n))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,_paragraph:/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,text:/^[^\n]+/};ae._label=/(?!\s*\])(?:\\.|[^\[\]\\])+/;ae._title=/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/;ae.def=We(ae.def).replace("label",ae._label).replace("title",ae._title).getRegex();ae.bullet=/(?:[*+-]|\d{1,9}[.)])/;ae.listItemStart=We(/^( *)(bull) */).replace("bull",ae.bullet).getRegex();ae.list=We(ae.list).replace(/bull/g,ae.bullet).replace("hr","\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def","\\n+(?="+ae.def.source+")").getRegex();ae._tag="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul";ae._comment=/|$)/;ae.html=We(ae.html,"i").replace("comment",ae._comment).replace("tag",ae._tag).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();ae.paragraph=We(ae._paragraph).replace("hr",ae.hr).replace("heading"," {0,3}#{1,6} ").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",ae._tag).getRegex();ae.blockquote=We(ae.blockquote).replace("paragraph",ae.paragraph).getRegex();ae.normal={...ae};ae.gfm={...ae.normal,table:"^ *([^\\n ].*\\|.*)\\n {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)"};ae.gfm.table=We(ae.gfm.table).replace("hr",ae.hr).replace("heading"," {0,3}#{1,6} ").replace("blockquote"," {0,3}>").replace("code"," {4}[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",ae._tag).getRegex();ae.gfm.paragraph=We(ae._paragraph).replace("hr",ae.hr).replace("heading"," {0,3}#{1,6} ").replace("|lheading","").replace("table",ae.gfm.table).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html",")|<(?:script|pre|style|textarea|!--)").replace("tag",ae._tag).getRegex();ae.pedantic={...ae.normal,html:We(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment",ae._comment).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:Mh,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:We(ae.normal._paragraph).replace("hr",ae.hr).replace("heading",` *#{1,6} *[^ +]`).replace("lheading",ae.lheading).replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").getRegex()};const Q={escape:/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,autolink:/^<(scheme:[^\s\x00-\x1f<>]*|email)>/,url:Mh,tag:"^comment|^|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^",link:/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,reflink:/^!?\[(label)\]\[(ref)\]/,nolink:/^!?\[(ref)\](?:\[\])?/,reflinkSearch:"reflink|nolink(?!\\()",emStrong:{lDelim:/^(?:\*+(?:([punct_])|[^\s*]))|^_+(?:([punct*])|([^\s_]))/,rDelimAst:/^(?:[^_*\\]|\\.)*?\_\_(?:[^_*\\]|\\.)*?\*(?:[^_*\\]|\\.)*?(?=\_\_)|(?:[^*\\]|\\.)+(?=[^*])|[punct_](\*+)(?=[\s]|$)|(?:[^punct*_\s\\]|\\.)(\*+)(?=[punct_\s]|$)|[punct_\s](\*+)(?=[^punct*_\s])|[\s](\*+)(?=[punct_])|[punct_](\*+)(?=[punct_])|(?:[^punct*_\s\\]|\\.)(\*+)(?=[^punct*_\s])/,rDelimUnd:/^(?:[^_*\\]|\\.)*?\*\*(?:[^_*\\]|\\.)*?\_(?:[^_*\\]|\\.)*?(?=\*\*)|(?:[^_\\]|\\.)+(?=[^_])|[punct*](\_+)(?=[\s]|$)|(?:[^punct*_\s\\]|\\.)(\_+)(?=[punct*\s]|$)|[punct*\s](\_+)(?=[^punct*_\s])|[\s](\_+)(?=[punct*])|[punct*](\_+)(?=[punct*])/},code:/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,br:/^( {2,}|\\)\n(?!\s*$)/,del:Mh,text:/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\?@\\[\\]`^{|}~";Q.punctuation=We(Q.punctuation).replace(/punctuation/g,Q._punctuation).getRegex();Q.blockSkip=/\[[^\]]*?\]\([^\)]*?\)|`[^`]*?`|<[^>]*?>/g;Q.escapedEmSt=/(?:^|[^\\])(?:\\\\)*\\[*_]/g;Q._comment=We(ae._comment).replace("(?:-->|$)","-->").getRegex();Q.emStrong.lDelim=We(Q.emStrong.lDelim).replace(/punct/g,Q._punctuation).getRegex();Q.emStrong.rDelimAst=We(Q.emStrong.rDelimAst,"g").replace(/punct/g,Q._punctuation).getRegex();Q.emStrong.rDelimUnd=We(Q.emStrong.rDelimUnd,"g").replace(/punct/g,Q._punctuation).getRegex();Q._escapes=/\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g;Q._scheme=/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/;Q._email=/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/;Q.autolink=We(Q.autolink).replace("scheme",Q._scheme).replace("email",Q._email).getRegex();Q._attribute=/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/;Q.tag=We(Q.tag).replace("comment",Q._comment).replace("attribute",Q._attribute).getRegex();Q._label=/(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/;Q._href=/<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/;Q._title=/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/;Q.link=We(Q.link).replace("label",Q._label).replace("href",Q._href).replace("title",Q._title).getRegex();Q.reflink=We(Q.reflink).replace("label",Q._label).replace("ref",ae._label).getRegex();Q.nolink=We(Q.nolink).replace("ref",ae._label).getRegex();Q.reflinkSearch=We(Q.reflinkSearch,"g").replace("reflink",Q.reflink).replace("nolink",Q.nolink).getRegex();Q.normal={...Q};Q.pedantic={...Q.normal,strong:{start:/^__|\*\*/,middle:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,endAst:/\*\*(?!\*)/g,endUnd:/__(?!_)/g},em:{start:/^_|\*/,middle:/^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,endAst:/\*(?!\*)/g,endUnd:/_(?!_)/g},link:We(/^!?\[(label)\]\((.*?)\)/).replace("label",Q._label).getRegex(),reflink:We(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",Q._label).getRegex()};Q.gfm={...Q.normal,escape:We(Q.escape).replace("])","~|])").getRegex(),_extended_email:/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,url:/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,_backpedal:/(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,text:/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\.5&&(n="x"+n.toString(16)),t+="&#"+n+";";return t}class ds{constructor(t){this.tokens=[],this.tokens.links=Object.create(null),this.options=t||Ta,this.options.tokenizer=this.options.tokenizer||new Mx,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};const r={block:ae.normal,inline:Q.normal};this.options.pedantic?(r.block=ae.pedantic,r.inline=Q.pedantic):this.options.gfm&&(r.block=ae.gfm,this.options.breaks?r.inline=Q.breaks:r.inline=Q.gfm),this.tokenizer.rules=r}static get rules(){return{block:ae,inline:Q}}static lex(t,r){return new ds(r).lex(t)}static lexInline(t,r){return new ds(r).inlineTokens(t)}lex(t){t=t.replace(/\r\n|\r/g,` +`),this.blockTokens(t,this.tokens);let r;for(;r=this.inlineQueue.shift();)this.inlineTokens(r.src,r.tokens);return this.tokens}blockTokens(t,r=[]){this.options.pedantic?t=t.replace(/\t/g," ").replace(/^ +$/gm,""):t=t.replace(/^( *)(\t+)/gm,(a,l,c)=>l+" ".repeat(c.length));let n,o,i,s;for(;t;)if(!(this.options.extensions&&this.options.extensions.block&&this.options.extensions.block.some(a=>(n=a.call({lexer:this},t,r))?(t=t.substring(n.raw.length),r.push(n),!0):!1))){if(n=this.tokenizer.space(t)){t=t.substring(n.raw.length),n.raw.length===1&&r.length>0?r[r.length-1].raw+=` +`:r.push(n);continue}if(n=this.tokenizer.code(t)){t=t.substring(n.raw.length),o=r[r.length-1],o&&(o.type==="paragraph"||o.type==="text")?(o.raw+=` +`+n.raw,o.text+=` +`+n.text,this.inlineQueue[this.inlineQueue.length-1].src=o.text):r.push(n);continue}if(n=this.tokenizer.fences(t)){t=t.substring(n.raw.length),r.push(n);continue}if(n=this.tokenizer.heading(t)){t=t.substring(n.raw.length),r.push(n);continue}if(n=this.tokenizer.hr(t)){t=t.substring(n.raw.length),r.push(n);continue}if(n=this.tokenizer.blockquote(t)){t=t.substring(n.raw.length),r.push(n);continue}if(n=this.tokenizer.list(t)){t=t.substring(n.raw.length),r.push(n);continue}if(n=this.tokenizer.html(t)){t=t.substring(n.raw.length),r.push(n);continue}if(n=this.tokenizer.def(t)){t=t.substring(n.raw.length),o=r[r.length-1],o&&(o.type==="paragraph"||o.type==="text")?(o.raw+=` +`+n.raw,o.text+=` +`+n.raw,this.inlineQueue[this.inlineQueue.length-1].src=o.text):this.tokens.links[n.tag]||(this.tokens.links[n.tag]={href:n.href,title:n.title});continue}if(n=this.tokenizer.table(t)){t=t.substring(n.raw.length),r.push(n);continue}if(n=this.tokenizer.lheading(t)){t=t.substring(n.raw.length),r.push(n);continue}if(i=t,this.options.extensions&&this.options.extensions.startBlock){let a=1/0;const l=t.slice(1);let c;this.options.extensions.startBlock.forEach(function(u){c=u.call({lexer:this},l),typeof c=="number"&&c>=0&&(a=Math.min(a,c))}),a<1/0&&a>=0&&(i=t.substring(0,a+1))}if(this.state.top&&(n=this.tokenizer.paragraph(i))){o=r[r.length-1],s&&o.type==="paragraph"?(o.raw+=` +`+n.raw,o.text+=` +`+n.text,this.inlineQueue.pop(),this.inlineQueue[this.inlineQueue.length-1].src=o.text):r.push(n),s=i.length!==t.length,t=t.substring(n.raw.length);continue}if(n=this.tokenizer.text(t)){t=t.substring(n.raw.length),o=r[r.length-1],o&&o.type==="text"?(o.raw+=` +`+n.raw,o.text+=` +`+n.text,this.inlineQueue.pop(),this.inlineQueue[this.inlineQueue.length-1].src=o.text):r.push(n);continue}if(t){const a="Infinite loop on byte: "+t.charCodeAt(0);if(this.options.silent){console.error(a);break}else throw new Error(a)}}return this.state.top=!0,r}inline(t,r=[]){return this.inlineQueue.push({src:t,tokens:r}),r}inlineTokens(t,r=[]){let n,o,i,s=t,a,l,c;if(this.tokens.links){const u=Object.keys(this.tokens.links);if(u.length>0)for(;(a=this.tokenizer.rules.inline.reflinkSearch.exec(s))!=null;)u.includes(a[0].slice(a[0].lastIndexOf("[")+1,-1))&&(s=s.slice(0,a.index)+"["+h4("a",a[0].length-2)+"]"+s.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;(a=this.tokenizer.rules.inline.blockSkip.exec(s))!=null;)s=s.slice(0,a.index)+"["+h4("a",a[0].length-2)+"]"+s.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);for(;(a=this.tokenizer.rules.inline.escapedEmSt.exec(s))!=null;)s=s.slice(0,a.index+a[0].length-2)+"++"+s.slice(this.tokenizer.rules.inline.escapedEmSt.lastIndex),this.tokenizer.rules.inline.escapedEmSt.lastIndex--;for(;t;)if(l||(c=""),l=!1,!(this.options.extensions&&this.options.extensions.inline&&this.options.extensions.inline.some(u=>(n=u.call({lexer:this},t,r))?(t=t.substring(n.raw.length),r.push(n),!0):!1))){if(n=this.tokenizer.escape(t)){t=t.substring(n.raw.length),r.push(n);continue}if(n=this.tokenizer.tag(t)){t=t.substring(n.raw.length),o=r[r.length-1],o&&n.type==="text"&&o.type==="text"?(o.raw+=n.raw,o.text+=n.text):r.push(n);continue}if(n=this.tokenizer.link(t)){t=t.substring(n.raw.length),r.push(n);continue}if(n=this.tokenizer.reflink(t,this.tokens.links)){t=t.substring(n.raw.length),o=r[r.length-1],o&&n.type==="text"&&o.type==="text"?(o.raw+=n.raw,o.text+=n.text):r.push(n);continue}if(n=this.tokenizer.emStrong(t,s,c)){t=t.substring(n.raw.length),r.push(n);continue}if(n=this.tokenizer.codespan(t)){t=t.substring(n.raw.length),r.push(n);continue}if(n=this.tokenizer.br(t)){t=t.substring(n.raw.length),r.push(n);continue}if(n=this.tokenizer.del(t)){t=t.substring(n.raw.length),r.push(n);continue}if(n=this.tokenizer.autolink(t,g4)){t=t.substring(n.raw.length),r.push(n);continue}if(!this.state.inLink&&(n=this.tokenizer.url(t,g4))){t=t.substring(n.raw.length),r.push(n);continue}if(i=t,this.options.extensions&&this.options.extensions.startInline){let u=1/0;const d=t.slice(1);let f;this.options.extensions.startInline.forEach(function(p){f=p.call({lexer:this},d),typeof f=="number"&&f>=0&&(u=Math.min(u,f))}),u<1/0&&u>=0&&(i=t.substring(0,u+1))}if(n=this.tokenizer.inlineText(i,tle)){t=t.substring(n.raw.length),n.raw.slice(-1)!=="_"&&(c=n.raw.slice(-1)),l=!0,o=r[r.length-1],o&&o.type==="text"?(o.raw+=n.raw,o.text+=n.text):r.push(n);continue}if(t){const u="Infinite loop on byte: "+t.charCodeAt(0);if(this.options.silent){console.error(u);break}else throw new Error(u)}}return r}}class Tx{constructor(t){this.options=t||Ta}code(t,r,n){const o=(r||"").match(/\S*/)[0];if(this.options.highlight){const i=this.options.highlight(t,o);i!=null&&i!==t&&(n=!0,t=i)}return t=t.replace(/\n$/,"")+` +`,o?'
'+(n?t:cr(t,!0))+`
+`:"
"+(n?t:cr(t,!0))+`
+`}blockquote(t){return`
+${t}
+`}html(t){return t}heading(t,r,n,o){if(this.options.headerIds){const i=this.options.headerPrefix+o.slug(n);return`${t} +`}return`${t} +`}hr(){return this.options.xhtml?`
+`:`
+`}list(t,r,n){const o=r?"ol":"ul",i=r&&n!==1?' start="'+n+'"':"";return"<"+o+i+`> +`+t+" +`}listitem(t){return`
  • ${t}
  • +`}checkbox(t){return" "}paragraph(t){return`

    ${t}

    +`}table(t,r){return r&&(r=`${r}`),` + +`+t+` +`+r+`
    +`}tablerow(t){return` +${t} +`}tablecell(t,r){const n=r.header?"th":"td";return(r.align?`<${n} align="${r.align}">`:`<${n}>`)+t+` +`}strong(t){return`${t}`}em(t){return`${t}`}codespan(t){return`${t}`}br(){return this.options.xhtml?"
    ":"
    "}del(t){return`${t}`}link(t,r,n){if(t=f4(this.options.sanitize,this.options.baseUrl,t),t===null)return n;let o='",o}image(t,r,n){if(t=f4(this.options.sanitize,this.options.baseUrl,t),t===null)return n;let o=`${n}":">",o}text(t){return t}}class IO{strong(t){return t}em(t){return t}codespan(t){return t}del(t){return t}html(t){return t}text(t){return t}link(t,r,n){return""+n}image(t,r,n){return""+n}br(){return""}}class DO{constructor(){this.seen={}}serialize(t){return t.toLowerCase().trim().replace(/<[!\/a-z].*?>/ig,"").replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g,"").replace(/\s/g,"-")}getNextSafeSlug(t,r){let n=t,o=0;if(this.seen.hasOwnProperty(n)){o=this.seen[t];do o++,n=t+"-"+o;while(this.seen.hasOwnProperty(n))}return r||(this.seen[t]=o,this.seen[n]=0),n}slug(t,r={}){const n=this.serialize(t);return this.getNextSafeSlug(n,r.dryrun)}}class fs{constructor(t){this.options=t||Ta,this.options.renderer=this.options.renderer||new Tx,this.renderer=this.options.renderer,this.renderer.options=this.options,this.textRenderer=new IO,this.slugger=new DO}static parse(t,r){return new fs(r).parse(t)}static parseInline(t,r){return new fs(r).parseInline(t)}parse(t,r=!0){let n="",o,i,s,a,l,c,u,d,f,p,h,m,b,v,g,y,x,k,w;const E=t.length;for(o=0;o0&&g.tokens[0].type==="paragraph"?(g.tokens[0].text=k+" "+g.tokens[0].text,g.tokens[0].tokens&&g.tokens[0].tokens.length>0&&g.tokens[0].tokens[0].type==="text"&&(g.tokens[0].tokens[0].text=k+" "+g.tokens[0].tokens[0].text)):g.tokens.unshift({type:"text",text:k}):v+=k),v+=this.parse(g.tokens,b),f+=this.renderer.listitem(v,x,y);n+=this.renderer.list(f,h,m);continue}case"html":{n+=this.renderer.html(p.text);continue}case"paragraph":{n+=this.renderer.paragraph(this.parseInline(p.tokens));continue}case"text":{for(f=p.tokens?this.parseInline(p.tokens):p.text;o+1{if(n.message+=` +Please report this to https://github.com/markedjs/marked.`,e){const o="

    An error occurred:

    "+cr(n.message+"",!0)+"
    ";if(t)return Promise.resolve(o);if(r){r(null,o);return}return o}if(t)return Promise.reject(n);if(r){r(n);return}throw n}}function $O(e,t){return(r,n,o)=>{typeof n=="function"&&(o=n,n=null);const i={...n};n={...se.defaults,...i};const s=rle(n.silent,n.async,o);if(typeof r>"u"||r===null)return s(new Error("marked(): input parameter is undefined or null"));if(typeof r!="string")return s(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(r)+", string expected"));if(Zae(n),n.hooks&&(n.hooks.options=n),o){const a=n.highlight;let l;try{n.hooks&&(r=n.hooks.preprocess(r)),l=e(r,n)}catch(d){return s(d)}const c=function(d){let f;if(!d)try{n.walkTokens&&se.walkTokens(l,n.walkTokens),f=t(l,n),n.hooks&&(f=n.hooks.postprocess(f))}catch(p){d=p}return n.highlight=a,d?s(d):o(null,f)};if(!a||a.length<3||(delete n.highlight,!l.length))return c();let u=0;se.walkTokens(l,function(d){d.type==="code"&&(u++,setTimeout(()=>{a(d.text,d.lang,function(f,p){if(f)return c(f);p!=null&&p!==d.text&&(d.text=p,d.escaped=!0),u--,u===0&&c()})},0))}),u===0&&c();return}if(n.async)return Promise.resolve(n.hooks?n.hooks.preprocess(r):r).then(a=>e(a,n)).then(a=>n.walkTokens?Promise.all(se.walkTokens(a,n.walkTokens)).then(()=>a):a).then(a=>t(a,n)).then(a=>n.hooks?n.hooks.postprocess(a):a).catch(s);try{n.hooks&&(r=n.hooks.preprocess(r));const a=e(r,n);n.walkTokens&&se.walkTokens(a,n.walkTokens);let l=t(a,n);return n.hooks&&(l=n.hooks.postprocess(l)),l}catch(a){return s(a)}}}function se(e,t,r){return $O(ds.lex,fs.parse)(e,t,r)}se.options=se.setOptions=function(e){return se.defaults={...se.defaults,...e},Bae(se.defaults),se};se.getDefaults=RO;se.defaults=Ta;se.use=function(...e){const t=se.defaults.extensions||{renderers:{},childTokens:{}};e.forEach(r=>{const n={...r};if(n.async=se.defaults.async||n.async||!1,r.extensions&&(r.extensions.forEach(o=>{if(!o.name)throw new Error("extension name required");if(o.renderer){const i=t.renderers[o.name];i?t.renderers[o.name]=function(...s){let a=o.renderer.apply(this,s);return a===!1&&(a=i.apply(this,s)),a}:t.renderers[o.name]=o.renderer}if(o.tokenizer){if(!o.level||o.level!=="block"&&o.level!=="inline")throw new Error("extension level must be 'block' or 'inline'");t[o.level]?t[o.level].unshift(o.tokenizer):t[o.level]=[o.tokenizer],o.start&&(o.level==="block"?t.startBlock?t.startBlock.push(o.start):t.startBlock=[o.start]:o.level==="inline"&&(t.startInline?t.startInline.push(o.start):t.startInline=[o.start]))}o.childTokens&&(t.childTokens[o.name]=o.childTokens)}),n.extensions=t),r.renderer){const o=se.defaults.renderer||new Tx;for(const i in r.renderer){const s=o[i];o[i]=(...a)=>{let l=r.renderer[i].apply(o,a);return l===!1&&(l=s.apply(o,a)),l}}n.renderer=o}if(r.tokenizer){const o=se.defaults.tokenizer||new Mx;for(const i in r.tokenizer){const s=o[i];o[i]=(...a)=>{let l=r.tokenizer[i].apply(o,a);return l===!1&&(l=s.apply(o,a)),l}}n.tokenizer=o}if(r.hooks){const o=se.defaults.hooks||new Th;for(const i in r.hooks){const s=o[i];Th.passThroughHooks.has(i)?o[i]=a=>{if(se.defaults.async)return Promise.resolve(r.hooks[i].call(o,a)).then(c=>s.call(o,c));const l=r.hooks[i].call(o,a);return s.call(o,l)}:o[i]=(...a)=>{let l=r.hooks[i].apply(o,a);return l===!1&&(l=s.apply(o,a)),l}}n.hooks=o}if(r.walkTokens){const o=se.defaults.walkTokens;n.walkTokens=function(i){let s=[];return s.push(r.walkTokens.call(this,i)),o&&(s=s.concat(o.call(this,i))),s}}se.setOptions(n)})};se.walkTokens=function(e,t){let r=[];for(const n of e)switch(r=r.concat(t.call(se,n)),n.type){case"table":{for(const o of n.header)r=r.concat(se.walkTokens(o.tokens,t));for(const o of n.rows)for(const i of o)r=r.concat(se.walkTokens(i.tokens,t));break}case"list":{r=r.concat(se.walkTokens(n.items,t));break}default:se.defaults.extensions&&se.defaults.extensions.childTokens&&se.defaults.extensions.childTokens[n.type]?se.defaults.extensions.childTokens[n.type].forEach(function(o){r=r.concat(se.walkTokens(n[o],t))}):n.tokens&&(r=r.concat(se.walkTokens(n.tokens,t)))}return r};se.parseInline=$O(ds.lexInline,fs.parseInline);se.Parser=fs;se.parser=fs.parse;se.Renderer=Tx;se.TextRenderer=IO;se.Lexer=ds;se.lexer=ds.lex;se.Tokenizer=Mx;se.Slugger=DO;se.Hooks=Th;se.parse=se;se.options;se.setOptions;se.use;se.walkTokens;se.parseInline;fs.parse;ds.lex;var nle=Object.defineProperty,ole=Object.getOwnPropertyDescriptor,Qm=(e,t,r,n)=>{for(var o=n>1?void 0:n?ole(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&nle(t,r,o),o},ile=Ph(Ed);function sle(e){return lle.turndown(e)}function x1(e){const t=e.parentNode;if(!et(t))return!1;if(t.nodeName==="THEAD")return!0;if(t.nodeName!=="TABLE"&&!HO(t))return!1;const r=[...e.childNodes];return r.every(n=>n.nodeName==="TH")&&r.some(n=>!!n.textContent)}function Oh(e){return et(e)&&e.matches("th[data-controller-cell]")}function ale(e){const t=e.parentNode;return!et(t)||t.nodeName!=="TABLE"&&!HO(t)?!1:[...e.childNodes].every(n=>Oh(n))}function HO(e){var t;if(e.nodeName!=="TBODY")return!1;const r=e.previousSibling;return r?et(r)&&r.nodeName==="THEAD"&&!((t=r.textContent)!=null&&t.trim()):!0}function v4(e){const t=e.closest("table");if(!t)return!1;const{parentNode:r}=t;return r?!!r.closest("table"):!0}function y4(e,t){var r;const n=[];for(const s of((r=t.parentNode)==null?void 0:r.childNodes)??[])Oh(s)||n.push(s);return`${(n.indexOf(t)===0?"| ":" ")+e.trim()} |`}var lle=new ile({codeBlockStyle:"fenced",headingStyle:"atx"}).addRule("taskListItems",{filter:e=>e.nodeName==="LI"&&e.hasAttribute("data-task-list-item"),replacement:(e,t)=>`- ${t.hasAttribute("data-checked")?"[x]":"[ ]"} ${e.trimStart()}`}).addRule("tableCell",{filter:["th","td"],replacement:(e,t)=>Oh(t)?"":y4(e,t)}).addRule("tableRow",{filter:"tr",replacement:(e,t)=>{let r="";const n={left:":--",right:"--:",center:":-:"},o=[...t.childNodes].filter(i=>!Oh(i));if(x1(t))for(const i of o){if(!et(i))continue;let s="---";const a=(i.getAttribute("align")??"").toLowerCase();a&&(s=n[a]||s),r+=y4(s,i)}return` +${e}${r?` +${r}`:""}`}}).addRule("table",{filter:e=>{if(e.nodeName!=="TABLE"||v4(e))return!1;const t=[...e.rows].filter(r=>!ale(r));return x1(t[0])},replacement:e=>(e=e.replace(` + +`,` +`),` + +${e} + +`)}).addRule("tableSection",{filter:["thead","tbody","tfoot"],replacement:function(e){return e}}).keep(e=>e.nodeName==="TABLE"&&!x1(e.rows[0])).keep(e=>e.nodeName==="TABLE"&&v4(e)).addRule("strikethrough",{filter:["del","s","strike"],replacement:function(e){return`~${e}~`}}).addRule("fencedCodeBlock",{filter:(e,t)=>!!(t.codeBlockStyle==="fenced"&&e.nodeName==="PRE"&&e.firstChild&&e.firstChild.nodeName==="CODE"),replacement:(e,t,r)=>{var n,o;re(et(t.firstChild),{code:B.EXTENSION,message:`Invalid node \`${(n=t.firstChild)==null?void 0:n.nodeName}\` encountered for codeblock when converting html to markdown.`});const s=((o=(t.firstChild.getAttribute("class")??"").match(/(?:lang|language)-(\S+)/))==null?void 0:o[1])??t.firstChild.getAttribute("data-code-block-language")??"";return` + +${r.fence}${s} +${t.firstChild.textContent} +${r.fence} + +`}});se.use({renderer:{list(e,t,r){return t?`
      +${e}
    +`:`
      +${e}
    +`},listitem(e,t,r){return t?`
  • ${e}
  • +`:`
  • ${e}
  • +`}}});function cle(e,t){return se(e,{gfm:!0,smartLists:!0,xhtml:!0,sanitizer:t})}function ule(e){re(typeof document,{code:B.EXTENSION,message:"Attempting to sanitize html within a non-browser environment. Please provide your own `sanitizeHtml` method to the `MarkdownExtension`."});const t=new DOMParser().parseFromString(`${e}`,"text/html");return t.normalize(),BO(t.body),t.body.innerHTML}function BO(e){if(!Z6(e)){if(!et(e)||/^(script|iframe|object|embed|svg)$/i.test(e.tagName))return e==null?void 0:e.remove();for(const{name:t}of e.attributes)/^(class|id|name|href|src|alt|align|valign)$/i.test(t)||e.attributes.removeNamedItem(t);for(const t of e.childNodes)BO(t)}}var Zl=class extends Ve{get name(){return"markdown"}onCreate(){this.store.setStringHandler("markdown",this.markdownToProsemirrorNode.bind(this))}createPlugin(){return{props:{clipboardTextSerializer:this.options.copyAsMarkdown?t=>{const r=document.createElement("div"),n=an.fromSchema(this.store.schema);return r.append(n.serializeFragment(t.content)),this.options.htmlToMarkdown(r.innerHTML)}:void 0}}}markdownToProsemirrorNode(e){return this.store.stringHandlers.html({...e,content:this.options.markdownToHtml(e.content,this.options.htmlSanitizer)})}insertMarkdown(e,t){return r=>{const{state:n}=r;let o=this.options.markdownToHtml(e,this.options.htmlSanitizer);o=!(t!=null&&t.alwaysWrapInBlock)&&o.startsWith("

    <")&&o.endsWith(`

    +`)?o.slice(3,-5):`
    ${o}
    `;const i=this.store.stringHandlers.html({content:o,schema:n.schema,fragment:!0});return this.store.commands.insertNode.original(i,{...t,replaceEmptyParentBlock:!0})(r)}}getMarkdown(e){return this.options.htmlToMarkdown(this.store.helpers.getHTML(e))}toggleBoldMarkdown(){return e=>!1}};Qm([U()],Zl.prototype,"insertMarkdown",1);Qm([He()],Zl.prototype,"getMarkdown",1);Qm([U()],Zl.prototype,"toggleBoldMarkdown",1);Zl=Qm([pe({defaultOptions:{htmlToMarkdown:sle,markdownToHtml:cle,htmlSanitizer:ule,activeNodes:[te.Code],copyAsMarkdown:!1},staticKeys:["htmlToMarkdown","markdownToHtml","htmlSanitizer"]})],Zl);var dle=Object.defineProperty,fle=Object.getOwnPropertyDescriptor,mr=(e,t,r,n)=>{for(var o=n>1?void 0:n?fle(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&dle(t,r,o),o},ple={label:({t:e})=>e(nc.INCREASE_INDENT_LABEL),icon:"indentIncrease"},hle={label:({t:e})=>e(nc.DECREASE_INDENT_LABEL),icon:"indentDecrease"},mle={label:({t:e})=>e(nc.CENTER_ALIGN_LABEL),icon:"alignCenter",active:Zm(({node:e})=>e.attrs.nodeTextAlignment==="center")},gle={label:({t:e})=>e(nc.JUSTIFY_ALIGN_LABEL),icon:"alignJustify",active:Zm(({node:e})=>e.attrs.nodeTextAlignment==="justify")},vle={label:({t:e})=>e(nc.RIGHT_ALIGN_LABEL),icon:"alignRight",active:Zm(({node:e})=>e.attrs.nodeTextAlignment==="right")},yle={label:({t:e})=>e(nc.LEFT_ALIGN_LABEL),icon:"alignLeft",active:Zm(({node:e})=>{const{nodeTextAlignment:t}=e.attrs;return t==="left"||t===""})};function Zm(e){return({excludeNodes:t},r)=>{const{getState:n,nodeTags:o}=r;return FO(n(),o.formattingNode,t).some(e)}}function b4(e,t,r){return r.includes(e.name)?!1:t.includes(e.name)}function FO(e,t,r){const n=[],{$from:o,$to:i}=e.selection,s=o.blockRange(i);if(!s)return[];const{parent:a,start:l,end:c}=s;return a.nodeSize-2===c-l&&b4(a.type,t,r)?[{node:a,pos:l-1}]:(e.doc.nodesBetween(l,c,(d,f)=>{if(!(fc)&&b4(d.type,t,r))return n.push({node:d,pos:f}),!1}),n)}var x4="data-node-indent",k4="data-node-text-align",w4="data-line-height-align";function ble(e,t){const r=Xs(Z4(e)),n=Xs(t??"0"),o=e.length??1,i=r/o;return Ad({max:o,min:0,value:Math.floor(n/i)})}var xle=/^\d+(?:\.\d+)?$/,kle=/^(\d+(?:\.\d+)?)%$/;function S4(e){if(Jt(e))return e;if(!e)return null;const t=e.trim(),r=t.match(kle);if(r)return Number.parseFloat(r[1])/100;const n=t.match(xle);return n?Number.parseFloat(n[0]):null}var Ft=class extends Ve{get name(){return"nodeFormatting"}createSchemaAttributes(){return[{identifiers:{type:"node",tags:[te.FormattingNode],excludeNames:this.options.excludeNodes},attributes:{nodeIndent:this.nodeIndent(),nodeTextAlignment:this.nodeTextAlignment(),nodeLineHeight:this.nodeLineHeight(),style:{default:"",parseDOM:()=>"",toDOM:({nodeIndent:e,nodeTextAlignment:t,nodeLineHeight:r,style:n})=>{const o=e?this.options.indents[e]:void 0;return{style:Gv({marginLeft:o,textAlign:t&&t!=="none"?t:void 0,lineHeight:r||void 0},n)}}}}}]}setLineHeight(e){return this.setNodeAttribute(({node:t})=>{if(e!==t.attrs.nodeLineHeight)return{nodeLineHeight:e}})}setTextAlignment(e){return this.setNodeAttribute(({node:t})=>{if(e!==t.attrs.nodeTextAlignment)return{nodeTextAlignment:e}})}setIndent(e){return this.setNodeAttribute(({node:t})=>{const r=t.attrs.nodeIndent??0,n=e==="-1"?r-1:e==="+1"?r+1:e,o=Ad({min:0,max:this.options.indents.length-1,value:n});if(o!==r)return{nodeIndent:o}})}centerAlign(){return this.setTextAlignment("center")}justifyAlign(){return this.setTextAlignment("justify")}leftAlign(){return this.setTextAlignment("left")}rightAlign(){return this.setTextAlignment("right")}increaseIndent(){return e=>this.setIndent("+1")(e)}decreaseIndent(){return e=>this.setIndent("-1")(e)}centerAlignShortcut(e){return this.centerAlign()(e)}justifyAlignShortcut(e){return this.justifyAlign()(e)}leftAlignShortcut(e){return this.leftAlign()(e)}rightAlignShortcut(e){return this.rightAlign()(e)}increaseIndentShortcut(e){return this.increaseIndent()(e)}decreaseIndentShortcut(e){return this.decreaseIndent()(e)}nodeIndent(){return{default:null,parseDOM:e=>e.getAttribute(x4)??ble(this.options.indents,e.style.marginLeft),toDOM:e=>{if(!e.nodeIndent)return;const t=`${e.nodeIndent}`;if(this.options.indents[e.nodeIndent])return{[x4]:t}}}}nodeTextAlignment(){return{default:null,parseDOM:e=>e.getAttribute(k4)??e.style.textAlign,toDOM:e=>{const t=e.nodeTextAlignment;if(!(!t||t==="none"))return{[k4]:t}}}}nodeLineHeight(){return{default:null,parseDOM:e=>{const t=e.getAttribute(w4);return S4(t)??S4(e.style.lineHeight)},toDOM:e=>{const t=e.nodeLineHeight;if(t)return{[w4]:t.toString()}}}}setNodeAttribute(e){return t=>{const{tr:r,dispatch:n}=t,o=FO(r,this.store.nodeTags.formattingNode,this.options.excludeNodes);if(Mo(o))return!1;if(!n)return!0;const i=[];for(const s of o){const{node:a,pos:l}=s,c=e(s);c&&i.push([l,{...a.attrs,...c}])}if(Mo(i))return!1;if(!n)return!0;for(const[s,a]of i)r.setNodeMarkup(s,void 0,a);return n(r),!0}}};mr([U()],Ft.prototype,"setLineHeight",1);mr([U()],Ft.prototype,"setTextAlignment",1);mr([U()],Ft.prototype,"setIndent",1);mr([U(mle)],Ft.prototype,"centerAlign",1);mr([U(gle)],Ft.prototype,"justifyAlign",1);mr([U(yle)],Ft.prototype,"leftAlign",1);mr([U(vle)],Ft.prototype,"rightAlign",1);mr([U(ple)],Ft.prototype,"increaseIndent",1);mr([U(hle)],Ft.prototype,"decreaseIndent",1);mr([je({shortcut:$.CenterAlignment,command:"centerAlign"})],Ft.prototype,"centerAlignShortcut",1);mr([je({shortcut:$.JustifyAlignment,command:"justifyAlign"})],Ft.prototype,"justifyAlignShortcut",1);mr([je({shortcut:$.LeftAlignment,command:"leftAlign"})],Ft.prototype,"leftAlignShortcut",1);mr([je({shortcut:$.RightAlignment,command:"rightAlign"})],Ft.prototype,"rightAlignShortcut",1);mr([je({shortcut:$.IncreaseIndent,command:"increaseIndent",priority:Ae.Low})],Ft.prototype,"increaseIndentShortcut",1);mr([je({shortcut:$.DecreaseIndent,command:"decreaseIndent",priority:Ae.Medium})],Ft.prototype,"decreaseIndentShortcut",1);Ft=mr([pe({defaultOptions:{indents:["0","20px","40px","60px","80px","100px","120px","140px","160px","180px","200px"],excludeNodes:[]},staticKeys:["indents"]})],Ft);var wle=Object.defineProperty,Sle=Object.getOwnPropertyDescriptor,Ox=(e,t,r,n)=>{for(var o=n>1?void 0:n?Sle(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&wle(t,r,o),o},Ele={icon:"strikethrough",label:({t:e})=>e(xk.LABEL),description:({t:e})=>e(xk.DESCRIPTION)},Cd=class extends ci{get name(){return"strike"}createTags(){return[te.FontStyle,te.FormattingMark]}createMarkSpec(e,t){return{...t,attrs:e.defaults(),parseDOM:[{tag:"s",getAttrs:e.parse},{tag:"del",getAttrs:e.parse},{tag:"strike",getAttrs:e.parse},{style:"text-decoration",getAttrs:r=>r==="line-through"?{}:!1},...t.parseDOM??[]],toDOM:r=>["s",e.dom(r),0]}}toggleStrike(){return is({type:this.type})}shortcut(e){return this.toggleStrike()(e)}createInputRules(){return[Vu({regexp:/~([^~]+)~$/,type:this.type,ignoreWhitespace:!0})]}createPasteRules(){return[{regexp:/~([^~]+)~/g,type:"mark",markType:this.type}]}};Ox([U(Ele)],Cd.prototype,"toggleStrike",1);Ox([je({shortcut:$.Strike,command:"toggleStrike"})],Cd.prototype,"shortcut",1);Cd=Ox([pe({})],Cd);var E4=new ka("trailingNode");function Cle(e){const{ignoredNodes:t=[],nodeName:r="paragraph"}=e??{},n=Ml([...t,r]);let o,i;return new Ro({key:E4,appendTransaction(s,a,l){const{doc:c,tr:u}=l,d=E4.getState(l),f=c.content.size;if(d)return u.insert(f,o.create())},state:{init:(s,{doc:a,schema:l})=>{var c;const u=l.nodes[r];if(!u)throw new Error(`Invalid node being used for trailing node extension: '${r}'`);return o=u,i=Object.values(l.nodes).map(d=>d).filter(d=>!n.includes(d.name)),fr(i,(c=a.lastChild)==null?void 0:c.type)},apply:(s,a)=>{var l;return s.docChanged?fr(i,(l=s.doc.lastChild)==null?void 0:l.type):a}}})}var Mle=Object.defineProperty,Tle=Object.getOwnPropertyDescriptor,Ole=(e,t,r,n)=>{for(var o=n>1?void 0:n?Tle(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&Mle(t,r,o),o},gv=class extends Ve{get name(){return"trailingNode"}onSetOptions(e){const{changes:t}=e;(t.disableTags.changed||t.ignoredNodes.changed||t.nodeName.changed)&&this.store.updateExtensionPlugins(this)}createExternalPlugins(){const{tags:e}=this.store,{disableTags:t,nodeName:r}=this.options,n=t?[...this.options.ignoredNodes]:[...this.options.ignoredNodes,...e.lastNodeCompatible];return[Cle({ignoredNodes:n,nodeName:r})]}};gv=Ole([pe({defaultOptions:{ignoredNodes:[],disableTags:!1,nodeName:"paragraph"}})],gv);var _le=Object.defineProperty,Ale=Object.getOwnPropertyDescriptor,_x=(e,t,r,n)=>{for(var o=n>1?void 0:n?Ale(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&_le(t,r,o),o},Nle={icon:"underline",label:({t:e})=>e(kk.LABEL),description:({t:e})=>e(kk.DESCRIPTION)},Md=class extends ci{get name(){return"underline"}createTags(){return[te.FontStyle,te.FormattingMark]}createMarkSpec(e,t){return{...t,attrs:e.defaults(),parseDOM:[{tag:"u",getAttrs:e.parse},{style:"text-decoration",getAttrs:r=>r==="underline"?{}:!1},...t.parseDOM??[]],toDOM:r=>["u",e.dom(r),0]}}toggleUnderline(e){return is({type:this.type,selection:e})}shortcut(e){return this.toggleUnderline()(e)}};_x([U(Nle)],Md.prototype,"toggleUnderline",1);_x([je({shortcut:$.Underline,command:"toggleUnderline"})],Md.prototype,"shortcut",1);Md=_x([pe({})],Md);const C4={};function Rle(e,t){if(C4[e])return;const r=document.createElement("style"),n=Ple(e)/1e4,o=zle({h:Math.abs(n),s:.6,v:.6}),i=Lle(o);r.type="text/css",r.textContent=` + .remirror-editor-wrapper .${t}${e}::before { + content: '[${e}]'; + font-family: monospace; + font-size: 90%; + color: ${i}; + } + + .remirror-editor-wrapper .${t}${e}::after { + content: '[/${e}]'; + font-family: monospace; + font-size: 90%; + color: ${i}; + } + `,document.head.appendChild(r),C4[e]=!0}function Ple(e){let t=0;if(!e||e.length===0)return t;for(let r=0;r{for(var o=n>1?void 0:n?Dle(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&Ile(t,r,o),o};const gp="__editor_";let ec=class extends ci{get name(){return"className"}constructor(e){super(e);for(const t of e.classNames||[])Rle(t,gp)}createTags(){return[te.FormattingMark]}createMarkSpec(e,t){return{...t,attrs:{...e.defaults(),className:{}},parseDOM:[{tag:"*",getAttrs:r=>{if(!et(r))return!1;for(let n of r.classList)if(n.startsWith(gp)&&(n=n.substring(gp.length)),this.options.classNames.indexOf(n)>=0)return{...e.parse(r),className:n};return!1}},...t.parseDOM??[]],toDOM:r=>{const{className:n,...o}=$d(r.attrs,e),i=e.dom(r),s=i.className,a=$le(n,s);return["span",{...o,...i,class:a},0]}}}setClassName(e,t){return this.store.commands.applyMark.original(this.type,{className:e},t)}removeClassName(e){return this.store.commands.removeMark.original({type:this.type,selection:e,expand:!0})}};Ax([U({})],ec.prototype,"setClassName",1);Ax([U({})],ec.prototype,"removeClassName",1);ec=Ax([pe({defaultOptions:{}})],ec);function $le(e,t){return e&&(e=`${gp}${e}`),e&&t?`${e} ${t}`:e||t}function VO(e){const[t,r]=S.useState(e),n=S.useRef(e);return n.current=t,[t,r,n]}function Hle(e,t,r){if(!e)return;const n=`${t}/api/assets/${r}/`;if(e.startsWith(n)){const o=e.substring(n.length).split(/[/?]+/);return o.length<1?null:{id:o[0]}}return null}function Ble(e,t,r){if(!e)return;const n=`${t}/api/content/${r}/`;if(e.startsWith(n)){const o=e.substring(n.length).split(/[/?]+/);return o.length<2?null:{schemaName:o[0],id:o[1]}}return null}const Fle=Ph(Ed),Nx=new Fle({hr:"---"});Nx.addRule("link2",{filter:(e,t)=>t.linkStyle==="inlined"&&e.nodeName==="A"&&!!e.getAttribute("href"),replacement:function(e,t){const r=t,n=r.getAttribute("href");if(!n)return"";const o=vv(r.getAttribute("title"));return o?`[${e}](${n} '${o}')`:`[${e}](${n})`}});Nx.addRule("link2",{filter:"img",replacement:(e,t)=>{const r=t,n=r.getAttribute("src")||"";if(!n)return"";const o=vv(r.getAttribute("alt")),i=vv(r.getAttribute("title"));return i?`![${o}](${n} '${i}')`:`![${o}](${n})`}});function vv(e){return(e==null?void 0:e.replace(/(\n+\s*)+/g,` +`))||""}function Vle(e){return Nx.turndown(e)}const li=e=>{const{type:t}=e;return t==="Assets"?O.jsxs("svg",{className:"custom-icon",version:"1.1",xmlns:"http://www.w3.org/2000/svg",width:"1rem",height:"1rem",viewBox:"0 0 28 28",children:[O.jsx("path",{d:"M21.875 28h-15.75c-3.413 0-6.125-2.713-6.125-6.125v-15.75c0-3.413 2.712-6.125 6.125-6.125h15.75c3.412 0 6.125 2.712 6.125 6.125v15.75c0 3.412-2.713 6.125-6.125 6.125zM6.125 1.75c-2.45 0-4.375 1.925-4.375 4.375v15.75c0 2.45 1.925 4.375 4.375 4.375h15.75c2.45 0 4.375-1.925 4.375-4.375v-15.75c0-2.45-1.925-4.375-4.375-4.375h-15.75z"}),O.jsx("path",{d:"M21.088 23.537h-11.988c-0.35 0-0.612-0.175-0.787-0.525s-0.088-0.7 0.088-0.962l8.225-9.713c0.175-0.175 0.438-0.35 0.7-0.35s0.525 0.175 0.7 0.35l5.25 7.525c0.088 0.087 0.088 0.175 0.088 0.262 0.438 1.225 0.087 2.012-0.175 2.45-0.613 0.875-1.925 0.963-2.1 0.963zM11.025 21.787h10.15c0.175 0 0.612-0.088 0.7-0.262 0.088-0.088 0.088-0.35 0-0.7l-4.55-6.475-6.3 7.438z"}),O.jsx("path",{d:"M9.1 13.737c-2.1 0-3.85-1.75-3.85-3.85s1.75-3.85 3.85-3.85 3.85 1.75 3.85 3.85-1.663 3.85-3.85 3.85zM9.1 7.788c-1.138 0-2.1 0.875-2.1 2.1s0.962 2.1 2.1 2.1 2.1-0.962 2.1-2.1-0.875-2.1-2.1-2.1z"})]}):t==="Contents"?O.jsxs("svg",{className:"custom-icon",version:"1.1",xmlns:"http://www.w3.org/2000/svg",width:"1rem",height:"1rem",viewBox:"0 0 28 28",children:[O.jsx("path",{d:"M21.875 28h-15.75c-3.413 0-6.125-2.713-6.125-6.125v-15.75c0-3.413 2.712-6.125 6.125-6.125h15.75c3.412 0 6.125 2.712 6.125 6.125v15.75c0 3.412-2.713 6.125-6.125 6.125zM6.125 1.75c-2.45 0-4.375 1.925-4.375 4.375v15.75c0 2.45 1.925 4.375 4.375 4.375h15.75c2.45 0 4.375-1.925 4.375-4.375v-15.75c0-2.45-1.925-4.375-4.375-4.375h-15.75z"}),O.jsx("path",{d:"M13.125 12.25h-5.775c-1.575 0-2.888-1.313-2.888-2.888v-2.013c0-1.575 1.313-2.888 2.888-2.888h5.775c1.575 0 2.887 1.313 2.887 2.888v2.013c0 1.575-1.312 2.888-2.887 2.888zM7.35 6.212c-0.613 0-1.138 0.525-1.138 1.138v2.012c0 0.612 0.525 1.138 1.138 1.138h5.775c0.612 0 1.138-0.525 1.138-1.138v-2.013c0-0.612-0.525-1.138-1.138-1.138h-5.775z"}),O.jsx("path",{d:"M22.662 16.713h-17.325c-0.525 0-0.875-0.35-0.875-0.875s0.35-0.875 0.875-0.875h17.237c0.525 0 0.875 0.35 0.875 0.875s-0.35 0.875-0.787 0.875z"}),O.jsx("path",{d:"M15.138 21.262h-9.8c-0.525 0-0.875-0.35-0.875-0.875s0.35-0.875 0.875-0.875h9.713c0.525 0 0.875 0.35 0.875 0.875s-0.35 0.875-0.787 0.875z"})]}):t==="Check"?O.jsx("svg",{className:"custom-icon",version:"1.1",xmlns:"http://www.w3.org/2000/svg",viewBox:"0 -960 960 960",width:"1rem",height:"1rem",children:O.jsx("path",{d:"M382-240 154-468l57-57 171 171 367-367 57 57-424 424Z"})}):t==="Cancel"?O.jsx("svg",{className:"custom-icon",version:"1.1",xmlns:"http://www.w3.org/2000/svg",viewBox:"0 -960 960 960",width:"1rem",height:"1rem",children:O.jsx("path",{d:"m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z"})}):t==="Edit"?O.jsx("svg",{className:"custom-icon",version:"1.1",xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",width:"1rem",height:"1rem",children:O.jsx("path",{d:"M15.728 9.686l-1.414-1.414L5 17.586V19h1.414l9.314-9.314zm1.414-1.414l1.414-1.414-1.414-1.414-1.414 1.414 1.414 1.414zM7.242 21H3v-4.243L16.435 3.322a1 1 0 0 1 1.414 0l2.829 2.829a1 1 0 0 1 0 1.414L7.243 21z"})}):null},jle=({node:e})=>{const t=Wd(Td),r=e.attrs.contentId,n=e.attrs.contentTitle,o=e.attrs.schemaName,i=t.options.onEditContent;return O.jsxs("div",{className:"squidex-editor-content-link",children:[O.jsx("button",{type:"button",className:"squidex-editor-button",onClick:()=>i(o,r),children:O.jsx(li,{type:"Contents"})}),O.jsx("div",{className:"squidex-editor-content-schema",children:o}),O.jsx("div",{className:"squidex-editor-content-name",children:n})]})};var Ule=Object.defineProperty,Wle=Object.getOwnPropertyDescriptor,jO=(e,t,r,n)=>{for(var o=n>1?void 0:n?Wle(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&Ule(t,r,o),o};let Td=class extends er{constructor(t){super({...t,disableExtraAttributes:!0});vc(this,"ReactComponent",jle)}get name(){return"contentLink"}createTags(){return[te.InlineNode,te.Media]}createNodeSpec(){return{inline:!0,attrs:{contentId:{default:""},contentTitle:{default:""},schemaName:{default:""}},toDOM:t=>["a",{href:`${this.options.baseUrl}/api/content/${this.options.appName}/${t.attrs.schemaName}/${t.attrs.contentId}`},t.attrs.contentTitle],parseDOM:[{tag:"a[href]",getAttrs:t=>{const r=t.getAttribute("href");if(!r)return!1;const n=Ble(r,this.options.baseUrl,this.options.appName);return n?{contentId:n.id,contentTitle:t.innerText,schemaName:n.schemaName}:!1},priority:1e5}]}}addContent(t,r){return this.store.commands.insertNode.original(this.type,{attrs:{contentId:t.id,contentTitle:t.title,schemaName:t.schemaName},selection:r})}};jO([U({})],Td.prototype,"addContent",1);Td=jO([pe({defaultOptions:{}})],Td);const Kle=e=>{const{appName:t,baseUrl:r,onEditNode:n,onEditAsset:o,node:i,getPosition:s}=e,a=Hle(i.attrs.src,r,t);return O.jsxs("div",{style:{position:"relative"},className:"squidex-editor-image-view",children:[O.jsx("img",{className:"squidex-editor-image-element",src:i.attrs.src}),O.jsxs("div",{className:"squidex-editor-image-buttons",children:[O.jsx("button",{type:"button",className:"squidex-editor-button",onClick:()=>n({node:i,getPos:s}),children:O.jsx(li,{type:"Edit"})}),a&&O.jsx("button",{type:"button",className:"squidex-editor-button",onClick:()=>o(a.id),children:O.jsx(li,{type:"Assets"})})]}),a&&O.jsx("div",{className:"squidex-editor-image-info",children:"Asset"})]})};class qle extends Ve{get name(){return"htmlCopy"}createPlugin(){return{props:{clipboardTextSerializer:this.options.copyAsHtml?r=>{const n=document.createElement("div");return n.append(an.fromSchema(this.store.schema).serializeFragment(r.content)),n.innerHTML}:void 0}}}}const Gle=({mode:e,onChange:t,state:r,value:n})=>{const{setContent:o}=fi(),{getMarkdown:i,getHTML:s}=fm(),a=S.useRef(null),l=S.useRef(!1),c=S.useRef(0),u=kj();return S.useEffect(()=>{c.current+=1},[u]),S.useEffect(()=>{l.current=!!n&&n.length>0,a.current!==n&&(a.current=n,o(n||""),c.current=-1)},[o,n]),S.useEffect(()=>{if(!t)return;function d(){switch(e){case"Markdown":return i(r);default:return s(r)}}if(c.current<=0)return;let f=d().trim();f==="

    "&&(f=""),a.current!==f&&(!l.current&&f.length===0?t(void 0):t(f),a.current=f,l.current=!!f&&f.length>0)},[s,i,e,t,r]),null},Yle=({node:e,getPosition:t,view:r})=>{const n=S.useCallback(o=>{const i=r.state.tr.setNodeAttribute(t(),"html",o.target.value);r.dispatch(i)},[t,r]);return O.jsxs("div",{className:"squidex-editor-html",children:[O.jsx("div",{className:"squidex-editor-html-label",children:"Plain HTML"}),O.jsx("textarea",{spellCheck:"false",value:e.attrs.content,onChange:n})]})};var Jle=Object.defineProperty,Xle=Object.getOwnPropertyDescriptor,UO=(e,t,r,n)=>{for(var o=n>1?void 0:n?Xle(t,r):t,i=e.length-1,s;i>=0;i--)(s=e[i])&&(o=(n?s(t,r,o):s(o))||o);return n&&o&&Jle(t,r,o),o};let _h=class extends er{constructor(){super({disableExtraAttributes:!0});vc(this,"ReactComponent",Yle)}get name(){return"plainHtml"}createTags(){return[te.Block,te.TextBlock,te.FormattingNode]}createNodeSpec(){return{attrs:{html:{default:""}},toDOM:t=>{const r=t.attrs.html;return["div",{class:"__editor_html"},...Qle(r)]},parseDOM:[{tag:"div[class~=__editor_html]",getAttrs:t=>({content:t.innerHTML}),priority:1e4}]}}insertPlainHtml(t){return this.store.commands.insertNode.original(this.type,{attrs:{content:""},selection:t})}};UO([U({})],_h.prototype,"insertPlainHtml",1);_h=UO([pe({defaultOptions:{}})],_h);function Qle(e){if(!e)return[""];const t=document.createElement("div");return t.innerHTML=e,WO(t)}function Zle(e){const t={};for(let r=0;r{const t=cc(),r=S.useCallback(async()=>{const n=await e();tce(n)&&n.length>0&&t.insertText(n),t.run()},[t,e]);return O.jsx(dt,{commandName:"addImage",enabled:!0,onSelect:r,label:"Add AI generated Text",icon:O.jsx("span",{style:{height:"16px",lineHeight:"16px"},children:"AI"})})};function tce(e){return typeof e=="string"||e instanceof String}const KO=e=>{const t=S.useRef(null);return S.useEffect(()=>{const r=window.requestAnimationFrame(()=>{var n;(n=t.current)==null||n.focus()});return()=>{window.cancelAnimationFrame(r)}},[]),O.jsx("input",{className:"squidex-editor-input",ref:t,...e})},qO=({children:e,title:t})=>O.jsxs("div",{className:"squidex-editor-modal-wrapper",children:[O.jsx("div",{className:"squidex-editor-modal-backdrop"}),O.jsxs("div",{className:"squidex-editor-modal-window",children:[t&&O.jsx("div",{className:"squidex-editor-modal-title",children:t}),O.jsx("div",{className:"squidex-editor-modal-body",children:e})]})]}),rce=({onSelectAssets:e})=>{const t=cc(),r=S.useCallback(async()=>{const n=await e();for(const o of n){if(o.mimeType.startsWith("image/")){const i={src:o.src,alt:o.alt,title:o.fileName};t.insertImage(i)}else t.insertAsset(o);t.insertText(" ")}t.run()},[t,e]);return O.jsx(dt,{commandName:"addImage",enabled:!0,onSelect:r,label:"Add Asset",icon:O.jsx(li,{type:"Assets"})})},nce=({onSelectContents:e})=>{const t=cc(),r=S.useCallback(async()=>{const n=await e();for(const o of n)t.addContent(o);t.run()},[t,e]);return O.jsx(dt,{commandName:"addContent",enabled:!0,onSelect:r,label:"Add Content",icon:O.jsx(li,{type:"Contents"})})},oce=()=>{const e=cc(),t=S.useCallback(async()=>{e.insertPlainHtml().run()},[e]);return O.jsx(dt,{commandName:"addImage",enabled:!0,onSelect:t,label:"Add HTML",icon:O.jsx("span",{style:{height:"16px",lineHeight:"16px"},children:"HTML"})})},ice=({attrs:e,...t})=>{const{setClassName:r}=tr(),n=S.useCallback(()=>{r(e.className)},[e.className,r]),o=qr().className(e);return O.jsx(Db,{...t,commandName:"toggleClass",active:o,attrs:e,enabled:!0,onSelect:n,label:(e==null?void 0:e.className)||"No Class"})},sce=({...e})=>{const{removeClassName:t}=tr(),r=S.useCallback(()=>{t()},[t]),n=!qr().className();return O.jsx(Db,{...e,commandName:"removeClass",active:n,attrs:{},enabled:!0,onSelect:r,label:"No Class"})},ace=()=>{const e=Wd(ec);return!e.options.classNames||e.options.classNames.length===0?null:O.jsxs(V3,{"aria-label":"Class Name",icon:O.jsx("span",{style:{height:"14px",lineHeight:"14px",fontSize:"14px"},children:"Class"}),children:[O.jsx(sce,{}),e.options.classNames.map(t=>O.jsx(ice,{attrs:{className:t}},t))]})},lce=()=>{const e=Wd(ss);return O.jsxs("div",{className:"squidex-editor-counter",children:["Words: ",O.jsx("strong",{children:e.getWordCount()}),", Characters: ",O.jsx("strong",{children:e.getCharacterCount()})]})},M4=({onEdit:e})=>{const t=cc(),n=qr().link(),o=rb(),i=S.useCallback(()=>{t.removeLink().focus().run()},[t]);return O.jsxs(O.Fragment,{children:[O.jsx(dt,{commandName:"updateLink",enabled:!o.empty,label:"Add or Edit Link",onSelect:e,icon:"link"}),O.jsx(dt,{commandName:"removeLink",enabled:n,label:"Remove Link",onSelect:i,icon:"linkUnlink"})]})},cce=({onClose:e})=>{const[t,r,n]=VO(""),o=cc(),i=cj(!0).link(),s=(i==null?void 0:i.href)??"",a=rb();S.useEffect(()=>{r(s)},[s,a,r]);const l=S.useCallback(()=>{const d=n.current;d?o.updateLink({href:d,auto:!1}):o.removeLink(),o.focus(a.to).run(),e()},[o,n,e,a.to]),c=S.useCallback(d=>{r(d.target.value)},[r]),u=S.useCallback(d=>{const{code:f}=d;f==="Enter"&&l(),f==="Escape"&&e()},[e,l]);return O.jsxs(qO,{title:"Change Link",children:[O.jsx(KO,{value:t,onChange:c,onKeyDown:u,placeholder:"Enter Link..."}),O.jsxs(En,{children:[O.jsx(dt,{commandName:"submitLink",enabled:!0,onSelect:l,icon:O.jsx(li,{type:"Check"})}),O.jsx(dt,{commandName:"cancelLink",enabled:!0,onSelect:e,icon:O.jsx(li,{type:"Cancel"})})]})]})},uce=({onClose:e,node:t})=>{const[r,n,o]=VO(""),i=tr();S.useEffect(()=>{n(t.node.attrs.title||"")},[t,n]);const s=S.useCallback(c=>{n(c.target.value)},[n]),a=S.useCallback(()=>{i.updateNodeAttributes(t.getPos()||0,{...t.node.attrs||{},title:o.current}),e()},[i,t,e,o]),l=S.useCallback(c=>{const{code:u}=c;u==="Enter"&&a(),u==="Escape"&&e()},[e,a]);return O.jsxs(qO,{title:"Change Image Title",children:[O.jsx(KO,{value:r,onChange:s,onKeyDown:l,placeholder:"Enter Title..."}),O.jsxs(En,{children:[O.jsx(dt,{commandName:"submitLink",enabled:!0,onSelect:a,icon:O.jsx(li,{type:"Check"})}),O.jsx(dt,{commandName:"cancelLink",enabled:!0,onSelect:e,icon:O.jsx(li,{type:"Cancel"})})]})]})};const dce=e=>{const{appName:t,classNames:r,canSelectAIText:n,canSelectAssets:o,canSelectContents:i,isDisabled:s,mode:a,onChange:l,onEditAsset:c,onEditContent:u,onSelectAIText:d,onSelectAssets:f,onSelectContents:p,onUpload:h,value:m}=e,b=S.useMemo(()=>{let z=e.baseUrl;return z.endsWith("/")&&(z=z.substring(0,z.length-1)),z},[e.baseUrl]),[v,g]=S.useState(),[y,x]=S.useState(!1),k=S.useCallback(()=>{x(!0)},[]),w=S.useCallback(()=>{x(!1)},[]),E=S.useCallback(()=>{g(null)},[]),M=S.useCallback(()=>[new nx,new ya({}),new bd({enableSpine:!0}),new ec({classNames:r}),new lo({}),new kd,new Td({appName:t,baseUrl:b,onEditContent:u}),new ss({}),new co,new wh,new Sh({}),new Eh,new qle({copyAsHtml:a==="Html"}),new wd({uploadHandler:h}),new Sd,new ba({autoLink:!0}),new va({enableCollapsible:!0}),new Zl({copyAsMarkdown:a==="Markdown",htmlToMarkdown:Vle}),new Ft,new xd,new _h,new Cd,new gv,new Md],[t,b,r,a,u,h]),{manager:C,state:T,setState:N}=xj({stringHandler:a==="Markdown"?"markdown":"html",content:m,nodeViewComponents:{image:z=>O.jsx(Kle,{...z,appName:t,baseUrl:b,onEditNode:g,onEditAsset:c})},extensions:M});return O.jsx(Tte,{children:O.jsx(Ete,{theme:{color:{primary:"#3389ff",active:{primary:"#3389ff"}}},children:O.jsxs(Sj,{classNames:s?["squidex-editor-disabled"]:[],manager:C,state:T,onChange:z=>N(z.state),children:[O.jsx("div",{className:"squidex-editor-menu",children:O.jsxs(U3,{children:[O.jsx(wte,{}),O.jsx(kte,{showAll:!0}),O.jsxs(En,{children:[O.jsx(cv,{}),O.jsx(dv,{}),O.jsx(fv,{}),O.jsx(uv,{})]}),O.jsxs(En,{children:[O.jsx(lte,{}),O.jsx(ute,{}),O.jsx(ste,{})]}),O.jsxs(En,{children:[O.jsx(cte,{}),O.jsx(dte,{})]}),a==="Html"&&r&&r.length>0&&O.jsx(En,{children:O.jsx(ace,{})}),O.jsx(En,{children:O.jsx(M4,{onEdit:k})}),O.jsxs(En,{children:[o&&f&&O.jsx(rce,{onSelectAssets:f}),i&&p&&O.jsx(nce,{onSelectContents:p}),n&&d&&O.jsx(ece,{onSelectAIText:d})]}),a==="Html"&&O.jsx(En,{children:O.jsx(oce,{})})]})}),O.jsx(Gle,{mode:a,onChange:l,state:T,value:m}),O.jsx(Y0,{}),y?O.jsx(cce,{onClose:w}):v?O.jsx(uce,{node:v,onClose:E}):O.jsxs(Mte,{className:"squidex-editor-floating",children:[O.jsx(cv,{}),O.jsx(dv,{}),O.jsx(fv,{}),O.jsx(uv,{}),O.jsx(M4,{onEdit:k})]}),O.jsx(lce,{})]})})})};var GO,T4=lm;GO=T4.createRoot,T4.hydrateRoot;class fce{constructor(t,r){vc(this,"root");this.element=t,this.props=r,this.root=GO(this.element),this.render()}update(t){this.props={...this.props,...t},this.render()}setValue(t){this.update({value:t})}setIsDisabled(t){this.update({isDisabled:t})}destroy(){this.root.unmount()}render(){this.root.render(O.jsx(dce,{...this.props}))}}window.SquidexEditorWrapper=fce; diff --git a/backend/src/Squidex/wwwroot/scripts/editor-combined.html b/backend/src/Squidex/wwwroot/scripts/editor-combined.html index 5d2abe715..84e6974d4 100644 --- a/backend/src/Squidex/wwwroot/scripts/editor-combined.html +++ b/backend/src/Squidex/wwwroot/scripts/editor-combined.html @@ -6,10 +6,21 @@ + + + - + + @@ -25,7 +27,7 @@ } - + + + + - - - - + + diff --git a/backend/src/Squidex/wwwroot/scripts/editor-editorjs.html b/backend/src/Squidex/wwwroot/scripts/editor-editorjs.html deleted file mode 100644 index d5d44b781..000000000 --- a/backend/src/Squidex/wwwroot/scripts/editor-editorjs.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - -
    -
    -
    - - - - - \ No newline at end of file diff --git a/backend/src/Squidex/wwwroot/scripts/editor-json-schema.html b/backend/src/Squidex/wwwroot/scripts/editor-json-schema.html deleted file mode 100644 index 874e6b458..000000000 --- a/backend/src/Squidex/wwwroot/scripts/editor-json-schema.html +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - -
    - - - - - \ No newline at end of file diff --git a/backend/src/Squidex/wwwroot/scripts/editor-log.html b/backend/src/Squidex/wwwroot/scripts/editor-log.html index f7dbd5004..09ae1df7f 100644 --- a/backend/src/Squidex/wwwroot/scripts/editor-log.html +++ b/backend/src/Squidex/wwwroot/scripts/editor-log.html @@ -7,22 +7,26 @@ + -
    - +
    +
    - + - - - - - - -
    - - - - - \ No newline at end of file diff --git a/backend/src/Squidex/wwwroot/scripts/editor-plain.html b/backend/src/Squidex/wwwroot/scripts/editor-plain.html index c16a04cf4..cfc77da1e 100644 --- a/backend/src/Squidex/wwwroot/scripts/editor-plain.html +++ b/backend/src/Squidex/wwwroot/scripts/editor-plain.html @@ -4,39 +4,31 @@ - + + - -
    - -
    - +
    - - + diff --git a/backend/src/Squidex/wwwroot/scripts/editor-sdk.d.ts b/backend/src/Squidex/wwwroot/scripts/editor-sdk.d.ts index 45cd14c4d..06c712e87 100644 --- a/backend/src/Squidex/wwwroot/scripts/editor-sdk.d.ts +++ b/backend/src/Squidex/wwwroot/scripts/editor-sdk.d.ts @@ -5,7 +5,14 @@ type PluginOptions = { acceptedOrigins?: string[]; } -declare class EditorPlugin { +declare class SquidexSidebar { + /** + * The constructor. + * + * @param options: The plugin options. + */ + constructor(options?: PluginOptions); + /** * Get the current context. */ @@ -36,6 +43,33 @@ declare class EditorPlugin { clean(): void; } +declare class SquidexWidget { + /** + * The constructor. + * + * @param options: The plugin options. + */ + constructor(options?: PluginOptions); + + /** + * Get the current context. + */ + getContext(): any; + + /** + * Register an function that is called when the sidebar is initialized. + * + * @param callback: The callback to invoke. + */ + onInit(callback: () => void): void; + + /** + * Clean the editor SDK. + */ + clean(): void; +} + + declare class SquidexFormField { /** * The constructor. @@ -96,12 +130,12 @@ declare class SquidexFormField { navigate(url: string): void; /** - * Notifies the parent to go to fullscreen mode. + * Notifies the parent to toggle the fullscreen mode. */ toggleFullscreen(): void; /** - * Notifies the parent to go to expanded mode. + * Notifies the parent to toggle the expanded mode. */ toggleExpanded(): void; @@ -147,8 +181,18 @@ declare class SquidexFormField { * * @param schemas: The list of schema names. * @param callback The callback to invoke when the dialog is completed or closed. +<<<<<<< HEAD +======= + * @param query: The initial query that is used in the UI. + * @param selectedIds: The selected ids to mark them as selected in the content selector dialog. + */ + pickContents(schemas: string[], callback: (assets: any[]) => void, query?: string, selectedIds?: string[]): void; + + /** + * Shows a dialog to pick a file. +>>>>>>> 8f149db852d984489e6ca1a07af988dac917ab56 */ - pickContents(schemas: string[], callback: (assets: any[]) => void): void; + pickFile(): void; /** * Register an function that is called when the field is initialized. diff --git a/backend/src/Squidex/wwwroot/scripts/editor-sdk.js b/backend/src/Squidex/wwwroot/scripts/editor-sdk.js index 1383c8b56..b0017a2d9 100644 --- a/backend/src/Squidex/wwwroot/scripts/editor-sdk.js +++ b/backend/src/Squidex/wwwroot/scripts/editor-sdk.js @@ -54,11 +54,11 @@ function isArrayOfStrings(value) { } /** - * Creates a new plugin for sidebars or widgets. + * Creates a new plugin for sidebars. * * @param {object} options with the accepted origins. */ -function SquidexPlugin(options) { +function SquidexSidebar(options) { var initHandler; var initCalled = false; var contentHandler; @@ -82,6 +82,7 @@ function SquidexPlugin(options) { function eventListener(event) { if (acceptedOrigins && acceptedOrigins.indexOf(event.origin) < 0) { + console.log('Origin not accepted: ' + event.origin); return; } @@ -100,13 +101,15 @@ function SquidexPlugin(options) { raiseInit(); } + + console.log('Received Message: ' + type); } window.addEventListener('message', eventListener, false); timer = measureAndNotifyParent(); - var editor = { + var plugin = { /** * Get the current context. */ @@ -165,9 +168,93 @@ function SquidexPlugin(options) { } }; - return editor; + return plugin; +} + + +/** + * Creates a new plugin for widgets. + * + * @param {object} options with the accepted origins. + */ +function SquidexWidget(options) { + var initHandler; + var initCalled = false; + var context; + var acceptedOrigins = options && isArrayOfStrings(options.acceptedOrigins) ? options.acceptedOrigins : null; + + document.body.style.margin = '0'; + document.body.style.padding = '0'; + + function raiseInit() { + if (initHandler && !initCalled && context) { + initHandler(context); + initCalled = true; + } + } + + function eventListener(event) { + if (acceptedOrigins && acceptedOrigins.indexOf(event.origin) < 0) { + console.log('Origin not accepted: ' + event.origin); + return; + } + + if (event.source === window) { + return; + } + + var type = event.data.type; + + if (type === 'init') { + context = event.data.context; + + raiseInit(); + } + + console.log('Received Message: ' + type); + } + + window.addEventListener('message', eventListener, false); + + var plugin = { + /** + * Get the current context. + */ + getContext: function () { + return context; + }, + + /** + * Register an function that is called when the sidebar is initialized. + * + * @param {function} callback: The callback to invoke. + */ + onInit: function (callback) { + if (!isFunction(callback)) { + return; + } + + initHandler = callback; + + raiseInit(); + }, + + /** + * Clean the editor SDK. + */ + clean: function () { + window.removeEventListener('message', eventListener); + } + }; + + return plugin; } +/** + * Creates a new plugin for form fields. + * + * @param {object} options with the accepted origins. + */ function SquidexFormField(options) { var context; var currentConfirm; @@ -192,6 +279,13 @@ function SquidexFormField(options) { var valueHandler; var acceptedOrigins = options && isArrayOfStrings(options.acceptedOrigins) ? options.acceptedOrigins : null; + function raiseInit() { + if (initHandler && !initCalled && context) { + initHandler(context); + initCalled = true; + } + } + function raiseDisabled() { if (disabledHandler) { disabledHandler(disabled); @@ -234,15 +328,9 @@ function SquidexFormField(options) { } } - function raiseInit() { - if (initHandler && !initCalled && context) { - initHandler(context); - initCalled = true; - } - } - function eventListener(event) { if (acceptedOrigins && acceptedOrigins.indexOf(event.origin) < 0) { + console.log('Origin not accepted: ' + event.origin); return; } @@ -329,7 +417,7 @@ function SquidexFormField(options) { timer = measureAndNotifyParent(); - var editor = { + var plugin = { /** * Get the current value. */ @@ -407,7 +495,7 @@ function SquidexFormField(options) { }, /** - * Notifies the parent to go to fullscreen mode. + * Notifies the parent to toggle the fullscreen mode. */ toggleFullscreen: function () { if (window.parent) { @@ -416,7 +504,7 @@ function SquidexFormField(options) { }, /** - * Notifies the parent to go to expanded mode. + * Notifies the parent to toggle the expanded mode. */ toggleExpanded: function () { if (window.parent) { @@ -473,10 +561,7 @@ function SquidexFormField(options) { var correlationId = new Date().getTime().toString(); - currentConfirm = { - correlationId: correlationId, - callback: callback - }; + currentConfirm = { correlationId: correlationId, callback: callback }; if (window.parent) { window.parent.postMessage({ type: 'confirm', title: title, text: text, correlationId: correlationId }, '*'); @@ -495,10 +580,7 @@ function SquidexFormField(options) { var correlationId = new Date().getTime().toString(); - currentPickAssets = { - correlationId: correlationId, - callback: callback - }; + currentPickAssets = { correlationId: correlationId, callback: callback }; if (window.parent) { window.parent.postMessage({ type: 'pickAssets', correlationId: correlationId }, '*'); @@ -508,23 +590,31 @@ function SquidexFormField(options) { /** * Shows the dialog to pick assets. * - * @param {string} schemas: The list of schema names. + * @param {string[]} schemas: The list of schema names. * @param {function} callback The callback to invoke when the dialog is completed or closed. + * @param {string} query: The initial filter that is used in the UI. + * @param {string[]} selectedIds: The selected ids to mark them as selected in the content selector dialog. */ - pickContents: function (schemas, callback) { - if (!isFunction(callback) || !isArrayOfStrings(schemas)) { + pickContents: function (schemas, callback, query, selectedIds) { + if (!isFunction(callback)) { return; } var correlationId = new Date().getTime().toString(); - currentPickContents = { - correlationId: correlationId, - callback: callback - }; + currentPickContents = { correlationId: correlationId, callback: callback }; + + if (window.parent) { + window.parent.postMessage({ type: 'pickContents', correlationId: correlationId, schemas: schemas, query: query, selectedIds: selectedIds }, '*'); + } + }, + /** + * Shows a dialog to pick a file. + */ + pickFile: function () { if (window.parent) { - window.parent.postMessage({ type: 'pickContents', correlationId: correlationId, schemas: schemas }, '*'); + window.parent.postMessage({ type: 'pickFile' }, '*'); } }, @@ -652,13 +742,13 @@ function SquidexFormField(options) { * Clean the editor SDK. */ clean: function () { - if (timer) { - window.removeEventListener('message', eventListener); + window.removeEventListener('message', eventListener); + if (timer) { timer(); } } }; - return editor; + return plugin; }; \ No newline at end of file diff --git a/backend/src/Squidex/wwwroot/scripts/editor-simple.html b/backend/src/Squidex/wwwroot/scripts/editor-simple.html deleted file mode 100644 index a63869b46..000000000 --- a/backend/src/Squidex/wwwroot/scripts/editor-simple.html +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - - - - - -
    Toggle fullscreen - - - - - - - \ No newline at end of file diff --git a/backend/src/Squidex/wwwroot/scripts/sidebar-content.html b/backend/src/Squidex/wwwroot/scripts/sidebar-content.html index ece7ad296..de643ebf9 100644 --- a/backend/src/Squidex/wwwroot/scripts/sidebar-content.html +++ b/backend/src/Squidex/wwwroot/scripts/sidebar-content.html @@ -7,14 +7,10 @@ + @@ -27,7 +23,7 @@ } - + + @@ -27,7 +23,7 @@ } - + - - - - - - - - - - - - -
    - - -
    -
    - - - - - \ No newline at end of file diff --git a/backend/src/Squidex/wwwroot/scripts/widget-context.html b/backend/src/Squidex/wwwroot/scripts/widget-context.html new file mode 100644 index 000000000..c1b7ad494 --- /dev/null +++ b/backend/src/Squidex/wwwroot/scripts/widget-context.html @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/DefaultValueFactoryTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/DefaultValueFactoryTests.cs index c388fa6d3..f3b53bcef 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/DefaultValueFactoryTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/ConvertContent/DefaultValueFactoryTests.cs @@ -19,6 +19,26 @@ public class DefaultValueFactoryTests private readonly Instant now = Instant.FromUtc(2017, 10, 12, 16, 30, 10); private readonly Language language = Language.DE; + [Fact] + public void Should_get_default_value_from_array_field() + { + var field = + Fields.Array(1, "1", Partitioning.Invariant, + new ArrayFieldProperties()); + + Assert.Equal(new JsonArray(), DefaultValueFactory.CreateDefaultValue(field, now, language.Iso2Code)); + } + + [Fact] + public void Should_get_default_value_from_array_field_if_set_to_null() + { + var field = + Fields.Array(1, "1", Partitioning.Invariant, + new ArrayFieldProperties { CalculatedDefaultValue = ArrayCalculatedDefaultValue.Null }); + + Assert.Equal(JsonValue.Null, DefaultValueFactory.CreateDefaultValue(field, now, language.Iso2Code)); + } + [Fact] public void Should_get_default_value_from_assets_field() { @@ -83,6 +103,26 @@ public class DefaultValueFactoryTests Assert.Equal(JsonValue.Null, DefaultValueFactory.CreateDefaultValue(field, now, language.Iso2Code)); } + [Fact] + public void Should_get_default_value_from_components_field() + { + var field = + Fields.Components(1, "1", Partitioning.Invariant, + new ComponentsFieldProperties()); + + Assert.Equal(new JsonArray(), DefaultValueFactory.CreateDefaultValue(field, now, language.Iso2Code)); + } + + [Fact] + public void Should_get_default_value_from_components_field_if_set_to_null() + { + var field = + Fields.Components(1, "1", Partitioning.Invariant, + new ComponentsFieldProperties { CalculatedDefaultValue = ArrayCalculatedDefaultValue.Null }); + + Assert.Equal(JsonValue.Null, DefaultValueFactory.CreateDefaultValue(field, now, language.Iso2Code)); + } + [Fact] public void Should_get_default_value_from_datetime_field() { diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Subscriptions/SubscriptionPublisherTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Subscriptions/SubscriptionPublisherTests.cs index 746f0e23c..7594fe0cc 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Subscriptions/SubscriptionPublisherTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Subscriptions/SubscriptionPublisherTests.cs @@ -29,7 +29,7 @@ public class SubscriptionPublisherTests [Fact] public void Should_return_content_and_asset_filter_for_events_filter() { - Assert.Equal("^(content-|asset-)", sut.EventsFilter); + Assert.Equal(StreamFilter.Prefix("content-", "asset-"), sut.EventsFilter); } [Fact] diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppEventDeleterTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppEventDeleterTests.cs index a00c1acc9..850f21228 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppEventDeleterTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppEventDeleterTests.cs @@ -33,7 +33,9 @@ public class AppEventDeleterTests : GivenContext { await sut.DeleteAppAsync(App, CancellationToken); - A.CallTo(() => eventStore.DeleteAsync($"^[a-zA-Z0-9]-{AppId.Id}", A._)) + var streamFilter = StreamFilter.Prefix($"[a-zA-Z0-9]-{AppId.Id}"); + + A.CallTo(() => eventStore.DeleteAsync(streamFilter, A._)) .MustNotHaveHappened(); } } diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppPermanentDeleterTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppPermanentDeleterTests.cs index 41df184f0..77a096bcc 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppPermanentDeleterTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppPermanentDeleterTests.cs @@ -29,7 +29,7 @@ public class AppPermanentDeleterTests : GivenContext [Fact] public void Should_return_assets_filter_for_events_filter() { - Assert.Equal("^app-", sut.EventsFilter); + Assert.Equal(StreamFilter.Prefix("app-"), sut.EventsFilter); } [Fact] @@ -41,7 +41,7 @@ public class AppPermanentDeleterTests : GivenContext [Fact] public void Should_return_type_name_for_name() { - Assert.Equal(nameof(AppPermanentDeleter), sut.Name); + Assert.Equal(nameof(AppPermanentDeleter), ((IEventConsumer)sut).Name); } [Fact] diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetPermanentDeleterTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetPermanentDeleterTests.cs index 9ada40d63..89e5a124c 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetPermanentDeleterTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetPermanentDeleterTests.cs @@ -27,7 +27,7 @@ public class AssetPermanentDeleterTests : GivenContext [Fact] public void Should_return_assets_filter_for_events_filter() { - Assert.Equal("^asset-", sut.EventsFilter); + Assert.Equal(StreamFilter.Prefix("asset-"), sut.EventsFilter); } [Fact] @@ -39,7 +39,7 @@ public class AssetPermanentDeleterTests : GivenContext [Fact] public void Should_return_type_name_for_name() { - Assert.Equal(nameof(AssetPermanentDeleter), sut.Name); + Assert.Equal(nameof(AssetPermanentDeleter), ((IEventConsumer)sut).Name); } [Fact] diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetUsageTrackerTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetUsageTrackerTests.cs index 4d6d5b48f..3aa8b6146 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetUsageTrackerTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/AssetUsageTrackerTests.cs @@ -35,7 +35,7 @@ public class AssetUsageTrackerTests : GivenContext [Fact] public void Should_return_assets_filter_for_events_filter() { - Assert.Equal("^asset-", sut.EventsFilter); + Assert.Equal(StreamFilter.Prefix("asset-"), sut.EventsFilter); } [Fact] @@ -47,7 +47,7 @@ public class AssetUsageTrackerTests : GivenContext [Fact] public void Should_return_type_name_for_name() { - Assert.Equal(nameof(AssetUsageTracker), sut.Name); + Assert.Equal(nameof(AssetUsageTracker), ((IEventConsumer)sut).Name); } [Fact] diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/RecursiveDeleterTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/RecursiveDeleterTests.cs index ffbd44f1a..08acb029e 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/RecursiveDeleterTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/RecursiveDeleterTests.cs @@ -33,7 +33,7 @@ public class RecursiveDeleterTests : GivenContext [Fact] public void Should_return_assets_filter_for_events_filter() { - Assert.Equal("^assetFolder-", sut.EventsFilter); + Assert.Equal(StreamFilter.Prefix("assetFolder-"), sut.EventsFilter); } [Fact] @@ -45,7 +45,7 @@ public class RecursiveDeleterTests : GivenContext [Fact] public void Should_return_type_name_for_name() { - Assert.Equal(nameof(RecursiveDeleter), sut.Name); + Assert.Equal(nameof(RecursiveDeleter), ((IEventConsumer)sut).Name); } [Fact] diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/RepairFilesTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/RepairFilesTests.cs index ba81142fd..9903f2177 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/RepairFilesTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Assets/RepairFilesTests.cs @@ -122,7 +122,9 @@ public class RepairFilesTests : GivenContext .Returns(null); } - A.CallTo(() => eventStore.QueryAllAsync("^asset\\-", null, int.MaxValue, CancellationToken)) + var streamFilter = StreamFilter.Prefix("asset-"); + + A.CallTo(() => eventStore.QueryAllAsync(streamFilter, null, int.MaxValue, CancellationToken)) .Returns(storedEvents.ToAsyncEnumerable()); } } diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Billing/UsageNotifierWorkerTest.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Billing/UsageNotifierWorkerTest.cs index 6bc29b1e4..cfba6cdb4 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Billing/UsageNotifierWorkerTest.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Billing/UsageNotifierWorkerTest.cs @@ -8,7 +8,7 @@ using NodaTime; using Squidex.Domain.Apps.Core.TestHelpers; using Squidex.Domain.Apps.Entities.Apps; -using Squidex.Domain.Apps.Entities.Notifications; +using Squidex.Domain.Apps.Entities.Collaboration; using Squidex.Domain.Apps.Entities.TestHelpers; using Squidex.Infrastructure; using Squidex.Infrastructure.TestHelpers; diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Collaboration/CommentCollaborationHandlerTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Collaboration/CommentCollaborationHandlerTests.cs new file mode 100644 index 000000000..ca7b7fa2e --- /dev/null +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Collaboration/CommentCollaborationHandlerTests.cs @@ -0,0 +1,335 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using LoremNET; +using Microsoft.Extensions.Logging; +using NodaTime; +using Squidex.Domain.Apps.Core.Comments; +using Squidex.Domain.Apps.Core.TestHelpers; +using Squidex.Domain.Apps.Entities.TestHelpers; +using Squidex.Domain.Apps.Events.Comments; +using Squidex.Infrastructure; +using Squidex.Infrastructure.EventSourcing; +using Squidex.Shared.Users; +using YDotNet.Document; +using YDotNet.Document.Cells; +using YDotNet.Extensions; +using YDotNet.Server; + +namespace Squidex.Domain.Apps.Entities.Collaboration; + +public class CommentCollaborationHandlerTests : GivenContext +{ + private readonly SimpleDocumentManager documentManager = new SimpleDocumentManager(); + private readonly IClock clock = A.Fake(); + private readonly IEventFormatter eventFormatter = A.Fake(); + private readonly IEventStore eventStore = A.Fake(); + private readonly IUserResolver userResolver = A.Fake(); + private readonly CommentCollaborationHandler sut; + + public CommentCollaborationHandlerTests() + { + var now = SystemClock.Instance.GetCurrentInstant(); + + A.CallTo(() => clock.GetCurrentInstant()) + .Returns(now); + + A.CallTo(() => userResolver.FindByIdOrEmailAsync(A._, default)) + .Returns(Task.FromResult(null)); + + var log = A.Fake>(); + + sut = new CommentCollaborationHandler(TestUtils.DefaultSerializer, eventStore, eventFormatter, userResolver, clock, log); + } + + [Fact] + public void Should_provider_user_document_name() + { + var name = sut.UserDocument("user42"); + + Assert.Equal("users/user42", name); + } + + [Fact] + public void Should_provider_app_document_name() + { + var name = sut.ResourceDocument(AppId, DomainId.Create("resource42")); + + Assert.Equal($"apps/{AppId}/resource42", name); + } + + [Fact] + public async Task Should_create_comment() + { + await sut.OnInitializedAsync(documentManager); + + var commentsId = DomainId.Create("resource42"); + + var document = new Doc(); + var docName = sut.ResourceDocument(AppId, commentsId); + + documentManager.Doc = document; + + Output? addedInput = null; + document.Array("stream").ObserveDeep(events => + { + addedInput = events.Single().ArrayEvent.Delta.Single().Values.Single(); + }); + + await sut.CommentAsync(AppId, commentsId, "My Comment", User, null, true, default); + + var commentJson = addedInput!.ToJson(document); + var commentItem = TestUtils.DefaultSerializer.Deserialize(commentJson); + + commentItem.Should().BeEquivalentTo( + new Comment(clock.GetCurrentInstant(), User, "My Comment", null, true)); + } + + [Fact] + public async Task Should_create_notification() + { + await sut.OnInitializedAsync(documentManager); + + var document = new Doc(); + var docName = sut.UserDocument(User.Identifier); + + documentManager.Doc = document; + + Output? addedInput = null; + document.Array("stream").ObserveDeep(events => + { + addedInput = events.Single().ArrayEvent.Delta.Single().Values.Single(); + }); + + await sut.NotifyAsync(User.Identifier, "My Notification", User, null, true, default); + + var commentJson = addedInput!.ToJson(document); + var commentItem = TestUtils.DefaultSerializer.Deserialize(commentJson); + + commentItem.Should().BeEquivalentTo( + new Comment(clock.GetCurrentInstant(), User, "My Notification", null, true)); + } + + [Fact] + public async Task Should_publish_event_for_comment() + { + var text = "My Comment"; + + var commentsId = DomainId.Create("resource42"); + var commentItem = new Comment(clock.GetCurrentInstant(), User, text); + + var storedEvent = await CreateCommentAsync(commentsId, commentItem); + + storedEvent?.Payload.Should().BeEquivalentTo( + new CommentCreated + { + Actor = User, + AppId = AppId, + CommentId = default, + CommentsId = commentsId, + Text = commentItem.Text, + Mentions = null, + }, opts => opts.Excluding(x => x.CommentId)); + } + + [Fact] + public async Task Should_not_enrich_comment_with_mentioned_users_if_users_not_found() + { + var text = "Hi @mail1@squidex.io, @mail2@squidex.io and @notfound@squidex.io"; + + var commentsId = DomainId.Create("resource42"); + var commentItem = new Comment(clock.GetCurrentInstant(), User, text); + + var storedEvent = await CreateCommentAsync(commentsId, commentItem); + + storedEvent?.Payload.Should().BeEquivalentTo( + new CommentCreated + { + Actor = User, + AppId = AppId, + CommentId = default, + CommentsId = commentsId, + Text = commentItem.Text, + Mentions = null, + }, opts => opts.Excluding(x => x.CommentId)); + } + + [Fact] + public async Task Should_enrich_comment_with_mentioned_users() + { + SetupUser("id1", "mail1@squidex.io"); + SetupUser("id2", "mail2@squidex.io"); + + var text = "Hi @mail1@squidex.io, @mail2@squidex.io and @notfound@squidex.io"; + + var commentsId = DomainId.Create("resource42"); + var commentItem = new Comment(clock.GetCurrentInstant(), User, text); + + var storedEvent = await CreateCommentAsync(commentsId, commentItem); + + storedEvent?.Payload.Should().BeEquivalentTo( + new CommentCreated + { + Actor = User, + AppId = AppId, + CommentId = default, + CommentsId = commentsId, + Text = commentItem.Text, + Mentions = new string[] { "id1", "id2" } + }, opts => opts.Excluding(x => x.CommentId)); + } + + [Fact] + public async Task Should_enrich_comment_with_mentioned_users_and_long_text() + { + SetupUser("id1", "mail1@squidex.io"); + SetupUser("id2", "mail2@squidex.io"); + + var text = $"Hi @mail1@squidex.io, @mail2@squidex.io and @notfound@squidex.io {Lorem.Paragraph(200, 10)}"; + + var commentsId = DomainId.Create("resource42"); + var commentItem = new Comment(clock.GetCurrentInstant(), User, text); + + var storedEvent = await CreateCommentAsync(commentsId, commentItem); + + storedEvent?.Payload.Should().BeEquivalentTo( + new CommentCreated + { + Actor = User, + AppId = AppId, + CommentId = default, + CommentsId = commentsId, + Text = commentItem.Text, + Mentions = new string[] { "id1", "id2" } + }, opts => opts.Excluding(x => x.CommentId)); + } + + private async Task?> CreateCommentAsync(DomainId commentsId, Comment comment) + { + var document = new Doc(); + var docName = sut.ResourceDocument(AppId, commentsId); + + documentManager.Doc = document; + + var stream = document.Array("stream"); + + await sut.OnDocumentLoadedAsync(new DocumentLoadEvent + { + Context = new DocumentContext(docName, 0), + Document = document, + Source = documentManager, + }); + + var commentJson = TestUtils.DefaultSerializer.Serialize(comment); + + Envelope? storedEvent = null; + + A.CallTo(() => eventFormatter.ToEventData(A>._, A._, true)) + .Invokes(c => + { + storedEvent = c.GetArgument>(0); + }); + + await documentManager.UpdateDocAsync(null!, doc => + { + using (var transaction = doc.WriteTransaction()) + { + stream.InsertRange(transaction, 0, InputFactory.FromJson(commentJson)); + } + }, default); + + await sut.LastTask; + + var streamName = $"comments-{DomainId.Combine(AppId.Id, commentsId)}"; + + A.CallTo(() => eventStore.AppendAsync(A._, streamName, EtagVersion.Any, A>._, A._)) + .MustHaveHappened(); + + return storedEvent; + } + + private void SetupUser(string id, string email) + { + var user = UserMocks.User(id, email); + + A.CallTo(() => userResolver.FindByIdOrEmailAsync(email, default)) + .Returns(user); + } + + private sealed class SimpleDocumentManager : IDocumentManager + { + private readonly SemaphoreSlim lockObject = new SemaphoreSlim(1); + + public Doc Doc { get; set; } + + public async ValueTask UpdateDocAsync(DocumentContext context, Action action, + CancellationToken ct = default) + { + await lockObject.WaitAsync(ct); + try + { + action(Doc); + } + finally + { + lockObject.Release(); + } + } + + public Task StartAsync(CancellationToken cancellationToken) + { + return Task.CompletedTask; + } + + public Task StopAsync(CancellationToken cancellationToken) + { + return Task.CompletedTask; + } + + public ValueTask CleanupAsync( + CancellationToken ct = default) + { + return default; + } + + public ValueTask PingAsync(DocumentContext context, ulong clock, string? state = null, + CancellationToken ct = default) + { + return default; + } + + public ValueTask DisconnectAsync(DocumentContext context, + CancellationToken ct = default) + { + return default; + } + + public ValueTask> GetAwarenessAsync(DocumentContext context, + CancellationToken ct = default) + { + return default; + } + + public ValueTask GetStateVectorAsync(DocumentContext context, + CancellationToken ct = default) + { + return default; + } + + public ValueTask GetUpdateAsync(DocumentContext context, byte[] stateVector, + CancellationToken ct = default) + { + return default; + } + + public ValueTask ApplyUpdateAsync(DocumentContext context, byte[] stateDiff, + CancellationToken ct = default) + { + return default; + } + } +} diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/CommentTriggerHandlerTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Collaboration/CommentTriggerHandlerTests.cs similarity index 98% rename from backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/CommentTriggerHandlerTests.cs rename to backend/tests/Squidex.Domain.Apps.Entities.Tests/Collaboration/CommentTriggerHandlerTests.cs index db3057d0b..a03492f63 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/CommentTriggerHandlerTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Collaboration/CommentTriggerHandlerTests.cs @@ -20,7 +20,7 @@ using Squidex.Infrastructure; using Squidex.Infrastructure.EventSourcing; using Squidex.Shared.Users; -namespace Squidex.Domain.Apps.Entities.Comments; +namespace Squidex.Domain.Apps.Entities.Collaboration; public class CommentTriggerHandlerTests { @@ -51,12 +51,6 @@ public class CommentTriggerHandlerTests Assert.True(sut.Handles(new CommentCreated())); } - [Fact] - public void Should_not_handle_comment_update_event() - { - Assert.False(sut.Handles(new CommentUpdated())); - } - [Fact] public void Should_not_handle_other_event() { diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Notifications/EmailUserNotificationsTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Collaboration/EmailUserNotificationsTests.cs similarity index 99% rename from backend/tests/Squidex.Domain.Apps.Entities.Tests/Notifications/EmailUserNotificationsTests.cs rename to backend/tests/Squidex.Domain.Apps.Entities.Tests/Collaboration/EmailUserNotificationsTests.cs index 673693afe..8b71d077c 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Notifications/EmailUserNotificationsTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Collaboration/EmailUserNotificationsTests.cs @@ -13,7 +13,7 @@ using Squidex.Domain.Apps.Entities.TestHelpers; using Squidex.Infrastructure.Email; using Squidex.Shared.Users; -namespace Squidex.Domain.Apps.Entities.Notifications; +namespace Squidex.Domain.Apps.Entities.Collaboration; public class EmailUserNotificationsTests : GivenContext { diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/CommentsLoaderTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/CommentsLoaderTests.cs deleted file mode 100644 index f00bf2395..000000000 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/CommentsLoaderTests.cs +++ /dev/null @@ -1,46 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using Squidex.Domain.Apps.Entities.Comments.DomainObject; -using Squidex.Domain.Apps.Entities.TestHelpers; -using Squidex.Infrastructure; -using Squidex.Infrastructure.Commands; - -namespace Squidex.Domain.Apps.Entities.Comments; - -public sealed class CommentsLoaderTests : GivenContext -{ - private readonly IDomainObjectFactory domainObjectFactory = A.Fake(); - private readonly CommentsLoader sut; - - public CommentsLoaderTests() - { - sut = new CommentsLoader(domainObjectFactory); - } - - [Fact] - public async Task Should_get_comments_from_domain_object() - { - var commentsId = DomainId.NewGuid(); - var comments = new CommentsResult(); - - var domainObject = A.Fake(); - - A.CallTo(() => domainObjectFactory.Create(commentsId)) - .Returns(domainObject); - - A.CallTo(() => domainObject.GetComments(11)) - .Returns(comments); - - var actual = await sut.GetCommentsAsync(commentsId, 11, CancellationToken); - - Assert.Same(comments, actual); - - A.CallTo(() => domainObject.LoadAsync(CancellationToken)) - .MustHaveHappened(); - } -} diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/DomainObject/CommentsCommandMiddlewareTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/DomainObject/CommentsCommandMiddlewareTests.cs deleted file mode 100644 index 56355d997..000000000 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/DomainObject/CommentsCommandMiddlewareTests.cs +++ /dev/null @@ -1,175 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using LoremNET; -using Squidex.Domain.Apps.Core.TestHelpers; -using Squidex.Domain.Apps.Entities.Comments.Commands; -using Squidex.Domain.Apps.Entities.TestHelpers; -using Squidex.Infrastructure; -using Squidex.Infrastructure.Commands; -using Squidex.Shared.Users; - -namespace Squidex.Domain.Apps.Entities.Comments.DomainObject; - -public class CommentsCommandMiddlewareTests : GivenContext -{ - private readonly IDomainObjectFactory domainObjectFactory = A.Fake(); - private readonly IUserResolver userResolver = A.Fake(); - private readonly ICommandBus commandBus = A.Fake(); - private readonly DomainId commentsId = DomainId.NewGuid(); - private readonly DomainId commentId = DomainId.NewGuid(); - private readonly CommentsCommandMiddleware sut; - - public CommentsCommandMiddlewareTests() - { - A.CallTo(() => userResolver.FindByIdOrEmailAsync(A._, default)) - .Returns(Task.FromResult(null)); - - sut = new CommentsCommandMiddleware(domainObjectFactory, userResolver); - } - - [Fact] - public async Task Should_invoke_domain_object_for_comments_command() - { - var command = CreateCommentsCommand(new CreateComment()); - var context = CrateCommandContext(command); - - var domainObject = A.Fake(); - - A.CallTo(() => domainObject.ExecuteAsync(command, CancellationToken)) - .Returns(CommandResult.Empty(commentsId, 0, 0)); - - A.CallTo(() => domainObjectFactory.Create(commentsId)) - .Returns(domainObject); - - var isNextCalled = false; - - await sut.HandleAsync(context, (c, ct) => - { - isNextCalled = true; - - return Task.CompletedTask; - }, CancellationToken); - - Assert.True(isNextCalled); - } - - [Fact] - public async Task Should_enrich_with_mentioned_user_ids_if_found() - { - SetupUser("id1", "mail1@squidex.io"); - SetupUser("id2", "mail2@squidex.io"); - - var command = CreateCommentsCommand(new CreateComment - { - Text = "Hi @mail1@squidex.io, @mail2@squidex.io and @notfound@squidex.io", - IsMention = false - }); - - var context = CrateCommandContext(command); - - await sut.HandleAsync(context, CancellationToken); - - Assert.Equal(command.Mentions, new[] { "id1", "id2" }); - } - - [Fact] - public async Task Should_enrich_with_mentioned_user_ids_if_found_and_long_text() - { - SetupUser("id1", "mail1@squidex.io"); - SetupUser("id2", "mail2@squidex.io"); - - var command = CreateCommentsCommand(new CreateComment - { - Text = $"Hi @mail1@squidex.io, @mail2@squidex.io and @notfound@squidex.io {Lorem.Paragraph(200, 10)}", - IsMention = false - }); - - var context = CrateCommandContext(command); - - await sut.HandleAsync(context, CancellationToken); - - Assert.Equal(command.Mentions, new[] { "id1", "id2" }); - } - - [Fact] - public async Task Should_not_invoke_commands_for_mentioned_users() - { - SetupUser("id1", "mail1@squidex.io"); - SetupUser("id2", "mail2@squidex.io"); - - var command = CreateCommentsCommand(new CreateComment - { - Text = "Hi @mail1@squidex.io and @mail2@squidex.io", - IsMention = false - }); - - var context = CrateCommandContext(command); - - await sut.HandleAsync(context, CancellationToken); - - A.CallTo(() => commandBus.PublishAsync(A._, A._)) - .MustNotHaveHappened(); - } - - [Fact] - public async Task Should_not_enrich_with_mentioned_user_ids_if_invalid_mentioned_tags_used() - { - var command = CreateCommentsCommand(new CreateComment - { - Text = "Hi invalid@squidex.io", - IsMention = false - }); - - var context = CrateCommandContext(command); - - await sut.HandleAsync(context, CancellationToken); - - A.CallTo(() => userResolver.FindByIdOrEmailAsync(A._, A._)) - .MustNotHaveHappened(); - } - - [Fact] - public async Task Should_not_enrich_with_mentioned_user_ids_for_notification() - { - var command = CreateCommentsCommand(new CreateComment - { - Text = "Hi @invalid@squidex.io", - IsMention = true - }); - - var context = CrateCommandContext(command); - - await sut.HandleAsync(context, CancellationToken); - - A.CallTo(() => userResolver.FindByIdOrEmailAsync(A._, A._)) - .MustNotHaveHappened(); - } - - private CommandContext CrateCommandContext(ICommand command) - { - return new CommandContext(command, commandBus); - } - - private void SetupUser(string id, string email) - { - var user = UserMocks.User(id, email); - - A.CallTo(() => userResolver.FindByIdOrEmailAsync(email, default)) - .Returns(user); - } - - private T CreateCommentsCommand(T command) where T : CommentCommand - { - command.AppId = AppId; - command.CommentsId = commentsId; - command.CommentId = commentId; - command.Actor = User; - - return command; - } -} diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/DomainObject/CommentsStreamTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/DomainObject/CommentsStreamTests.cs deleted file mode 100644 index a4d622c3d..000000000 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/DomainObject/CommentsStreamTests.cs +++ /dev/null @@ -1,175 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using NodaTime; -using Squidex.Domain.Apps.Core.Comments; -using Squidex.Domain.Apps.Entities.Comments.Commands; -using Squidex.Domain.Apps.Entities.TestHelpers; -using Squidex.Domain.Apps.Events.Comments; -using Squidex.Infrastructure; -using Squidex.Infrastructure.Commands; -using Squidex.Infrastructure.EventSourcing; - -namespace Squidex.Domain.Apps.Entities.Comments.DomainObject; - -public class CommentsStreamTests -{ - private readonly IEventFormatter eventFormatter = A.Fake(); - private readonly IEventStore eventStore = A.Fake(); - private readonly DomainId commentsId = DomainId.NewGuid(); - private readonly DomainId commentId = DomainId.NewGuid(); - private readonly RefToken actor = RefToken.User("me"); - private readonly CommentsStream sut; - - public IEnumerable> LastEvents { get; private set; } = Enumerable.Empty>(); - - public CommentsStreamTests() - { - A.CallTo(() => eventStore.AppendAsync(A._, A._, A._, A>._, default)) - .Invokes(x => LastEvents = sut!.GetUncommittedEvents().Select(x => x.To()).ToList()); - - sut = new CommentsStream(commentsId, eventFormatter, eventStore); - } - - [Fact] - public async Task Create_should_create_events() - { - var command = new CreateComment { Text = "text1", Url = new Uri("http://uri") }; - - var actual = await sut.ExecuteAsync(CreateCommentsCommand(command), default); - - actual.ShouldBeEquivalent(CommandResult.Empty(commentsId, 0, EtagVersion.Empty)); - - sut.GetComments(0).Should().BeEquivalentTo(new CommentsResult - { - Version = 0 - }); - - sut.GetComments(-1).Should().BeEquivalentTo(new CommentsResult - { - CreatedComments = new List - { - new Comment(command.CommentId, GetTime(), command.Actor, "text1", command.Url) - }, - Version = 0 - }); - - LastEvents - .ShouldHaveSameEvents( - CreateCommentsEvent(new CommentCreated { Text = command.Text, Url = command.Url }) - ); - } - - [Fact] - public async Task Update_should_create_events() - { - await ExecuteCreateAsync(); - - var updateCommand = new UpdateComment { Text = "text2" }; - - var actual = await sut.ExecuteAsync(CreateCommentsCommand(updateCommand), default); - - actual.ShouldBeEquivalent(CommandResult.Empty(commentsId, 1, 0)); - - sut.GetComments(-1).Should().BeEquivalentTo(new CommentsResult - { - CreatedComments = new List - { - new Comment(commentId, GetTime(), updateCommand.Actor, "text2") - }, - Version = 1 - }); - - sut.GetComments(0).Should().BeEquivalentTo(new CommentsResult - { - UpdatedComments = new List - { - new Comment(commentId, GetTime(), updateCommand.Actor, "text2") - }, - Version = 1 - }); - - LastEvents - .ShouldHaveSameEvents( - CreateCommentsEvent(new CommentUpdated { Text = updateCommand.Text }) - ); - } - - [Fact] - public async Task Delete_should_create_events() - { - await ExecuteCreateAsync(); - await ExecuteUpdateAsync(); - - var deleteCommand = new DeleteComment(); - - var actual = await sut.ExecuteAsync(CreateCommentsCommand(deleteCommand), default); - - actual.ShouldBeEquivalent(CommandResult.Empty(commentsId, 2, 1)); - - sut.GetComments(-1).Should().BeEquivalentTo(new CommentsResult - { - Version = 2 - }); - - sut.GetComments(0).Should().BeEquivalentTo(new CommentsResult - { - DeletedComments = new List - { - commentId - }, - Version = 2 - }); - - sut.GetComments(1).Should().BeEquivalentTo(new CommentsResult - { - DeletedComments = new List - { - commentId - }, - Version = 2 - }); - - LastEvents - .ShouldHaveSameEvents( - CreateCommentsEvent(new CommentDeleted()) - ); - } - - private Task ExecuteCreateAsync() - { - return sut.ExecuteAsync(CreateCommentsCommand(new CreateComment { Text = "text1" }), default); - } - - private Task ExecuteUpdateAsync() - { - return sut.ExecuteAsync(CreateCommentsCommand(new UpdateComment { Text = "text2" }), default); - } - - private T CreateCommentsEvent(T @event) where T : CommentsEvent - { - @event.Actor = actor; - @event.CommentsId = commentsId; - @event.CommentId = commentId; - - return @event; - } - - private T CreateCommentsCommand(T command) where T : CommentCommand - { - command.Actor = actor; - command.CommentsId = commentsId; - command.CommentId = commentId; - - return command; - } - - private Instant GetTime() - { - return LastEvents.ElementAt(0).Headers.Timestamp(); - } -} diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/DomainObject/Guards/GuardCommentsTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/DomainObject/Guards/GuardCommentsTests.cs deleted file mode 100644 index 134071626..000000000 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/DomainObject/Guards/GuardCommentsTests.cs +++ /dev/null @@ -1,191 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using Squidex.Domain.Apps.Core.TestHelpers; -using Squidex.Domain.Apps.Entities.Comments.Commands; -using Squidex.Domain.Apps.Entities.TestHelpers; -using Squidex.Domain.Apps.Events.Comments; -using Squidex.Infrastructure; -using Squidex.Infrastructure.EventSourcing; -using Squidex.Infrastructure.Validation; - -namespace Squidex.Domain.Apps.Entities.Comments.DomainObject.Guards; - -public class GuardCommentsTests : IClassFixture -{ - private readonly string commentsId = DomainId.NewGuid().ToString(); - private readonly RefToken user1 = RefToken.User("1"); - private readonly RefToken user2 = RefToken.User("2"); - - [Fact] - public void CanCreate_should_throw_exception_if_text_not_defined() - { - var command = new CreateComment(); - - ValidationAssert.Throws(() => GuardComments.CanCreate(command), - new ValidationError("Text is required.", "Text")); - } - - [Fact] - public void CanCreate_should_not_throw_exception_if_text_defined() - { - var command = new CreateComment { Text = "text" }; - - GuardComments.CanCreate(command); - } - - [Fact] - public void CanUpdate_should_throw_exception_if_text_not_defined() - { - var commentId = DomainId.NewGuid(); - var command = new UpdateComment { CommentId = commentId, Actor = user1 }; - - var events = new List> - { - Envelope.Create(new CommentCreated { CommentId = commentId, Actor = user1 }).To() - }; - - ValidationAssert.Throws(() => GuardComments.CanUpdate(command, commentsId, events), - new ValidationError("Text is required.", "Text")); - } - - [Fact] - public void CanUpdate_should_throw_exception_if_comment_from_another_user() - { - var commentId = DomainId.NewGuid(); - var command = new UpdateComment { CommentId = commentId, Actor = user2, Text = "text2" }; - - var events = new List> - { - Envelope.Create(new CommentCreated { CommentId = commentId, Actor = user1 }).To() - }; - - Assert.Throws(() => GuardComments.CanUpdate(command, commentsId, events)); - } - - [Fact] - public void CanUpdate_should_throw_exception_if_comment_not_found() - { - var commentId = DomainId.NewGuid(); - var command = new UpdateComment { CommentId = commentId, Actor = user1 }; - - var events = new List>(); - - Assert.Throws(() => GuardComments.CanUpdate(command, commentsId, events)); - } - - [Fact] - public void CanUpdate_should_throw_exception_if_comment_deleted_found() - { - var commentId = DomainId.NewGuid(); - var command = new UpdateComment { CommentId = commentId, Actor = user1 }; - - var events = new List> - { - Envelope.Create(new CommentCreated { CommentId = commentId, Actor = user1 }).To(), - Envelope.Create(new CommentDeleted { CommentId = commentId }).To() - }; - - Assert.Throws(() => GuardComments.CanUpdate(command, commentsId, events)); - } - - [Fact] - public void CanUpdate_should_not_throw_exception_if_comment_is_own_notification() - { - var commentId = DomainId.NewGuid(); - var command = new UpdateComment { CommentId = commentId, Actor = user1, Text = "text2" }; - - var events = new List> - { - Envelope.Create(new CommentCreated { CommentId = commentId, Actor = user1 }).To() - }; - - GuardComments.CanUpdate(command, user1.Identifier, events); - } - - [Fact] - public void CanUpdate_should_not_throw_exception_if_comment_from_same_user() - { - var commentId = DomainId.NewGuid(); - var command = new UpdateComment { CommentId = commentId, Actor = user1, Text = "text2" }; - - var events = new List> - { - Envelope.Create(new CommentCreated { CommentId = commentId, Actor = user1 }).To() - }; - - GuardComments.CanUpdate(command, commentsId, events); - } - - [Fact] - public void CanDelete_should_throw_exception_if_comment_from_another_user() - { - var commentId = DomainId.NewGuid(); - var command = new DeleteComment { CommentId = commentId, Actor = user2 }; - - var events = new List> - { - Envelope.Create(new CommentCreated { CommentId = commentId, Actor = user1 }).To() - }; - - Assert.Throws(() => GuardComments.CanDelete(command, commentsId, events)); - } - - [Fact] - public void CanDelete_should_throw_exception_if_comment_not_found() - { - var commentId = DomainId.NewGuid(); - var command = new DeleteComment { CommentId = commentId, Actor = user1 }; - - var events = new List>(); - - Assert.Throws(() => GuardComments.CanDelete(command, commentsId, events)); - } - - [Fact] - public void CanDelete_should_throw_exception_if_comment_deleted() - { - var commentId = DomainId.NewGuid(); - var command = new DeleteComment { CommentId = commentId, Actor = user1 }; - - var events = new List> - { - Envelope.Create(new CommentCreated { CommentId = commentId, Actor = user1 }), - Envelope.Create(new CommentDeleted { CommentId = commentId }) - }; - - Assert.Throws(() => GuardComments.CanDelete(command, commentsId, events)); - } - - [Fact] - public void CanDelete_should_not_throw_exception_if_comment_is_own_notification() - { - var commentId = DomainId.NewGuid(); - var command = new DeleteComment { CommentId = commentId, Actor = user1 }; - - var events = new List> - { - Envelope.Create(new CommentCreated { CommentId = commentId, Actor = user1 }).To() - }; - - GuardComments.CanDelete(command, user1.Identifier, events); - } - - [Fact] - public void CanDelete_should_not_throw_exception_if_comment_from_same_user() - { - var commentId = DomainId.NewGuid(); - var command = new DeleteComment { CommentId = commentId, Actor = user1 }; - - var events = new List> - { - Envelope.Create(new CommentCreated { CommentId = commentId, Actor = user1 }).To() - }; - - GuardComments.CanDelete(command, commentsId, events); - } -} diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/WatchingServiceTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/WatchingServiceTests.cs deleted file mode 100644 index e96a39a9a..000000000 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Comments/WatchingServiceTests.cs +++ /dev/null @@ -1,82 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using NodaTime; -using Squidex.Domain.Apps.Entities.TestHelpers; -using Squidex.Infrastructure.TestHelpers; - -namespace Squidex.Domain.Apps.Entities.Comments; - -public class WatchingServiceTests : GivenContext -{ - private readonly TestState state1; - private readonly TestState state2; - private readonly IClock clock = A.Fake(); - private readonly string resource1 = "resource1"; - private readonly string resource2 = "resource2"; - private readonly WatchingService sut; - private Instant now = SystemClock.Instance.GetCurrentInstant(); - - public WatchingServiceTests() - { - A.CallTo(() => clock.GetCurrentInstant()) - .ReturnsLazily(() => now); - - state1 = new TestState($"{AppId.Id}_{resource1}"); - state2 = new TestState($"{AppId.Id}_{resource2}", state1.PersistenceFactory); - - sut = new WatchingService(state1.PersistenceFactory) - { - Clock = clock - }; - } - - [Fact] - public async Task Should_only_return_self_if_no_one_watching() - { - var watching = await sut.GetWatchingUsersAsync(AppId.Id, resource1, "user1", CancellationToken); - - Assert.Equal(new[] { "user1" }, watching); - } - - [Fact] - public async Task Should_return_users_watching_on_same_resource() - { - await sut.GetWatchingUsersAsync(AppId.Id, resource1, "user1", CancellationToken); - await sut.GetWatchingUsersAsync(AppId.Id, resource2, "user2", CancellationToken); - - var watching1 = await sut.GetWatchingUsersAsync(AppId.Id, resource1, "user3", CancellationToken); - var watching2 = await sut.GetWatchingUsersAsync(AppId.Id, resource2, "user4", CancellationToken); - - Assert.Equal(new[] { "user1", "user3" }, watching1); - Assert.Equal(new[] { "user2", "user4" }, watching2); - } - - [Fact] - public async Task Should_cleanup_old_users() - { - await sut.GetWatchingUsersAsync(AppId.Id, resource1, "user1", CancellationToken); - await sut.GetWatchingUsersAsync(AppId.Id, resource2, "user2", CancellationToken); - - now = now.Plus(Duration.FromMinutes(2)); - - await sut.GetWatchingUsersAsync(AppId.Id, resource1, "user3", CancellationToken); - await sut.GetWatchingUsersAsync(AppId.Id, resource2, "user4", CancellationToken); - - var watching1 = await sut.GetWatchingUsersAsync(AppId.Id, resource1, "user5", CancellationToken); - var watching2 = await sut.GetWatchingUsersAsync(AppId.Id, resource2, "user6", CancellationToken); - - Assert.Equal(new[] { "user3", "user5" }, watching1); - Assert.Equal(new[] { "user4", "user6" }, watching2); - - A.CallTo(() => state1.Persistence.WriteSnapshotAsync(A._, CancellationToken)) - .MustHaveHappened(); - - A.CallTo(() => state2.Persistence.WriteSnapshotAsync(A._, CancellationToken)) - .MustHaveHappened(); - } -} diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLQueriesTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLQueriesTests.cs index 79666087b..db79711dc 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLQueriesTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLQueriesTests.cs @@ -53,7 +53,7 @@ public class GraphQLQueriesTests : GraphQLTestBase var contentId = DomainId.NewGuid(); var content = TestContent.Create(contentId); - A.CallTo(() => contentQuery.QueryAsync(MatchsContentContext(), TestSchemas.Default.Id.ToString(), + A.CallTo(() => contentQuery.QueryAsync(MatchsContentContext(), content.SchemaId.Id.ToString(), A.That.Matches(x => x.QueryAsOdata == "?$skip=0&$search=\"Hello\"" && x.NoTotal), A._)) .Returns(ResultList.CreateFrom(0, content)); @@ -345,7 +345,7 @@ public class GraphQLQueriesTests : GraphQLTestBase var contentId = DomainId.NewGuid(); var content = TestContent.Create(contentId); - A.CallTo(() => contentQuery.QueryAsync(MatchsContentContext(), TestSchemas.Default.Id.ToString(), + A.CallTo(() => contentQuery.QueryAsync(MatchsContentContext(), content.SchemaId.Id.ToString(), A.That.Matches(x => x.QueryAsOdata == "?$top=30&$skip=5" && x.NoTotal), A._)) .Returns(ResultList.CreateFrom(0, content)); @@ -384,7 +384,7 @@ public class GraphQLQueriesTests : GraphQLTestBase var contentId = DomainId.NewGuid(); var content = TestContent.Create(contentId); - A.CallTo(() => contentQuery.QueryAsync(MatchsContentContext(), TestSchemas.Default.Id.ToString(), + A.CallTo(() => contentQuery.QueryAsync(MatchsContentContext(), content.SchemaId.Id.ToString(), A.That.Matches(x => x.QueryAsOdata == "?$top=30&$skip=5" && x.NoTotal), A._)) .Returns(ResultList.CreateFrom(0, content)); @@ -423,7 +423,7 @@ public class GraphQLQueriesTests : GraphQLTestBase var contentId = DomainId.NewGuid(); var content = TestContent.Create(contentId); - A.CallTo(() => contentQuery.QueryAsync(MatchsContentContext(), TestSchemas.Default.Id.ToString(), + A.CallTo(() => contentQuery.QueryAsync(MatchsContentContext(), content.SchemaId.Id.ToString(), A.That.Matches(x => x.QueryAsOdata == "?$top=30&$skip=5" && !x.NoTotal), A._)) .Returns(ResultList.CreateFrom(10, content)); @@ -503,7 +503,7 @@ public class GraphQLQueriesTests : GraphQLTestBase public async Task Should_return_null_if_single_content_from_another_schema() { var contentId = DomainId.NewGuid(); - var content = TestContent.CreateRef(TestSchemas.Reference1.NamedId(), contentId, "reference1-field", "reference1"); + var content = TestContent.CreateSimple(TestSchemas.Reference1.NamedId(), contentId, "reference1-field", "reference1"); A.CallTo(() => contentQuery.QueryAsync(MatchsContentContext(), A.That.HasIdsWithoutTotal(contentId), @@ -537,7 +537,7 @@ public class GraphQLQueriesTests : GraphQLTestBase } [Fact] - public async Task Should_return_single_content_if_finding_content() + public async Task Should_find_single_content() { var contentId = DomainId.NewGuid(); var content = TestContent.Create(contentId); @@ -574,12 +574,12 @@ public class GraphQLQueriesTests : GraphQLTestBase } [Fact] - public async Task Should_return_single_content_if_finding_content_with_version() + public async Task Should_find_single_content_with_version() { var contentId = DomainId.NewGuid(); var content = TestContent.Create(contentId); - A.CallTo(() => contentQuery.FindAsync(MatchsContentContext(), TestSchemas.Default.Id.ToString(), contentId, 3, + A.CallTo(() => contentQuery.FindAsync(MatchsContentContext(), content.SchemaId.Id.ToString(), contentId, 3, A._)) .Returns(content); @@ -609,11 +609,102 @@ public class GraphQLQueriesTests : GraphQLTestBase AssertResult(expected, actual); } + [Fact] + public async Task Should_find_singleton_content() + { + var contentId = TestSchemas.Singleton.Id; + var content = TestContent.CreateSimple(TestSchemas.Singleton.NamedId(), contentId, "singleton-field", "Hello"); + + A.CallTo(() => contentQuery.QueryAsync(MatchsContentContext(), + A.That.HasIdsWithoutTotal(contentId), + A._)) + .Returns(ResultList.CreateFrom(1, content)); + + var actual = await ExecuteAsync(new TestQuery + { + Query = @" + query { + findMySingletonSingleton { + id, + flatData { + singletonField + } + } + }", + Args = new + { + contentId + } + }); + + var expected = new + { + data = new + { + findMySingletonSingleton = new + { + id = contentId, + flatData = new + { + singletonField = "Hello" + } + } + } + }; + + AssertResult(expected, actual); + } + + [Fact] + public async Task Should_find_singleton_content_with_version() + { + var contentId = TestSchemas.Singleton.Id; + var content = TestContent.CreateSimple(TestSchemas.Singleton.NamedId(), contentId, "singleton-field", "Hello"); + + A.CallTo(() => contentQuery.FindAsync(MatchsContentContext(), content.SchemaId.Id.ToString(), contentId, 3, + A._)) + .Returns(content); + + var actual = await ExecuteAsync(new TestQuery + { + Query = @" + query { + findMySingletonSingleton(version: 3) { + id, + flatData { + singletonField + } + } + }", + Args = new + { + contentId + } + }); + + var expected = new + { + data = new + { + findMySingletonSingleton = new + { + id = contentId, + flatData = new + { + singletonField = "Hello" + } + } + } + }; + + AssertResult(expected, actual); + } + [Fact] public async Task Should_also_fetch_embedded_contents_if_field_is_included_in_query() { var contentRefId = DomainId.NewGuid(); - var contentRef = TestContent.CreateRef(TestSchemas.Reference1.NamedId(), contentRefId, "reference1-field", "reference1"); + var contentRef = TestContent.CreateSimple(TestSchemas.Reference1.NamedId(), contentRefId, "reference1-field", "reference1"); var contentId = DomainId.NewGuid(); var content = TestContent.Create(contentId, contentRefId); @@ -703,7 +794,7 @@ public class GraphQLQueriesTests : GraphQLTestBase public async Task Should_also_fetch_referenced_contents_if_field_is_included_in_query() { var contentRefId = DomainId.NewGuid(); - var contentRef = TestContent.CreateRef(TestSchemas.Reference1.NamedId(), contentRefId, "reference1-field", "reference1"); + var contentRef = TestContent.CreateSimple(TestSchemas.Reference1.NamedId(), contentRefId, "reference1-field", "reference1"); var contentId = DomainId.NewGuid(); var content = TestContent.Create(contentId, contentRefId); @@ -782,7 +873,7 @@ public class GraphQLQueriesTests : GraphQLTestBase public async Task Should_also_fetch_referenced_contents_from_flat_data_if_field_is_included_in_query() { var contentRefId = DomainId.NewGuid(); - var contentRef = TestContent.CreateRef(TestSchemas.Reference1.NamedId(), contentRefId, "reference1-field", "reference1"); + var contentRef = TestContent.CreateSimple(TestSchemas.Reference1.NamedId(), contentRefId, "reference1-field", "reference1"); var contentId = DomainId.NewGuid(); var content = TestContent.Create(contentId, contentRefId); @@ -844,7 +935,7 @@ public class GraphQLQueriesTests : GraphQLTestBase public async Task Should_cache_referenced_contents_from_flat_data_if_field_is_included_in_query() { var contentRefId = DomainId.NewGuid(); - var contentRef = TestContent.CreateRef(TestSchemas.Reference1.NamedId(), contentRefId, "reference1-field", "reference1"); + var contentRef = TestContent.CreateSimple(TestSchemas.Reference1.NamedId(), contentRefId, "reference1-field", "reference1"); var contentId = DomainId.NewGuid(); var content = TestContent.Create(contentId, contentRefId); @@ -915,7 +1006,7 @@ public class GraphQLQueriesTests : GraphQLTestBase public async Task Should_also_fetch_referencing_contents_if_field_is_included_in_query() { var contentRefId = DomainId.NewGuid(); - var contentRef = TestContent.CreateRef(TestSchemas.Reference1.NamedId(), contentRefId, "reference1-field", "reference1"); + var contentRef = TestContent.CreateSimple(TestSchemas.Reference1.NamedId(), contentRefId, "reference1-field", "reference1"); var contentId = DomainId.NewGuid(); var content = TestContent.Create(contentId, contentRefId); @@ -984,7 +1075,7 @@ public class GraphQLQueriesTests : GraphQLTestBase public async Task Should_also_fetch_referencing_contents_with_total_if_field_is_included_in_query() { var contentRefId = DomainId.NewGuid(); - var contentRef = TestContent.CreateRef(TestSchemas.Reference1.NamedId(), contentRefId, "reference1-field", "reference1"); + var contentRef = TestContent.CreateSimple(TestSchemas.Reference1.NamedId(), contentRefId, "reference1-field", "reference1"); var contentId = DomainId.NewGuid(); var content = TestContent.Create(contentId, contentRefId); @@ -1060,7 +1151,7 @@ public class GraphQLQueriesTests : GraphQLTestBase public async Task Should_also_fetch_references_contents_if_field_is_included_in_query() { var contentRefId = DomainId.NewGuid(); - var contentRef = TestContent.CreateRef(TestSchemas.Reference1.NamedId(), contentRefId, "reference1-field", "reference1"); + var contentRef = TestContent.CreateSimple(TestSchemas.Reference1.NamedId(), contentRefId, "reference1-field", "reference1"); var contentId = DomainId.NewGuid(); var content = TestContent.Create(contentId, contentRefId); @@ -1117,7 +1208,7 @@ public class GraphQLQueriesTests : GraphQLTestBase public async Task Should_also_fetch_references_contents_with_total_if_field_is_included_in_query() { var contentRefId = DomainId.NewGuid(); - var contentRef = TestContent.CreateRef(TestSchemas.Reference1.NamedId(), contentRefId, "reference1-field", "reference1"); + var contentRef = TestContent.CreateSimple(TestSchemas.Reference1.NamedId(), contentRefId, "reference1-field", "reference1"); var contentId = DomainId.NewGuid(); var content = TestContent.Create(contentId, contentRefId); @@ -1181,7 +1272,7 @@ public class GraphQLQueriesTests : GraphQLTestBase public async Task Should_also_fetch_union_contents_if_field_is_included_in_query() { var contentRefId = DomainId.NewGuid(); - var contentRef = TestContent.CreateRef(TestSchemas.Reference1.NamedId(), contentRefId, "reference1-field", "reference1"); + var contentRef = TestContent.CreateSimple(TestSchemas.Reference1.NamedId(), contentRefId, "reference1-field", "reference1"); var contentId = DomainId.NewGuid(); var content = TestContent.Create(contentId, contentRefId); diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLTestBase.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLTestBase.cs index 50be7d694..508bd5553 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLTestBase.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLTestBase.cs @@ -76,7 +76,12 @@ public abstract class GraphQLTestBase : IClassFixture protected Task ExecuteAsync(TestQuery query) { // Use a shared instance to test caching. - sut ??= CreateSut(TestSchemas.Default, TestSchemas.Reference1, TestSchemas.Reference2, TestSchemas.Component); + sut ??= CreateSut( + TestSchemas.Default, + TestSchemas.Reference1, + TestSchemas.Reference2, + TestSchemas.Singleton, + TestSchemas.Component); var options = query.ToOptions(sut.Services); diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/TestContent.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/TestContent.cs index a593e3993..c35923490 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/TestContent.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/TestContent.cs @@ -346,7 +346,7 @@ public static class TestContent return content; } - public static IEnrichedContentEntity CreateRef(NamedId schemaId, DomainId id, string field, string value) + public static IEnrichedContentEntity CreateSimple(NamedId schemaId, DomainId id, string field, string value) { var now = SystemClock.Instance.GetCurrentInstant(); diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/TestSchemas.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/TestSchemas.cs index 0946c4d6c..cb6501228 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/TestSchemas.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/TestSchemas.cs @@ -19,6 +19,7 @@ public static class TestSchemas public static readonly ISchemaEntity Default; public static readonly ISchemaEntity Reference1; public static readonly ISchemaEntity Reference2; + public static readonly ISchemaEntity Singleton; public static readonly ISchemaEntity Component; static TestSchemas() @@ -57,6 +58,11 @@ public static class TestSchemas .Publish() .AddString(1, "reference2-field", Partitioning.Invariant)); + Singleton = Mocks.Schema(TestApp.DefaultId, DomainId.NewGuid(), + new Schema("my-singleton", type: SchemaType.Singleton) + .Publish() + .AddString(1, "singleton-field", Partitioning.Invariant)); + Default = Mocks.Schema(TestApp.DefaultId, DomainId.NewGuid(), new Schema("my-schema") .Publish() diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/TestData/FakeUrlGenerator.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/TestData/FakeUrlGenerator.cs index ce6ba5dbc..cd41ae86f 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/TestData/FakeUrlGenerator.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/TestData/FakeUrlGenerator.cs @@ -30,6 +30,11 @@ public sealed class FakeUrlGenerator : IUrlGenerator return $"assets/{appId.Name}/{idOrSlug}"; } + public string AssetContent(NamedId appId, string idOrSlug, long version) + { + return $"assets/{appId.Name}/{idOrSlug}?version={version}"; + } + public string ContentUI(NamedId appId, NamedId schemaId, DomainId contentId) { return $"contents/{schemaId.Name}/{contentId}"; diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Text/TextIndexerTestsBase.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Text/TextIndexerTestsBase.cs index 4cbdfefde..82f0324c5 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Text/TextIndexerTestsBase.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/Text/TextIndexerTestsBase.cs @@ -49,6 +49,12 @@ public abstract class TextIndexerTestsBase : GivenContext public abstract ITextIndex CreateIndex(); + [Fact] + public void Should_return_content_filter_for_events_filter() + { + Assert.Equal(StreamFilter.Prefix("content-"), Sut.EventsFilter); + } + [Fact] public async Task Should_search_with_fuzzy() { diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Invitation/InvitationEventConsumerTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Invitation/InvitationEventConsumerTests.cs index 0195372c7..67ee6f659 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Invitation/InvitationEventConsumerTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Invitation/InvitationEventConsumerTests.cs @@ -9,7 +9,7 @@ using Microsoft.Extensions.Logging; using NodaTime; using Squidex.Domain.Apps.Core.TestHelpers; using Squidex.Domain.Apps.Entities.Apps; -using Squidex.Domain.Apps.Entities.Notifications; +using Squidex.Domain.Apps.Entities.Collaboration; using Squidex.Domain.Apps.Entities.Teams; using Squidex.Domain.Apps.Entities.TestHelpers; using Squidex.Domain.Apps.Events.Apps; @@ -45,6 +45,24 @@ public class InvitationEventConsumerTests : GivenContext sut = new InvitationEventConsumer(AppProvider, userNotifications, userResolver, log); } + [Fact] + public void Should_return_app_filter_for_events_filter() + { + Assert.Equal(StreamFilter.Prefix("app-"), sut.EventsFilter); + } + + [Fact] + public async Task Should_do_nothing_on_clear() + { + await ((IEventConsumer)sut).ClearAsync(); + } + + [Fact] + public void Should_return_custom_name() + { + Assert.Equal("NotificationEmailSender", sut.Name); + } + [Fact] public async Task Should_not_send_app_email_if_contributors_assigned_by_clients() { diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleEnqueuerTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleEnqueuerTests.cs index 947ae910b..fa738f598 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleEnqueuerTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleEnqueuerTests.cs @@ -52,7 +52,7 @@ public class RuleEnqueuerTests : GivenContext [Fact] public void Should_return_wildcard_filter_for_events_filter() { - Assert.Equal(".*", ((IEventConsumer)sut).EventsFilter); + Assert.Equal(default, ((IEventConsumer)sut).EventsFilter); } [Fact] diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/DomainObject/SchemaState.json b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/DomainObject/SchemaState.json index 498ac7af4..2235e95eb 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/DomainObject/SchemaState.json +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Schemas/DomainObject/SchemaState.json @@ -130,6 +130,7 @@ "isDisabled": false, "properties": { "$type": "ComponentsField", + "calculatedDefaultValue": "EmptyArray", "schemaId": "62a1d2a8-f08d-4870-8cb9-cb3ba286d56c", "schemaIds": [ "62a1d2a8-f08d-4870-8cb9-cb3ba286d56c" @@ -267,6 +268,7 @@ "isDisabled": false, "properties": { "$type": "ArrayField", + "calculatedDefaultValue": "EmptyArray", "isRequired": false, "isRequiredOnPublish": false, "isHalfWidth": false diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Squidex.Domain.Apps.Entities.Tests.csproj b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Squidex.Domain.Apps.Entities.Tests.csproj index 87313fab7..21f5e6939 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Squidex.Domain.Apps.Entities.Tests.csproj +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Squidex.Domain.Apps.Entities.Tests.csproj @@ -34,6 +34,7 @@ + diff --git a/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/Consume/EventConsumerProcessorTests.cs b/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/Consume/EventConsumerProcessorTests.cs index a65a67564..9f41151c5 100644 --- a/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/Consume/EventConsumerProcessorTests.cs +++ b/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/Consume/EventConsumerProcessorTests.cs @@ -62,7 +62,7 @@ public class EventConsumerProcessorTests } }; - A.CallTo(() => eventStore.CreateSubscription(A>._, A._, A._)) + A.CallTo(() => eventStore.CreateSubscription(A>._, A._, A._)) .Returns(eventSubscription); A.CallTo(() => eventConsumer.Name) @@ -101,15 +101,17 @@ public class EventConsumerProcessorTests { state.Snapshot = new EventConsumerState(); + var filter = StreamFilter.Name("my-filter"); + A.CallTo(() => eventConsumer.StartLatest) .Returns(true); A.CallTo(() => eventConsumer.EventsFilter) - .Returns("my-filter"); + .Returns(filter); var latestPosition = "LATEST"; - A.CallTo(() => eventStore.QueryAllReverseAsync("my-filter", default, 1, A._)) + A.CallTo(() => eventStore.QueryAllReverseAsync(filter, default, 1, A._)) .Returns(Enumerable.Repeat(new StoredEvent("Stream", latestPosition, 1, eventData), 1).ToAsyncEnumerable()); await sut.InitializeAsync(default); @@ -129,7 +131,7 @@ public class EventConsumerProcessorTests AssertGrainState(isStopped: true, position: initialPosition); - A.CallTo(() => eventStore.CreateSubscription(A>._, A._, A._)) + A.CallTo(() => eventStore.CreateSubscription(A>._, A._, A._)) .MustNotHaveHappened(); } @@ -143,7 +145,7 @@ public class EventConsumerProcessorTests AssertGrainState(isStopped: false, position: initialPosition); - A.CallTo(() => eventStore.CreateSubscription(A>._, A._, A._)) + A.CallTo(() => eventStore.CreateSubscription(A>._, A._, A._)) .MustHaveHappenedOnceExactly(); } @@ -159,7 +161,7 @@ public class EventConsumerProcessorTests AssertGrainState(isStopped: false, position: initialPosition); - A.CallTo(() => eventStore.CreateSubscription(A>._, A._, A._)) + A.CallTo(() => eventStore.CreateSubscription(A>._, A._, A._)) .MustHaveHappenedOnceExactly(); } @@ -173,7 +175,7 @@ public class EventConsumerProcessorTests AssertGrainState(isStopped: false, position: initialPosition); - A.CallTo(() => eventStore.CreateSubscription(A>._, A._, A._)) + A.CallTo(() => eventStore.CreateSubscription(A>._, A._, A._)) .MustHaveHappenedOnceExactly(); } @@ -219,10 +221,10 @@ public class EventConsumerProcessorTests A.CallTo(() => eventSubscription.Dispose()) .MustHaveHappenedOnceExactly(); - A.CallTo(() => eventStore.CreateSubscription(A>._, A._, state.Snapshot.Position)) + A.CallTo(() => eventStore.CreateSubscription(A>._, A._, state.Snapshot.Position)) .MustHaveHappenedOnceExactly(); - A.CallTo(() => eventStore.CreateSubscription(A>._, A._, null)) + A.CallTo(() => eventStore.CreateSubscription(A>._, A._, null)) .MustHaveHappenedOnceExactly(); } @@ -530,7 +532,7 @@ public class EventConsumerProcessorTests A.CallTo(() => eventSubscription.Dispose()) .MustHaveHappenedOnceExactly(); - A.CallTo(() => eventStore.CreateSubscription(A>._, A._, A._)) + A.CallTo(() => eventStore.CreateSubscription(A>._, A._, A._)) .MustHaveHappened(2, Times.Exactly); } diff --git a/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/EventStoreTests.cs b/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/EventStoreTests.cs index 0cd4cd593..0a19c38d6 100644 --- a/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/EventStoreTests.cs +++ b/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/EventStoreTests.cs @@ -6,7 +6,6 @@ // ========================================================================== using System.Globalization; -using System.Text.RegularExpressions; namespace Squidex.Infrastructure.EventSourcing; @@ -90,6 +89,7 @@ public abstract class EventStoreTests where T : IEventStore public async Task Should_append_events() { var streamName = $"test-{Guid.NewGuid()}"; + var streamFilter = StreamFilter.Name(streamName); var commit1 = new[] { @@ -107,7 +107,7 @@ public abstract class EventStoreTests where T : IEventStore await Sut.AppendAsync(Guid.NewGuid(), streamName, EtagVersion.Any, commit2); var readEvents1 = await QueryAsync(streamName); - var readEvents2 = await QueryAllAsync(streamName); + var readEvents2 = await QueryAllAsync(streamFilter); var expected = new[] { @@ -125,6 +125,7 @@ public abstract class EventStoreTests where T : IEventStore public async Task Should_append_events_unsafe() { var streamName = $"test-{Guid.NewGuid()}"; + var streamFilter = StreamFilter.Name(streamName); var commit1 = new[] { @@ -138,7 +139,7 @@ public abstract class EventStoreTests where T : IEventStore }); var readEvents1 = await QueryAsync(streamName); - var readEvents2 = await QueryAllAsync(streamName); + var readEvents2 = await QueryAllAsync(streamFilter); var expected = new[] { @@ -154,6 +155,7 @@ public abstract class EventStoreTests where T : IEventStore public async Task Should_subscribe_to_events() { var streamName = $"test-{Guid.NewGuid()}"; + var streamFilter = StreamFilter.Name(streamName); var commit1 = new[] { @@ -161,7 +163,7 @@ public abstract class EventStoreTests where T : IEventStore CreateEventData(2) }; - var readEvents = await QueryWithSubscriptionAsync(streamName, async () => + var readEvents = await QueryWithSubscriptionAsync(streamFilter, async () => { await Sut.AppendAsync(Guid.NewGuid(), streamName, EtagVersion.Any, commit1); }); @@ -179,6 +181,7 @@ public abstract class EventStoreTests where T : IEventStore public async Task Should_subscribe_to_next_events() { var streamName = $"test-{Guid.NewGuid()}"; + var streamFilter = StreamFilter.Name(streamName); var commit1 = new[] { @@ -187,7 +190,7 @@ public abstract class EventStoreTests where T : IEventStore }; // Append and read in parallel. - await QueryWithSubscriptionAsync(streamName, async () => + await QueryWithSubscriptionAsync(streamFilter, async () => { await Sut.AppendAsync(Guid.NewGuid(), streamName, EtagVersion.Any, commit1); }); @@ -199,7 +202,7 @@ public abstract class EventStoreTests where T : IEventStore }; // Append and read in parallel. - var readEventsFromPosition = await QueryWithSubscriptionAsync(streamName, async () => + var readEventsFromPosition = await QueryWithSubscriptionAsync(streamFilter, async () => { await Sut.AppendAsync(Guid.NewGuid(), streamName, EtagVersion.Any, commit2); }); @@ -210,7 +213,7 @@ public abstract class EventStoreTests where T : IEventStore new StoredEvent(streamName, "Position", 3, commit2[1]) }; - var readEventsFromBeginning = await QueryWithSubscriptionAsync(streamName, fromBeginning: true); + var readEventsFromBeginning = await QueryWithSubscriptionAsync(streamFilter, fromBeginning: true); var expectedFromBeginning = new[] { @@ -228,12 +231,13 @@ public abstract class EventStoreTests where T : IEventStore public async Task Should_subscribe_with_parallel_writes() { var streamName = $"test-{Guid.NewGuid()}"; + var streamFilter = StreamFilter.Prefix(streamName); var numTasks = 50; var numEvents = 100; // Append and read in parallel. - var readEvents = await QueryWithSubscriptionAsync($"^{streamName}", async () => + var readEvents = await QueryWithSubscriptionAsync(streamFilter, async () => { await Parallel.ForEachAsync(Enumerable.Range(0, numTasks), async (i, ct) => { @@ -277,7 +281,7 @@ public abstract class EventStoreTests where T : IEventStore await Sut.AppendAsync(Guid.NewGuid(), streamName1, EtagVersion.Any, stream1Commit); await Sut.AppendAsync(Guid.NewGuid(), streamName2, EtagVersion.Any, stream2Commit); - var readEvents = await Sut.QueryManyAsync(new[] { streamName1, streamName2 }); + var readEvents = await Sut.QueryAllAsync(StreamFilter.Name(streamName1, streamName2)).ToListAsync(); var expected1 = new[] { @@ -291,8 +295,8 @@ public abstract class EventStoreTests where T : IEventStore new StoredEvent(streamName2, "Position", 1, stream2Commit[1]) }; - ShouldBeEquivalentTo(readEvents[streamName1], expected1); - ShouldBeEquivalentTo(readEvents[streamName2], expected2); + ShouldBeEquivalentTo(readEvents.Where(x => x.StreamName == streamName1), expected1); + ShouldBeEquivalentTo(readEvents.Where(x => x.StreamName == streamName2), expected2); } [Theory] @@ -300,7 +304,7 @@ public abstract class EventStoreTests where T : IEventStore [InlineData(5, 30)] [InlineData(5, 300)] [InlineData(5, 3000)] - public async Task Should_read_events_from_offset(int commits, int count) + public async Task Should_query_events_from_offset(int commits, int count) { var streamName = $"test-{Guid.NewGuid()}"; @@ -308,7 +312,7 @@ public abstract class EventStoreTests where T : IEventStore var readEvents0 = await QueryAsync(streamName); var readEvents1 = await QueryAsync(streamName, count - 2); - var readEvents2 = await QueryAllAsync(streamName, readEvents0[^2].EventPosition); + var readEvents2 = await QueryAllAsync(default, readEvents0[^2].EventPosition); var expected = new[] { @@ -319,33 +323,14 @@ public abstract class EventStoreTests where T : IEventStore ShouldBeEquivalentTo(readEvents2, expected); } - [Theory] - [InlineData(5, 30)] - [InlineData(5, 300)] - public async Task Should_read_reverse(int commits, int count) - { - var streamName = $"test-{Guid.NewGuid()}"; - - var eventsWritten = await AppendEventsAsync(streamName, count, commits); - var eventsStored = eventsWritten.Select((x, i) => new StoredEvent(streamName, "Position", i, x)).ToArray(); - - for (var take = 0; take < count; take += count / 10) - { - var eventsExpected = eventsStored.TakeLast(take).ToArray(); - var eventsQueried = await Sut.QueryReverseAsync(streamName, take); - - ShouldBeEquivalentTo(eventsQueried, eventsExpected); - } - } - [Theory] [InlineData(5, 30)] [InlineData(5, 300)] [InlineData(5, 3000)] - public async Task Should_read_all_reverse_by_name(int commits, int count) + public async Task Should_query_all_reverse_by_names(int commits, int count) { var streamName = $"test-{Guid.NewGuid()}"; - var streamFilter = streamName; + var streamFilter = StreamFilter.Name(streamName, "invalid"); var eventsWritten = await AppendEventsAsync(streamName, count, commits); var eventsStored = eventsWritten.Select((x, i) => new StoredEvent(streamName, "Position", i, x)).ToArray(); @@ -353,7 +338,7 @@ public abstract class EventStoreTests where T : IEventStore for (var take = 0; take < count; take += count / 10) { var eventsExpected = eventsStored.Reverse().Take(take).ToArray(); - var eventsQueried = await Sut.QueryAllReverseAsync(streamName, default, take).ToArrayAsync(); + var eventsQueried = await Sut.QueryAllReverseAsync(streamFilter, default, take).ToArrayAsync(); ShouldBeEquivalentTo(eventsQueried, eventsExpected); } @@ -363,10 +348,10 @@ public abstract class EventStoreTests where T : IEventStore [InlineData(5, 30)] [InlineData(5, 300)] [InlineData(5, 3000)] - public async Task Should_read_all_reverse_by_filter(int commits, int count) + public async Task Should_query_all_reverse_by_filter(int commits, int count) { var streamName = $"test-{Guid.NewGuid()}-suffix"; - var streamFilter = $"^{Regex.Escape(streamName)}"; + var streamFilter = StreamFilter.Prefix(streamName[..^7], "invalid"); var eventsWritten = await AppendEventsAsync(streamName, count, commits); var eventsStored = eventsWritten.Select((x, i) => new StoredEvent(streamName, "Position", i, x)).ToArray(); @@ -387,7 +372,7 @@ public abstract class EventStoreTests where T : IEventStore public async Task Should_read_all_reverse(int commits, int count) { var streamName = $"test-{Guid.NewGuid()}-suffix"; - var streamFilter = ".*"; + var streamFilter = default(StreamFilter); await AppendEventsAsync(streamName, count, commits); @@ -403,6 +388,7 @@ public abstract class EventStoreTests where T : IEventStore public async Task Should_delete_by_filter() { var streamName = $"test-{Guid.NewGuid()}"; + var streamFilter = StreamFilter.Prefix($"{streamName[..10]}"); await AppendEventsAsync(streamName, 2, 1); @@ -410,7 +396,7 @@ public abstract class EventStoreTests where T : IEventStore for (var i = 0; i < 5; i++) { - await Sut.DeleteAsync($"^{streamName[..10]}"); + await Sut.DeleteAsync(streamFilter); readEvents = await QueryAsync(streamName); @@ -427,9 +413,10 @@ public abstract class EventStoreTests where T : IEventStore } [Fact] - public async Task Should_delete_stream() + public async Task Should_delete_by_name() { var streamName = $"test-{Guid.NewGuid()}"; + var streamFilter = StreamFilter.Name(streamName); await AppendEventsAsync(streamName, 2, 1); @@ -437,7 +424,7 @@ public abstract class EventStoreTests where T : IEventStore for (var i = 0; i < 5; i++) { - await Sut.DeleteStreamAsync(streamName); + await Sut.DeleteAsync(streamFilter); readEvents = await QueryAsync(streamName); @@ -455,12 +442,12 @@ public abstract class EventStoreTests where T : IEventStore private async Task> QueryAsync(string streamName, long position = EtagVersion.Any) { - return await Sut.QueryAsync(streamName, position); + return await Sut.QueryStreamAsync(streamName, position); } - private async Task?> QueryAllAsync(string? streamFilter = null, string? position = null) + private async Task?> QueryAllAsync(StreamFilter filter, string? position = null) { - return await Sut.QueryAllAsync(streamFilter, position).ToListAsync(); + return await Sut.QueryAllAsync(filter, position).ToListAsync(); } private static EventData CreateEventData(int i) @@ -473,7 +460,7 @@ public abstract class EventStoreTests where T : IEventStore return new EventData($"Type{i}", headers, i.ToString(CultureInfo.InvariantCulture)); } - private async Task?> QueryWithSubscriptionAsync(string streamFilter, + private async Task?> QueryWithSubscriptionAsync(StreamFilter streamFilter, Func? subscriptionRunning = null, bool fromBeginning = false) { var subscriber = new EventSubscriber(); diff --git a/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/MongoEventStoreTests.cs b/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/MongoEventStoreTests.cs index 4f18b632d..ec5b5270e 100644 --- a/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/MongoEventStoreTests.cs +++ b/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/MongoEventStoreTests.cs @@ -41,9 +41,8 @@ public abstract class MongoEventStoreTests : EventStoreTests, I Assert.All(queries, query => { - Assert.Equal(query.NumDocuments, query.DocsExamined); - Assert.True(query.KeysExamined >= query.NumDocuments); - Assert.True(query.KeysExamined <= query.NumDocuments * 2); + Assert.InRange(query.DocsExamined, 0, query.NumDocuments); + Assert.InRange(query.KeysExamined, query.NumDocuments, (Math.Max(1, query.NumDocuments) * 2) + 1); }); } } diff --git a/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/MongoParallelInsertTests.cs b/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/MongoParallelInsertTests.cs index 999319152..b72f177fa 100644 --- a/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/MongoParallelInsertTests.cs +++ b/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/MongoParallelInsertTests.cs @@ -38,7 +38,7 @@ public sealed class MongoParallelInsertTests : IClassFixture $"^{Name}"; + public StreamFilter EventsFilter => StreamFilter.Prefix(Name); public Task Completed => tcs.Task; diff --git a/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/PollingSubscriptionTests.cs b/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/PollingSubscriptionTests.cs index 013ecc5ac..c5f65e29d 100644 --- a/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/PollingSubscriptionTests.cs +++ b/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/PollingSubscriptionTests.cs @@ -13,8 +13,8 @@ public class PollingSubscriptionTests { private readonly IEventStore eventStore = A.Fake(); private readonly IEventSubscriber eventSubscriber = A.Fake>(); + private readonly StreamFilter filter = StreamFilter.Name("my-stream"); private readonly string position = Guid.NewGuid().ToString(); - private readonly string filter = "^my-stream"; [Fact] public async Task Should_subscribe_on_start() diff --git a/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/RetrySubscriptionTests.cs b/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/RetrySubscriptionTests.cs index 9118f2dbf..8317e4513 100644 --- a/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/RetrySubscriptionTests.cs +++ b/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/RetrySubscriptionTests.cs @@ -17,10 +17,10 @@ public class RetrySubscriptionTests public RetrySubscriptionTests() { - A.CallTo(() => eventStore.CreateSubscription(A>._, A._, A._)) + A.CallTo(() => eventStore.CreateSubscription(A>._, A._, A._)) .Returns(eventSubscription); - sut = new RetrySubscription(eventSubscriber, s => eventStore.CreateSubscription(s)) { ReconnectWaitMs = 50 }; + sut = new RetrySubscription(eventSubscriber, s => eventStore.CreateSubscription(s, default)) { ReconnectWaitMs = 50 }; sutSubscriber = sut; } @@ -29,7 +29,7 @@ public class RetrySubscriptionTests { sut.Dispose(); - A.CallTo(() => eventStore.CreateSubscription(sut, A._, A._)) + A.CallTo(() => eventStore.CreateSubscription(sut, A._, A._)) .MustHaveHappened(); } @@ -47,7 +47,7 @@ public class RetrySubscriptionTests A.CallTo(() => eventSubscription.Dispose()) .MustHaveHappened(2, Times.Exactly); - A.CallTo(() => eventStore.CreateSubscription(A>._, A._, A._)) + A.CallTo(() => eventStore.CreateSubscription(A>._, A._, A._)) .MustHaveHappened(2, Times.Exactly); A.CallTo(() => eventSubscriber.OnErrorAsync(eventSubscription, A._)) diff --git a/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/StreamFilterTests.cs b/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/StreamFilterTests.cs new file mode 100644 index 000000000..45c310c63 --- /dev/null +++ b/backend/tests/Squidex.Infrastructure.Tests/EventSourcing/StreamFilterTests.cs @@ -0,0 +1,27 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +namespace Squidex.Infrastructure.EventSourcing; + +public class StreamFilterTests +{ + [Fact] + public void Should_simplify_input_to_default_filter() + { + var sut = new StreamFilter(StreamFilterKind.MatchFull); + + Assert.Equal(default, sut); + } + + [Fact] + public void Should_simplify_input_to_default_filter_with_factory() + { + var sut = StreamFilter.Name(); + + Assert.Equal(default, sut); + } +} diff --git a/backend/tests/Squidex.Infrastructure.Tests/States/PersistenceBatchTests.cs b/backend/tests/Squidex.Infrastructure.Tests/States/PersistenceBatchTests.cs index bbebf7178..1e2b24b2c 100644 --- a/backend/tests/Squidex.Infrastructure.Tests/States/PersistenceBatchTests.cs +++ b/backend/tests/Squidex.Infrastructure.Tests/States/PersistenceBatchTests.cs @@ -185,12 +185,10 @@ public class PersistenceBatchTests private void SetupEventStore(Dictionary> streams) { - var storedStreams = new Dictionary>(); + var events = new List(); foreach (var (id, stream) in streams) { - var storedStream = new List(); - var i = 0; foreach (var @event in stream) @@ -198,23 +196,20 @@ public class PersistenceBatchTests var eventData = new EventData("Type", new EnvelopeHeaders(), "Payload"); var eventStored = new StoredEvent(id.ToString(), i.ToString(CultureInfo.InvariantCulture), i, eventData); - storedStream.Add(eventStored); - A.CallTo(() => eventFormatter.Parse(eventStored)) .Returns(new Envelope(@event)); A.CallTo(() => eventFormatter.ParseIfKnown(eventStored)) .Returns(new Envelope(@event)); + events.Add(eventStored); i++; } - - storedStreams[id.ToString()] = storedStream; } - var streamNames = streams.Keys.Select(x => x.ToString()).ToArray(); + var filter = StreamFilter.Name(streams.Keys.Select(x => x.ToString()).ToArray()); - A.CallTo(() => eventStore.QueryManyAsync(A>.That.IsSameSequenceAs(streamNames), A._)) - .Returns(storedStreams); + A.CallTo(() => eventStore.QueryAllAsync(filter, null, int.MaxValue, A._)) + .Returns(events.ToAsyncEnumerable()); } } diff --git a/backend/tests/Squidex.Infrastructure.Tests/States/PersistenceEventSourcingTests.cs b/backend/tests/Squidex.Infrastructure.Tests/States/PersistenceEventSourcingTests.cs index 02761c9e6..f640b0349 100644 --- a/backend/tests/Squidex.Infrastructure.Tests/States/PersistenceEventSourcingTests.cs +++ b/backend/tests/Squidex.Infrastructure.Tests/States/PersistenceEventSourcingTests.cs @@ -65,7 +65,7 @@ public class PersistenceEventSourcingTests { var storedEvent = new StoredEvent("1", "1", 0, new EventData("Type", new EnvelopeHeaders(), "Payload")); - A.CallTo(() => eventStore.QueryAsync(key.ToString(), -1, A._)) + A.CallTo(() => eventStore.QueryStreamAsync(key.ToString(), -1, A._)) .Returns(new List { storedEvent }); A.CallTo(() => eventFormatter.ParseIfKnown(storedEvent)) @@ -96,7 +96,7 @@ public class PersistenceEventSourcingTests Assert.False(persistence.IsSnapshotStale); - A.CallTo(() => eventStore.QueryAsync(key.ToString(), 2, A._)) + A.CallTo(() => eventStore.QueryStreamAsync(key.ToString(), 2, A._)) .MustHaveHappened(); } @@ -116,7 +116,7 @@ public class PersistenceEventSourcingTests Assert.True(persistence.IsSnapshotStale); - A.CallTo(() => eventStore.QueryAsync(key.ToString(), 1, A._)) + A.CallTo(() => eventStore.QueryStreamAsync(key.ToString(), 1, A._)) .MustHaveHappened(); } @@ -327,7 +327,7 @@ public class PersistenceEventSourcingTests await persistence.DeleteAsync(); - A.CallTo(() => eventStore.DeleteStreamAsync(key.ToString(), A._)) + A.CallTo(() => eventStore.DeleteAsync(StreamFilter.Name(key.ToString()), A._)) .MustHaveHappened(); A.CallTo(() => snapshotStore.RemoveAsync(key, A._)) @@ -341,7 +341,7 @@ public class PersistenceEventSourcingTests await persistence.DeleteAsync(); - A.CallTo(() => eventStore.DeleteStreamAsync(key.ToString(), A._)) + A.CallTo(() => eventStore.DeleteAsync(StreamFilter.Name(key.ToString()), A._)) .MustHaveHappened(); A.CallTo(() => snapshotStore.RemoveAsync(key, A._)) @@ -382,7 +382,7 @@ public class PersistenceEventSourcingTests i++; } - A.CallTo(() => eventStore.QueryAsync(key.ToString(), readPosition, A._)) + A.CallTo(() => eventStore.QueryStreamAsync(key.ToString(), readPosition, A._)) .Returns(eventsStored); } } diff --git a/backend/tests/Squidex.Infrastructure.Tests/States/PersistenceSnapshotTests.cs b/backend/tests/Squidex.Infrastructure.Tests/States/PersistenceSnapshotTests.cs index 64e634bfe..f77683b88 100644 --- a/backend/tests/Squidex.Infrastructure.Tests/States/PersistenceSnapshotTests.cs +++ b/backend/tests/Squidex.Infrastructure.Tests/States/PersistenceSnapshotTests.cs @@ -162,7 +162,7 @@ public class PersistenceSnapshotTests await persistence.DeleteAsync(); - A.CallTo(() => eventStore.DeleteStreamAsync(A._, A._)) + A.CallTo(() => eventStore.DeleteAsync(A._, A._)) .MustNotHaveHappened(); A.CallTo(() => snapshotStore.RemoveAsync(key, A._)) diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js index a8f1ac994..44e04d120 100644 --- a/frontend/.eslintrc.js +++ b/frontend/.eslintrc.js @@ -6,7 +6,9 @@ module.exports = { "node": true }, "extends": [ - "airbnb-typescript/base" + "airbnb-typescript/base", + "plugin:@angular-eslint/recommended", + "plugin:@angular-eslint/template/process-inline-templates" ], "parser": "@typescript-eslint/parser", "parserOptions": { @@ -19,6 +21,25 @@ module.exports = { ], "rules": { "deprecation/deprecation": "warn", + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "sqx", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "sqx", + "style": "kebab-case" + } + ], + "@angular-eslint/use-lifecycle-interface": [ + "off" + ], "@typescript-eslint/dot-notation": "off", "@typescript-eslint/indent": "off", "@typescript-eslint/lines-between-class-members": "off", diff --git a/frontend/angular.json b/frontend/angular.json index c4f54c5b0..ab46f38fb 100644 --- a/frontend/angular.json +++ b/frontend/angular.json @@ -154,11 +154,23 @@ "compodoc": false, "outputDir": "storybook-static" } + }, + "lint": { + "builder": "@angular-eslint/builder:lint", + "options": { + "lintFilePatterns": [ + "src/**/*.ts", + "src/**/*.html" + ] + } } } } }, "cli": { - "analytics": "a157454d-c7c0-4947-986a-982746edc974" + "analytics": "a157454d-c7c0-4947-986a-982746edc974", + "schematicCollections": [ + "@angular-eslint/schematics" + ] } -} \ No newline at end of file +} diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 492291d75..7bf318515 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -37,7 +37,7 @@ "date-fns": "2.30.0", "font-awesome": "4.7.0", "graphiql": "3.0.5", - "graphql": "16.7.1", + "graphql": "16.8.1", "graphql-ws": "^5.14.0", "image-focus": "1.2.1", "keycharm": "0.4.0", @@ -59,7 +59,6 @@ "rxjs": "7.8.1", "simplemde": "1.11.2", "slugify": "1.6.6", - "tinymce": "5.10.2", "tslib": "2.6.1", "tui-calendar": "^1.15.3", "typemoq": "^2.1.0", @@ -67,11 +66,18 @@ "vis-data": "7.1.6", "vis-network": "9.1.6", "vis-util": "5.0.3", + "y-protocols": "^1.0.6", + "y-websocket": "^1.5.0", "zone.js": "0.13.1" }, "devDependencies": { "@angular-builders/custom-webpack": "^16.0.0", "@angular-devkit/build-angular": "^16.1.7", + "@angular-eslint/builder": "16.2.0", + "@angular-eslint/eslint-plugin": "16.2.0", + "@angular-eslint/eslint-plugin-template": "16.2.0", + "@angular-eslint/schematics": "16.2.0", + "@angular-eslint/template-parser": "16.2.0", "@angular/cli": "^16.1.7", "@angular/compiler": "^16.1.8", "@angular/compiler-cli": "^16.1.8", @@ -95,14 +101,13 @@ "@types/react-dom": "18.2.7", "@types/simplemde": "1.11.8", "@types/tapable": "2.2.3", - "@types/tinymce": "4.6.5", "@types/ws": "8.5.5", - "@typescript-eslint/eslint-plugin": "6.2.1", - "@typescript-eslint/parser": "6.2.1", + "@typescript-eslint/eslint-plugin": "5.62.0", + "@typescript-eslint/parser": "5.62.0", "@webcomponents/custom-elements": "^1.6.0", "babel-loader": "^9.1.3", "copy-webpack-plugin": "11.0.0", - "eslint": "8.46.0", + "eslint": "^8.49.0", "eslint-config-airbnb-typescript": "17.1.0", "eslint-plugin-deprecation": "^1.5.0", "eslint-plugin-import": "2.28.0", @@ -316,7 +321,7 @@ "vite": "4.3.9", "webpack": "5.86.0", "webpack-dev-middleware": "6.1.1", - "webpack-dev-server": "4.15.0", + "webpack-dev-server": "4.15.1", "webpack-merge": "5.9.0", "webpack-subresource-integrity": "5.1.0" }, @@ -912,12 +917,6 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, - "node_modules/@angular-devkit/build-angular/node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "dev": true - }, "node_modules/@angular-devkit/build-angular/node_modules/magic-string": { "version": "0.30.0", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz", @@ -1226,12 +1225,6 @@ } } }, - "node_modules/@angular-devkit/core/node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "dev": true - }, "node_modules/@angular-devkit/core/node_modules/source-map": { "version": "0.7.4", "dev": true, @@ -1258,12 +1251,6 @@ "yarn": ">= 1.13.0" } }, - "node_modules/@angular-devkit/schematics/node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "dev": true - }, "node_modules/@angular-devkit/schematics/node_modules/magic-string": { "version": "0.30.0", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.0.tgz", @@ -1276,6 +1263,150 @@ "node": ">=12" } }, + "node_modules/@angular-eslint/builder": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-16.2.0.tgz", + "integrity": "sha512-SZjXOi3YIjuX2CocuRsR2QH6k1ca9lRO6IMm0YIYMmBPFCRP2KFHkL6aQnXM6DSaymQNN2TXfpuvUd45NxhU1w==", + "dev": true, + "dependencies": { + "@nx/devkit": "16.5.1", + "nx": "16.5.1" + }, + "peerDependencies": { + "eslint": "^7.20.0 || ^8.0.0", + "typescript": "*" + } + }, + "node_modules/@angular-eslint/bundled-angular-compiler": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-16.2.0.tgz", + "integrity": "sha512-ct9orDYxkMl2+uvM7UBfgV28Dq57V4dEs+Drh7cD673JIMa6sXbgmd0QEtm8W3cmyK/jcTzmuoufxbH7hOxd6g==", + "dev": true + }, + "node_modules/@angular-eslint/eslint-plugin": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-16.2.0.tgz", + "integrity": "sha512-zdiAIox1T+B71HL+A8m+1jWdU34nvPGLhCRw/uZNwHzknsF4tYzNQ9W7T/SC/g/2s1yT2yNosEVNJSGSFvunJg==", + "dev": true, + "dependencies": { + "@angular-eslint/utils": "16.2.0", + "@typescript-eslint/utils": "5.62.0" + }, + "peerDependencies": { + "eslint": "^7.20.0 || ^8.0.0", + "typescript": "*" + } + }, + "node_modules/@angular-eslint/eslint-plugin-template": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-16.2.0.tgz", + "integrity": "sha512-YFdQ6hHX6NlQj0lfogZwfyKjU8pqkJU+Zsk0ehjlXP8VfKFVmDeQT5/Xr6Df9C8pveC3hvq6Jgd8vo67S9Enxg==", + "dev": true, + "dependencies": { + "@angular-eslint/bundled-angular-compiler": "16.2.0", + "@angular-eslint/utils": "16.2.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "aria-query": "5.3.0", + "axobject-query": "3.2.1" + }, + "peerDependencies": { + "eslint": "^7.20.0 || ^8.0.0", + "typescript": "*" + } + }, + "node_modules/@angular-eslint/eslint-plugin-template/node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/@angular-eslint/schematics": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-16.2.0.tgz", + "integrity": "sha512-2JUVR7hAKx37mgWeDjvyWEMH5uSeeksYuaQT5wwlgIzgrO4BNFuqs6Rgyp2jiYa7BFMX/qHULSa+bSq5J5ceEA==", + "dev": true, + "dependencies": { + "@angular-eslint/eslint-plugin": "16.2.0", + "@angular-eslint/eslint-plugin-template": "16.2.0", + "@nx/devkit": "16.5.1", + "ignore": "5.2.4", + "nx": "16.5.1", + "strip-json-comments": "3.1.1", + "tmp": "0.2.1" + }, + "peerDependencies": { + "@angular/cli": ">= 16.0.0 < 17.0.0" + } + }, + "node_modules/@angular-eslint/schematics/node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/@angular-eslint/template-parser": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-16.2.0.tgz", + "integrity": "sha512-v2jVKTy2wN7iM9nHpBkxLn2wfL8jSl4IlPrXThIqj8No2VHtpLQZPKuXbGPUXQX05VS2Mj5feScQ36ZVGS8Rbw==", + "dev": true, + "dependencies": { + "@angular-eslint/bundled-angular-compiler": "16.2.0", + "eslint-scope": "^7.0.0" + }, + "peerDependencies": { + "eslint": "^7.20.0 || ^8.0.0", + "typescript": "*" + } + }, + "node_modules/@angular-eslint/template-parser/node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@angular-eslint/template-parser/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@angular-eslint/utils": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-16.2.0.tgz", + "integrity": "sha512-NxMRwnlIgzmbJQfWkfd9y3Sz0hzjFdK5LH44i+3D5NhpPdZ6SzwHAjMYWoYsmmNQX5tlDXoicYF9Mz9Wz8DJ/A==", + "dev": true, + "dependencies": { + "@angular-eslint/bundled-angular-compiler": "16.2.0", + "@typescript-eslint/utils": "5.62.0" + }, + "peerDependencies": { + "eslint": "^7.20.0 || ^8.0.0", + "typescript": "*" + } + }, "node_modules/@angular/animations": { "version": "16.1.8", "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-16.1.8.tgz", @@ -1352,12 +1483,6 @@ "yarn": ">= 1.13.0" } }, - "node_modules/@angular/cli/node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "dev": true - }, "node_modules/@angular/cli/node_modules/open": { "version": "8.4.2", "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", @@ -4562,9 +4687,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.1.tgz", - "integrity": "sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -4607,9 +4732,9 @@ "dev": true }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -4652,9 +4777,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.46.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.46.0.tgz", - "integrity": "sha512-a8TLtmPi8xzPkCbp/OGFUo5yhRkHM2Ko9kOWP4znJr0WAhWyThaw3PnwX4vOTWOAMsV2uRt32PPDcEz63esSaA==", + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.52.0.tgz", + "integrity": "sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4838,12 +4963,12 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", + "@humanwhocodes/object-schema": "^2.0.1", "debug": "^4.1.1", "minimatch": "^3.0.5" }, @@ -4864,9 +4989,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, "node_modules/@iharbeck/ngx-virtual-scroller": { @@ -5592,147 +5717,401 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@popperjs/core": { - "version": "2.11.8", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", - "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", - "peer": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/popperjs" - } - }, - "node_modules/@radix-ui/number": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.1.tgz", - "integrity": "sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==", + "node_modules/@nrwl/devkit": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@nrwl/devkit/-/devkit-16.5.1.tgz", + "integrity": "sha512-NB+DE/+AFJ7lKH/WBFyatJEhcZGj25F24ncDkwjZ6MzEiSOGOJS0LaV/R+VUsmS5EHTPXYOpn3zHWWAcJhyOmA==", "dev": true, "dependencies": { - "@babel/runtime": "^7.13.10" + "@nx/devkit": "16.5.1" } }, - "node_modules/@radix-ui/primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz", - "integrity": "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==", + "node_modules/@nrwl/tao": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@nrwl/tao/-/tao-16.5.1.tgz", + "integrity": "sha512-x+gi/fKdM6uQNIti9exFlm3V5LBP3Y8vOEziO42HdOigyrXa0S0HD2WMpccmp6PclYKhwEDUjKJ39xh5sdh4Ig==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.13.10" + "nx": "16.5.1" + }, + "bin": { + "tao": "index.js" } }, - "node_modules/@radix-ui/react-arrow": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.0.3.tgz", - "integrity": "sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==", + "node_modules/@nx/devkit": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-16.5.1.tgz", + "integrity": "sha512-T1acZrVVmJw/sJ4PIGidCBYBiBqlg/jT9e8nIGXLSDS20xcLvfo4zBQf8UZLrmHglnwwpDpOWuVJCp2rYA5aDg==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-primitive": "1.0.3" + "@nrwl/devkit": "16.5.1", + "ejs": "^3.1.7", + "ignore": "^5.0.4", + "semver": "7.5.3", + "tmp": "~0.2.1", + "tslib": "^2.3.0" }, "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } + "nx": ">= 15 <= 17" } }, - "node_modules/@radix-ui/react-collection": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.0.3.tgz", - "integrity": "sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==", + "node_modules/@nx/devkit/node_modules/semver": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-slot": "1.0.2" + "lru-cache": "^6.0.0" }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "bin": { + "semver": "bin/semver.js" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } + "engines": { + "node": ">=10" } }, - "node_modules/@radix-ui/react-compose-refs": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz", - "integrity": "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==", + "node_modules/@nx/devkit/node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" + "rimraf": "^3.0.0" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "engines": { + "node": ">=8.17.0" } }, - "node_modules/@radix-ui/react-context": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.1.tgz", - "integrity": "sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "node_modules/@nx/nx-darwin-arm64": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-16.5.1.tgz", + "integrity": "sha512-q98TFI4B/9N9PmKUr1jcbtD4yAFs1HfYd9jUXXTQOlfO9SbDjnrYJgZ4Fp9rMNfrBhgIQ4x1qx0AukZccKmH9Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" } }, - "node_modules/@radix-ui/react-dialog": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.4.tgz", - "integrity": "sha512-hJtRy/jPULGQZceSAP2Re6/4NpKo8im6V8P2hUqZsdFiSL8l35kYsw3qbRI6Ay5mQd2+wlLqje770eq+RJ3yZg==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-dismissable-layer": "1.0.4", - "@radix-ui/react-focus-guards": "1.0.1", - "@radix-ui/react-focus-scope": "1.0.3", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-portal": "1.0.3", - "@radix-ui/react-presence": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-slot": "1.0.2", - "@radix-ui/react-use-controllable-state": "1.0.1", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.5.5" - }, + "node_modules/@nx/nx-darwin-x64": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-16.5.1.tgz", + "integrity": "sha512-j9HmL1l8k7EVJ3eOM5y8COF93gqrydpxCDoz23ZEtsY+JHY77VAiRQsmqBgEx9GGA2dXi9VEdS67B0+1vKariw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-freebsd-x64": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-16.5.1.tgz", + "integrity": "sha512-CXSPT01aVS869tvCCF2tZ7LnCa8l41wJ3mTVtWBkjmRde68E5Up093hklRMyXb3kfiDYlfIKWGwrV4r0eH6x1A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm-gnueabihf": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-16.5.1.tgz", + "integrity": "sha512-BhrumqJSZCWFfLFUKl4CAUwR0Y0G2H5EfFVGKivVecEQbb+INAek1aa6c89evg2/OvetQYsJ+51QknskwqvLsA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm64-gnu": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-16.5.1.tgz", + "integrity": "sha512-x7MsSG0W+X43WVv7JhiSq2eKvH2suNKdlUHEG09Yt0vm3z0bhtym1UCMUg3IUAK7jy9hhLeDaFVFkC6zo+H/XQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-arm64-musl": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-16.5.1.tgz", + "integrity": "sha512-J+/v/mFjOm74I0PNtH5Ka+fDd+/dWbKhpcZ2R1/6b9agzZk+Ff/SrwJcSYFXXWKbPX+uQ4RcJoytT06Zs3s0ow==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-x64-gnu": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-16.5.1.tgz", + "integrity": "sha512-igooWJ5YxQ94Zft7IqgL+Lw0qHaY15Btw4gfK756g/YTYLZEt4tTvR1y6RnK/wdpE3sa68bFTLVBNCGTyiTiDQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-linux-x64-musl": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-16.5.1.tgz", + "integrity": "sha512-zF/exnPqFYbrLAduGhTmZ7zNEyADid2bzNQiIjJkh8Y6NpDwrQIwVIyvIxqynsjMrIs51kBH+8TUjKjj2Jgf5A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-win32-arm64-msvc": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-16.5.1.tgz", + "integrity": "sha512-qtqiLS9Y9TYyAbbpq58kRoOroko4ZXg5oWVqIWFHoxc5bGPweQSJCROEqd1AOl2ZDC6BxfuVHfhDDop1kK05WA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nx/nx-win32-x64-msvc": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.5.1.tgz", + "integrity": "sha512-kUJBLakK7iyA9WfsGGQBVennA4jwf5XIgm0lu35oMOphtZIluvzItMt0EYBmylEROpmpEIhHq0P6J9FA+WH0Rg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.0.4.tgz", + "integrity": "sha512-cTDi+FUDBIUOBKEtj+nhiJ71AZVlkAsQFuGQTun5tV9mwQBQgZvhCzG+URPQc8myeN32yRVZEfVAPCs1RW+Jvg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "node-addon-api": "^3.2.1", + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/node-gyp-build": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.1.tgz", + "integrity": "sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==", + "dev": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@radix-ui/number": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.1.tgz", + "integrity": "sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@radix-ui/primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz", + "integrity": "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.0.3.tgz", + "integrity": "sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.0.3.tgz", + "integrity": "sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz", + "integrity": "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.1.tgz", + "integrity": "sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.4.tgz", + "integrity": "sha512-hJtRy/jPULGQZceSAP2Re6/4NpKo8im6V8P2hUqZsdFiSL8l35kYsw3qbRI6Ay5mQd2+wlLqje770eq+RJ3yZg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.4", + "@radix-ui/react-focus-guards": "1.0.1", + "@radix-ui/react-focus-scope": "1.0.3", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-portal": "1.0.3", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-controllable-state": "1.0.1", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" + }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", @@ -6321,12 +6700,6 @@ "yarn": ">= 1.13.0" } }, - "node_modules/@schematics/angular/node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "dev": true - }, "node_modules/@sigstore/bundle": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-1.0.0.tgz", @@ -13586,14 +13959,6 @@ "integrity": "sha512-9YHUdvuNDDRJYXZwHqSsO72Ok0vmqoJbNn73ttyITQp/VA60SarnZ+MPLD37rJAhVoKp+9BWOvJP5tHIRfZylQ==", "dev": true }, - "node_modules/@types/jquery": { - "version": "3.5.11", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/sizzle": "*" - } - }, "node_modules/@types/json-schema": { "version": "7.0.12", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", @@ -13775,11 +14140,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/sizzle": { - "version": "2.3.3", - "dev": true, - "license": "MIT" - }, "node_modules/@types/sockjs": { "version": "0.3.33", "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz", @@ -13805,14 +14165,6 @@ "@types/estree": "*" } }, - "node_modules/@types/tinymce": { - "version": "4.6.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/jquery": "*" - } - }, "node_modules/@types/unist": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.7.tgz", @@ -13849,34 +14201,32 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.1.tgz", - "integrity": "sha512-iZVM/ALid9kO0+I81pnp1xmYiFyqibAHzrqX4q5YvvVEyJqY+e6rfTXSCsc2jUxGNqJqTfFSSij/NFkZBiBzLw==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", "dev": true, "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.2.1", - "@typescript-eslint/type-utils": "6.2.1", - "@typescript-eslint/utils": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1", + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", "debug": "^4.3.4", "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", + "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "semver": "^7.3.7", + "tsutils": "^3.21.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -13885,26 +14235,25 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.2.1.tgz", - "integrity": "sha512-Ld+uL1kYFU8e6btqBFpsHkwQ35rw30IWpdQxgOqOh4NfxSDH6uCkah1ks8R/RgQqI5hHPXMaLy9fbFseIe+dIg==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.2.1", - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/typescript-estree": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", "debug": "^4.3.4" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -13913,16 +14262,16 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.2.1.tgz", - "integrity": "sha512-UCqBF9WFqv64xNsIEPfBtenbfodPXsJ3nPAr55mGPkQIkiQvgoWNo+astj9ZUfJfVKiYgAZDMnM6dIpsxUMp3Q==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1" + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", @@ -13930,25 +14279,25 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.2.1.tgz", - "integrity": "sha512-fTfCgomBMIgu2Dh2Or3gMYgoNAnQm3RLtRp+jP7A8fY+LJ2+9PNpi5p6QB5C4RSP+U3cjI0vDlI3mspAkpPVbQ==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.2.1", - "@typescript-eslint/utils": "6.2.1", + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" + "tsutils": "^3.21.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "*" }, "peerDependenciesMeta": { "typescript": { @@ -13957,12 +14306,12 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.2.1.tgz", - "integrity": "sha512-528bGcoelrpw+sETlyM91k51Arl2ajbNT9L4JwoXE2dvRe1yd8Q64E4OL7vHYw31mlnVsf+BeeLyAZUEQtqahQ==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "dev": true, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", @@ -13970,21 +14319,21 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.2.1.tgz", - "integrity": "sha512-G+UJeQx9AKBHRQBpmvr8T/3K5bJa485eu+4tQBxFq0KoT22+jJyzo1B50JDT9QdC1DEmWQfdKsa8ybiNWYsi0Q==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/visitor-keys": "6.2.1", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "semver": "^7.3.7", + "tsutils": "^3.21.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", @@ -13997,47 +14346,54 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.2.1.tgz", - "integrity": "sha512-eBIXQeupYmxVB6S7x+B9SdBeB6qIdXKjgQBge2J+Ouv8h9Cxm5dHf/gfAZA6dkMaag+03HdbVInuXMmqFB/lKQ==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", "dev": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.2.1", - "@typescript-eslint/types": "6.2.1", - "@typescript-eslint/typescript-estree": "6.2.1", - "semver": "^7.5.4" + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.2.1.tgz", - "integrity": "sha512-iTN6w3k2JEZ7cyVdZJTVJx2Lv7t6zFA8DCrJEHD2mwfc16AEvvBWVhbFh34XyG2NORCd0viIgQY1+u7kPI0WpA==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.2.1", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/@videojs/http-streaming": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-3.0.2.tgz", @@ -14308,6 +14664,37 @@ "dev": true, "license": "BSD-2-Clause" }, + "node_modules/@yarnpkg/parsers": { + "version": "3.0.0-rc.46", + "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.0-rc.46.tgz", + "integrity": "sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q==", + "dev": true, + "dependencies": { + "js-yaml": "^3.10.0", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=14.15.0" + } + }, + "node_modules/@zkochan/js-yaml": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@zkochan/js-yaml/-/js-yaml-0.0.6.tgz", + "integrity": "sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@zkochan/js-yaml/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "node_modules/abab": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", @@ -14320,6 +14707,22 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true }, + "node_modules/abstract-leveldown": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", + "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", + "optional": true, + "dependencies": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/accepts": { "version": "1.3.8", "dev": true, @@ -14899,7 +15302,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true + "devOptional": true }, "node_modules/asynckit": { "version": "0.4.0", @@ -14928,6 +15331,31 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.1.tgz", + "integrity": "sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==", + "dev": true, + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axios/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/axobject-query": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", @@ -15187,7 +15615,7 @@ }, "node_modules/base64-js": { "version": "1.5.1", - "dev": true, + "devOptional": true, "funding": [ { "type": "github", @@ -15494,7 +15922,7 @@ }, "node_modules/buffer": { "version": "5.7.1", - "dev": true, + "devOptional": true, "funding": [ { "type": "github", @@ -17070,6 +17498,19 @@ "clone": "^1.0.2" } }, + "node_modules/deferred-leveldown": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz", + "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==", + "optional": true, + "dependencies": { + "abstract-leveldown": "~6.2.1", + "inherits": "^2.0.3" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/define-lazy-prop": { "version": "2.0.0", "dev": true, @@ -17370,6 +17811,15 @@ "tslib": "^2.0.3" } }, + "node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/duplexer": { "version": "0.1.2", "dev": true, @@ -17504,6 +17954,21 @@ "iconv-lite": "^0.6.2" } }, + "node_modules/encoding-down": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz", + "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==", + "optional": true, + "dependencies": { + "abstract-leveldown": "^6.2.1", + "inherits": "^2.0.3", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/encoding/node_modules/iconv-lite": { "version": "0.6.3", "dev": true, @@ -17585,6 +18050,18 @@ "node": ">=10.13.0" } }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/ent": { "version": "2.2.0", "dev": true, @@ -17627,7 +18104,6 @@ }, "node_modules/errno": { "version": "0.1.8", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -18322,18 +18798,19 @@ } }, "node_modules/eslint": { - "version": "8.46.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.46.0.tgz", - "integrity": "sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg==", + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.52.0.tgz", + "integrity": "sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.1", - "@eslint/js": "^8.46.0", - "@humanwhocodes/config-array": "^0.11.10", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "8.52.0", + "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -18341,7 +18818,7 @@ "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.2", + "eslint-visitor-keys": "^3.4.3", "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", @@ -18439,142 +18916,42 @@ "node_modules/eslint-module-utils": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", - "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", - "dev": true, - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-deprecation": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-deprecation/-/eslint-plugin-deprecation-1.5.0.tgz", - "integrity": "sha512-mRcssI/tLROueBQ6yf4LnnGTijbMsTCPIpbRbPj5R5wGYVCpk1zDmAS0SEkgcUDXOPc22qMNFR24Qw7vSPrlTA==", - "dev": true, - "dependencies": { - "@typescript-eslint/utils": "^5.57.0", - "tslib": "^2.3.1", - "tsutils": "^3.21.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0", - "typescript": "^3.7.5 || ^4.0.0 || ^5.0.0" - } - }, - "node_modules/eslint-plugin-deprecation/node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-deprecation/node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-deprecation/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "debug": "^3.2.7" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=4" }, "peerDependenciesMeta": { - "typescript": { + "eslint": { "optional": true } } }, - "node_modules/eslint-plugin-deprecation/node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "ms": "^2.1.1" } }, - "node_modules/eslint-plugin-deprecation/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "node_modules/eslint-plugin-deprecation": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-deprecation/-/eslint-plugin-deprecation-1.5.0.tgz", + "integrity": "sha512-mRcssI/tLROueBQ6yf4LnnGTijbMsTCPIpbRbPj5R5wGYVCpk1zDmAS0SEkgcUDXOPc22qMNFR24Qw7vSPrlTA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "@typescript-eslint/utils": "^5.57.0", + "tslib": "^2.3.1", + "tsutils": "^3.21.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0", + "typescript": "^3.7.5 || ^4.0.0 || ^5.0.0" } }, "node_modules/eslint-plugin-import": { @@ -18716,106 +19093,6 @@ "eslint": ">=6" } }, - "node_modules/eslint-plugin-storybook/node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-storybook/node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-storybook/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-storybook/node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/eslint-plugin-storybook/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/eslint-scope": { "version": "5.1.1", "dev": true, @@ -18829,9 +19106,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz", - "integrity": "sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -19735,6 +20012,15 @@ "node": ">=8" } }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, "node_modules/flat-cache": { "version": "3.0.4", "dev": true, @@ -19762,7 +20048,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.14.6", + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", + "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", "dev": true, "funding": [ { @@ -19770,7 +20058,6 @@ "url": "https://github.com/sponsors/RubenVerborgh" } ], - "license": "MIT", "engines": { "node": ">=4.0" }, @@ -20460,9 +20747,9 @@ } }, "node_modules/graphql": { - "version": "16.7.1", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.7.1.tgz", - "integrity": "sha512-DRYR9tf+UGU0KOsMcKAlXeFfX89UiiIZ0dRU3mR0yJfu6OjZqUcp68NnFLnqQU5RexygFoDy1EW+ccOYcPfmHg==", + "version": "16.8.1", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.1.tgz", + "integrity": "sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==", "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } @@ -21021,7 +21308,7 @@ }, "node_modules/ieee754": { "version": "1.2.1", - "dev": true, + "devOptional": true, "funding": [ { "type": "github", @@ -21103,6 +21390,12 @@ "node": ">=0.10.0" } }, + "node_modules/immediate": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", + "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", + "optional": true + }, "node_modules/immutable": { "version": "4.0.0", "dev": true, @@ -21169,7 +21462,7 @@ }, "node_modules/inherits": { "version": "2.0.4", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/ini": { @@ -21797,6 +22090,15 @@ "node": ">=0.10.0" } }, + "node_modules/isomorphic.js": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/isomorphic.js/-/isomorphic.js-0.2.5.tgz", + "integrity": "sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==", + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + } + }, "node_modules/istanbul-lib-coverage": { "version": "3.2.0", "dev": true, @@ -22510,6 +22812,12 @@ "node": ">=6" } }, + "node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -22875,7 +23183,140 @@ "dev": true, "optional": true, "engines": { - "node": ">=0.10.0" + "node": ">=0.10.0" + } + }, + "node_modules/level": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/level/-/level-6.0.1.tgz", + "integrity": "sha512-psRSqJZCsC/irNhfHzrVZbmPYXDcEYhA5TVNwr+V92jF44rbf86hqGp8fiT702FyiArScYIlPSBTDUASCVNSpw==", + "optional": true, + "dependencies": { + "level-js": "^5.0.0", + "level-packager": "^5.1.0", + "leveldown": "^5.4.0" + }, + "engines": { + "node": ">=8.6.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/level" + } + }, + "node_modules/level-codec": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz", + "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==", + "optional": true, + "dependencies": { + "buffer": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-concat-iterator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz", + "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz", + "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", + "optional": true, + "dependencies": { + "errno": "~0.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-iterator-stream": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz", + "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==", + "optional": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.4.0", + "xtend": "^4.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-js": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/level-js/-/level-js-5.0.2.tgz", + "integrity": "sha512-SnBIDo2pdO5VXh02ZmtAyPP6/+6YTJg2ibLtl9C34pWvmtMEmRTWpra+qO/hifkUtBTOtfx6S9vLDjBsBK4gRg==", + "optional": true, + "dependencies": { + "abstract-leveldown": "~6.2.3", + "buffer": "^5.5.0", + "inherits": "^2.0.3", + "ltgt": "^2.1.2" + } + }, + "node_modules/level-packager": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-5.1.1.tgz", + "integrity": "sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==", + "optional": true, + "dependencies": { + "encoding-down": "^6.3.0", + "levelup": "^4.3.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-supports": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz", + "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==", + "optional": true, + "dependencies": { + "xtend": "^4.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/leveldown": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-5.6.0.tgz", + "integrity": "sha512-iB8O/7Db9lPaITU1aA2txU/cBEXAt4vWwKQRrrWuS6XDgbP4QZGj9BL2aNbwb002atoQ/lIotJkfyzz+ygQnUQ==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "abstract-leveldown": "~6.2.1", + "napi-macros": "~2.0.0", + "node-gyp-build": "~4.1.0" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/levelup": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz", + "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==", + "optional": true, + "dependencies": { + "deferred-leveldown": "~5.3.0", + "level-errors": "~2.0.0", + "level-iterator-stream": "~4.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" } }, "node_modules/leven": { @@ -22900,6 +23341,25 @@ "node": ">= 0.8.0" } }, + "node_modules/lib0": { + "version": "0.2.86", + "resolved": "https://registry.npmjs.org/lib0/-/lib0-0.2.86.tgz", + "integrity": "sha512-kxigQTM4Q7NwJkEgdqQvU21qiR37twcqqLmh+/SbiGbRLfPlLVbHyY9sWp7PwXh0Xus9ELDSjsUOwcrdt5yZ4w==", + "dependencies": { + "isomorphic.js": "^0.2.4" + }, + "bin": { + "0gentesthtml": "bin/gentesthtml.js", + "0serve": "bin/0serve.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + } + }, "node_modules/license-webpack-plugin": { "version": "4.0.2", "dev": true, @@ -22969,8 +23429,7 @@ "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, "node_modules/lodash.merge": { "version": "4.6.2", @@ -23123,6 +23582,12 @@ "node": ">=10" } }, + "node_modules/ltgt": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", + "integrity": "sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA==", + "optional": true + }, "node_modules/lunr": { "version": "2.3.9", "dev": true, @@ -24156,6 +24621,12 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/napi-macros": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz", + "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==", + "optional": true + }, "node_modules/natural-compare": { "version": "1.4.0", "dev": true, @@ -24309,6 +24780,12 @@ "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", "dev": true }, + "node_modules/node-addon-api": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", + "dev": true + }, "node_modules/node-dir": { "version": "0.1.17", "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz", @@ -24380,6 +24857,17 @@ "node": "^12.13 || ^14.13 || >=16" } }, + "node_modules/node-gyp-build": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.1.1.tgz", + "integrity": "sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ==", + "optional": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, "node_modules/node-gyp/node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -24469,175 +24957,428 @@ "npm-normalize-package-bin": "^3.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-install-checks": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.1.1.tgz", + "integrity": "sha512-dH3GmQL4vsPtld59cOn8uY0iOqRmqKvV+DLGwNXV/Q7MDgD2QfOADWd/mFXcIE5LVhYYGjA3baz6W9JneqnuCw==", + "dev": true, + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-package-arg": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz", + "integrity": "sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^6.0.0", + "proc-log": "^3.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-package-arg/node_modules/hosted-git-info": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", + "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "dev": true, + "dependencies": { + "lru-cache": "^7.5.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-package-arg/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/npm-packlist": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-7.0.4.tgz", + "integrity": "sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==", + "dev": true, + "dependencies": { + "ignore-walk": "^6.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-8.0.1.tgz", + "integrity": "sha512-mRtvlBjTsJvfCCdmPtiu2bdlx8d/KXtF7yNXNWe7G0Z36qWA9Ny5zXsI2PfBZEv7SXgoxTmNaTzGSbbzDZChoA==", + "dev": true, + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^10.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-registry-fetch": { + "version": "14.0.5", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz", + "integrity": "sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA==", + "dev": true, + "dependencies": { + "make-fetch-happen": "^11.0.0", + "minipass": "^5.0.0", + "minipass-fetch": "^3.0.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.1.2", + "npm-package-arg": "^10.0.0", + "proc-log": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npmlog": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "dev": true, + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/npmlog/node_modules/are-we-there-yet": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "dev": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/nth-check": { + "version": "2.0.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/nullthrows": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==" + }, + "node_modules/nx": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/nx/-/nx-16.5.1.tgz", + "integrity": "sha512-I3hJRE4hG7JWAtncWwDEO3GVeGPpN0TtM8xH5ArZXyDuVeTth/i3TtJzdDzqXO1HHtIoAQN0xeq4n9cLuMil5g==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@nrwl/tao": "16.5.1", + "@parcel/watcher": "2.0.4", + "@yarnpkg/lockfile": "^1.1.0", + "@yarnpkg/parsers": "3.0.0-rc.46", + "@zkochan/js-yaml": "0.0.6", + "axios": "^1.0.0", + "chalk": "^4.1.0", + "cli-cursor": "3.1.0", + "cli-spinners": "2.6.1", + "cliui": "^7.0.2", + "dotenv": "~10.0.0", + "enquirer": "~2.3.6", + "fast-glob": "3.2.7", + "figures": "3.2.0", + "flat": "^5.0.2", + "fs-extra": "^11.1.0", + "glob": "7.1.4", + "ignore": "^5.0.4", + "js-yaml": "4.1.0", + "jsonc-parser": "3.2.0", + "lines-and-columns": "~2.0.3", + "minimatch": "3.0.5", + "npm-run-path": "^4.0.1", + "open": "^8.4.0", + "semver": "7.5.3", + "string-width": "^4.2.3", + "strong-log-transformer": "^2.1.0", + "tar-stream": "~2.2.0", + "tmp": "~0.2.1", + "tsconfig-paths": "^4.1.2", + "tslib": "^2.3.0", + "v8-compile-cache": "2.3.0", + "yargs": "^17.6.2", + "yargs-parser": "21.1.1" + }, + "bin": { + "nx": "bin/nx.js" + }, + "optionalDependencies": { + "@nx/nx-darwin-arm64": "16.5.1", + "@nx/nx-darwin-x64": "16.5.1", + "@nx/nx-freebsd-x64": "16.5.1", + "@nx/nx-linux-arm-gnueabihf": "16.5.1", + "@nx/nx-linux-arm64-gnu": "16.5.1", + "@nx/nx-linux-arm64-musl": "16.5.1", + "@nx/nx-linux-x64-gnu": "16.5.1", + "@nx/nx-linux-x64-musl": "16.5.1", + "@nx/nx-win32-arm64-msvc": "16.5.1", + "@nx/nx-win32-x64-msvc": "16.5.1" + }, + "peerDependencies": { + "@swc-node/register": "^1.4.2", + "@swc/core": "^1.2.173" + }, + "peerDependenciesMeta": { + "@swc-node/register": { + "optional": true + }, + "@swc/core": { + "optional": true + } + } + }, + "node_modules/nx/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/nx/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/nx/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/npm-install-checks": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.1.1.tgz", - "integrity": "sha512-dH3GmQL4vsPtld59cOn8uY0iOqRmqKvV+DLGwNXV/Q7MDgD2QfOADWd/mFXcIE5LVhYYGjA3baz6W9JneqnuCw==", + "node_modules/nx/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { - "semver": "^7.1.1" + "color-name": "~1.1.4" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=7.0.0" } }, - "node_modules/npm-normalize-package-bin": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", - "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } + "node_modules/nx/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, - "node_modules/npm-package-arg": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-10.1.0.tgz", - "integrity": "sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==", + "node_modules/nx/node_modules/fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", "dev": true, "dependencies": { - "hosted-git-info": "^6.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/npm-package-arg/node_modules/hosted-git-info": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.1.tgz", - "integrity": "sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==", + "node_modules/nx/node_modules/glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", "dev": true, "dependencies": { - "lru-cache": "^7.5.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "*" } }, - "node_modules/npm-package-arg/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "node_modules/nx/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { - "node": ">=12" + "node": ">=8" } }, - "node_modules/npm-packlist": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-7.0.4.tgz", - "integrity": "sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==", + "node_modules/nx/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "dependencies": { - "ignore-walk": "^6.0.0" + "argparse": "^2.0.1" }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/npm-pick-manifest": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-8.0.1.tgz", - "integrity": "sha512-mRtvlBjTsJvfCCdmPtiu2bdlx8d/KXtF7yNXNWe7G0Z36qWA9Ny5zXsI2PfBZEv7SXgoxTmNaTzGSbbzDZChoA==", + "node_modules/nx/node_modules/lines-and-columns": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.3.tgz", + "integrity": "sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==", "dev": true, - "dependencies": { - "npm-install-checks": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "npm-package-arg": "^10.0.0", - "semver": "^7.3.5" - }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, - "node_modules/npm-registry-fetch": { - "version": "14.0.5", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz", - "integrity": "sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA==", + "node_modules/nx/node_modules/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", "dev": true, "dependencies": { - "make-fetch-happen": "^11.0.0", - "minipass": "^5.0.0", - "minipass-fetch": "^3.0.0", - "minipass-json-stream": "^1.0.1", - "minizlib": "^2.1.2", - "npm-package-arg": "^10.0.0", - "proc-log": "^3.0.0" + "brace-expansion": "^1.1.7" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-registry-fetch/node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "dev": true, - "engines": { - "node": ">=8" + "node": "*" } }, - "node_modules/npm-run-path": { - "version": "4.0.1", + "node_modules/nx/node_modules/semver": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dev": true, - "license": "MIT", "dependencies": { - "path-key": "^3.0.0" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/npmlog": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", - "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "node_modules/nx/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">=8" } }, - "node_modules/npmlog/node_modules/are-we-there-yet": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", - "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "node_modules/nx/node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", "dev": true, "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" + "rimraf": "^3.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">=8.17.0" } }, - "node_modules/nth-check": { - "version": "2.0.1", + "node_modules/nx/node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "boolbase": "^1.0.0" + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" + "engines": { + "node": ">=6" } }, - "node_modules/nullthrows": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", - "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==" - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -26012,7 +26753,6 @@ }, "node_modules/prr": { "version": "1.0.1", - "dev": true, "license": "MIT", "optional": true }, @@ -26588,7 +27328,7 @@ }, "node_modules/readable-stream": { "version": "3.6.0", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -28192,7 +28932,7 @@ }, "node_modules/string_decoder": { "version": "1.3.0", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" @@ -28200,7 +28940,7 @@ }, "node_modules/string_decoder/node_modules/safe-buffer": { "version": "5.2.1", - "dev": true, + "devOptional": true, "funding": [ { "type": "github", @@ -28355,6 +29095,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strong-log-transformer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz", + "integrity": "sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==", + "dev": true, + "dependencies": { + "duplexer": "^0.1.1", + "minimist": "^1.2.0", + "through": "^2.3.4" + }, + "bin": { + "sl-log-transformer": "bin/sl-log-transformer.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/style-mod": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.0.3.tgz", @@ -29111,11 +29868,6 @@ "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==", "dev": true }, - "node_modules/tinymce": { - "version": "5.10.2", - "resolved": "https://registry.npmjs.org/tinymce/-/tinymce-5.10.2.tgz", - "integrity": "sha512-5QhnZ6c8F28fYucLLc00MM37fZoAZ4g7QCYzwIl38i5TwJR5xGqzOv6YMideyLM4tytCzLCRwJoQen2LI66p5A==" - }, "node_modules/tmp": { "version": "0.0.33", "dev": true, @@ -29203,18 +29955,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ts-api-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz", - "integrity": "sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==", - "dev": true, - "engines": { - "node": ">=16.13.0" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, "node_modules/ts-dedent": { "version": "2.2.0", "dev": true, @@ -29895,7 +30635,7 @@ }, "node_modules/util-deprecate": { "version": "1.0.2", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/utila": { @@ -29918,6 +30658,12 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "dev": true, @@ -30229,9 +30975,9 @@ } }, "node_modules/webpack-dev-server": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.0.tgz", - "integrity": "sha512-HmNB5QeSl1KpulTBQ8UT4FPrByYyaLxpJoQ0+s7EvUrMc16m0ZS1sgb1XGqzmgCPk0c9y+aaXxn11tbLzuM7NQ==", + "version": "4.15.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", + "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", "dev": true, "dependencies": { "@types/bonjour": "^3.5.9", @@ -30240,7 +30986,7 @@ "@types/serve-index": "^1.9.1", "@types/serve-static": "^1.13.10", "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.1", + "@types/ws": "^8.5.5", "ansi-html-community": "^0.0.8", "bonjour-service": "^1.0.11", "chokidar": "^3.5.3", @@ -30736,11 +31482,81 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, + "devOptional": true, "engines": { "node": ">=0.4" } }, + "node_modules/y-leveldb": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/y-leveldb/-/y-leveldb-0.1.2.tgz", + "integrity": "sha512-6ulEn5AXfXJYi89rXPEg2mMHAyyw8+ZfeMMdOtBbV8FJpQ1NOrcgi6DTAcXof0dap84NjHPT2+9d0rb6cFsjEg==", + "optional": true, + "dependencies": { + "level": "^6.0.1", + "lib0": "^0.2.31" + }, + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + }, + "peerDependencies": { + "yjs": "^13.0.0" + } + }, + "node_modules/y-protocols": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/y-protocols/-/y-protocols-1.0.6.tgz", + "integrity": "sha512-vHRF2L6iT3rwj1jub/K5tYcTT/mEYDUppgNPXwp8fmLpui9f7Yeq3OEtTLVF012j39QnV+KEQpNqoN7CWU7Y9Q==", + "dependencies": { + "lib0": "^0.2.85" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=8.0.0" + }, + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + }, + "peerDependencies": { + "yjs": "^13.0.0" + } + }, + "node_modules/y-websocket": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/y-websocket/-/y-websocket-1.5.0.tgz", + "integrity": "sha512-A8AO6XtnQlYwWFytWdkDCeXg4l8ghRTIw5h2YUgUYDmEC9ugWGIwYNW80yadhSFAF7CvuWTEkQNEpevnH6EiZw==", + "dependencies": { + "lib0": "^0.2.52", + "lodash.debounce": "^4.0.8", + "y-protocols": "^1.0.5" + }, + "bin": { + "y-websocket": "bin/server.js", + "y-websocket-server": "bin/server.js" + }, + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + }, + "optionalDependencies": { + "ws": "^6.2.1", + "y-leveldb": "^0.1.0" + }, + "peerDependencies": { + "yjs": "^13.5.6" + } + }, + "node_modules/y-websocket/node_modules/ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "optional": true, + "dependencies": { + "async-limiter": "~1.0.0" + } + }, "node_modules/y18n": { "version": "5.0.8", "license": "ISC", @@ -30809,6 +31625,23 @@ "fd-slicer": "~1.1.0" } }, + "node_modules/yjs": { + "version": "13.6.8", + "resolved": "https://registry.npmjs.org/yjs/-/yjs-13.6.8.tgz", + "integrity": "sha512-ZPq0hpJQb6f59B++Ngg4cKexDJTvfOgeiv0sBc4sUm8CaBWH7OQC4kcCgrqbjJ/B2+6vO49exvTmYfdlPtcjbg==", + "peer": true, + "dependencies": { + "lib0": "^0.2.74" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=8.0.0" + }, + "funding": { + "type": "GitHub Sponsors ❤", + "url": "https://github.com/sponsors/dmonad" + } + }, "node_modules/yn": { "version": "3.1.1", "dev": true, diff --git a/frontend/package.json b/frontend/package.json index 99a67cd13..2d5646e0a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -44,7 +44,7 @@ "date-fns": "2.30.0", "font-awesome": "4.7.0", "graphiql": "3.0.5", - "graphql": "16.7.1", + "graphql": "16.8.1", "graphql-ws": "^5.14.0", "image-focus": "1.2.1", "keycharm": "0.4.0", @@ -66,7 +66,6 @@ "rxjs": "7.8.1", "simplemde": "1.11.2", "slugify": "1.6.6", - "tinymce": "5.10.2", "tslib": "2.6.1", "tui-calendar": "^1.15.3", "typemoq": "^2.1.0", @@ -74,11 +73,18 @@ "vis-data": "7.1.6", "vis-network": "9.1.6", "vis-util": "5.0.3", + "y-protocols": "^1.0.6", + "y-websocket": "^1.5.0", "zone.js": "0.13.1" }, "devDependencies": { "@angular-builders/custom-webpack": "^16.0.0", "@angular-devkit/build-angular": "^16.1.7", + "@angular-eslint/builder": "16.2.0", + "@angular-eslint/eslint-plugin": "16.2.0", + "@angular-eslint/eslint-plugin-template": "16.2.0", + "@angular-eslint/schematics": "16.2.0", + "@angular-eslint/template-parser": "16.2.0", "@angular/cli": "^16.1.7", "@angular/compiler": "^16.1.8", "@angular/compiler-cli": "^16.1.8", @@ -102,14 +108,13 @@ "@types/react-dom": "18.2.7", "@types/simplemde": "1.11.8", "@types/tapable": "2.2.3", - "@types/tinymce": "4.6.5", "@types/ws": "8.5.5", - "@typescript-eslint/eslint-plugin": "6.2.1", - "@typescript-eslint/parser": "6.2.1", + "@typescript-eslint/eslint-plugin": "5.62.0", + "@typescript-eslint/parser": "5.62.0", "@webcomponents/custom-elements": "^1.6.0", "babel-loader": "^9.1.3", "copy-webpack-plugin": "11.0.0", - "eslint": "8.46.0", + "eslint": "^8.49.0", "eslint-config-airbnb-typescript": "17.1.0", "eslint-plugin-deprecation": "^1.5.0", "eslint-plugin-import": "2.28.0", @@ -136,4 +141,4 @@ "ng2-charts-schematics": "0.1.7" } } -} +} \ No newline at end of file diff --git a/frontend/src/app/app.component.html b/frontend/src/app/app.component.html index c70d2283c..f0454dfc4 100644 --- a/frontend/src/app/app.component.html +++ b/frontend/src/app/app.component.html @@ -1,4 +1,4 @@ -
    +
    diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index d10307f83..f5d369044 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -10,7 +10,7 @@ import { APP_BASE_HREF, CommonModule } from '@angular/common'; import { HttpClientModule } from '@angular/common/http'; -import { ApplicationRef, NgModule } from '@angular/core'; +import { ApplicationRef, DoBootstrap, NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { BrowserModule } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; @@ -117,7 +117,7 @@ export class AppRouteReuseStrategy extends BaseRouteReuseStrategy { { provide: APP_BASE_HREF, useValue: basePath() }, ], }) -export class AppModule { +export class AppModule implements DoBootstrap { public ngDoBootstrap(appRef: ApplicationRef) { try { appRef.bootstrap(AppComponent); diff --git a/frontend/src/app/declarations.d.ts b/frontend/src/app/declarations.d.ts index 1f72c1dbd..d8f9fa8d8 100644 --- a/frontend/src/app/declarations.d.ts +++ b/frontend/src/app/declarations.d.ts @@ -6,4 +6,110 @@ */ declare module 'pikaday/pikaday'; -declare module 'progressbar.js'; \ No newline at end of file +declare module 'progressbar.js'; + +declare class SquidexEditorWrapper { + constructor(element: HTMLElement, props: EditorProps); + + update(newProps: Partial): void; + + setValue(value: string): void; + + setIsDisabled(isDisabled: boolean): void; + + destroy(): void; +} + +type Asset = { + // The alternative text of the image. + alt?: string; + + // The src to the asset. + src: string; + + // The mime type. + type: string; + + // The file name of the asset. + fileName: string; +}; + +type Content = { + // The title of the content. + id: string; + + // The name of the schema. + schemaName: string; + + // The title of the content item. + title: string; +}; + +type OnSelectAIText = () => Promise; +type OnSelectAssets = () => Promise; +type OnSelectContents = () => Promise; + +type OnChange = (value: string | undefined) => void; + +type SquidexEditorMode = 'Html' | 'Markdown'; + +interface UploadRequest { + // The file to upload. + file: File; + + // The upload progress to update. + progress: (progress: number) => void; +} + +interface EditorProps { + // The mode of the editor. + mode: SquidexEditorMode; + + // The incoming value. + value?: string; + + // The base url. + baseUrl: string; + + // The name to the app. + appName: string; + + // The class names. + classNames?: ReadonlyArray; + + // Called when the value has been changed. + onChange?: OnChange; + + // Called when AI text selected. + onSelectAIText?: OnSelectAIText; + + // Called when assets are selected. + onSelectAssets?: OnSelectAssets; + + // Called when content items should be selected. + onSelectContents?: OnSelectContents; + + // Called when an asset is to be edited. + onEditAsset: (assetId: string) => void; + + // Called when a content is to be edited. + onEditContent: (schemaName: string, contentId: string) => void; + + + // Called when a file needs to be uploaded. + onUpload?: (images: UploadRequest[]) => DelayedPromiseCreator[]; + + // True, if disabled. + isDisabled?: boolean; + + // Indicates whether AI text can be selected. + canSelectAIText?: boolean; + + // Indicates whether assets can be selected. + canSelectAssets?: boolean; + + // Indicates whether content items can be selected. + canSelectContents?: boolean; +} + +type DelayedPromiseCreator = (context: unknown) => Promise; \ No newline at end of file diff --git a/frontend/src/app/features/administration/pages/event-consumers/event-consumer.component.html b/frontend/src/app/features/administration/pages/event-consumers/event-consumer.component.html index 5257ab0fb..3bd883557 100644 --- a/frontend/src/app/features/administration/pages/event-consumers/event-consumer.component.html +++ b/frontend/src/app/features/administration/pages/event-consumers/event-consumer.component.html @@ -1,7 +1,7 @@ - + {{eventConsumer.name}} diff --git a/frontend/src/app/features/administration/pages/event-consumers/event-consumer.component.ts b/frontend/src/app/features/administration/pages/event-consumers/event-consumer.component.ts index 90d40a084..c22d1313e 100644 --- a/frontend/src/app/features/administration/pages/event-consumers/event-consumer.component.ts +++ b/frontend/src/app/features/administration/pages/event-consumers/event-consumer.component.ts @@ -5,6 +5,8 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ +/* eslint-disable @angular-eslint/component-selector */ + import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core'; import { EventConsumerDto, EventConsumersState } from '@app/features/administration/internal'; @@ -16,7 +18,7 @@ import { EventConsumerDto, EventConsumersState } from '@app/features/administrat }) export class EventConsumerComponent { @Output() - public error = new EventEmitter(); + public failure = new EventEmitter(); @Input('sqxEventConsumer') public eventConsumer!: EventConsumerDto; diff --git a/frontend/src/app/features/administration/pages/event-consumers/event-consumers-page.component.html b/frontend/src/app/features/administration/pages/event-consumers/event-consumers-page.component.html index f68fc0b31..458f6407c 100644 --- a/frontend/src/app/features/administration/pages/event-consumers/event-consumers-page.component.html +++ b/frontend/src/app/features/administration/pages/event-consumers/event-consumers-page.component.html @@ -33,7 +33,7 @@ + [sqxEventConsumer]="eventConsumer" (failure)="showError(eventConsumer)">
    @@ -57,7 +57,7 @@ - + {{ 'common.error' | sqxTranslate }} diff --git a/frontend/src/app/features/administration/pages/event-consumers/event-consumers-page.component.ts b/frontend/src/app/features/administration/pages/event-consumers/event-consumers-page.component.ts index 62cc0dc0f..924abb45c 100644 --- a/frontend/src/app/features/administration/pages/event-consumers/event-consumers-page.component.ts +++ b/frontend/src/app/features/administration/pages/event-consumers/event-consumers-page.component.ts @@ -9,27 +9,28 @@ import { Component, OnInit } from '@angular/core'; import { timer } from 'rxjs'; import { switchMap } from 'rxjs/operators'; import { EventConsumerDto, EventConsumersState } from '@app/features/administration/internal'; -import { DialogModel, ResourceOwner } from '@app/shared'; +import { DialogModel, Subscriptions } from '@app/shared'; @Component({ selector: 'sqx-event-consumers-page', styleUrls: ['./event-consumers-page.component.scss'], templateUrl: './event-consumers-page.component.html', }) -export class EventConsumersPageComponent extends ResourceOwner implements OnInit { +export class EventConsumersPageComponent implements OnInit { + private readonly subscriptions = new Subscriptions(); + public eventConsumerErrorDialog = new DialogModel(); public eventConsumerError?: string; constructor( public readonly eventConsumersState: EventConsumersState, ) { - super(); } public ngOnInit() { this.eventConsumersState.load(); - this.own(timer(1000, 1000).pipe(switchMap(() => this.eventConsumersState.load(false, true)))); + this.subscriptions.add(timer(1000, 1000).pipe(switchMap(() => this.eventConsumersState.load(false, true)))); } public reload() { diff --git a/frontend/src/app/features/administration/pages/users/user-page.component.ts b/frontend/src/app/features/administration/pages/users/user-page.component.ts index da8f2d2e7..59168ea12 100644 --- a/frontend/src/app/features/administration/pages/users/user-page.component.ts +++ b/frontend/src/app/features/administration/pages/users/user-page.component.ts @@ -8,14 +8,16 @@ import { Component, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { UpsertUserDto, UserDto, UserForm, UsersState } from '@app/features/administration/internal'; -import { ResourceOwner } from '@app/shared'; +import { Subscriptions } from '@app/shared'; @Component({ selector: 'sqx-user-page', styleUrls: ['./user-page.component.scss'], templateUrl: './user-page.component.html', }) -export class UserPageComponent extends ResourceOwner implements OnInit { +export class UserPageComponent implements OnInit { + private readonly subscriptions = new Subscriptions(); + public isEditable = false; public user?: UserDto | null; @@ -26,11 +28,10 @@ export class UserPageComponent extends ResourceOwner implements OnInit { private readonly route: ActivatedRoute, private readonly router: Router, ) { - super(); } public ngOnInit() { - this.own( + this.subscriptions.add( this.usersState.selectedUser .subscribe(user => { this.user = user; diff --git a/frontend/src/app/features/administration/pages/users/user.component.ts b/frontend/src/app/features/administration/pages/users/user.component.ts index 3b615fd9f..0bd9c4935 100644 --- a/frontend/src/app/features/administration/pages/users/user.component.ts +++ b/frontend/src/app/features/administration/pages/users/user.component.ts @@ -5,6 +5,8 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ +/* eslint-disable @angular-eslint/component-selector */ + import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; import { UserDto, UsersState } from '@app/features/administration/internal'; diff --git a/frontend/src/app/features/administration/pages/users/users-page.component.ts b/frontend/src/app/features/administration/pages/users/users-page.component.ts index 00741ff27..550609542 100644 --- a/frontend/src/app/features/administration/pages/users/users-page.component.ts +++ b/frontend/src/app/features/administration/pages/users/users-page.component.ts @@ -8,7 +8,7 @@ import { Component, OnInit } from '@angular/core'; import { UntypedFormControl } from '@angular/forms'; import { UserDto, UsersState } from '@app/features/administration/internal'; -import { ResourceOwner, Router2State } from '@app/framework'; +import { Router2State, Subscriptions } from '@app/framework'; @Component({ selector: 'sqx-users-page', @@ -18,16 +18,16 @@ import { ResourceOwner, Router2State } from '@app/framework'; Router2State, ], }) -export class UsersPageComponent extends ResourceOwner implements OnInit { +export class UsersPageComponent implements OnInit { + private readonly subscriptions = new Subscriptions(); + public usersFilter = new UntypedFormControl(); constructor( public readonly usersRoute: Router2State, public readonly usersState: UsersState, ) { - super(); - - this.own( + this.subscriptions.add( this.usersState.query .subscribe(q => this.usersFilter.setValue(q || ''))); } diff --git a/frontend/src/app/features/api/pages/graphql/graphql-page.component.html b/frontend/src/app/features/api/pages/graphql/graphql-page.component.html index 5ad002df6..052d3d6bb 100644 --- a/frontend/src/app/features/api/pages/graphql/graphql-page.component.html +++ b/frontend/src/app/features/api/pages/graphql/graphql-page.component.html @@ -8,7 +8,7 @@ - + {{ 'api.selectClient' | sqxTranslate }} diff --git a/frontend/src/app/features/apps/pages/apps-page.component.html b/frontend/src/app/features/apps/pages/apps-page.component.html index 1db5be6ed..c94de37cb 100644 --- a/frontend/src/app/features/apps/pages/apps-page.component.html +++ b/frontend/src/app/features/apps/pages/apps-page.component.html @@ -67,13 +67,13 @@
    + (dialogClose)="addAppDialog.hide()" [template]="addAppTemplate"> + (dialogClose)="onboardingDialog.hide()"> + (dialogClose)="newsDialog.hide()"> \ No newline at end of file diff --git a/frontend/src/app/features/apps/pages/apps-page.component.ts b/frontend/src/app/features/apps/pages/apps-page.component.ts index 846c8ddad..6ded4e811 100644 --- a/frontend/src/app/features/apps/pages/apps-page.component.ts +++ b/frontend/src/app/features/apps/pages/apps-page.component.ts @@ -68,8 +68,8 @@ export class AppsPageComponent implements OnInit { private readonly tourState: TourState, private readonly uiOptions: UIOptions, ) { - if (uiOptions.get('showInfo')) { - this.info = uiOptions.get('info'); + if (uiOptions.value.showInfo) { + this.info = uiOptions.value.info; } } @@ -87,7 +87,7 @@ export class AppsPageComponent implements OnInit { this.tourState.complete(); } - if (!this.uiOptions.get('hideNews')) { + if (!this.uiOptions.value.hideNews) { const newsVersion = this.localStore.getInt(Settings.Local.NEWS_VERSION); this.newsService.getFeatures(newsVersion) diff --git a/frontend/src/app/features/apps/pages/news-dialog.component.html b/frontend/src/app/features/apps/pages/news-dialog.component.html index 8a34a726e..06acfc3c8 100644 --- a/frontend/src/app/features/apps/pages/news-dialog.component.html +++ b/frontend/src/app/features/apps/pages/news-dialog.component.html @@ -1,4 +1,4 @@ - + {{ 'news.title' | sqxTranslate }} diff --git a/frontend/src/app/features/apps/pages/news-dialog.component.ts b/frontend/src/app/features/apps/pages/news-dialog.component.ts index f7e269d22..4d754d2b9 100644 --- a/frontend/src/app/features/apps/pages/news-dialog.component.ts +++ b/frontend/src/app/features/apps/pages/news-dialog.component.ts @@ -15,7 +15,7 @@ import { FeatureDto } from '@app/shared'; }) export class NewsDialogComponent { @Output() - public close = new EventEmitter(); + public dialogClose = new EventEmitter(); @Input({ required: true }) public features!: ReadonlyArray; diff --git a/frontend/src/app/features/apps/pages/onboarding-dialog.component.html b/frontend/src/app/features/apps/pages/onboarding-dialog.component.html index e214344ea..ebbf45d76 100644 --- a/frontend/src/app/features/apps/pages/onboarding-dialog.component.html +++ b/frontend/src/app/features/apps/pages/onboarding-dialog.component.html @@ -6,7 +6,7 @@ - {{ 'tour.skip' | sqxTranslate }} + {{ 'tour.skip' | sqxTranslate }}
    diff --git a/frontend/src/app/features/apps/pages/onboarding-dialog.component.ts b/frontend/src/app/features/apps/pages/onboarding-dialog.component.ts index bdfdecae3..00f6c5b4d 100644 --- a/frontend/src/app/features/apps/pages/onboarding-dialog.component.ts +++ b/frontend/src/app/features/apps/pages/onboarding-dialog.component.ts @@ -21,7 +21,7 @@ import { TourState, UsersService } from '@app/shared'; export class OnboardingDialogComponent { @Output() - public close = new EventEmitter(); + public dialogClose = new EventEmitter(); public answersForm = this.formBuilder.group({ @@ -46,12 +46,12 @@ export class OnboardingDialogComponent { public start() { this.tourState.start(); - this.close.emit(); + this.dialogClose.emit(); } public cancel() { this.tourState.complete(); - this.close.emit(); + this.dialogClose.emit(); } public next() { diff --git a/frontend/src/app/features/assets/pages/asset-tag-dialog.component.html b/frontend/src/app/features/assets/pages/asset-tag-dialog.component.html index be0009ad4..8e4ad3adf 100644 --- a/frontend/src/app/features/assets/pages/asset-tag-dialog.component.html +++ b/frontend/src/app/features/assets/pages/asset-tag-dialog.component.html @@ -1,5 +1,5 @@
    - + {{ 'common.renameTag' | sqxTranslate }} diff --git a/frontend/src/app/features/assets/pages/asset-tag-dialog.component.ts b/frontend/src/app/features/assets/pages/asset-tag-dialog.component.ts index 5f76f591f..a199f9e1d 100644 --- a/frontend/src/app/features/assets/pages/asset-tag-dialog.component.ts +++ b/frontend/src/app/features/assets/pages/asset-tag-dialog.component.ts @@ -15,7 +15,7 @@ import { AssetsState, RenameAssetTagForm } from '@app/shared/internal'; }) export class AssetTagDialogComponent implements OnInit { @Output() - public close = new EventEmitter(); + public dialogClose = new EventEmitter(); @Input({ required: true }) public tagName!: string; @@ -32,7 +32,7 @@ export class AssetTagDialogComponent implements OnInit { } public emitClose() { - this.close.emit(); + this.dialogClose.emit(); } public renameAssetTag() { diff --git a/frontend/src/app/features/assets/pages/asset-tags.component.html b/frontend/src/app/features/assets/pages/asset-tags.component.html index 02c502967..14c8ba9a8 100644 --- a/frontend/src/app/features/assets/pages/asset-tags.component.html +++ b/frontend/src/app/features/assets/pages/asset-tags.component.html @@ -1,6 +1,6 @@ + (dialogClose)="tagRenameDialog.hide()" [tagName]="tagRenaming!.name"> \ No newline at end of file diff --git a/frontend/src/app/features/assets/pages/asset-tags.component.ts b/frontend/src/app/features/assets/pages/asset-tags.component.ts index 9c95959c9..2057b658d 100644 --- a/frontend/src/app/features/assets/pages/asset-tags.component.ts +++ b/frontend/src/app/features/assets/pages/asset-tags.component.ts @@ -18,7 +18,7 @@ import { DialogModel, TagItem, TagsSelected } from '@app/shared'; }) export class AssetTagsComponent { @Output() - public reset = new EventEmitter(); + public tagsReset = new EventEmitter(); @Output() public toggle = new EventEmitter(); diff --git a/frontend/src/app/features/assets/pages/assets-filters-page.component.html b/frontend/src/app/features/assets/pages/assets-filters-page.component.html index 0bbd1540e..85db6b121 100644 --- a/frontend/src/app/features/assets/pages/assets-filters-page.component.html +++ b/frontend/src/app/features/assets/pages/assets-filters-page.component.html @@ -1,9 +1,10 @@

    {{ 'common.tags' | sqxTranslate }}

    - diff --git a/frontend/src/app/features/assets/pages/assets-page.component.html b/frontend/src/app/features/assets/pages/assets-page.component.html index d042e7505..8529a5ddc 100644 --- a/frontend/src/app/features/assets/pages/assets-page.component.html +++ b/frontend/src/app/features/assets/pages/assets-page.component.html @@ -89,12 +89,12 @@ + (dialogClose)="addAssetFolderDialog.hide()"> + (dialogClose)="editDone()"> \ No newline at end of file diff --git a/frontend/src/app/features/assets/pages/assets-page.component.ts b/frontend/src/app/features/assets/pages/assets-page.component.ts index fe7259c3b..588651a3a 100644 --- a/frontend/src/app/features/assets/pages/assets-page.component.ts +++ b/frontend/src/app/features/assets/pages/assets-page.component.ts @@ -6,7 +6,7 @@ */ import { Component, OnInit } from '@angular/core'; -import { AssetDto, AssetsState, DialogModel, LocalStoreService, MathHelper, Queries, Query, QueryFullTextSynchronizer, ResourceOwner, Router2State, UIState } from '@app/shared'; +import { AssetDto, AssetsState, DialogModel, LocalStoreService, MathHelper, Queries, Query, QueryFullTextSynchronizer, Router2State, UIState } from '@app/shared'; import { Settings } from '@app/shared/state/settings'; @Component({ @@ -17,7 +17,7 @@ import { Settings } from '@app/shared/state/settings'; Router2State, ], }) -export class AssetsPageComponent extends ResourceOwner implements OnInit { +export class AssetsPageComponent implements OnInit { public editAsset?: AssetDto; public listQueries = new Queries(this.uiState, 'assets'); @@ -31,8 +31,6 @@ export class AssetsPageComponent extends ResourceOwner implements OnInit { private readonly localStore: LocalStoreService, private readonly uiState: UIState, ) { - super(); - this.listMode = this.localStore.getBoolean(Settings.Local.ASSETS_MODE); } diff --git a/frontend/src/app/features/content/declarations.ts b/frontend/src/app/features/content/declarations.ts index 7e6bb098e..0862ab669 100644 --- a/frontend/src/app/features/content/declarations.ts +++ b/frontend/src/app/features/content/declarations.ts @@ -28,7 +28,6 @@ export * from './shared/due-time-selector.component'; export * from './shared/forms/array-editor.component'; export * from './shared/forms/array-item.component'; export * from './shared/forms/assets-editor.component'; -export * from './shared/forms/chat-dialog.component'; export * from './shared/forms/component-section.component'; export * from './shared/forms/component.component'; export * from './shared/forms/field-editor.component'; diff --git a/frontend/src/app/features/content/module.ts b/frontend/src/app/features/content/module.ts index 9053f00a0..19fc38168 100644 --- a/frontend/src/app/features/content/module.ts +++ b/frontend/src/app/features/content/module.ts @@ -9,7 +9,7 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { VirtualScrollerModule } from '@iharbeck/ngx-virtual-scroller'; import { CanDeactivateGuard, ContentMustExistGuard, LoadLanguagesGuard, LoadSchemasGuard, SchemaMustExistPublishedGuard, SchemaMustNotBeSingletonGuard, SqxFrameworkModule, SqxSharedModule } from '@app/shared'; -import { ArrayEditorComponent, ArrayItemComponent, AssetsEditorComponent, CalendarPageComponent, ChatDialogComponent, CommentsPageComponent, ComponentComponent, ComponentSectionComponent, ContentComponent, ContentCreatorComponent, ContentEditorComponent, ContentEventComponent, ContentExtensionComponent, ContentFieldComponent, ContentHistoryPageComponent, ContentInspectionComponent, ContentPageComponent, ContentReferencesComponent, ContentSectionComponent, ContentsFiltersPageComponent, ContentsPageComponent, CustomViewEditorComponent, DueTimeSelectorComponent, FieldCopyButtonComponent, FieldEditorComponent, FieldLanguagesComponent, IFrameEditorComponent, PreviewButtonComponent, ReferenceDropdownComponent, ReferenceItemComponent, ReferencesCheckboxesComponent, ReferencesEditorComponent, ReferencesPageComponent, ReferencesTagsComponent, SchemasPageComponent, SidebarPageComponent, StockPhotoEditorComponent } from './declarations'; +import { ArrayEditorComponent, ArrayItemComponent, AssetsEditorComponent, CalendarPageComponent, CommentsPageComponent, ComponentComponent, ComponentSectionComponent, ContentComponent, ContentCreatorComponent, ContentEditorComponent, ContentEventComponent, ContentExtensionComponent, ContentFieldComponent, ContentHistoryPageComponent, ContentInspectionComponent, ContentPageComponent, ContentReferencesComponent, ContentSectionComponent, ContentsFiltersPageComponent, ContentsPageComponent, CustomViewEditorComponent, DueTimeSelectorComponent, FieldCopyButtonComponent, FieldEditorComponent, FieldLanguagesComponent, IFrameEditorComponent, PreviewButtonComponent, ReferenceDropdownComponent, ReferenceItemComponent, ReferencesCheckboxesComponent, ReferencesEditorComponent, ReferencesPageComponent, ReferencesTagsComponent, SchemasPageComponent, SidebarPageComponent, StockPhotoEditorComponent } from './declarations'; const routes: Routes = [ { @@ -97,7 +97,6 @@ const routes: Routes = [ ArrayItemComponent, AssetsEditorComponent, CalendarPageComponent, - ChatDialogComponent, CommentsPageComponent, ComponentComponent, ComponentSectionComponent, diff --git a/frontend/src/app/features/content/pages/calendar/calendar-page.component.html b/frontend/src/app/features/content/pages/calendar/calendar-page.component.html index 69cf8a2fc..0ff57f89c 100644 --- a/frontend/src/app/features/content/pages/calendar/calendar-page.component.html +++ b/frontend/src/app/features/content/pages/calendar/calendar-page.component.html @@ -23,7 +23,7 @@
    - + {{ 'common.content' | sqxTranslate }} diff --git a/frontend/src/app/features/content/pages/calendar/calendar-page.component.ts b/frontend/src/app/features/content/pages/calendar/calendar-page.component.ts index 307073673..0119dc841 100644 --- a/frontend/src/app/features/content/pages/calendar/calendar-page.component.ts +++ b/frontend/src/app/features/content/pages/calendar/calendar-page.component.ts @@ -5,7 +5,7 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ -import { AfterViewInit, ChangeDetectorRef, Component, ElementRef, HostListener, OnDestroy, ViewChild } from '@angular/core'; +import { AfterViewInit, ChangeDetectorRef, Component, ElementRef, HostListener, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { AppsState, ContentDto, ContentsService, DateTime, DialogModel, getContentValue, LanguageDto, LanguagesState, LocalizerService, ResourceLoaderService } from '@app/shared'; declare const tui: any; @@ -17,7 +17,7 @@ type ViewMode = 'day' | 'week' | 'month'; styleUrls: ['./calendar-page.component.scss'], templateUrl: './calendar-page.component.html', }) -export class CalendarPageComponent implements AfterViewInit, OnDestroy { +export class CalendarPageComponent implements AfterViewInit, OnDestroy, OnInit { private calendar: any; private language!: LanguageDto; diff --git a/frontend/src/app/features/content/pages/content/content-history-page.component.ts b/frontend/src/app/features/content/pages/content/content-history-page.component.ts index be92f9fdb..a345736ec 100644 --- a/frontend/src/app/features/content/pages/content/content-history-page.component.ts +++ b/frontend/src/app/features/content/pages/content/content-history-page.component.ts @@ -8,7 +8,7 @@ import { Component, OnInit, ViewChild } from '@angular/core'; import { Observable, timer } from 'rxjs'; import { map } from 'rxjs/operators'; -import { AppsState, ContentDto, ContentsState, defined, HistoryEventDto, HistoryService, ModalModel, ResourceOwner, SchemasState, switchSafe } from '@app/shared'; +import { AppsState, ContentDto, ContentsState, defined, HistoryEventDto, HistoryService, ModalModel, SchemasState, Subscriptions, switchSafe } from '@app/shared'; import { DueTimeSelectorComponent } from './../../shared/due-time-selector.component'; import { ContentPageComponent } from './content-page.component'; @@ -17,7 +17,9 @@ import { ContentPageComponent } from './content-page.component'; styleUrls: ['./content-history-page.component.scss'], templateUrl: './content-history-page.component.html', }) -export class ContentHistoryPageComponent extends ResourceOwner implements OnInit { +export class ContentHistoryPageComponent implements OnInit { + private readonly subscriptions = new Subscriptions(); + @ViewChild('dueTimeSelector', { static: false }) public dueTimeSelector!: DueTimeSelectorComponent; @@ -38,11 +40,10 @@ export class ContentHistoryPageComponent extends ResourceOwner implements OnInit private readonly historyService: HistoryService, private readonly schemasState: SchemasState, ) { - super(); } public ngOnInit() { - this.own( + this.subscriptions.add( this.contentsState.selectedContent.pipe(defined()) .subscribe(content => { this.content = content; diff --git a/frontend/src/app/features/content/pages/content/content-page.component.html b/frontend/src/app/features/content/pages/content/content-page.component.html index 374524299..3cad2e815 100644 --- a/frontend/src/app/features/content/pages/content/content-page.component.html +++ b/frontend/src/app/features/content/pages/content/content-page.component.html @@ -51,7 +51,7 @@
    +
    -
    -
    - - -
    +
    +
    + +
    diff --git a/frontend/src/app/features/schemas/module.ts b/frontend/src/app/features/schemas/module.ts index ae1b30e23..861285a68 100644 --- a/frontend/src/app/features/schemas/module.ts +++ b/frontend/src/app/features/schemas/module.ts @@ -9,6 +9,7 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { HelpComponent, HistoryComponent, LoadSchemasGuard, SchemaMustExistGuard, SqxFrameworkModule, SqxSharedModule } from '@app/shared'; import { ArrayValidationComponent, AssetsUIComponent, AssetsValidationComponent, BooleanUIComponent, BooleanValidationComponent, ComponentsUIComponent, ComponentsValidationComponent, ComponentUIComponent, ComponentValidationComponent, DateTimeUIComponent, DateTimeValidationComponent, FieldComponent, FieldFormCommonComponent, FieldFormComponent, FieldFormUIComponent, FieldFormValidationComponent, FieldGroupComponent, FieldListComponent, FieldWizardComponent, GeolocationUIComponent, GeolocationValidationComponent, JsonMoreComponent, JsonUIComponent, JsonValidationComponent, NumberUIComponent, NumberValidationComponent, ReferencesUIComponent, ReferencesValidationComponent, SchemaEditFormComponent, SchemaExportFormComponent, SchemaFieldRulesFormComponent, SchemaFieldsComponent, SchemaFormComponent, SchemaPageComponent, SchemaPreviewUrlsFormComponent, SchemaScriptsFormComponent, SchemasPageComponent, SchemaUIFormComponent, SortableFieldListComponent, StringUIComponent, StringValidationComponent, TagsUIComponent, TagsValidationComponent } from './declarations'; +import { ArrayUIComponent } from './pages/schema/fields/types/array-ui.component'; const routes: Routes = [ { @@ -51,6 +52,7 @@ const routes: Routes = [ SchemaMustExistGuard, ], declarations: [ + ArrayUIComponent, ArrayValidationComponent, AssetsUIComponent, AssetsValidationComponent, diff --git a/frontend/src/app/features/schemas/pages/schema/fields/field-wizard.component.html b/frontend/src/app/features/schemas/pages/schema/fields/field-wizard.component.html index 0a1751d30..87b19332e 100644 --- a/frontend/src/app/features/schemas/pages/schema/fields/field-wizard.component.html +++ b/frontend/src/app/features/schemas/pages/schema/fields/field-wizard.component.html @@ -1,4 +1,4 @@ - + {{ 'schemas.addNestedField' | sqxTranslate }} diff --git a/frontend/src/app/features/schemas/pages/schema/fields/field-wizard.component.ts b/frontend/src/app/features/schemas/pages/schema/fields/field-wizard.component.ts index 761ce73a7..bf221f70b 100644 --- a/frontend/src/app/features/schemas/pages/schema/fields/field-wizard.component.ts +++ b/frontend/src/app/features/schemas/pages/schema/fields/field-wizard.component.ts @@ -29,7 +29,7 @@ export class FieldWizardComponent implements OnInit { public parent: RootFieldDto | null | undefined; @Output() - public close = new EventEmitter(); + public dialogClose = new EventEmitter(); public fieldTypes = fieldTypes; public field!: FieldDto; @@ -55,7 +55,7 @@ export class FieldWizardComponent implements OnInit { } public emitClose() { - this.close.emit(); + this.dialogClose.emit(); } public addField(addNew: boolean, edit = false) { diff --git a/frontend/src/app/features/schemas/pages/schema/fields/field.component.html b/frontend/src/app/features/schemas/pages/schema/fields/field.component.html index 9f24d03bd..fb381fd01 100644 --- a/frontend/src/app/features/schemas/pages/schema/fields/field.component.html +++ b/frontend/src/app/features/schemas/pages/schema/fields/field.component.html @@ -130,7 +130,7 @@ [parent]="$any(field)" [schema]="schema" [settings]="settings" - (close)="fieldWizard.hide()"> + (dialogClose)="fieldWizard.hide()"> diff --git a/frontend/src/app/features/schemas/pages/schema/fields/forms/field-form-ui.component.html b/frontend/src/app/features/schemas/pages/schema/fields/forms/field-form-ui.component.html index 300c95e8c..7416d0e45 100644 --- a/frontend/src/app/features/schemas/pages/schema/fields/forms/field-form-ui.component.html +++ b/frontend/src/app/features/schemas/pages/schema/fields/forms/field-form-ui.component.html @@ -13,6 +13,9 @@ + + + diff --git a/frontend/src/app/features/schemas/pages/schema/fields/forms/field-form.component.html b/frontend/src/app/features/schemas/pages/schema/fields/forms/field-form.component.html index 96831a0dc..04dc9891f 100644 --- a/frontend/src/app/features/schemas/pages/schema/fields/forms/field-form.component.html +++ b/frontend/src/app/features/schemas/pages/schema/fields/forms/field-form.component.html @@ -23,7 +23,7 @@
    - diff --git a/frontend/src/app/features/schemas/pages/schema/fields/forms/field-form.component.ts b/frontend/src/app/features/schemas/pages/schema/fields/forms/field-form.component.ts index 6b4b831ea..036305deb 100644 --- a/frontend/src/app/features/schemas/pages/schema/fields/forms/field-form.component.ts +++ b/frontend/src/app/features/schemas/pages/schema/fields/forms/field-form.component.ts @@ -40,7 +40,7 @@ export class FieldFormComponent implements AfterViewInit { public isLocalizable?: boolean | null; @Output() - public close = new EventEmitter(); + public dialogClose = new EventEmitter(); public selectedTab = 0; diff --git a/frontend/src/app/features/schemas/pages/schema/fields/schema-fields.component.html b/frontend/src/app/features/schemas/pages/schema/fields/schema-fields.component.html index 718072fc9..93ac111fc 100644 --- a/frontend/src/app/features/schemas/pages/schema/fields/schema-fields.component.html +++ b/frontend/src/app/features/schemas/pages/schema/fields/schema-fields.component.html @@ -26,6 +26,6 @@ + (dialogClose)="fieldWizard.hide()"> \ No newline at end of file diff --git a/frontend/src/app/features/schemas/pages/schema/fields/types/array-ui.component.html b/frontend/src/app/features/schemas/pages/schema/fields/types/array-ui.component.html new file mode 100644 index 000000000..f3fbddf8d --- /dev/null +++ b/frontend/src/app/features/schemas/pages/schema/fields/types/array-ui.component.html @@ -0,0 +1,11 @@ +
    +
    + + +
    + +
    +
    +
    \ No newline at end of file diff --git a/frontend/src/app/features/schemas/pages/schema/fields/types/array-ui.component.scss b/frontend/src/app/features/schemas/pages/schema/fields/types/array-ui.component.scss new file mode 100644 index 000000000..2742d895e --- /dev/null +++ b/frontend/src/app/features/schemas/pages/schema/fields/types/array-ui.component.scss @@ -0,0 +1,2 @@ +@import 'mixins'; +@import 'vars'; \ No newline at end of file diff --git a/frontend/src/app/features/schemas/pages/schema/fields/types/array-ui.component.ts b/frontend/src/app/features/schemas/pages/schema/fields/types/array-ui.component.ts new file mode 100644 index 000000000..cd10bf685 --- /dev/null +++ b/frontend/src/app/features/schemas/pages/schema/fields/types/array-ui.component.ts @@ -0,0 +1,30 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. + */ + +import { Component, Input } from '@angular/core'; +import { UntypedFormGroup } from '@angular/forms'; +import { ArrayFieldPropertiesDto, FieldDto } from '@app/shared'; + +const CALCULATED_DEFAULT_VALUES: ReadonlyArray = ['EmptyArray', 'Null']; + +@Component({ + selector: 'sqx-array-ui', + styleUrls: ['array-ui.component.scss'], + templateUrl: 'array-ui.component.html', +}) +export class ArrayUIComponent { + @Input({ required: true }) + public fieldForm!: UntypedFormGroup; + + @Input({ required: true }) + public field!: FieldDto; + + @Input({ required: true }) + public properties!: ArrayFieldPropertiesDto; + + public calculatedDefaultValues = CALCULATED_DEFAULT_VALUES; +} diff --git a/frontend/src/app/features/schemas/pages/schema/fields/types/components-ui.component.html b/frontend/src/app/features/schemas/pages/schema/fields/types/components-ui.component.html index e69de29bb..f3fbddf8d 100644 --- a/frontend/src/app/features/schemas/pages/schema/fields/types/components-ui.component.html +++ b/frontend/src/app/features/schemas/pages/schema/fields/types/components-ui.component.html @@ -0,0 +1,11 @@ +
    +
    + + +
    + +
    +
    +
    \ No newline at end of file diff --git a/frontend/src/app/features/schemas/pages/schema/fields/types/components-ui.component.ts b/frontend/src/app/features/schemas/pages/schema/fields/types/components-ui.component.ts index 671346161..508417b4d 100644 --- a/frontend/src/app/features/schemas/pages/schema/fields/types/components-ui.component.ts +++ b/frontend/src/app/features/schemas/pages/schema/fields/types/components-ui.component.ts @@ -9,6 +9,8 @@ import { Component, Input } from '@angular/core'; import { UntypedFormGroup } from '@angular/forms'; import { FieldDto, ReferencesFieldPropertiesDto } from '@app/shared'; +const CALCULATED_DEFAULT_VALUES: ReadonlyArray = ['EmptyArray', 'Null']; + @Component({ selector: 'sqx-components-ui', styleUrls: ['components-ui.component.scss'], @@ -23,4 +25,6 @@ export class ComponentsUIComponent { @Input({ required: true }) public properties!: ReferencesFieldPropertiesDto; + + public calculatedDefaultValues = CALCULATED_DEFAULT_VALUES; } diff --git a/frontend/src/app/features/schemas/pages/schema/fields/types/number-ui.component.ts b/frontend/src/app/features/schemas/pages/schema/fields/types/number-ui.component.ts index e564f1fc4..db6b07065 100644 --- a/frontend/src/app/features/schemas/pages/schema/fields/types/number-ui.component.ts +++ b/frontend/src/app/features/schemas/pages/schema/fields/types/number-ui.component.ts @@ -8,14 +8,16 @@ import { Component, Input } from '@angular/core'; import { UntypedFormGroup } from '@angular/forms'; import { Observable } from 'rxjs'; -import { FieldDto, FloatConverter, NUMBER_FIELD_EDITORS, NumberFieldPropertiesDto, ResourceOwner, valueProjection$, TypedSimpleChanges } from '@app/shared'; +import { FieldDto, FloatConverter, NUMBER_FIELD_EDITORS, NumberFieldPropertiesDto, Subscriptions, TypedSimpleChanges, valueProjection$ } from '@app/shared'; @Component({ selector: 'sqx-number-ui', styleUrls: ['number-ui.component.scss'], templateUrl: 'number-ui.component.html', }) -export class NumberUIComponent extends ResourceOwner { +export class NumberUIComponent { + private readonly subscriptions = new Subscriptions(); + public readonly converter = FloatConverter.INSTANCE; public readonly editors = NUMBER_FIELD_EDITORS; @@ -33,7 +35,7 @@ export class NumberUIComponent extends ResourceOwner { public ngOnChanges(changes: TypedSimpleChanges) { if (changes.fieldForm) { - this.unsubscribeAll(); + this.subscriptions.unsubscribeAll(); const editor = this.fieldForm.controls['editor']; @@ -43,14 +45,14 @@ export class NumberUIComponent extends ResourceOwner { this.hideInlineEditable = valueProjection$(editor, x => x === 'Radio'); - this.own( + this.subscriptions.add( this.hideAllowedValues.subscribe(isSelection => { if (isSelection) { this.fieldForm.controls['allowedValues'].setValue(undefined); } })); - this.own( + this.subscriptions.add( this.hideInlineEditable.subscribe(isSelection => { if (isSelection) { this.fieldForm.controls['inlineEditable'].setValue(false); diff --git a/frontend/src/app/features/schemas/pages/schema/fields/types/references-ui.component.html b/frontend/src/app/features/schemas/pages/schema/fields/types/references-ui.component.html index 3361b2c2d..9caec57f3 100644 --- a/frontend/src/app/features/schemas/pages/schema/fields/types/references-ui.component.html +++ b/frontend/src/app/features/schemas/pages/schema/fields/types/references-ui.component.html @@ -27,4 +27,16 @@
    + +
    + + +
    + + + + {{ 'schemas.fieldTypes.references.queryHint' | sqxTranslate }} + +
    +
    \ No newline at end of file diff --git a/frontend/src/app/features/schemas/pages/schema/fields/types/string-ui.component.html b/frontend/src/app/features/schemas/pages/schema/fields/types/string-ui.component.html index 76a52a376..70fb5eaba 100644 --- a/frontend/src/app/features/schemas/pages/schema/fields/types/string-ui.component.html +++ b/frontend/src/app/features/schemas/pages/schema/fields/types/string-ui.component.html @@ -25,6 +25,18 @@ +
    + + +
    + + + + {{ 'schemas.fieldTypes.string.classNamesHint' | sqxTranslate }} + +
    +
    +
    diff --git a/frontend/src/app/features/schemas/pages/schema/fields/types/string-ui.component.ts b/frontend/src/app/features/schemas/pages/schema/fields/types/string-ui.component.ts index b2e86a65b..24f89b1e4 100644 --- a/frontend/src/app/features/schemas/pages/schema/fields/types/string-ui.component.ts +++ b/frontend/src/app/features/schemas/pages/schema/fields/types/string-ui.component.ts @@ -8,14 +8,16 @@ import { Component, Input } from '@angular/core'; import { UntypedFormGroup } from '@angular/forms'; import { Observable } from 'rxjs'; -import { FieldDto, ResourceOwner, SchemaTagSource, STRING_FIELD_EDITORS, StringFieldPropertiesDto, valueProjection$, TypedSimpleChanges } from '@app/shared'; +import { FieldDto, SchemaTagSource, STRING_FIELD_EDITORS, StringFieldPropertiesDto, Subscriptions, TypedSimpleChanges, valueProjection$ } from '@app/shared'; @Component({ selector: 'sqx-string-ui', styleUrls: ['string-ui.component.scss'], templateUrl: 'string-ui.component.html', }) -export class StringUIComponent extends ResourceOwner { +export class StringUIComponent { + private readonly subscriptions = new Subscriptions(); + public readonly editors = STRING_FIELD_EDITORS; @Input({ required: true }) @@ -28,38 +30,41 @@ export class StringUIComponent extends ResourceOwner { public properties!: StringFieldPropertiesDto; public hideAllowedValues?: Observable; + public hideClassNames?: Observable; public hideInlineEditable?: Observable; public hideSchemaIds?: Observable; constructor( public readonly schemasSource: SchemaTagSource, ) { - super(); } public ngOnChanges(changes: TypedSimpleChanges) { if (changes.fieldForm) { - this.unsubscribeAll(); + this.subscriptions.unsubscribeAll(); const editor = this.fieldForm.controls['editor']; this.hideAllowedValues = valueProjection$(editor, x => !(x && (x === 'Radio' || x === 'Dropdown'))); + this.hideClassNames = + valueProjection$(editor, x => !(x && (x === 'RichText'))); + this.hideInlineEditable = valueProjection$(editor, x => !(x && (x === 'Input' || x === 'Dropdown' || x === 'Slug'))); this.hideSchemaIds = valueProjection$(this.fieldForm.controls['isEmbeddable'], x => !x); - this.own( + this.subscriptions.add( this.hideAllowedValues.subscribe(isSelection => { if (isSelection) { this.fieldForm.controls['allowedValues'].setValue(undefined); } })); - this.own( + this.subscriptions.add( this.hideInlineEditable.subscribe(isSelection => { if (isSelection) { this.fieldForm.controls['inlineEditable'].setValue(false); diff --git a/frontend/src/app/features/schemas/pages/schema/fields/types/string-validation.component.ts b/frontend/src/app/features/schemas/pages/schema/fields/types/string-validation.component.ts index e0d7bbe89..d1973b740 100644 --- a/frontend/src/app/features/schemas/pages/schema/fields/types/string-validation.component.ts +++ b/frontend/src/app/features/schemas/pages/schema/fields/types/string-validation.component.ts @@ -8,14 +8,16 @@ import { booleanAttribute, Component, Input } from '@angular/core'; import { UntypedFormGroup } from '@angular/forms'; import { Observable } from 'rxjs'; -import { AppSettingsDto, FieldDto, hasNoValue$, hasValue$, LanguageDto, ModalModel, PatternDto, ResourceOwner, RootFieldDto, SchemaDto, STRING_CONTENT_TYPES, StringFieldPropertiesDto, TypedSimpleChanges, Types, value$ } from '@app/shared'; +import { AppSettingsDto, FieldDto, hasNoValue$, hasValue$, LanguageDto, ModalModel, PatternDto, RootFieldDto, SchemaDto, STRING_CONTENT_TYPES, StringFieldPropertiesDto, Subscriptions, TypedSimpleChanges, Types, value$ } from '@app/shared'; @Component({ selector: 'sqx-string-validation', styleUrls: ['string-validation.component.scss'], templateUrl: 'string-validation.component.html', }) -export class StringValidationComponent extends ResourceOwner { +export class StringValidationComponent { + private readonly subscriptions = new Subscriptions(); + public readonly contentTypes = STRING_CONTENT_TYPES; @Input({ required: true }) @@ -55,7 +57,7 @@ export class StringValidationComponent extends ResourceOwner { } if (changes.fieldForm) { - this.unsubscribeAll(); + this.subscriptions.unsubscribeAll(); this.showPatternSuggestions = hasNoValue$(this.fieldForm.controls['pattern']); @@ -66,7 +68,7 @@ export class StringValidationComponent extends ResourceOwner { this.showPatternMessage = hasValue$(this.fieldForm.controls['pattern']); - this.own( + this.subscriptions.add( value$(this.fieldForm.controls['pattern']) .subscribe((value: string) => { if (!value) { diff --git a/frontend/src/app/features/schemas/pages/schema/schema-page.component.ts b/frontend/src/app/features/schemas/pages/schema/schema-page.component.ts index e8286175b..99b56c5c3 100644 --- a/frontend/src/app/features/schemas/pages/schema/schema-page.component.ts +++ b/frontend/src/app/features/schemas/pages/schema/schema-page.component.ts @@ -8,7 +8,7 @@ import { Component, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { map } from 'rxjs/operators'; -import { defined, MessageBus, ModalModel, ResourceOwner, SchemaDto, SchemasState } from '@app/shared'; +import { defined, MessageBus, ModalModel, SchemaDto, SchemasState, Subscriptions } from '@app/shared'; import { SchemaCloning } from './../messages'; @Component({ @@ -16,7 +16,9 @@ import { SchemaCloning } from './../messages'; styleUrls: ['./schema-page.component.scss'], templateUrl: './schema-page.component.html', }) -export class SchemaPageComponent extends ResourceOwner implements OnInit { +export class SchemaPageComponent implements OnInit { + private readonly subscriptions = new Subscriptions(); + public readonly exact = { exact: true }; public schema!: SchemaDto; @@ -30,11 +32,10 @@ export class SchemaPageComponent extends ResourceOwner implements OnInit { private readonly router: Router, private readonly messageBus: MessageBus, ) { - super(); } public ngOnInit() { - this.own( + this.subscriptions.add( this.schemasState.selectedSchema.pipe(defined()) .subscribe(schema => { this.schema = schema; diff --git a/frontend/src/app/features/schemas/pages/schema/scripts/schema-scripts-form.component.ts b/frontend/src/app/features/schemas/pages/schema/scripts/schema-scripts-form.component.ts index ec3727d07..3e3805f04 100644 --- a/frontend/src/app/features/schemas/pages/schema/scripts/schema-scripts-form.component.ts +++ b/frontend/src/app/features/schemas/pages/schema/scripts/schema-scripts-form.component.ts @@ -7,7 +7,7 @@ import { Component, Input } from '@angular/core'; import { EMPTY, Observable, shareReplay } from 'rxjs'; -import { AppsState, EditSchemaScriptsForm, ScriptCompletions, SchemaDto, SchemasService, SchemasState } from '@app/shared'; +import { AppsState, EditSchemaScriptsForm, SchemaDto, SchemasService, SchemasState, ScriptCompletions } from '@app/shared'; @Component({ selector: 'sqx-schema-scripts-form', diff --git a/frontend/src/app/features/schemas/pages/schemas/schema-form.component.html b/frontend/src/app/features/schemas/pages/schemas/schema-form.component.html index a8ea94ac6..1c46a0d3d 100644 --- a/frontend/src/app/features/schemas/pages/schemas/schema-form.component.html +++ b/frontend/src/app/features/schemas/pages/schemas/schema-form.component.html @@ -1,5 +1,5 @@
    - + {{ 'schemas.clone' | sqxTranslate }} @@ -110,7 +110,7 @@ - diff --git a/frontend/src/app/features/schemas/pages/schemas/schema-form.component.ts b/frontend/src/app/features/schemas/pages/schemas/schema-form.component.ts index 6fb560cd5..47fb70479 100644 --- a/frontend/src/app/features/schemas/pages/schemas/schema-form.component.ts +++ b/frontend/src/app/features/schemas/pages/schemas/schema-form.component.ts @@ -18,7 +18,7 @@ export class SchemaFormComponent implements OnInit { public create = new EventEmitter(); @Output() - public close = new EventEmitter(); + public dialogClose = new EventEmitter(); @Input() public import: any; @@ -51,7 +51,7 @@ export class SchemaFormComponent implements OnInit { } public emitClose() { - this.close.emit(); + this.dialogClose.emit(); } public createSchema() { diff --git a/frontend/src/app/features/schemas/pages/schemas/schemas-page.component.html b/frontend/src/app/features/schemas/pages/schemas/schemas-page.component.html index b367891b6..ef16d6a38 100644 --- a/frontend/src/app/features/schemas/pages/schemas/schemas-page.component.html +++ b/frontend/src/app/features/schemas/pages/schemas/schemas-page.component.html @@ -33,7 +33,7 @@ + (dialogClose)="addSchemaDialog.hide()" (create)="redirectSchema($event)" [import]="import"> diff --git a/frontend/src/app/features/schemas/pages/schemas/schemas-page.component.ts b/frontend/src/app/features/schemas/pages/schemas/schemas-page.component.ts index aface6153..4fb24bfdf 100644 --- a/frontend/src/app/features/schemas/pages/schemas/schemas-page.component.ts +++ b/frontend/src/app/features/schemas/pages/schemas/schemas-page.component.ts @@ -10,7 +10,7 @@ import { UntypedFormControl } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; import { combineLatest } from 'rxjs'; import { map } from 'rxjs/operators'; -import { CreateCategoryForm, DialogModel, getCategoryTree, MessageBus, ResourceOwner, SchemaCategory, SchemaDto, SchemasState, value$ } from '@app/shared'; +import { CreateCategoryForm, DialogModel, getCategoryTree, MessageBus, SchemaCategory, SchemaDto, SchemasState, Subscriptions, value$ } from '@app/shared'; import { SchemaCloning } from './../messages'; @Component({ @@ -18,7 +18,9 @@ import { SchemaCloning } from './../messages'; styleUrls: ['./schemas-page.component.scss'], templateUrl: './schemas-page.component.html', }) -export class SchemasPageComponent extends ResourceOwner implements OnInit { +export class SchemasPageComponent implements OnInit { + private readonly subscriptions = new Subscriptions(); + public addSchemaDialog = new DialogModel(); public addCategoryForm = new CreateCategoryForm(); @@ -41,11 +43,10 @@ export class SchemasPageComponent extends ResourceOwner implements OnInit { private readonly route: ActivatedRoute, private readonly router: Router, ) { - super(); } public ngOnInit() { - this.own( + this.subscriptions.add( this.messageBus.of(SchemaCloning) .subscribe(event => { this.import = event.schema; @@ -53,7 +54,7 @@ export class SchemasPageComponent extends ResourceOwner implements OnInit { this.addSchemaDialog.show(); })); - this.own( + this.subscriptions.add( this.route.params.pipe(map(q => q['showDialog'])) .subscribe(showDialog => { if (showDialog) { diff --git a/frontend/src/app/features/settings/pages/asset-scripts/asset-scripts-page.component.ts b/frontend/src/app/features/settings/pages/asset-scripts/asset-scripts-page.component.ts index 5e35f8fa8..6117db245 100644 --- a/frontend/src/app/features/settings/pages/asset-scripts/asset-scripts-page.component.ts +++ b/frontend/src/app/features/settings/pages/asset-scripts/asset-scripts-page.component.ts @@ -7,14 +7,14 @@ import { Component, OnInit } from '@angular/core'; import { EMPTY, Observable, shareReplay } from 'rxjs'; -import { AppsState, AssetScriptsState, AssetsService, EditAssetScriptsForm, ResourceOwner, ScriptCompletions } from '@app/shared'; +import { AppsState, AssetScriptsState, AssetsService, EditAssetScriptsForm, ScriptCompletions } from '@app/shared'; @Component({ selector: 'sqx-asset-scripts-page', styleUrls: ['./asset-scripts-page.component.scss'], templateUrl: './asset-scripts-page.component.html', }) -export class AssetScriptsPageComponent extends ResourceOwner implements OnInit { +export class AssetScriptsPageComponent implements OnInit { public assetScript = 'query'; public assetCompletions: Observable = EMPTY; @@ -27,7 +27,6 @@ export class AssetScriptsPageComponent extends ResourceOwner implements OnInit { private readonly assetScriptsState: AssetScriptsState, private readonly assetsService: AssetsService, ) { - super(); } public ngOnInit() { diff --git a/frontend/src/app/features/settings/pages/backups/backups-page.component.ts b/frontend/src/app/features/settings/pages/backups/backups-page.component.ts index 2fbb774fd..531c4c69c 100644 --- a/frontend/src/app/features/settings/pages/backups/backups-page.component.ts +++ b/frontend/src/app/features/settings/pages/backups/backups-page.component.ts @@ -8,25 +8,26 @@ import { Component, OnInit } from '@angular/core'; import { timer } from 'rxjs'; import { switchMap } from 'rxjs/operators'; -import { ApiUrlConfig, BackupDto, BackupsState, ResourceOwner } from '@app/shared'; +import { ApiUrlConfig, BackupDto, BackupsState, Subscriptions } from '@app/shared'; @Component({ selector: 'sqx-backups-page', styleUrls: ['./backups-page.component.scss'], templateUrl: './backups-page.component.html', }) -export class BackupsPageComponent extends ResourceOwner implements OnInit { +export class BackupsPageComponent implements OnInit { + private readonly subscriptions = new Subscriptions(); + constructor( public readonly apiUrl: ApiUrlConfig, public readonly backupsState: BackupsState, ) { - super(); } public ngOnInit() { this.backupsState.load(true); - this.own(timer(3000, 3000).pipe(switchMap(() => this.backupsState.load(false, true)))); + this.subscriptions.add(timer(3000, 3000).pipe(switchMap(() => this.backupsState.load(false, true)))); } public reload() { diff --git a/frontend/src/app/features/settings/pages/clients/client-connect-form.component.html b/frontend/src/app/features/settings/pages/clients/client-connect-form.component.html index 4f4ba0db0..b1ec97967 100644 --- a/frontend/src/app/features/settings/pages/clients/client-connect-form.component.html +++ b/frontend/src/app/features/settings/pages/clients/client-connect-form.component.html @@ -1,4 +1,4 @@ - + {{ 'clients.connect' | sqxTranslate }} @@ -9,7 +9,7 @@ - + - @@ -54,18 +54,10 @@
    -
    -
    {{ 'clients.connectWizard.dotnetSdk' | sqxTranslate }}
    +
    +
    {{ 'clients.connectWizard.sdk' | sqxTranslate }}
    - {{ 'clients.connectWizard.dotnetSdkHint' | sqxTranslate }} - - -
    - -
    -
    {{ 'clients.connectWizard.javascriptSdk' | sqxTranslate }}
    - - {{ 'clients.connectWizard.javascriptSdkHint' | sqxTranslate }} + {{ 'clients.connectWizard.sdkHint' | sqxTranslate }}
    @@ -144,132 +136,35 @@

    - -
    - - {{ 'clients.connectWizard.dotnetSdkDocumentation' | sqxTranslate }} {{ 'common.documentation' | sqxTranslate }} - -
    - -
    -
    1 {{ 'clients.connectWizard.dotnetSdkStep1' | sqxTranslate }}
    - -
    - -

    - dotnet add package Squidex.ClientLibrary -

    -
    - -
    -
    2 {{ 'clients.connectWizard.dotnetSdkStep2' | sqxTranslate }}
    - -

    - -

    using Squidex.ClientLibrary;
    -
     
    -
    var clientManager = new SquidexClientManager(new SquidexOptions
    -
    {{'{'}}
    -
    AppName = "{{appName}}",
    -
    ClientId = "{{appName}}:{{client.id}}",
    -
    ClientSecret = "{{client.secret}}",
    -
    Url = "{{apiUrl.value}}"
    -
    });
    - -

    -
    - -
    -
    2 {{ 'clients.connectWizard.dotnetSdkStep2_15' | sqxTranslate }}
    - -

    - -

    using Squidex.ClientLibrary;
    -
     
    -
    var client = new SquidexClient(new SquidexOptions
    -
    {{'{'}}
    -
    AppName = "{{appName}}",
    -
    ClientId = "{{appName}}:{{client.id}},
    -
    ClientSecret = "{{client.secret}}",
    -
    Url = "{{apiUrl.value}}"
    -
    });
    - -

    -
    - -
    -
    3 {{ 'clients.connectWizard.dotnetSdkStep3' | sqxTranslate }}
    - -
    - -

    - dotnet add package Squidex.ClientLibrary.ServiceExtensions -

    + +
    +
    + + {{availableSDK.value.name}} +
    -
    -
    4 {{ 'clients.connectWizard.dotnetSdkStep4' | sqxTranslate }}
    +
    + -

    - -

    using Microsoft.Extensions.DependencyInjection;
    -
     
    -
    services.AddSquidex(options =>
    -
    {{'{'}}
    -
    options.AppName = "{{appName}}";
    -
    options.ClientId = "{{appName}}:{{client.id}}";
    -
    options.ClientSecret = "{{client.secret}}";
    -
    options.Url = "{{apiUrl.value}}";
    -
    });
    - -

    +
    -
    +
    {{ 'clients.connectWizard.sdkHelp' | sqxTranslate }} {{ 'clients.connectWizard.sdkHelpLink' | sqxTranslate }}
    - -
    - - {{ 'clients.connectWizard.javascriptSdkDocumentation' | sqxTranslate }} {{ 'common.documentation' | sqxTranslate }} - -
    - -
    -
    1 {{ 'clients.connectWizard.javascriptSdkStep1' | sqxTranslate }}
    - -
    - -

    - npm i @squidex/squidex --save -

    -
    - -
    -
    2 {{ 'clients.connectWizard.javascriptSdkStep2' | sqxTranslate }}
    - -

    - -

    import {{'{'}} SquidexClient } from "@squidex/squidex";
    -
     
    -
    const client = new SquidexClient({{'{'}}
    -
    appName: "{{appName}}",
    -
    clientId: "{{appName}}:{{client.id}}",
    -
    clientSecret: "{{client.secret}}",
    -
    environment: "{{apiUrl.value}}"
    -
    });
    - -

    -
    -
    - diff --git a/frontend/src/app/features/settings/pages/clients/client-connect-form.component.scss b/frontend/src/app/features/settings/pages/clients/client-connect-form.component.scss index 9bf1100f4..255463ba6 100644 --- a/frontend/src/app/features/settings/pages/clients/client-connect-form.component.scss +++ b/frontend/src/app/features/settings/pages/clients/client-connect-form.component.scss @@ -1,6 +1,26 @@ @import 'mixins'; @import 'vars'; +sqx-code { + pre { + white-space: pre; + } +} + +:host ::ng-deep { + svg { + max-height: 100%; + } + + h3 { + margin-top: 1.75rem; + } + + .code-container { + margin: .5rem 0; + } +} + .badge { @include circle(1.3rem); font-size: $font-smallest; @@ -23,6 +43,30 @@ } } +.sdk-header { + border: 1px solid $color-border; + border-radius: $border-radius; + display: inline-block; + cursor: pointer; + padding: 1rem; + margin-bottom: .5rem; + margin-right: .5rem; + width: 160px; + text-align: center; + + &.active { + border-color: $color-theme-brand; + } + + &:hover { + border-color: $color-theme-brand-dark; + } + + .logo { + height: 100px; + } +} + .option { background: none; border: 1px solid $color-border; @@ -43,10 +87,4 @@ font-size: $font-smallest; font-weight: normal; } -} - -sqx-code { - pre { - white-space: pre; - } } \ No newline at end of file diff --git a/frontend/src/app/features/settings/pages/clients/client-connect-form.component.ts b/frontend/src/app/features/settings/pages/clients/client-connect-form.component.ts index 35d583ade..0760a0aa8 100644 --- a/frontend/src/app/features/settings/pages/clients/client-connect-form.component.ts +++ b/frontend/src/app/features/settings/pages/clients/client-connect-form.component.ts @@ -6,7 +6,7 @@ */ import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { AccessTokenDto, ApiUrlConfig, AppsState, ClientDto, ClientsService, ClientTourStated, DialogService, MessageBus } from '@app/shared'; +import { AccessTokenDto, ApiUrlConfig, AppsState, ClientDto, ClientsService, ClientTourStated, DialogService, HelpService, MessageBus, SDKEntry } from '@app/shared'; @Component({ selector: 'sqx-client-connect-form', @@ -15,26 +15,26 @@ import { AccessTokenDto, ApiUrlConfig, AppsState, ClientDto, ClientsService, Cli }) export class ClientConnectFormComponent implements OnInit { @Output() - public close = new EventEmitter(); + public dialogClose = new EventEmitter(); @Input({ required: true }) public client!: ClientDto; + public sdks = this.helpService.getSDKs(); + public sdk?: SDKEntry; + public appName!: string; public appToken?: AccessTokenDto; public step = 'Start'; - public get isStart() { - return this.step === 'Start'; - } - constructor( public readonly appsState: AppsState, public readonly apiUrl: ApiUrlConfig, private readonly changeDetector: ChangeDetectorRef, private readonly clientsService: ClientsService, private readonly dialogs: DialogService, + private readonly helpService: HelpService, private readonly messageBus: MessageBus, ) { } @@ -57,6 +57,15 @@ export class ClientConnectFormComponent implements OnInit { this.messageBus.emit(new ClientTourStated()); } + public select(sdk: SDKEntry) { + sdk.instructions = sdk.instructions.replace(//g, this.appName); + sdk.instructions = sdk.instructions.replace(//g, `${this.appName}:${this.client.id}`); + sdk.instructions = sdk.instructions.replace(//g, this.client.secret); + sdk.instructions = sdk.instructions.replace(//g, this.apiUrl.value); + + this.sdk = sdk; + } + public go(step: string) { this.step = step; } diff --git a/frontend/src/app/features/settings/pages/clients/client.component.html b/frontend/src/app/features/settings/pages/clients/client.component.html index 8ee6bc0c8..25ca6f11e 100644 --- a/frontend/src/app/features/settings/pages/clients/client.component.html +++ b/frontend/src/app/features/settings/pages/clients/client.component.html @@ -108,5 +108,5 @@
    + (dialogClose)="connectDialog.hide()" [client]="client"> \ No newline at end of file diff --git a/frontend/src/app/features/settings/pages/clients/client.component.ts b/frontend/src/app/features/settings/pages/clients/client.component.ts index 6ef18c945..c356f014a 100644 --- a/frontend/src/app/features/settings/pages/clients/client.component.ts +++ b/frontend/src/app/features/settings/pages/clients/client.component.ts @@ -23,7 +23,7 @@ export class ClientComponent { public apiCallsLimit = 0; - public connectDialog = new DialogModel(); + public connectDialog = new DialogModel(false); constructor( public readonly appsState: AppsState, diff --git a/frontend/src/app/features/settings/pages/contributors/contributor-add-form.component.html b/frontend/src/app/features/settings/pages/contributors/contributor-add-form.component.html index f5863d2bb..8b9f96fc0 100644 --- a/frontend/src/app/features/settings/pages/contributors/contributor-add-form.component.html +++ b/frontend/src/app/features/settings/pages/contributors/contributor-add-form.component.html @@ -35,5 +35,5 @@
    + (dialogClose)="importDialog.hide()" [roles]="roles" > \ No newline at end of file diff --git a/frontend/src/app/features/settings/pages/contributors/contributor.component.ts b/frontend/src/app/features/settings/pages/contributors/contributor.component.ts index ec5284be9..37cf91988 100644 --- a/frontend/src/app/features/settings/pages/contributors/contributor.component.ts +++ b/frontend/src/app/features/settings/pages/contributors/contributor.component.ts @@ -5,6 +5,8 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ +/* eslint-disable @angular-eslint/component-selector */ + import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; import { ContributorDto, ContributorsState, RoleDto } from '@app/shared'; diff --git a/frontend/src/app/features/settings/pages/contributors/import-contributors-dialog.component.html b/frontend/src/app/features/settings/pages/contributors/import-contributors-dialog.component.html index 7d9c66d0c..469dcfc4e 100644 --- a/frontend/src/app/features/settings/pages/contributors/import-contributors-dialog.component.html +++ b/frontend/src/app/features/settings/pages/contributors/import-contributors-dialog.component.html @@ -1,5 +1,5 @@ - + {{ 'contributors.importTitle' | sqxTranslate }} @@ -47,7 +47,7 @@
    - diff --git a/frontend/src/app/features/settings/pages/contributors/import-contributors-dialog.component.ts b/frontend/src/app/features/settings/pages/contributors/import-contributors-dialog.component.ts index 246b71b38..f454160c3 100644 --- a/frontend/src/app/features/settings/pages/contributors/import-contributors-dialog.component.ts +++ b/frontend/src/app/features/settings/pages/contributors/import-contributors-dialog.component.ts @@ -24,7 +24,7 @@ type ImportStatus = { }) export class ImportContributorsDialogComponent { @Output() - public close = new EventEmitter(); + public dialogClose = new EventEmitter(); @Input({ required: true }) public roles!: ReadonlyArray; diff --git a/frontend/src/app/features/settings/pages/more/more-page.component.ts b/frontend/src/app/features/settings/pages/more/more-page.component.ts index a57342989..694296137 100644 --- a/frontend/src/app/features/settings/pages/more/more-page.component.ts +++ b/frontend/src/app/features/settings/pages/more/more-page.component.ts @@ -7,14 +7,16 @@ import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; -import { AppDto, AppsState, defined, DialogService, ResourceOwner, TeamsState, TransferAppForm, Types, UpdateAppForm } from '@app/shared'; +import { AppDto, AppsState, defined, DialogService, Subscriptions, TeamsState, TransferAppForm, Types, UpdateAppForm } from '@app/shared'; @Component({ selector: 'sqx-more-page', styleUrls: ['./more-page.component.scss'], templateUrl: './more-page.component.html', }) -export class MorePageComponent extends ResourceOwner implements OnInit { +export class MorePageComponent implements OnInit { + private readonly subscriptions = new Subscriptions(); + public app!: AppDto; public teams: { id: string | null; name: string }[] = []; @@ -37,11 +39,10 @@ export class MorePageComponent extends ResourceOwner implements OnInit { private readonly router: Router, public readonly teamsState: TeamsState, ) { - super(); } public ngOnInit() { - this.own( + this.subscriptions.add( this.appsState.selectedApp.pipe(defined()) .subscribe(app => { this.app = app; diff --git a/frontend/src/app/features/settings/pages/roles/roles-page.component.ts b/frontend/src/app/features/settings/pages/roles/roles-page.component.ts index b17961e81..92babaf8c 100644 --- a/frontend/src/app/features/settings/pages/roles/roles-page.component.ts +++ b/frontend/src/app/features/settings/pages/roles/roles-page.component.ts @@ -5,12 +5,12 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ +/* eslint-disable no-return-assign */ + import { Component, OnInit } from '@angular/core'; import { Observable, of } from 'rxjs'; import { AppsState, AutocompleteSource, RoleDto, RolesService, RolesState, SchemasState } from '@app/shared'; -/* eslint-disable no-return-assign */ - class PermissionsAutocomplete implements AutocompleteSource { private permissions: ReadonlyArray = []; diff --git a/frontend/src/app/features/settings/pages/settings/settings-page.component.ts b/frontend/src/app/features/settings/pages/settings/settings-page.component.ts index ee1224157..3470eeccb 100644 --- a/frontend/src/app/features/settings/pages/settings/settings-page.component.ts +++ b/frontend/src/app/features/settings/pages/settings/settings-page.component.ts @@ -6,14 +6,16 @@ */ import { Component, OnInit } from '@angular/core'; -import { AppSettingsDto, AppsState, EditAppSettingsForm, ResourceOwner } from '@app/shared'; +import { AppSettingsDto, AppsState, EditAppSettingsForm, Subscriptions } from '@app/shared'; @Component({ selector: 'sqx-settings-page', styleUrls: ['./settings-page.component.scss'], templateUrl: './settings-page.component.html', }) -export class SettingsPageComponent extends ResourceOwner implements OnInit { +export class SettingsPageComponent implements OnInit { + private readonly subscriptions = new Subscriptions(); + public isEditable = false; public editForm = new EditAppSettingsForm(); @@ -22,13 +24,12 @@ export class SettingsPageComponent extends ResourceOwner implements OnInit { constructor( private readonly appsState: AppsState, ) { - super(); } public ngOnInit() { this.appsState.loadSettings(); - this.own( + this.subscriptions.add( this.appsState.selectedSettings .subscribe(settings => { if (settings) { diff --git a/frontend/src/app/features/settings/pages/templates/templates-page.component.ts b/frontend/src/app/features/settings/pages/templates/templates-page.component.ts index 53ece4890..d1c7e7d6a 100644 --- a/frontend/src/app/features/settings/pages/templates/templates-page.component.ts +++ b/frontend/src/app/features/settings/pages/templates/templates-page.component.ts @@ -6,19 +6,18 @@ */ import { Component, OnInit } from '@angular/core'; -import { ClientsState, ResourceOwner, TemplateDto, TemplatesState } from '@app/shared'; +import { ClientsState, TemplateDto, TemplatesState } from '@app/shared'; @Component({ selector: 'sqx-templates-page', styleUrls: ['./templates-page.component.scss'], templateUrl: './templates-page.component.html', }) -export class TemplatesPageComponent extends ResourceOwner implements OnInit { +export class TemplatesPageComponent implements OnInit { constructor( public readonly clientsState: ClientsState, public readonly templatesState: TemplatesState, ) { - super(); } public ngOnInit() { diff --git a/frontend/src/app/features/settings/pages/workflows/workflows-page.component.ts b/frontend/src/app/features/settings/pages/workflows/workflows-page.component.ts index d9cb20caa..f82f2dc44 100644 --- a/frontend/src/app/features/settings/pages/workflows/workflows-page.component.ts +++ b/frontend/src/app/features/settings/pages/workflows/workflows-page.component.ts @@ -6,14 +6,16 @@ */ import { Component, OnInit } from '@angular/core'; -import { ResourceOwner, RolesState, SchemaTagSource, WorkflowDto, WorkflowsState } from '@app/shared'; +import { RolesState, SchemaTagSource, Subscriptions, WorkflowDto, WorkflowsState } from '@app/shared'; @Component({ selector: 'sqx-workflows-page', styleUrls: ['./workflows-page.component.scss'], templateUrl: './workflows-page.component.html', }) -export class WorkflowsPageComponent extends ResourceOwner implements OnInit { +export class WorkflowsPageComponent implements OnInit { + private readonly subscriptions = new Subscriptions(); + public roles: ReadonlyArray = []; constructor( @@ -21,11 +23,10 @@ export class WorkflowsPageComponent extends ResourceOwner implements OnInit { public readonly schemasSource: SchemaTagSource, public readonly workflowsState: WorkflowsState, ) { - super(); } public ngOnInit() { - this.own( + this.subscriptions.add( this.rolesState.roles .subscribe(roles => { this.roles = roles.map(x => x.name); diff --git a/frontend/src/app/features/teams/pages/contributors/contributor-add-form.component.html b/frontend/src/app/features/teams/pages/contributors/contributor-add-form.component.html index 6d3a45a49..63f1ff407 100644 --- a/frontend/src/app/features/teams/pages/contributors/contributor-add-form.component.html +++ b/frontend/src/app/features/teams/pages/contributors/contributor-add-form.component.html @@ -30,5 +30,5 @@
    + (dialogClose)="importDialog.hide()"> \ No newline at end of file diff --git a/frontend/src/app/features/teams/pages/contributors/contributor.component.ts b/frontend/src/app/features/teams/pages/contributors/contributor.component.ts index affc6ddfd..fd30ada2b 100644 --- a/frontend/src/app/features/teams/pages/contributors/contributor.component.ts +++ b/frontend/src/app/features/teams/pages/contributors/contributor.component.ts @@ -5,6 +5,8 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ +/* eslint-disable @angular-eslint/component-selector */ + import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; import { TeamContributorsState } from '@app/features/teams/internal'; import { ContributorDto } from '@app/shared'; diff --git a/frontend/src/app/features/teams/pages/contributors/import-contributors-dialog.component.html b/frontend/src/app/features/teams/pages/contributors/import-contributors-dialog.component.html index b0b941b4e..4d84d7a05 100644 --- a/frontend/src/app/features/teams/pages/contributors/import-contributors-dialog.component.html +++ b/frontend/src/app/features/teams/pages/contributors/import-contributors-dialog.component.html @@ -1,5 +1,5 @@ - + {{ 'contributors.importTitle' | sqxTranslate }} @@ -41,7 +41,7 @@
    - diff --git a/frontend/src/app/features/teams/pages/contributors/import-contributors-dialog.component.ts b/frontend/src/app/features/teams/pages/contributors/import-contributors-dialog.component.ts index cb262f1ca..88752757c 100644 --- a/frontend/src/app/features/teams/pages/contributors/import-contributors-dialog.component.ts +++ b/frontend/src/app/features/teams/pages/contributors/import-contributors-dialog.component.ts @@ -25,7 +25,7 @@ type ImportStatus = { }) export class ImportContributorsDialogComponent { @Output() - public close = new EventEmitter(); + public dialogClose = new EventEmitter(); public importForm = new ImportContributorsForm(); public importStatus: ReadonlyArray = []; diff --git a/frontend/src/app/features/teams/pages/dashboard/dashboard-page.component.html b/frontend/src/app/features/teams/pages/dashboard/dashboard-page.component.html index 07134dc71..2dc903cab 100644 --- a/frontend/src/app/features/teams/pages/dashboard/dashboard-page.component.html +++ b/frontend/src/app/features/teams/pages/dashboard/dashboard-page.component.html @@ -56,7 +56,7 @@ - +
    diff --git a/frontend/src/app/features/teams/pages/dashboard/dashboard-page.component.ts b/frontend/src/app/features/teams/pages/dashboard/dashboard-page.component.ts index 18fdc2483..1463b3b2c 100644 --- a/frontend/src/app/features/teams/pages/dashboard/dashboard-page.component.ts +++ b/frontend/src/app/features/teams/pages/dashboard/dashboard-page.component.ts @@ -7,7 +7,7 @@ import { AfterViewInit, Component, NgZone, OnInit, Renderer2, ViewChild } from '@angular/core'; import { GridsterComponent, GridsterConfig, GridsterItem, GridType } from 'angular-gridster2'; -import { AuthService, CallsUsageDto, CurrentStorageDto, DateTime, defined, fadeAnimation, LocalStoreService, ResourceOwner, Settings, StorageUsagePerDateDto, switchSafe, TeamsState, UsagesService } from '@app/shared'; +import { AuthService, CallsUsageDto, CurrentStorageDto, DateTime, defined, fadeAnimation, LocalStoreService, Settings, StorageUsagePerDateDto, Subscriptions, switchSafe, TeamsState, UsagesService } from '@app/shared'; @Component({ selector: 'sqx-dashboard-page', @@ -17,7 +17,9 @@ import { AuthService, CallsUsageDto, CurrentStorageDto, DateTime, defined, fadeA fadeAnimation, ], }) -export class DashboardPageComponent extends ResourceOwner implements AfterViewInit, OnInit { +export class DashboardPageComponent implements AfterViewInit, OnInit { + private readonly subscriptions = new Subscriptions(); + @ViewChild('grid') public grid!: GridsterComponent; @@ -48,8 +50,6 @@ export class DashboardPageComponent extends ResourceOwner implements AfterViewIn private readonly usagesService: UsagesService, private readonly zone: NgZone, ) { - super(); - this.isStacked = localStore.getBoolean(Settings.Local.DASHBOARD_CHART_STACKED); } @@ -57,19 +57,19 @@ export class DashboardPageComponent extends ResourceOwner implements AfterViewIn const dateTo = DateTime.today().toStringFormat('yyyy-MM-dd'); const dateFrom = DateTime.today().addDays(-20).toStringFormat('yyyy-MM-dd'); - this.own( + this.subscriptions.add( this.selectedTeam.pipe(switchSafe(team => this.usagesService.getTodayStorageForTeam(team.id))) .subscribe(dto => { this.storageCurrent = dto; })); - this.own( + this.subscriptions.add( this.selectedTeam.pipe(switchSafe(team => this.usagesService.getStorageUsagesForTeam(team.id, dateFrom, dateTo))) .subscribe(dtos => { this.storageUsage = dtos; })); - this.own( + this.subscriptions.add( this.selectedTeam.pipe(switchSafe(team => this.usagesService.getCallsUsagesForTeam(team.id, dateFrom, dateTo))) .subscribe(dto => { this.callsUsage = dto; diff --git a/frontend/src/app/features/teams/pages/more/more-page.component.ts b/frontend/src/app/features/teams/pages/more/more-page.component.ts index 6468bcda3..1be8434c5 100644 --- a/frontend/src/app/features/teams/pages/more/more-page.component.ts +++ b/frontend/src/app/features/teams/pages/more/more-page.component.ts @@ -6,14 +6,16 @@ */ import { Component, OnInit } from '@angular/core'; -import { defined, ResourceOwner, TeamDto, TeamsState, UpdateTeamForm } from '@app/shared'; +import { defined, Subscriptions, TeamDto, TeamsState, UpdateTeamForm } from '@app/shared'; @Component({ selector: 'sqx-more-page', styleUrls: ['./more-page.component.scss'], templateUrl: './more-page.component.html', }) -export class MorePageComponent extends ResourceOwner implements OnInit { +export class MorePageComponent implements OnInit { + private readonly subscriptions = new Subscriptions(); + public team!: TeamDto; public isEditable = false; @@ -23,11 +25,10 @@ export class MorePageComponent extends ResourceOwner implements OnInit { constructor( private readonly teamsState: TeamsState, ) { - super(); } public ngOnInit() { - this.own( + this.subscriptions.add( this.teamsState.selectedTeam.pipe(defined()) .subscribe(team => { this.team = team; diff --git a/frontend/src/app/framework/angular/code.component.html b/frontend/src/app/framework/angular/code.component.html index dd797f9dc..64f56826e 100644 --- a/frontend/src/app/framework/angular/code.component.html +++ b/frontend/src/app/framework/angular/code.component.html @@ -1,7 +1,7 @@ -
    - -
    +
    \ No newline at end of file diff --git a/frontend/src/app/framework/angular/code.component.scss b/frontend/src/app/framework/angular/code.component.scss index b7cb6a2ab..2742d895e 100644 --- a/frontend/src/app/framework/angular/code.component.scss +++ b/frontend/src/app/framework/angular/code.component.scss @@ -1,34 +1,2 @@ @import 'mixins'; -@import 'vars'; - -.code { - background: $color-code-background; - margin: .25rem 0; - padding-left: .5rem; - padding-right: 3rem; -} - -.code, -.code-copy { - @include text-code; - min-height: 27px; - padding-bottom: .25rem; - padding-top: .25rem; -} - -.copy-container { - position: relative; -} - -.code-copy { - @include absolute(0, 0, auto, auto); - background: darken($color-border-dark, 30%); - border: 0; - color: $color-white; - padding-left: .375rem; - padding-right: .375rem; - - &:focus { - background: darken($color-border-dark, 40%); - } -} \ No newline at end of file +@import 'vars'; \ No newline at end of file diff --git a/frontend/src/app/framework/angular/code.component.ts b/frontend/src/app/framework/angular/code.component.ts index 5d1bf4108..2cb1318a7 100644 --- a/frontend/src/app/framework/angular/code.component.ts +++ b/frontend/src/app/framework/angular/code.component.ts @@ -6,6 +6,7 @@ */ import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { MathHelper } from '../internal'; @Component({ selector: 'sqx-code', @@ -13,4 +14,6 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; templateUrl: './code.component.html', changeDetection: ChangeDetectionStrategy.OnPush, }) -export class CodeComponent {} +export class CodeComponent { + public readonly id = MathHelper.guid(); +} diff --git a/frontend/src/app/framework/angular/compensate-scrollbar.directive.ts b/frontend/src/app/framework/angular/compensate-scrollbar.directive.ts index 39e9bc324..3f1b49fc8 100644 --- a/frontend/src/app/framework/angular/compensate-scrollbar.directive.ts +++ b/frontend/src/app/framework/angular/compensate-scrollbar.directive.ts @@ -5,13 +5,14 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ -import { booleanAttribute, Directive, ElementRef, HostListener, Input, Renderer2 } from '@angular/core'; -import { ResizeListener, ResizeService, ResourceOwner } from '@app/framework/internal'; +import { AfterViewInit, booleanAttribute, Directive, ElementRef, HostListener, Input, Renderer2 } from '@angular/core'; +import { ResizeListener, ResizeService, Subscriptions } from '@app/framework/internal'; @Directive({ selector: '[sqxCompensateScrollbar]', }) -export class CompensateScrollbarDirective extends ResourceOwner implements ResizeListener { +export class CompensateScrollbarDirective implements AfterViewInit, ResizeListener { + private readonly subscriptions = new Subscriptions(); private previousScrollbarWidth = -1; @Input({ alias: 'sqxCompensateScrollbar', transform: booleanAttribute }) @@ -22,9 +23,7 @@ export class CompensateScrollbarDirective extends ResourceOwner implements Resiz private readonly element: ElementRef, private readonly resizeService: ResizeService, ) { - super(); - - this.own(this.resizeService.listen(this.element.nativeElement, this)); + this.subscriptions.add(this.resizeService.listen(this.element.nativeElement, this)); } public ngAfterViewInit() { diff --git a/frontend/src/app/framework/angular/dropdown-menu.component.ts b/frontend/src/app/framework/angular/dropdown-menu.component.ts index 5e3b8a5a3..c92aec9ec 100644 --- a/frontend/src/app/framework/angular/dropdown-menu.component.ts +++ b/frontend/src/app/framework/angular/dropdown-menu.component.ts @@ -5,6 +5,8 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ +/* eslint-disable @angular-eslint/no-host-metadata-property */ + import { ChangeDetectionStrategy, Component, ElementRef, HostBinding } from '@angular/core'; import { fadeAnimation } from './animations'; diff --git a/frontend/src/app/framework/angular/forms/control-errors.component.ts b/frontend/src/app/framework/angular/forms/control-errors.component.ts index 3bb511f58..f239f6301 100644 --- a/frontend/src/app/framework/angular/forms/control-errors.component.ts +++ b/frontend/src/app/framework/angular/forms/control-errors.component.ts @@ -8,7 +8,7 @@ import { ChangeDetectionStrategy, Component, Host, Input, OnDestroy, Optional } from '@angular/core'; import { AbstractControl, FormGroupDirective, UntypedFormArray } from '@angular/forms'; import { merge } from 'rxjs'; -import { LocalizerService, StatefulComponent, Types } from '@app/framework/internal'; +import { LocalizerService, StatefulComponent, Subscriptions, Types } from '@app/framework/internal'; import { formatError } from './error-formatting'; import { touchedChange$ } from './forms-helper'; @@ -24,6 +24,7 @@ interface State { changeDetection: ChangeDetectionStrategy.OnPush, }) export class ControlErrorsComponent extends StatefulComponent implements OnDestroy { + private readonly subscriptions = new Subscriptions(); private controlDisplayName = ''; private control: AbstractControl | null = null; @@ -74,10 +75,10 @@ export class ControlErrorsComponent extends StatefulComponent implements } if (this.control !== previousControl) { - this.unsubscribeAll(); + this.subscriptions.unsubscribeAll(); if (this.control) { - this.own( + this.subscriptions.add( merge( this.control.valueChanges, this.control.statusChanges, diff --git a/frontend/src/app/framework/angular/forms/copy-global.directive.ts b/frontend/src/app/framework/angular/forms/copy-global.directive.ts new file mode 100644 index 000000000..f668e4388 --- /dev/null +++ b/frontend/src/app/framework/angular/forms/copy-global.directive.ts @@ -0,0 +1,91 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. + */ + +import { Directive, HostListener, Renderer2 } from '@angular/core'; +import { DialogService, Types } from '@app/framework/internal'; + +@Directive({ + selector: '[sqxCopyGlobal]', +}) +export class CopyGlobalDirective { + constructor( + private readonly dialogs: DialogService, + private readonly renderer: Renderer2, + ) { + } + + @HostListener('document:click', ['$event']) + public onClick(event: MouseEvent) { + function findElement(target: HTMLElement | null): string | null { + if (!target) { + return null; + } + + const id = target.getAttribute('copy')!; + + if (id) { + return id; + } + + return findElement(target.parentElement); + } + + const toCopy = document.getElementById(findElement(event.target as any)!); + + if (!toCopy) { + return; + } + + this.copyToClipbord(toCopy); + } + + private copyToClipbord(element: HTMLElement) { + if (Types.is(element, HTMLInputElement) || Types.is(element, HTMLTextAreaElement)) { + const currentFocus: any = document.activeElement; + + const prevSelectionStart = element.selectionStart; + const prevSelectionEnd = element.selectionEnd; + + element.focus(); + element.setSelectionRange(0, element.value.length); + + this.copy(); + + element.setSelectionRange(prevSelectionStart!, prevSelectionEnd!); + + if (currentFocus && Types.isFunction(currentFocus.focus)) { + currentFocus.focus(); + } + } else { + const input = this.renderer.createElement('textarea'); + + this.renderer.setStyle(input, 'position', 'absolute'); + this.renderer.setStyle(input, 'right', '-1000px'); + this.renderer.appendChild(document.body, input); + + input.value = element.innerText; + input.select(); + + this.copy(); + + this.renderer.removeChild(document.body, input); + } + } + + private copy() { + try { + // eslint-disable-next-line deprecation/deprecation + document.execCommand('copy'); + + this.dialogs.notifyInfo('i18n:common.clipboardAdded'); + + return true; + } catch (e) { + return false; + } + } +} diff --git a/frontend/src/app/framework/angular/forms/editors/autocomplete.component.html b/frontend/src/app/framework/angular/forms/editors/autocomplete.component.html index b40272925..a260646d5 100644 --- a/frontend/src/app/framework/angular/forms/editors/autocomplete.component.html +++ b/frontend/src/app/framework/angular/forms/editors/autocomplete.component.html @@ -1,6 +1,7 @@
    >; @@ -45,6 +45,7 @@ const NO_EMIT = { emitEvent: false }; changeDetection: ChangeDetectionStrategy.OnPush, }) export class AutocompleteComponent extends StatefulControlComponent> implements OnInit, OnDestroy { + private readonly subscriptions = new Subscriptions(); private readonly modalStream = new Subject(); private timer: any; @@ -133,7 +134,7 @@ export class AutocompleteComponent extends StatefulControlComponent { if (!this.itemsSource) { diff --git a/frontend/src/app/framework/angular/forms/editors/code-editor.component.ts b/frontend/src/app/framework/angular/forms/editors/code-editor.component.ts index 1ff4b5aa7..bb5386b24 100644 --- a/frontend/src/app/framework/angular/forms/editors/code-editor.component.ts +++ b/frontend/src/app/framework/angular/forms/editors/code-editor.component.ts @@ -294,6 +294,8 @@ export class CodeEditorComponent extends StatefulControlComponent<{}, any> imple printMargin: !this.singleLine, showGutter: !this.singleLine, }); + + this.aceEditor.commands.bindKey('Enter|Shift-Enter', this.singleLine ? 'null' : undefined); } private setValue(value: string) { diff --git a/frontend/src/app/framework/angular/forms/editors/date-time-editor.component.html b/frontend/src/app/framework/angular/forms/editors/date-time-editor.component.html index b97347f64..14686fe47 100644 --- a/frontend/src/app/framework/angular/forms/editors/date-time-editor.component.html +++ b/frontend/src/app/framework/angular/forms/editors/date-time-editor.component.html @@ -11,7 +11,10 @@
    + (blur)="callTouched()" + minlength="0" + maxlength="10" + #dateInput>
    diff --git a/frontend/src/app/framework/angular/forms/editors/date-time-editor.component.ts b/frontend/src/app/framework/angular/forms/editors/date-time-editor.component.ts index c9aa4bb18..5da284468 100644 --- a/frontend/src/app/framework/angular/forms/editors/date-time-editor.component.ts +++ b/frontend/src/app/framework/angular/forms/editors/date-time-editor.component.ts @@ -5,10 +5,10 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ -import { AfterViewInit, booleanAttribute, ChangeDetectionStrategy, Component, ElementRef, EventEmitter, forwardRef, Input, OnInit, Output, ViewChild } from '@angular/core'; +import { AfterViewInit, booleanAttribute, ChangeDetectionStrategy, Component, ElementRef, EventEmitter, forwardRef, inject, Input, OnInit, Output, ViewChild } from '@angular/core'; import { NG_VALUE_ACCESSOR, UntypedFormControl } from '@angular/forms'; import * as Pikaday from 'pikaday/pikaday'; -import { DateHelper, DateTime, StatefulControlComponent, UIOptions } from '@app/framework/internal'; +import { DateHelper, DateTime, StatefulControlComponent, Subscriptions, UIOptions } from '@app/framework/internal'; import { FocusComponent } from './../forms-helper'; declare module 'pikaday/pikaday'; @@ -34,14 +34,15 @@ interface State { changeDetection: ChangeDetectionStrategy.OnPush, }) export class DateTimeEditorComponent extends StatefulControlComponent implements OnInit, AfterViewInit, FocusComponent { - private readonly hideDateButtonsSettings: boolean; - private readonly hideDateTimeModeButtonSetting: boolean; + private readonly subscriptions = new Subscriptions(); + private readonly hideDateButtonsSettings: boolean = !!inject(UIOptions).value.hideDateButtons; + private readonly hideDateTimeModeButtonSetting: boolean = !!inject(UIOptions).value.hideDateTimeModeButton; private picker: any; private dateTime?: DateTime | null; private suppressEvents = false; @Output() - public blur = new EventEmitter(); + public editorBlur = new EventEmitter(); @Input() public mode: 'DateTime' | 'Date' = 'Date'; @@ -88,22 +89,19 @@ export class DateTimeEditorComponent extends StatefulControlComponent { this.dateTime = this.getValue(); this.callChangeFormatted(); })); - this.own( + this.subscriptions.add( this.dateControl.valueChanges.subscribe(() => { this.dateTime = this.getValue(); @@ -122,7 +120,7 @@ export class DateTimeEditorComponent extends StatefulControlComponent DropdownComponent), multi: true, @@ -38,13 +38,14 @@ interface State { changeDetection: ChangeDetectionStrategy.OnPush, }) export class DropdownComponent extends StatefulControlComponent> implements AfterContentInit, OnInit { + private readonly subscriptions = new Subscriptions(); private value: any; @Output() - public open = new EventEmitter(); + public dropdownOpen = new EventEmitter(); @Output() - public close = new EventEmitter(); + public dropdownClose = new EventEmitter(); @Input({ transform: booleanAttribute }) public itemsLoading?: boolean | null; @@ -100,7 +101,7 @@ export class DropdownComponent extends StatefulControlComponent { if (!this.items || !queryText) { @@ -190,7 +191,7 @@ export class DropdownComponent extends StatefulControlComponent + (dropdownOpen)="load()"> `, diff --git a/frontend/src/app/framework/angular/forms/editors/localized-input.component.html b/frontend/src/app/framework/angular/forms/editors/localized-input.component.html index 04a29d604..2aa84f544 100644 --- a/frontend/src/app/framework/angular/forms/editors/localized-input.component.html +++ b/frontend/src/app/framework/angular/forms/editors/localized-input.component.html @@ -30,30 +30,30 @@ + (editorBlur)="callTouched()"> + (editorBlur)="callTouched()"> + (editorBlur)="callTouched()">
    + (blur)="callTouched()">
    diff --git a/frontend/src/app/framework/angular/forms/editors/tag-editor.component.html b/frontend/src/app/framework/angular/forms/editors/tag-editor.component.html index 32b7ac2de..78807000e 100644 --- a/frontend/src/app/framework/angular/forms/editors/tag-editor.component.html +++ b/frontend/src/app/framework/angular/forms/editors/tag-editor.component.html @@ -14,7 +14,12 @@ TagEditorComponent), multi: true, @@ -38,6 +38,7 @@ interface State { changeDetection: ChangeDetectionStrategy.OnPush, }) export class TagEditorComponent extends StatefulControlComponent> implements AfterViewInit, OnInit { + private readonly subscriptions = new Subscriptions(); private readonly textMeasurer: TextMeasurer; private latestValue: any; private latestInput?: string; @@ -49,13 +50,13 @@ export class TagEditorComponent extends StatefulControlComponent; @Output() - public open = new EventEmitter(); + public dropdownOpen = new EventEmitter(); @Output() - public close = new EventEmitter(); + public dropdownClose = new EventEmitter(); @Output() - public blur = new EventEmitter(); + public editorBlur = new EventEmitter(); @Input() public itemConverter = StringConverter.INSTANCE; @@ -147,7 +148,7 @@ export class TagEditorComponent extends StatefulControlComponent { this.resetSize(); @@ -163,7 +164,7 @@ export class TagEditorComponent extends StatefulControlComponent + (dropdownOpen)="load()"> `, diff --git a/frontend/src/app/framework/angular/forms/extended-form-array.spec.ts b/frontend/src/app/framework/angular/forms/extended-form-array.spec.ts index 4bac0f7af..6f8acca46 100644 --- a/frontend/src/app/framework/angular/forms/extended-form-array.spec.ts +++ b/frontend/src/app/framework/angular/forms/extended-form-array.spec.ts @@ -41,6 +41,18 @@ describe('UndefinableFormArray', () => { valueActual: [1], }]; + it('should initialize with undefined', () => { + const control = new UndefinableFormArray(); + + expect(control.value).toBeUndefined(); + }); + + it('should initialize with empty array', () => { + const control = new UndefinableFormArray([]); + + expect(control.value).toEqual([]); + }); + it('should provide value even if controls are disabled', () => { const control = new UndefinableFormArray([ new UntypedFormControl('1'), diff --git a/frontend/src/app/framework/angular/forms/extended-form-array.ts b/frontend/src/app/framework/angular/forms/extended-form-array.ts index 9913c1fef..ed024f902 100644 --- a/frontend/src/app/framework/angular/forms/extended-form-array.ts +++ b/frontend/src/app/framework/angular/forms/extended-form-array.ts @@ -25,8 +25,8 @@ export class ExtendedFormArray extends UntypedFormArray { export class UndefinableFormArray extends ExtendedFormArray { private isUndefined = false; - constructor(controls: AbstractControl[], validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null) { - super(controls, validatorOrOpts, asyncValidator); + constructor(controls?: AbstractControl[], validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null) { + super(controls || [], validatorOrOpts, asyncValidator); const reduce = (this as any)['_reduceValue']; @@ -37,6 +37,12 @@ export class UndefinableFormArray extends ExtendedFormArray { return reduce.apply(this); } }; + + if (Types.isUndefined(controls)) { + this.isUndefined = true; + + super.reset([], { emitEvent: false }); + } } public getRawValue() { diff --git a/frontend/src/app/framework/angular/forms/extended-form-group.spec.ts b/frontend/src/app/framework/angular/forms/extended-form-group.spec.ts index 9da6d9c3d..4bf25cfbb 100644 --- a/frontend/src/app/framework/angular/forms/extended-form-group.spec.ts +++ b/frontend/src/app/framework/angular/forms/extended-form-group.spec.ts @@ -8,7 +8,7 @@ import { UntypedFormControl, UntypedFormGroup } from '@angular/forms'; import { ExtendedFormGroup, UndefinableFormGroup } from './extended-form-group'; -describe('UndefinableFormGroup', () => { +describe('ExtendedFormGroup', () => { it('should provide value even if controls are disabled', () => { const control = new ExtendedFormGroup({ test1: new UntypedFormControl('1'), @@ -23,7 +23,7 @@ describe('UndefinableFormGroup', () => { }); }); -describe('ExtendedFormGroup', () => { +describe('UndefinableFormGroup', () => { const tests = [{ name: 'undefined (on)', undefinable: true, @@ -41,8 +41,20 @@ describe('ExtendedFormGroup', () => { valueActual: { field: 1 }, }]; + it('should initialize with undefined', () => { + const control = new UndefinableFormGroup(); + + expect(control.value).toBeUndefined(); + }); + + it('should initialize with empty array', () => { + const control = new UndefinableFormGroup({}); + + expect(control.value).toEqual({}); + }); + it('should provide value even if controls are disabled', () => { - const control = new ExtendedFormGroup({ + const control = new UndefinableFormGroup({ test1: new UntypedFormControl('1'), test2: new UntypedFormControl('2'), }); diff --git a/frontend/src/app/framework/angular/forms/extended-form-group.ts b/frontend/src/app/framework/angular/forms/extended-form-group.ts index ab65bcdd6..e08e7328f 100644 --- a/frontend/src/app/framework/angular/forms/extended-form-group.ts +++ b/frontend/src/app/framework/angular/forms/extended-form-group.ts @@ -31,8 +31,8 @@ export class ExtendedFormGroup extends UntypedFormGroup { export class UndefinableFormGroup extends ExtendedFormGroup { private isUndefined = false; - constructor(controls: { [key: string]: AbstractControl }, validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null) { - super(controls, validatorOrOpts, asyncValidator); + constructor(controls?: { [key: string]: AbstractControl }, validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null) { + super(controls || {}, validatorOrOpts, asyncValidator); const reduce = (this as any)['_reduceValue']; @@ -43,6 +43,12 @@ export class UndefinableFormGroup extends ExtendedFormGroup { return reduce.apply(this); } }; + + if (Types.isUndefined(controls)) { + this.isUndefined = true; + + super.reset({}, { emitEvent: false }); + } } public getRawValue() { diff --git a/frontend/src/app/framework/angular/forms/file-drop.directive.ts b/frontend/src/app/framework/angular/forms/file-drop.directive.ts index d1b1be8d7..7ac4298ca 100644 --- a/frontend/src/app/framework/angular/forms/file-drop.directive.ts +++ b/frontend/src/app/framework/angular/forms/file-drop.directive.ts @@ -5,6 +5,8 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ +/* eslint-disable @angular-eslint/no-input-rename */ + import { booleanAttribute, Directive, ElementRef, EventEmitter, HostListener, Input, Output, Renderer2 } from '@angular/core'; import { Types } from '@app/framework/internal'; @@ -27,7 +29,7 @@ export class FileDropDirective { public disabled = false; @Output('sqxDropFile') - public drop = new EventEmitter>(); + public fileDrop = new EventEmitter>(); constructor( private readonly element: ElementRef, @@ -43,7 +45,7 @@ export class FileDropDirective { const files = await this.getAllowedFiles(event.clipboardData); if (files && !this.disabled) { - this.drop.emit(files); + this.fileDrop.emit(files); } } } @@ -84,7 +86,7 @@ export class FileDropDirective { const files = await this.getAllowedFiles(event.dataTransfer); if (files && !this.disabled) { - this.drop.emit(files); + this.fileDrop.emit(files); } } } @@ -121,7 +123,6 @@ export class FileDropDirective { } const files: File[] = []; - const items = getItems(dataTransfer); // Loop over files first, otherwise Chromes deletes them in the async call. @@ -139,7 +140,7 @@ export class FileDropDirective { if (webkitEntry && webkitEntry.isDirectory) { // eslint-disable-next-line no-await-in-loop - await this.transferWebkitTree(webkitEntry, files); + await this.traverseWebkitTree(webkitEntry, files); } } } @@ -151,7 +152,7 @@ export class FileDropDirective { return files; } - private async transferWebkitTree(item: any, files: File[]) { + private async traverseWebkitTree(item: any, files: File[]) { if (item.isFile) { const file = await getFilePromise(item); @@ -163,7 +164,7 @@ export class FileDropDirective { for (const entry of entries) { // eslint-disable-next-line no-await-in-loop - await this.transferWebkitTree(entry, files); + await this.traverseWebkitTree(entry, files); } } } diff --git a/frontend/src/app/framework/angular/forms/templated-form-group.spec.ts b/frontend/src/app/framework/angular/forms/templated-form-group.spec.ts index 13f2c1433..f29a8b3ef 100644 --- a/frontend/src/app/framework/angular/forms/templated-form-group.spec.ts +++ b/frontend/src/app/framework/angular/forms/templated-form-group.spec.ts @@ -48,6 +48,7 @@ describe('TemplatedFormGroup', () => { expect(formArray.value).toEqual(value1); }); + it(`Should call template to clear items with for ${name}`, () => { const value1 = { value: 1, diff --git a/frontend/src/app/framework/angular/image-source.directive.ts b/frontend/src/app/framework/angular/image-source.directive.ts index 2f435bc85..4222b871c 100644 --- a/frontend/src/app/framework/angular/image-source.directive.ts +++ b/frontend/src/app/framework/angular/image-source.directive.ts @@ -6,14 +6,15 @@ */ import { AfterViewInit, Directive, ElementRef, Input, NgZone, numberAttribute, OnDestroy, OnInit, Renderer2 } from '@angular/core'; -import { MathHelper, ResourceOwner, StringHelper } from '@app/framework/internal'; +import { MathHelper, StringHelper, Subscriptions } from '@app/framework/internal'; const LAYOUT_CACHE: { [key: string]: { width: number; height: number } } = {}; @Directive({ selector: '[sqxImageSource]', }) -export class ImageSourceDirective extends ResourceOwner implements OnDestroy, OnInit, AfterViewInit { +export class ImageSourceDirective implements OnDestroy, OnInit, AfterViewInit { + private readonly subscriptions = new Subscriptions(); private size: any; private loadTimer: any; private loadRetries = 0; @@ -36,12 +37,9 @@ export class ImageSourceDirective extends ResourceOwner implements OnDestroy, O private readonly element: ElementRef, private readonly renderer: Renderer2, ) { - super(); } public ngOnDestroy() { - super.ngOnDestroy(); - clearTimeout(this.loadTimer); } @@ -51,17 +49,17 @@ export class ImageSourceDirective extends ResourceOwner implements OnDestroy, O } this.zone.runOutsideAngular(() => { - this.own( + this.subscriptions.add( this.renderer.listen(this.parent, 'resize', () => { this.resize(); })); - this.own( + this.subscriptions.add( this.renderer.listen(this.element.nativeElement, 'load', () => { this.onLoad(); })); - this.own( + this.subscriptions.add( this.renderer.listen(this.element.nativeElement, 'error', () => { this.onError(); })); diff --git a/frontend/src/app/framework/angular/image-url.directive.ts b/frontend/src/app/framework/angular/image-url.directive.ts index 09ae0b7a6..5a88a20ad 100644 --- a/frontend/src/app/framework/angular/image-url.directive.ts +++ b/frontend/src/app/framework/angular/image-url.directive.ts @@ -6,12 +6,14 @@ */ import { Directive, ElementRef, HostBinding, Input, NgZone, OnInit, Renderer2 } from '@angular/core'; -import { ResourceOwner } from '@app/framework/internal'; +import { Subscriptions } from '@app/framework/internal'; @Directive({ selector: '[sqxImageUrl]', }) -export class ImageUrlDirective extends ResourceOwner implements OnInit { +export class ImageUrlDirective implements OnInit { + private readonly subscriptions = new Subscriptions(); + @Input('sqxImageUrl') @HostBinding('attr.src') public imageUrl!: string; @@ -20,17 +22,16 @@ export class ImageUrlDirective extends ResourceOwner implements OnInit { private readonly element: ElementRef, private readonly renderer: Renderer2, ) { - super(); } public ngOnInit() { this.zone.runOutsideAngular(() => { - this.own( + this.subscriptions.add( this.renderer.listen(this.element.nativeElement, 'load', () => { this.onLoad(); })); - this.own( + this.subscriptions.add( this.renderer.listen(this.element.nativeElement, 'error', () => { this.onError(); })); diff --git a/frontend/src/app/framework/angular/layout.component.ts b/frontend/src/app/framework/angular/layout.component.ts index 31fcd31d7..c9758855e 100644 --- a/frontend/src/app/framework/angular/layout.component.ts +++ b/frontend/src/app/framework/angular/layout.component.ts @@ -5,8 +5,6 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ -/* eslint-disable import/no-cycle */ - import { AfterViewInit, booleanAttribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Input, numberAttribute, OnDestroy, OnInit, Optional, Renderer2, ViewChild } from '@angular/core'; import { ActivatedRoute, NavigationEnd, QueryParamsHandling, Router } from '@angular/router'; import { concat, defer, filter, map, of } from 'rxjs'; diff --git a/frontend/src/app/framework/angular/long-hover.directive.ts b/frontend/src/app/framework/angular/long-hover.directive.ts index be7575e94..da6fc3b46 100644 --- a/frontend/src/app/framework/angular/long-hover.directive.ts +++ b/frontend/src/app/framework/angular/long-hover.directive.ts @@ -5,6 +5,9 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ +/* eslint-disable @angular-eslint/no-input-rename */ +/* eslint-disable @angular-eslint/no-output-rename */ + import { Directive, EventEmitter, HostListener, Input, numberAttribute, Output, Renderer2 } from '@angular/core'; @Directive({ diff --git a/frontend/src/app/framework/angular/markdown.directive.ts b/frontend/src/app/framework/angular/markdown.directive.ts index 54ab21a30..77e48b071 100644 --- a/frontend/src/app/framework/angular/markdown.directive.ts +++ b/frontend/src/app/framework/angular/markdown.directive.ts @@ -15,6 +15,9 @@ export class MarkdownDirective { @Input('sqxMarkdown') public markdown!: string; + @Input({ transform: booleanAttribute }) + public trusted = false; + @Input({ transform: booleanAttribute }) public inline = true; @@ -43,7 +46,7 @@ export class MarkdownDirective { } else if (this.optional && !hasExclamation) { html = markdown; } else if (this.markdown) { - html = renderMarkdown(markdown, this.inline); + html = renderMarkdown(markdown, this.inline, this.trusted); } const hasHtml = html.indexOf('<') >= 0 || html.indexOf('&') >= 0; diff --git a/frontend/src/app/framework/angular/modals/dialog-renderer.component.html b/frontend/src/app/framework/angular/modals/dialog-renderer.component.html index c735cd789..7821e6742 100644 --- a/frontend/src/app/framework/angular/modals/dialog-renderer.component.html +++ b/frontend/src/app/framework/angular/modals/dialog-renderer.component.html @@ -1,7 +1,7 @@ - + {{request.title | sqxTranslate}} @@ -32,7 +32,7 @@
    - +
    diff --git a/frontend/src/app/framework/angular/modals/dialog-renderer.component.ts b/frontend/src/app/framework/angular/modals/dialog-renderer.component.ts index 5d9981cf8..9b20e5c9f 100644 --- a/frontend/src/app/framework/angular/modals/dialog-renderer.component.ts +++ b/frontend/src/app/framework/angular/modals/dialog-renderer.component.ts @@ -7,7 +7,7 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import { timer } from 'rxjs'; -import { DialogModel, DialogRequest, DialogService, fadeAnimation, Notification, StatefulComponent, Tooltip } from '@app/framework/internal'; +import { DialogModel, DialogRequest, DialogService, fadeAnimation, Notification, StatefulComponent, Subscriptions, Tooltip } from '@app/framework/internal'; interface State { // The pending dialog request. @@ -30,6 +30,8 @@ interface State { changeDetection: ChangeDetectionStrategy.OnPush, }) export class DialogRendererComponent extends StatefulComponent implements OnInit { + private readonly subscriptions = new Subscriptions(); + public dialogView = new DialogModel(); constructor( @@ -39,14 +41,14 @@ export class DialogRendererComponent extends StatefulComponent implements } public ngOnInit() { - this.own( + this.subscriptions.add( this.dialogView.isOpenChanges.subscribe(isOpen => { if (!isOpen) { this.finishRequest(false); } })); - this.own( + this.subscriptions.add( this.dialogs.notifications.subscribe(notification => { this.next(s => ({ ...s, @@ -54,13 +56,13 @@ export class DialogRendererComponent extends StatefulComponent implements })); if (notification.displayTime > 0) { - this.own(timer(notification.displayTime).subscribe(() => { + this.subscriptions.add(timer(notification.displayTime).subscribe(() => { this.close(notification); })); } })); - this.own( + this.subscriptions.add( this.dialogs.dialogs .subscribe(dialogRequest => { this.cancel(); @@ -70,7 +72,7 @@ export class DialogRendererComponent extends StatefulComponent implements this.next({ dialogRequest }); })); - this.own( + this.subscriptions.add( this.dialogs.tooltips .subscribe(tooltip => { this.next(s => { diff --git a/frontend/src/app/framework/angular/modals/modal-dialog.component.html b/frontend/src/app/framework/angular/modals/modal-dialog.component.html index 9eabdc04d..267e5de19 100644 --- a/frontend/src/app/framework/angular/modals/modal-dialog.component.html +++ b/frontend/src/app/framework/angular/modals/modal-dialog.component.html @@ -8,7 +8,7 @@ - +
    - \ No newline at end of file + \ No newline at end of file diff --git a/frontend/src/app/framework/angular/modals/modal-dialog.component.ts b/frontend/src/app/framework/angular/modals/modal-dialog.component.ts index d233ac3eb..32976db4b 100644 --- a/frontend/src/app/framework/angular/modals/modal-dialog.component.ts +++ b/frontend/src/app/framework/angular/modals/modal-dialog.component.ts @@ -19,7 +19,7 @@ import { fadeAnimation } from '@app/framework/internal'; }) export class ModalDialogComponent implements AfterViewInit { @Output() - public close = new EventEmitter(); + public dialogClose = new EventEmitter(); @Input({ transform: booleanAttribute }) public showClose?: boolean | null = true; diff --git a/frontend/src/app/framework/angular/modals/modal.directive.ts b/frontend/src/app/framework/angular/modals/modal.directive.ts index f75157ddf..d76ba69b0 100644 --- a/frontend/src/app/framework/angular/modals/modal.directive.ts +++ b/frontend/src/app/framework/angular/modals/modal.directive.ts @@ -5,8 +5,10 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ +/* eslint-disable @angular-eslint/no-input-rename */ + import { booleanAttribute, ChangeDetectorRef, Directive, EmbeddedViewRef, Input, OnDestroy, Renderer2, TemplateRef, ViewContainerRef } from '@angular/core'; -import { DialogModel, ModalModel, ResourceOwner, Types } from '@app/framework/internal'; +import { DialogModel, ModalModel, Subscriptions, Types } from '@app/framework/internal'; import { RootViewComponent } from './root-view.component'; declare type Model = DialogModel | ModalModel | any; @@ -15,8 +17,8 @@ declare type Model = DialogModel | ModalModel | any; selector: '[sqxModal]', }) export class ModalDirective implements OnDestroy { - private readonly eventsView = new ResourceOwner(); - private readonly eventsModel = new ResourceOwner(); + private readonly eventsView = new Subscriptions(); + private readonly eventsModel = new Subscriptions(); private static backdrop: any; private currentModel: DialogModel | ModalModel | null = null; private currentContext: ModalContext = new ModalContext(); @@ -112,7 +114,7 @@ export class ModalDirective implements OnDestroy { if (isModel(value)) { this.currentModel = value; - this.eventsModel.own(value.isOpenChanges.subscribe(isOpen => this.update(isOpen))); + this.eventsModel.add(value.isOpenChanges.subscribe(isOpen => this.update(isOpen))); } else { this.currentContext.$implicit = value; @@ -143,12 +145,12 @@ export class ModalDirective implements OnDestroy { insertBefore(this.renderer, this.renderRoots[0], backdrop); - this.eventsView.own(this.renderer.listen(backdrop, 'click', this.backdropListener)); + this.eventsView.add(this.renderer.listen(backdrop, 'click', this.backdropListener)); } if (this.closeAlways && this.renderRoots) { for (const node of this.renderRoots) { - this.eventsView.own(this.renderer.listen(node, 'click', this.elementListener)); + this.eventsView.add(this.renderer.listen(node, 'click', this.elementListener)); } } } diff --git a/frontend/src/app/framework/angular/modals/tooltip.directive.ts b/frontend/src/app/framework/angular/modals/tooltip.directive.ts index d5e26ac63..0029d5758 100644 --- a/frontend/src/app/framework/angular/modals/tooltip.directive.ts +++ b/frontend/src/app/framework/angular/modals/tooltip.directive.ts @@ -5,6 +5,8 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ +/* eslint-disable @angular-eslint/directive-selector */ + import { Directive, ElementRef, HostListener, Input, numberAttribute, OnDestroy, Renderer2 } from '@angular/core'; import { DialogService, FloatingPlacement, Tooltip } from '@app/framework/internal'; diff --git a/frontend/src/app/framework/angular/pipes/array.pipes.ts b/frontend/src/app/framework/angular/pipes/array.pipes.ts new file mode 100644 index 000000000..26b3bd9ad --- /dev/null +++ b/frontend/src/app/framework/angular/pipes/array.pipes.ts @@ -0,0 +1,18 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. + */ + +import { Pipe, PipeTransform } from '@angular/core'; + +@Pipe({ + name: 'sqxReverse', + pure: true, +}) +export class ReversePipe implements PipeTransform { + public transform(value: ReadonlyArray) { + return value.slice().reverse(); + } +} \ No newline at end of file diff --git a/frontend/src/app/framework/angular/pipes/colors.pipes.spec.ts b/frontend/src/app/framework/angular/pipes/colors.pipes.spec.ts index 75010f346..dc554e226 100644 --- a/frontend/src/app/framework/angular/pipes/colors.pipes.spec.ts +++ b/frontend/src/app/framework/angular/pipes/colors.pipes.spec.ts @@ -5,7 +5,9 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ -import { DarkenPipe, LightenPipe } from './colors.pipes'; +/* eslint-disable @typescript-eslint/naming-convention */ + +import { DarkenPipe, LightenPipe, StringColorPipe } from './colors.pipes'; describe('DarkenPipe', () => { const pipe = new DarkenPipe(); @@ -62,3 +64,17 @@ describe('LightenPipe', () => { expect(result).toEqual('#98567d'); }); }); + +describe('StringColorPipe', () => { + const pipe = new StringColorPipe(); + + it('should compute color from string', () => { + const color1_1 = pipe.transform('sebastian@squidex.io'); + const color1_2 = pipe.transform('sebastian@squidex.io'); + + const color2 = pipe.transform('hello@squidex.io'); + + expect(color1_1).toEqual(color1_2); + expect(color1_1).not.toEqual(color2); + }); +}); diff --git a/frontend/src/app/framework/angular/pipes/colors.pipes.ts b/frontend/src/app/framework/angular/pipes/colors.pipes.ts index 89863933b..0d604845a 100644 --- a/frontend/src/app/framework/angular/pipes/colors.pipes.ts +++ b/frontend/src/app/framework/angular/pipes/colors.pipes.ts @@ -5,137 +5,8 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ -/* eslint-disable one-var-declaration-per-line */ -/* eslint-disable one-var */ -/* eslint-disable no-sequences */ - import { Pipe, PipeTransform } from '@angular/core'; - -interface RGBColor { - r: number; - g: number; - b: number; -} - -interface HSVColor { - h: number; - s: number; - v: number; -} - -interface ColorDefinition { - regex: RegExp; - - process(bots: RegExpExecArray): RGBColor; -} - -const ColorDefinitions: ReadonlyArray = [ - { - regex: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/, - process: (bits) => ({ - r: parseInt(bits[1], 10) / 255, - g: parseInt(bits[2], 10) / 255, - b: parseInt(bits[3], 10) / 255, - }), - }, - { - regex: /^(\w{2})(\w{2})(\w{2})$/, - process: (bits) => ({ - r: parseInt(bits[1], 16) / 255, - g: parseInt(bits[2], 16) / 255, - b: parseInt(bits[3], 16) / 255, - }), - }, - { - regex: /^(\w{1})(\w{1})(\w{1})$/, - process: (bits) => ({ - r: parseInt(bits[1] + bits[1], 16) / 255, - g: parseInt(bits[2] + bits[2], 16) / 255, - b: parseInt(bits[3] + bits[3], 16) / 255, - }), - }, -]; - -function parseColor(value: string) { - if (value.charAt(0) === '#') { - value = value.substring(1, 7); - } - - value = value.replace(/ /g, '').toLowerCase(); - - for (const colorDefinition of ColorDefinitions) { - const bits = colorDefinition.regex.exec(value); - - if (bits) { - return colorDefinition.process(bits); - } - } - - throw new Error('Color is not in a valid format.'); -} - -function rgbToHsv({ r, g, b }: RGBColor): HSVColor { - const max = Math.max(r, g, b); - const min = Math.min(r, g, b); - - let h = 0; - const d = max - min; - const s = max === 0 ? 0 : d / max; - const v = max; - - if (max === min) { - h = 0; - } else { - switch (max) { - case r: h = (g - b) / d + (g < b ? 6 : 0); break; - case g: h = (b - r) / d + 2; break; - case b: h = (r - g) / d + 4; break; - } - - h /= 6; - } - - return { h, s, v }; -} - -function hsvToRgb({ h, s, v }: HSVColor): RGBColor { - let r = 0, g = 0, b = 0; - - const i = Math.floor(h * 6); - const f = h * 6 - i; - const p = v * (1 - s); - const q = v * (1 - f * s); - const t = v * (1 - (1 - f) * s); - - switch (i % 6) { - case 0: r = v, g = t, b = p; break; - case 1: r = q, g = v, b = p; break; - case 2: r = p, g = v, b = t; break; - case 3: r = p, g = q, b = v; break; - case 4: r = t, g = p, b = v; break; - case 5: r = v, g = p, b = q; break; - } - - return { r, g, b }; -} - -function colorString({ r, g, b }: RGBColor) { - let rs = Math.round(r * 255).toString(16); - let gs = Math.round(g * 255).toString(16); - let bs = Math.round(b * 255).toString(16); - - if (rs.length === 1) { - rs = `0${rs}`; - } - if (gs.length === 1) { - gs = `0${gs}`; - } - if (bs.length === 1) { - bs = `0${bs}`; - } - - return `#${rs}${gs}${bs}`; -} +import { ColorHelper } from '@app/framework/utils/color-helper'; @Pipe({ name: 'sqxDarken', @@ -143,12 +14,12 @@ function colorString({ r, g, b }: RGBColor) { }) export class DarkenPipe implements PipeTransform { public transform(value: string, percentage: number): any { - const rgb = parseColor(value); - const hsv = rgbToHsv(rgb); + const rgb = ColorHelper.parseColor(value); + const hsv = ColorHelper.rgbToHsv(rgb); hsv.v = Math.max(0, hsv.v * (1 - (percentage / 100))); - return colorString(hsvToRgb(hsv)); + return ColorHelper.colorString(ColorHelper.hsvToRgb(hsv)); } } @@ -158,11 +29,21 @@ export class DarkenPipe implements PipeTransform { }) export class LightenPipe implements PipeTransform { public transform(value: string, percentage: number): any { - const rgb = parseColor(value); - const hsv = rgbToHsv(rgb); + const rgb = ColorHelper.parseColor(value); + const hsv = ColorHelper.rgbToHsv(rgb); hsv.v = Math.min(1, hsv.v * (1 + (percentage / 100))); - return colorString(hsvToRgb(hsv)); + return ColorHelper.colorString(ColorHelper.hsvToRgb(hsv)); + } +} + +@Pipe({ + name: 'sqxStringColor', + pure: true, +}) +export class StringColorPipe implements PipeTransform { + public transform(value: string) { + return ColorHelper.fromStringHash(value); } } diff --git a/frontend/src/app/framework/angular/pipes/date-time.pipes.spec.ts b/frontend/src/app/framework/angular/pipes/date-time.pipes.spec.ts index e4133d093..197fb0ab8 100644 --- a/frontend/src/app/framework/angular/pipes/date-time.pipes.spec.ts +++ b/frontend/src/app/framework/angular/pipes/date-time.pipes.spec.ts @@ -8,7 +8,17 @@ import { DateHelper, DateTime, Duration } from '@app/framework/internal'; import { DatePipe, DayOfWeekPipe, DayPipe, DurationPipe, FromNowPipe, FullDateTimePipe, ISODatePipe, MonthPipe, ShortDatePipe, ShortTimePipe } from './date-time.pipes'; -const dateTime = DateTime.parseISO('2013-10-03T12:13:14.125', false); +const dateSource = '2013-10-03T12:13:14.125'; +const dateTime = DateTime.parseISO(dateSource, false); +const dateString = dateTime.toISOString(); + +const TestCases = [{ + value: dateString, + name: 'String', +}, { + value: dateTime, + name: 'DateTime', +}]; describe('DurationPipe', () => { beforeEach(() => { @@ -35,92 +45,107 @@ describe('DurationPipe', () => { }); }); -describe('DatePipe', () => { +describe('FromNowPipe', () => { beforeEach(() => { DateHelper.setlocale(null); }); - it('should format to two digit day number and short month name and year', () => { - const pipe = new DatePipe(); + it('should format to from now string from DateTime', () => { + const pipe = new FromNowPipe(); + + const actual = pipe.transform(DateTime.now().addMinutes(-4)); + const expected = '4 minutes ago'; + + expect(actual).toBe(expected); + }); + + it('should format to from now string from String', () => { + const pipe = new FromNowPipe(); - const actual = pipe.transform(dateTime); - const expected = '03. Oct 2013'; + const actual = pipe.transform(DateTime.now().addMinutes(-4).toISOString()); + const expected = '4 minutes ago'; expect(actual).toBe(expected); }); [null, undefined].forEach(x => { it('should use fallback for non value', () => { - const actual = new DatePipe().transform(x, '-'); + const actual = new FromNowPipe().transform(x, '-'); expect(actual).toBe('-'); }); }); }); -describe('DayPipe', () => { +describe('DatePipe', () => { beforeEach(() => { DateHelper.setlocale(null); }); - it('should format to day numbers', () => { - const pipe = new DayPipe(); + TestCases.forEach(x => { + it(`should format to two digit day number and short month name and year from ${x.name}`, () => { + const pipe = new DatePipe(); - const actual = pipe.transform(dateTime); - const expected = '03'; + const actual = pipe.transform(x.value); + const expected = '03. Oct 2013'; - expect(actual).toBe(expected); + expect(actual).toBe(expected); + }); }); [null, undefined].forEach(x => { it('should use fallback for non value', () => { - const actual = new DayPipe().transform(x, '-'); + const actual = new DatePipe().transform(x, '-'); expect(actual).toBe('-'); }); }); }); -describe('DayOfWeekPipe', () => { +describe('DayPipe', () => { beforeEach(() => { DateHelper.setlocale(null); }); - it('should format to short week of day string', () => { - const pipe = new DayOfWeekPipe(); + TestCases.forEach(x => { + it(`should format to day numbers from ${x.name}`, () => { + const pipe = new DayPipe(); - const actual = pipe.transform(dateTime); - const expected = 'Thu'; + const actual = pipe.transform(x.value); + const expected = '03'; - expect(actual).toBe(expected); + expect(actual).toBe(expected); + }); }); [null, undefined].forEach(x => { it('should use fallback for non value', () => { - const actual = new DayOfWeekPipe().transform(x, '-'); + const actual = new DayPipe().transform(x, '-'); expect(actual).toBe('-'); }); }); }); -describe('FromNowPipe', () => { +describe('DayOfWeekPipe', () => { beforeEach(() => { DateHelper.setlocale(null); }); - it('should format to from now string', () => { - const pipe = new FromNowPipe(); + TestCases.forEach(x => { + it(`should format to short week of day string from ${x.name}`, () => { + const pipe = new DayOfWeekPipe(); - const actual = pipe.transform(DateTime.now().addMinutes(-4)); - const expected = '4 minutes ago'; + const actual = pipe.transform(x.value); + const expected = 'Thu'; - expect(actual).toBe(expected); + expect(actual).toBe(expected); + }); }); [null, undefined].forEach(x => { it('should use fallback for non value', () => { - const actual = new FromNowPipe().transform(x, '-'); + const actual = new DayOfWeekPipe().transform(x, '-'); expect(actual).toBe('-'); }); @@ -132,13 +157,15 @@ describe('FullDateTimePipe', () => { DateHelper.setlocale(null); }); - it('should format to nice string', () => { - const pipe = new FullDateTimePipe(); + TestCases.forEach(x => { + it(`should format to nice string from ${x.name}`, () => { + const pipe = new FullDateTimePipe(); - const actual = pipe.transform(dateTime); - const expected = 'Oct 3, 2013, 12:13:14 PM'; + const actual = pipe.transform(x.value); + const expected = 'Oct 3, 2013, 12:13:14 PM'; - expect(actual).toBe(expected); + expect(actual).toBe(expected); + }); }); [null, undefined].forEach(x => { @@ -155,13 +182,15 @@ describe('MonthPipe', () => { DateHelper.setlocale(null); }); - it('should format to long month name', () => { - const pipe = new MonthPipe(); + TestCases.forEach(x => { + it(`should format to long month name from ${x.name}`, () => { + const pipe = new MonthPipe(); - const actual = pipe.transform(dateTime); - const expected = 'October'; + const actual = pipe.transform(x.value); + const expected = 'October'; - expect(actual).toBe(expected); + expect(actual).toBe(expected); + }); }); [null, undefined].forEach(x => { @@ -178,13 +207,15 @@ describe('ShortDatePipe', () => { DateHelper.setlocale(null); }); - it('should format to two digit day number and short month name', () => { - const pipe = new ShortDatePipe(); + TestCases.forEach(x => { + it(`should format to two digit day number and short month name from ${x.name}`, () => { + const pipe = new ShortDatePipe(); - const actual = pipe.transform(dateTime); - const expected = '03. Oct'; + const actual = pipe.transform(x.value); + const expected = '03. Oct'; - expect(actual).toBe(expected); + expect(actual).toBe(expected); + }); }); [null, undefined].forEach(x => { @@ -201,13 +232,15 @@ describe('ShortTimePipe', () => { DateHelper.setlocale(null); }); - it('should format to short time string', () => { - const pipe = new ShortTimePipe(); + TestCases.forEach(x => { + it(`should format to short time string from ${x.name}`, () => { + const pipe = new ShortTimePipe(); - const actual = pipe.transform(dateTime); - const expected = '12:13'; + const actual = pipe.transform(x.value); + const expected = '12:13'; - expect(actual).toBe(expected); + expect(actual).toBe(expected); + }); }); [null, undefined].forEach(x => { @@ -224,13 +257,15 @@ describe('ISODatePipe', () => { DateHelper.setlocale(null); }); - it('should format to short time string', () => { - const pipe = new ISODatePipe(); + TestCases.forEach(x => { + it(`should format to short time string from ${x.name}`, () => { + const pipe = new ISODatePipe(); - const actual = pipe.transform(dateTime); - const expected = dateTime.toISOString(); + const actual = pipe.transform(x.value); + const expected = dateTime.toISOString(); - expect(actual).toBe(expected); + expect(actual).toBe(expected); + }); }); [null, undefined].forEach(x => { diff --git a/frontend/src/app/framework/angular/pipes/date-time.pipes.ts b/frontend/src/app/framework/angular/pipes/date-time.pipes.ts index b2acd23fc..3cb9f51b8 100644 --- a/frontend/src/app/framework/angular/pipes/date-time.pipes.ts +++ b/frontend/src/app/framework/angular/pipes/date-time.pipes.ts @@ -6,18 +6,22 @@ */ import { Pipe, PipeTransform } from '@angular/core'; -import { DateTime, Duration } from '@app/framework/internal'; +import { DateTime, Duration, Types } from '@app/framework/internal'; @Pipe({ name: 'sqxShortDate', pure: true, }) export class ShortDatePipe implements PipeTransform { - public transform(value: DateTime | undefined | null, fallback = ''): string { + public transform(value: DateTime | string | undefined | null, fallback = ''): string { if (!value) { return fallback; } + if (Types.isString(value)) { + value = DateTime.parseISO(value); + } + return value.toStringFormat('dd. MMM'); } } @@ -27,11 +31,15 @@ export class ShortDatePipe implements PipeTransform { pure: true, }) export class ISODatePipe implements PipeTransform { - public transform(value: DateTime | undefined | null, fallback = ''): string { + public transform(value: DateTime | string | undefined | null, fallback = ''): string { if (!value) { return fallback; } + if (Types.isString(value)) { + value = DateTime.parseISO(value); + } + return value.toISOString(); } } @@ -41,11 +49,15 @@ export class ISODatePipe implements PipeTransform { pure: true, }) export class DatePipe implements PipeTransform { - public transform(value: DateTime | undefined | null, fallback = ''): string { + public transform(value: DateTime | string | undefined | null, fallback = ''): string { if (!value) { return fallback; } + if (Types.isString(value)) { + value = DateTime.parseISO(value); + } + return value.toStringFormat('dd. LLL yyyy'); } } @@ -55,11 +67,15 @@ export class DatePipe implements PipeTransform { pure: true, }) export class MonthPipe implements PipeTransform { - public transform(value: DateTime | undefined | null, fallback = ''): string { + public transform(value: DateTime | string | undefined | null, fallback = ''): string { if (!value) { return fallback; } + if (Types.isString(value)) { + value = DateTime.parseISO(value); + } + return value.toStringFormat('LLLL'); } } @@ -69,11 +85,15 @@ export class MonthPipe implements PipeTransform { pure: true, }) export class FromNowPipe implements PipeTransform { - public transform(value: DateTime | undefined | null, fallback = ''): string { + public transform(value: DateTime | string | undefined | null, fallback = ''): string { if (!value) { return fallback; } + if (Types.isString(value)) { + value = DateTime.parseISO(value); + } + return value.toFromNow(); } } @@ -83,11 +103,15 @@ export class FromNowPipe implements PipeTransform { pure: true, }) export class DayOfWeekPipe implements PipeTransform { - public transform(value: DateTime | undefined | null, fallback = ''): string { + public transform(value: DateTime | string | undefined | null, fallback = ''): string { if (!value) { return fallback; } + if (Types.isString(value)) { + value = DateTime.parseISO(value); + } + return value.toStringFormat('E'); } } @@ -97,11 +121,15 @@ export class DayOfWeekPipe implements PipeTransform { pure: true, }) export class DayPipe implements PipeTransform { - public transform(value: DateTime | undefined | null, fallback = ''): string { + public transform(value: DateTime | string | undefined | null, fallback = ''): string { if (!value) { return fallback; } + if (Types.isString(value)) { + value = DateTime.parseISO(value); + } + return value.toStringFormat('dd'); } } @@ -111,11 +139,15 @@ export class DayPipe implements PipeTransform { pure: true, }) export class ShortTimePipe implements PipeTransform { - public transform(value: DateTime | undefined | null, fallback = ''): string { + public transform(value: DateTime | string | undefined | null, fallback = ''): string { if (!value) { return fallback; } + if (Types.isString(value)) { + value = DateTime.parseISO(value); + } + return value.toStringFormat('HH:mm'); } } @@ -125,11 +157,15 @@ export class ShortTimePipe implements PipeTransform { pure: true, }) export class FullDateTimePipe implements PipeTransform { - public transform(value: DateTime | undefined | null, fallback = ''): string { + public transform(value: DateTime | string | undefined | null, fallback = ''): string { if (!value) { return fallback; } + if (Types.isString(value)) { + value = DateTime.parseISO(value); + } + return value.toStringFormat('PPpp'); } } diff --git a/frontend/src/app/framework/angular/resized.directive.ts b/frontend/src/app/framework/angular/resized.directive.ts index d6cf781a4..65e684466 100644 --- a/frontend/src/app/framework/angular/resized.directive.ts +++ b/frontend/src/app/framework/angular/resized.directive.ts @@ -5,13 +5,16 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ -import { Directive, ElementRef, EventEmitter, Input, NgZone, numberAttribute, OnDestroy, Output } from '@angular/core'; -import { ResizeListener, ResizeService, ResourceOwner } from '@app/framework/internal'; +/* eslint-disable @angular-eslint/no-input-rename */ + +import { Directive, ElementRef, EventEmitter, Input, NgZone, numberAttribute, Output } from '@angular/core'; +import { ResizeListener, ResizeService, Subscriptions } from '@app/framework/internal'; @Directive({ selector: '[sqxResized], [sqxResizeCondition]', }) -export class ResizedDirective extends ResourceOwner implements OnDestroy, ResizeListener { +export class ResizedDirective implements ResizeListener { + private readonly subscriptions = new Subscriptions(); private condition: ((rect: DOMRect) => boolean) | undefined; private conditionValue = false; @@ -25,14 +28,12 @@ export class ResizedDirective extends ResourceOwner implements OnDestroy, Resize public resizeCondition = new EventEmitter(); @Output('sqxResized') - public resize = new EventEmitter(); + public resizeChange = new EventEmitter(); constructor(resizeService: ResizeService, element: ElementRef, private readonly zone: NgZone, ) { - super(); - - this.own(resizeService.listen(element.nativeElement, this)); + this.subscriptions.add(resizeService.listen(element.nativeElement, this)); } public ngOnChanges() { @@ -63,7 +64,7 @@ export class ResizedDirective extends ResourceOwner implements OnDestroy, Resize } } else { this.zone.run(() => { - this.resize.emit(rect); + this.resizeChange.emit(rect); }); } } diff --git a/frontend/src/app/framework/angular/routers/parent-link.directive.ts b/frontend/src/app/framework/angular/routers/parent-link.directive.ts index 8e674e11f..13f1c5374 100644 --- a/frontend/src/app/framework/angular/routers/parent-link.directive.ts +++ b/frontend/src/app/framework/angular/routers/parent-link.directive.ts @@ -7,12 +7,13 @@ import { booleanAttribute, Directive, ElementRef, HostListener, Input, OnInit, Renderer2 } from '@angular/core'; import { ActivatedRoute, NavigationEnd, QueryParamsHandling, Router } from '@angular/router'; -import { ResourceOwner } from '@app/framework/internal'; +import { Subscriptions } from '@app/framework/internal'; @Directive({ selector: '[sqxParentLink]', }) -export class ParentLinkDirective extends ResourceOwner implements OnInit { +export class ParentLinkDirective implements OnInit { + private readonly subscriptions = new Subscriptions(); private url?: string; @Input({ transform: booleanAttribute }) @@ -27,17 +28,16 @@ export class ParentLinkDirective extends ResourceOwner implements OnInit { private readonly element: ElementRef, private readonly renderer: Renderer2, ) { - super(); } public ngOnInit() { - this.own( + this.subscriptions.add( this.route.url .subscribe(() => { this.updateUrl(); })); - this.own( + this.subscriptions.add( this.router.events .subscribe(event => { if (event instanceof NavigationEnd) { diff --git a/frontend/src/app/framework/angular/scroll-active.directive.ts b/frontend/src/app/framework/angular/scroll-active.directive.ts index ac08b2f34..95fa5c75e 100644 --- a/frontend/src/app/framework/angular/scroll-active.directive.ts +++ b/frontend/src/app/framework/angular/scroll-active.directive.ts @@ -5,6 +5,8 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ +/* eslint-disable @angular-eslint/no-input-rename */ + import { AfterViewInit, booleanAttribute, Directive, ElementRef, Input, Renderer2 } from '@angular/core'; @Directive({ @@ -43,17 +45,17 @@ export class ScrollActiveDirective implements AfterViewInit { const body = document.body; - const scrollOffset = (targetRect.top + body.scrollTop) - (parentRect.top + body.scrollTop); + const scrollDiff = (targetRect.top + body.scrollTop) - (parentRect.top + body.scrollTop); const scrollTop = parent.scrollTop; - if (scrollOffset < 0) { - this.renderer.setProperty(parent, 'scrollTop', scrollTop + scrollOffset); + if (scrollDiff < 0) { + this.renderer.setProperty(parent, 'scrollTop', scrollTop + scrollDiff); } else { const targetHeight = targetRect.height; const parentHeight = parentRect.height; - if ((scrollOffset + targetHeight) > parentHeight) { - this.renderer.setProperty(parent, 'scrollTop', scrollTop + scrollOffset - parentHeight + targetHeight); + if ((scrollDiff + targetHeight) > parentHeight) { + this.renderer.setProperty(parent, 'scrollTop', scrollTop + scrollDiff - parentHeight + targetHeight); } } } diff --git a/frontend/src/app/framework/angular/shortcut.directive.ts b/frontend/src/app/framework/angular/shortcut.directive.ts index 2dadf9f67..6fd93583c 100644 --- a/frontend/src/app/framework/angular/shortcut.directive.ts +++ b/frontend/src/app/framework/angular/shortcut.directive.ts @@ -5,6 +5,8 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ +/* eslint-disable @angular-eslint/directive-selector */ + import { Directive, ElementRef, Input, OnDestroy, OnInit } from '@angular/core'; import { ShortcutService } from '@app/framework/internal'; diff --git a/frontend/src/app/framework/angular/stateful.component.ts b/frontend/src/app/framework/angular/stateful.component.ts index 75f3abf90..7bc20c851 100644 --- a/frontend/src/app/framework/angular/stateful.component.ts +++ b/frontend/src/app/framework/angular/stateful.component.ts @@ -5,52 +5,13 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ -import { Directive, OnDestroy, inject, ChangeDetectorRef } from '@angular/core'; +import { ChangeDetectorRef, Directive, inject, OnDestroy } from '@angular/core'; import { ControlValueAccessor } from '@angular/forms'; -import { catchError, EMPTY, Observable, skip, Subscription } from 'rxjs'; +import { skip, Subscription } from 'rxjs'; import { State } from './../state'; -import { Types } from './../utils/types'; - -declare type UnsubscribeFunction = () => void; - -@Directive() -export class ResourceOwner implements OnDestroy { - private subscriptions: (Subscription | UnsubscribeFunction)[] = []; - - public own(subscription: Subscription | UnsubscribeFunction | Observable | null | undefined) { - if (subscription) { - if (Types.isFunction((subscription as any)['subscribe'])) { - const observable = >subscription; - - this.subscriptions.push(observable.pipe(catchError(_ => EMPTY)).subscribe()); - } else { - this.subscriptions.push(subscription); - } - } - } - - public ngOnDestroy() { - this.unsubscribeAll(); - } - - public unsubscribeAll() { - try { - for (const subscription of this.subscriptions) { - if (Types.isFunction(subscription)) { - subscription(); - } else { - subscription.unsubscribe(); - } - } - } finally { - this.subscriptions = []; - } - } -} @Directive() export abstract class StatefulComponent extends State implements OnDestroy { - private readonly subscriptions = new ResourceOwner(); private readonly subscription: Subscription; private readonly changeDetector = inject(ChangeDetectorRef); @@ -65,12 +26,6 @@ export abstract class StatefulComponent extends State public ngOnDestroy() { this.subscription.unsubscribe(); - - this.unsubscribeAll(); - } - - protected unsubscribeAll() { - this.subscriptions.unsubscribeAll(); } protected detach() { @@ -80,10 +35,6 @@ export abstract class StatefulComponent extends State protected detectChanges() { this.changeDetector.detectChanges(); } - - public own(subscription: Subscription | UnsubscribeFunction | Observable | null | undefined) { - this.subscriptions.own(subscription); - } } type Disabled = { isDisabled: boolean }; diff --git a/frontend/src/app/framework/angular/subscriptions.ts b/frontend/src/app/framework/angular/subscriptions.ts new file mode 100644 index 000000000..9b29bb5c4 --- /dev/null +++ b/frontend/src/app/framework/angular/subscriptions.ts @@ -0,0 +1,50 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. + */ + +import { ChangeDetectorRef, inject, ViewRef } from '@angular/core'; +import { catchError, EMPTY, Observable, Subscription } from 'rxjs'; +import { Types } from './../utils/types'; + +export type UnsubscribeFunction = () => void; + +export class Subscriptions { + private subscriptions: (Subscription | UnsubscribeFunction)[] = []; + + constructor() { + const viewRef = inject(ChangeDetectorRef) as ViewRef; + + viewRef.onDestroy(() => { + this.unsubscribeAll(); + }); + } + + public add(subscription: Subscription | UnsubscribeFunction | Observable | null | undefined) { + if (subscription) { + if (Types.isFunction((subscription as any)['subscribe'])) { + const observable = >subscription; + + this.subscriptions.push(observable.pipe(catchError(_ => EMPTY)).subscribe()); + } else { + this.subscriptions.push(subscription); + } + } + } + + public unsubscribeAll() { + try { + for (const subscription of this.subscriptions) { + if (Types.isFunction(subscription)) { + subscription(); + } else { + subscription.unsubscribe(); + } + } + } finally { + this.subscriptions = []; + } + } +} \ No newline at end of file diff --git a/frontend/src/app/framework/angular/sync-width.directive.ts b/frontend/src/app/framework/angular/sync-width.directive.ts index b47dd5b0e..4fed351a0 100644 --- a/frontend/src/app/framework/angular/sync-width.directive.ts +++ b/frontend/src/app/framework/angular/sync-width.directive.ts @@ -6,12 +6,14 @@ */ import { AfterViewInit, Directive, ElementRef, Input, Renderer2 } from '@angular/core'; -import { ResizeListener, ResizeService, ResourceOwner } from '@app/framework/internal'; +import { ResizeListener, ResizeService, Subscriptions } from '@app/framework/internal'; @Directive({ selector: '[sqxSyncWidth]', }) -export class SyncWidthDirective extends ResourceOwner implements AfterViewInit, ResizeListener { +export class SyncWidthDirective implements AfterViewInit, ResizeListener { + private readonly subscriptions = new Subscriptions(); + @Input('sqxSyncWidth') public target!: HTMLElement; @@ -20,9 +22,7 @@ export class SyncWidthDirective extends ResourceOwner implements AfterViewInit, private readonly renderer: Renderer2, private readonly resizeService: ResizeService, ) { - super(); - - this.own(this.resizeService.listen(this.element.nativeElement, this)); + this.subscriptions.add(this.resizeService.listen(this.element.nativeElement, this)); } public ngAfterViewInit() { diff --git a/frontend/src/app/framework/angular/title.component.ts b/frontend/src/app/framework/angular/title.component.ts index 052880555..354709ff2 100644 --- a/frontend/src/app/framework/angular/title.component.ts +++ b/frontend/src/app/framework/angular/title.component.ts @@ -5,8 +5,6 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ -// tslint:disable: readonly-array - import { ChangeDetectionStrategy, Component, Input, OnDestroy } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { TitleService, Types } from '@app/framework/internal'; diff --git a/frontend/src/app/framework/configurations.ts b/frontend/src/app/framework/configurations.ts index 4b1fd7fd3..b7568b268 100644 --- a/frontend/src/app/framework/configurations.ts +++ b/frontend/src/app/framework/configurations.ts @@ -10,28 +10,6 @@ export class UIOptions { public readonly value: any, ) { } - - public get(path: string) { - if (!path) { - return undefined; - } - - let value = this.value; - - if (value) { - const parts = path.split('.'); - - for (const part of parts) { - value = value[part]; - - if (!value) { - break; - } - } - } - - return value; - } } export class ApiUrlConfig { diff --git a/frontend/src/app/framework/declarations.ts b/frontend/src/app/framework/declarations.ts index c83e476d9..2962ec7c2 100644 --- a/frontend/src/app/framework/declarations.ts +++ b/frontend/src/app/framework/declarations.ts @@ -14,6 +14,7 @@ export * from './angular/forms/confirm-click.directive'; export * from './angular/forms/control-errors-messages.component'; export * from './angular/forms/control-errors.component'; export * from './angular/forms/copy.directive'; +export * from './angular/forms/copy-global.directive'; export * from './angular/forms/editable-title.component'; export * from './angular/forms/editors/autocomplete.component'; export * from './angular/forms/editors/checkbox-group.component'; diff --git a/frontend/src/app/framework/internal.ts b/frontend/src/app/framework/internal.ts index 5ec5f89d7..57fe32008 100644 --- a/frontend/src/app/framework/internal.ts +++ b/frontend/src/app/framework/internal.ts @@ -9,6 +9,7 @@ export * from './angular/animations'; export * from './angular/drag-helper'; export * from './angular/routers/router-utils'; export * from './angular/stateful.component'; +export * from './angular/subscriptions'; export * from './configurations'; export * from './services/analytics.service'; export * from './services/clipboard.service'; diff --git a/frontend/src/app/framework/module.ts b/frontend/src/app/framework/module.ts index 08b760227..697e0d0f7 100644 --- a/frontend/src/app/framework/module.ts +++ b/frontend/src/app/framework/module.ts @@ -12,7 +12,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { RouterModule } from '@angular/router'; import { ColorPickerModule } from 'ngx-color-picker'; import { TourService as BaseTourService } from 'ngx-ui-tour-core'; -import { AnalyticsService, AutocompleteComponent, AvatarComponent, CachingInterceptor, CanDeactivateGuard, CheckboxGroupComponent, ClipboardService, CodeComponent, CodeEditorComponent, ColorPickerComponent, CompensateScrollbarDirective, ConfirmClickDirective, ControlErrorsComponent, ControlErrorsMessagesComponent, CopyDirective, DarkenPipe, DatePipe, DateTimeEditorComponent, DayOfWeekPipe, DayPipe, DialogRendererComponent, DialogService, DisplayNamePipe, DropdownComponent, DropdownMenuComponent, DurationPipe, EditableTitleComponent, ExternalLinkDirective, FileDropDirective, FileSizePipe, FocusOnInitDirective, FormAlertComponent, FormErrorComponent, FormHintComponent, FromNowPipe, FullDateTimePipe, GlobalErrorHandler, HighlightPipe, HoverBackgroundDirective, IfOnceDirective, ImageSourceDirective, ImageUrlDirective, IndeterminateValueDirective, ISODatePipe, JoinPipe, KeysPipe, KNumberPipe, LanguageSelectorComponent, LayoutComponent, LayoutContainerDirective, LightenPipe, ListViewComponent, LoaderComponent, LoadingInterceptor, LoadingService, LocalizedInputComponent, LocalStoreService, LongHoverDirective, MarkdownDirective, MarkdownInlinePipe, MarkdownPipe, MessageBus, ModalDialogComponent, ModalDirective, ModalPlacementDirective, MonthPipe, PagerComponent, ParentLinkDirective, ProgressBarComponent, RadioGroupComponent, ResizedDirective, ResizeService, ResourceLoaderService, RootViewComponent, SafeHtmlPipe, SafeResourceUrlPipe, SafeUrlPipe, ScrollActiveDirective, ShortcutComponent, ShortcutDirective, ShortcutService, ShortDatePipe, ShortTimePipe, StarsComponent, StatusIconComponent, StopClickDirective, StopDragDirective, SyncScollingDirective, SyncWidthDirective, TabRouterlinkDirective, TagEditorComponent, TemplateWrapperDirective, TempService, TitleComponent, TitleService, ToggleComponent, ToolbarComponent, TooltipDirective, TourService, TourStepDirective, TourTemplateComponent, TransformInputDirective, TranslatePipe, VideoPlayerComponent } from './declarations'; +import { AnalyticsService, AutocompleteComponent, AvatarComponent, CachingInterceptor, CanDeactivateGuard, CheckboxGroupComponent, ClipboardService, CodeComponent, CodeEditorComponent, ColorPickerComponent, CompensateScrollbarDirective, ConfirmClickDirective, ControlErrorsComponent, ControlErrorsMessagesComponent, CopyDirective, CopyGlobalDirective, DarkenPipe, DatePipe, DateTimeEditorComponent, DayOfWeekPipe, DayPipe, DialogRendererComponent, DialogService, DisplayNamePipe, DropdownComponent, DropdownMenuComponent, DurationPipe, EditableTitleComponent, ExternalLinkDirective, FileDropDirective, FileSizePipe, FocusOnInitDirective, FormAlertComponent, FormErrorComponent, FormHintComponent, FromNowPipe, FullDateTimePipe, GlobalErrorHandler, HighlightPipe, HoverBackgroundDirective, IfOnceDirective, ImageSourceDirective, ImageUrlDirective, IndeterminateValueDirective, ISODatePipe, JoinPipe, KeysPipe, KNumberPipe, LanguageSelectorComponent, LayoutComponent, LayoutContainerDirective, LightenPipe, ListViewComponent, LoaderComponent, LoadingInterceptor, LoadingService, LocalizedInputComponent, LocalStoreService, LongHoverDirective, MarkdownDirective, MarkdownInlinePipe, MarkdownPipe, MessageBus, ModalDialogComponent, ModalDirective, ModalPlacementDirective, MonthPipe, PagerComponent, ParentLinkDirective, ProgressBarComponent, RadioGroupComponent, ResizedDirective, ResizeService, ResourceLoaderService, RootViewComponent, SafeHtmlPipe, SafeResourceUrlPipe, SafeUrlPipe, ScrollActiveDirective, ShortcutComponent, ShortcutDirective, ShortcutService, ShortDatePipe, ShortTimePipe, StarsComponent, StatusIconComponent, StopClickDirective, StopDragDirective, StringColorPipe, SyncScollingDirective, SyncWidthDirective, TabRouterlinkDirective, TagEditorComponent, TemplateWrapperDirective, TempService, TitleComponent, TitleService, ToggleComponent, ToolbarComponent, TooltipDirective, TourService, TourStepDirective, TourTemplateComponent, TransformInputDirective, TranslatePipe, VideoPlayerComponent } from './declarations'; @NgModule({ imports: [ @@ -34,6 +34,7 @@ import { AnalyticsService, AutocompleteComponent, AvatarComponent, CachingInterc ControlErrorsComponent, ControlErrorsMessagesComponent, CopyDirective, + CopyGlobalDirective, DarkenPipe, DatePipe, DateTimeEditorComponent, @@ -97,6 +98,7 @@ import { AnalyticsService, AutocompleteComponent, AvatarComponent, CachingInterc StatusIconComponent, StopClickDirective, StopDragDirective, + StringColorPipe, SyncScollingDirective, SyncWidthDirective, TabRouterlinkDirective, @@ -124,6 +126,7 @@ import { AnalyticsService, AutocompleteComponent, AvatarComponent, CachingInterc ConfirmClickDirective, ControlErrorsComponent, CopyDirective, + CopyGlobalDirective, DarkenPipe, DatePipe, DateTimeEditorComponent, @@ -189,6 +192,7 @@ import { AnalyticsService, AutocompleteComponent, AvatarComponent, CachingInterc StatusIconComponent, StopClickDirective, StopDragDirective, + StringColorPipe, SyncScollingDirective, SyncWidthDirective, TabRouterlinkDirective, diff --git a/frontend/src/app/framework/utils/color-helper.spec.ts b/frontend/src/app/framework/utils/color-helper.spec.ts new file mode 100644 index 000000000..a9e94ff83 --- /dev/null +++ b/frontend/src/app/framework/utils/color-helper.spec.ts @@ -0,0 +1,38 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. + */ + +/* eslint-disable @typescript-eslint/naming-convention */ + +import { ColorHelper } from './color-helper'; + +describe('ColorHelper', () => { + [ + { r: 1, g: 0, b: 0, h: 0, name: 'red' }, + { r: 1, g: 1, b: 0, h: 60, name: 'yellow' }, + { r: 0, g: 1, b: 0, h: 120, name: 'green' }, + { r: 0, g: 1, b: 1, h: 180, name: 'cyan' }, + { r: 0, g: 0, b: 1, h: 240, name: 'blue' }, + { r: 1, g: 0, b: 1, h: 300, name: 'pink' }, + { r: 1, g: 0, b: 0, h: 360, name: 'red2' }, + ].forEach(test => { + it(`should convert from hsv ${test.name}`, () => { + const color = ColorHelper.hsvToRgb({ h: test.h, s: 1, v: 1 }); + + expect(color).toEqual({ r: test.r, g: test.g, b: test.b }); + }); + }); + + it('should compute color from string', () => { + const color1_1 = ColorHelper.fromStringHash('sebastian@squidex.io'); + const color1_2 = ColorHelper.fromStringHash('sebastian@squidex.io'); + + const color2 = ColorHelper.fromStringHash('hello@squidex.io'); + + expect(color1_1).toEqual(color1_2); + expect(color1_1).not.toEqual(color2); + }); +}); \ No newline at end of file diff --git a/frontend/src/app/framework/utils/color-helper.ts b/frontend/src/app/framework/utils/color-helper.ts new file mode 100644 index 000000000..c9d7f3aa7 --- /dev/null +++ b/frontend/src/app/framework/utils/color-helper.ts @@ -0,0 +1,162 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. + */ + +import { MathHelper } from './math-helper'; +import { StringHelper } from './string-helper'; + +export module ColorHelper { + interface RGBColor { + r: number; + g: number; + b: number; + } + + interface HSVColor { + h: number; + s: number; + v: number; + } + + interface ColorDefinition { + regex: RegExp; + + process(bots: RegExpExecArray): RGBColor; + } + + const ColorDefinitions: ReadonlyArray = [ + { + regex: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/, + process: (bits) => ({ + r: parseInt(bits[1], 10) / 255, + g: parseInt(bits[2], 10) / 255, + b: parseInt(bits[3], 10) / 255, + }), + }, + { + regex: /^(\w{2})(\w{2})(\w{2})$/, + process: (bits) => ({ + r: parseInt(bits[1], 16) / 255, + g: parseInt(bits[2], 16) / 255, + b: parseInt(bits[3], 16) / 255, + }), + }, + { + regex: /^(\w{1})(\w{1})(\w{1})$/, + process: (bits) => ({ + r: parseInt(bits[1] + bits[1], 16) / 255, + g: parseInt(bits[2] + bits[2], 16) / 255, + b: parseInt(bits[3] + bits[3], 16) / 255, + }), + }, + ]; + + export function parseColor(value: string) { + if (value.charAt(0) === '#') { + value = value.substring(1, 7); + } + + value = value.replace(/ /g, '').toLowerCase(); + + for (const colorDefinition of ColorDefinitions) { + const bits = colorDefinition.regex.exec(value); + + if (bits) { + return colorDefinition.process(bits); + } + } + + throw new Error('Color is not in a valid format.'); + } + + export function rgbToHsv({ r, g, b }: RGBColor): HSVColor { + const max = Math.max(r, g, b); + const min = Math.min(r, g, b); + + let h = 0; + const d = max - min; + const s = max === 0 ? 0 : d / max; + const v = max; + + if (max === min) { + h = 0; + } else { + switch (max) { + case r: h = (g - b) / d + (g < b ? 6 : 0); break; + case g: h = (b - r) / d + 2; break; + case b: h = (r - g) / d + 4; break; + } + + h /= 6; + } + + return { h: h * 360, s, v }; + } + + export function hsvToRgb({ h, s, v }: HSVColor): RGBColor { + h /= 60; + + const i = Math.floor(h); + const f = (h - i); + const p = (v * (1 - s)); + const q = (v * (1 - (f * s))); + const t = (v * (1 - ((1 - f) * s))); + + function color(r: number, g: number, b: number) { + return { r, g, b }; + } + + switch (i % 6) { + case 0: + return color(v, t, p); + case 1: + return color(q, v, p); + case 2: + return color(p, v, t); + case 3: + return color(p, q, v); + case 4: + return color(t, p, v); + default: + return color(v, p, q); + } + } + + export function colorString({ r, g, b }: RGBColor) { + let rs = Math.round(r * 255).toString(16); + let gs = Math.round(g * 255).toString(16); + let bs = Math.round(b * 255).toString(16); + + if (rs.length === 1) { + rs = `0${rs}`; + } + if (gs.length === 1) { + gs = `0${gs}`; + } + if (bs.length === 1) { + bs = `0${bs}`; + } + + return `#${rs}${gs}${bs}`; + } + + export function fromStringHash(input: string) { + let color = CACHE_COLORS[input]; + + if (!color) { + const colorHash = StringHelper.hashCode(input) / 10000; + const colorValue = hsvToRgb({ h: MathHelper.toPositiveDegree(colorHash), s: 0.6, v: 0.6 }); + + color = colorString(colorValue); + + CACHE_COLORS[input] = color; + } + + return color; + } +} + +const CACHE_COLORS: { [email: string]: string } = {}; \ No newline at end of file diff --git a/frontend/src/app/framework/utils/markdown.ts b/frontend/src/app/framework/utils/markdown.ts index c6bb9a851..1d1b86230 100644 --- a/frontend/src/app/framework/utils/markdown.ts +++ b/frontend/src/app/framework/utils/markdown.ts @@ -6,6 +6,7 @@ */ import { marked } from 'marked'; +import { MathHelper } from './math-helper'; function renderLink(href: string, _: string, text: string) { if (href && href.startsWith('mailto')) { @@ -15,6 +16,20 @@ function renderLink(href: string, _: string, text: string) { } } +function renderCode(code: string) { + const id = MathHelper.guid(); + + return ` +
    + + +
    ${code}
    +
    + `; +} + function renderInlineParagraph(text: string) { return text; } @@ -24,14 +39,18 @@ const RENDERER_INLINE = new marked.Renderer(); RENDERER_INLINE.paragraph = renderInlineParagraph; RENDERER_INLINE.link = renderLink; +RENDERER_INLINE.code = renderCode; RENDERER_DEFAULT.link = renderLink; +RENDERER_DEFAULT.code = renderCode; -export function renderMarkdown(input: string | undefined | null, inline: boolean) { +export function renderMarkdown(input: string | undefined | null, inline: boolean, trusted = false) { if (!input) { return ''; } - input = escapeHTML(input); + if (!trusted) { + input = escapeHTML(input); + } if (inline) { return marked(input, { renderer: RENDERER_INLINE, mangle: false, headerIds: false }); diff --git a/frontend/src/app/framework/utils/picasso.ts b/frontend/src/app/framework/utils/picasso.ts index 48bd15d84..37bc0c7c8 100644 --- a/frontend/src/app/framework/utils/picasso.ts +++ b/frontend/src/app/framework/utils/picasso.ts @@ -6,6 +6,7 @@ */ import MersenneTwister from 'mersenne-twister'; +import { StringHelper } from './string-helper'; const ALL_COLORS: ReadonlyArray = [ 'rgb(226,27,12)', @@ -32,23 +33,8 @@ const RADIUSES: ReadonlyArray = [20, 25, 30, 35, 40, 45, 50]; const X_CENTERS: ReadonlyArray = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]; const Y_CENTERS: ReadonlyArray = [30, 40, 50, 60, 70]; -function hash(str: string) { - if (str.length === 0) { - return 0; - } - - let result = 0; - - for (let i = 0; i < str.length; i++) { - result = result * 31 + str.charCodeAt(i); - result %= (2 ** 32); - } - - return result; -} - export function picasso(content: string) { - const seed = hash(content); + const seed = StringHelper.hashCode(content); const rand = new MersenneTwister(seed); const colors = [...ALL_COLORS]; diff --git a/frontend/src/app/framework/utils/string-helper.spec.ts b/frontend/src/app/framework/utils/string-helper.spec.ts index 5d9077fd6..d32fcc8a1 100644 --- a/frontend/src/app/framework/utils/string-helper.spec.ts +++ b/frontend/src/app/framework/utils/string-helper.spec.ts @@ -46,6 +46,18 @@ describe('StringHelper', () => { expect(StringHelper.appendLast('text.', '.')).toBe('text.'); }); + it('should return hash for null value', () => { + expect(StringHelper.hashCode(null!)).toBe(0); + }); + + it('should return hash for empty value', () => { + expect(StringHelper.hashCode('')).toBe(0); + }); + + it('should return hash for concrete values', () => { + expect(StringHelper.hashCode('ABC')).not.toBe(StringHelper.hashCode('XYZ')); + }); + it('should append query string to url if url already contains query', () => { const url = StringHelper.appendToUrl('http://squidex.io?query=value', 'other', 1); diff --git a/frontend/src/app/framework/utils/string-helper.ts b/frontend/src/app/framework/utils/string-helper.ts index 2ea84ce9b..f96c36ba1 100644 --- a/frontend/src/app/framework/utils/string-helper.ts +++ b/frontend/src/app/framework/utils/string-helper.ts @@ -45,4 +45,21 @@ export module StringHelper { return row; } } + + export function hashCode(value: string) { + let hash = 0; + + if (!value || value.length === 0) { + return hash; + } + + for (let i = 0; i < value.length; i++) { + const char = value.charCodeAt(i); + + hash = ((hash << 5) - hash) + char; + hash |= 0; + } + + return hash; + } } diff --git a/frontend/src/app/shared/components/app-form.component.html b/frontend/src/app/shared/components/app-form.component.html index a02b6196f..43864a725 100644 --- a/frontend/src/app/shared/components/app-form.component.html +++ b/frontend/src/app/shared/components/app-form.component.html @@ -1,5 +1,5 @@ - + {{ 'apps.createWithTemplate' | sqxTranslate: { template: template.title } }} diff --git a/frontend/src/app/shared/components/app-form.component.ts b/frontend/src/app/shared/components/app-form.component.ts index 9e4fdd9c1..08cae0442 100644 --- a/frontend/src/app/shared/components/app-form.component.ts +++ b/frontend/src/app/shared/components/app-form.component.ts @@ -16,7 +16,7 @@ import { ApiUrlConfig, AppsState, CreateAppForm, TemplateDto } from '@app/shared }) export class AppFormComponent { @Output() - public close = new EventEmitter(); + public dialogClose = new EventEmitter(); @Input() public template?: TemplateDto; @@ -30,7 +30,7 @@ export class AppFormComponent { } public emitClose() { - this.close.emit(); + this.dialogClose.emit(); } public createApp() { diff --git a/frontend/src/app/shared/components/assets/asset-dialog.component.html b/frontend/src/app/shared/components/assets/asset-dialog.component.html index a65ed67d1..0c5abd7ac 100644 --- a/frontend/src/app/shared/components/assets/asset-dialog.component.html +++ b/frontend/src/app/shared/components/assets/asset-dialog.component.html @@ -1,5 +1,5 @@ - + {{ 'assets.edit' | sqxTranslate }} diff --git a/frontend/src/app/shared/components/assets/asset-dialog.component.ts b/frontend/src/app/shared/components/assets/asset-dialog.component.ts index 253f95dac..3d75f190a 100644 --- a/frontend/src/app/shared/components/assets/asset-dialog.component.ts +++ b/frontend/src/app/shared/components/assets/asset-dialog.component.ts @@ -22,7 +22,7 @@ import { ImageFocusPointComponent } from './image-focus-point.component'; }) export class AssetDialogComponent implements OnInit { @Output() - public close = new EventEmitter(); + public dialogClose = new EventEmitter(); @Output() public assetReplaced = new EventEmitter(); diff --git a/frontend/src/app/shared/components/assets/asset-folder-dialog.component.html b/frontend/src/app/shared/components/assets/asset-folder-dialog.component.html index 254735284..821ab83e2 100644 --- a/frontend/src/app/shared/components/assets/asset-folder-dialog.component.html +++ b/frontend/src/app/shared/components/assets/asset-folder-dialog.component.html @@ -1,5 +1,5 @@ - + {{ 'assets.renameFolder' | sqxTranslate }} diff --git a/frontend/src/app/shared/components/assets/asset-folder-dialog.component.ts b/frontend/src/app/shared/components/assets/asset-folder-dialog.component.ts index 622a02197..2e30086db 100644 --- a/frontend/src/app/shared/components/assets/asset-folder-dialog.component.ts +++ b/frontend/src/app/shared/components/assets/asset-folder-dialog.component.ts @@ -15,7 +15,7 @@ import { AssetFolderDto, AssetsState, RenameAssetFolderForm } from '@app/shared/ }) export class AssetFolderDialogComponent implements OnInit { @Output() - public close = new EventEmitter(); + public dialogClose = new EventEmitter(); @Input() public assetFolder?: AssetFolderDto; @@ -34,7 +34,7 @@ export class AssetFolderDialogComponent implements OnInit { } public emitClose() { - this.close.emit(); + this.dialogClose.emit(); } public createAssetFolder() { diff --git a/frontend/src/app/shared/components/assets/asset-folder.component.html b/frontend/src/app/shared/components/assets/asset-folder.component.html index 8e63801ff..202b6b53f 100644 --- a/frontend/src/app/shared/components/assets/asset-folder.component.html +++ b/frontend/src/app/shared/components/assets/asset-folder.component.html @@ -37,5 +37,5 @@
    + (dialogClose)="editDialog.hide()" [assetFolder]="assetFolder"> \ No newline at end of file diff --git a/frontend/src/app/shared/components/assets/asset-selector.component.html b/frontend/src/app/shared/components/assets/asset-selector.component.html index f0d87d36b..436f00ce8 100644 --- a/frontend/src/app/shared/components/assets/asset-selector.component.html +++ b/frontend/src/app/shared/components/assets/asset-selector.component.html @@ -1,4 +1,4 @@ - + {{ 'assets.selectMany' | sqxTranslate }} @@ -46,11 +46,11 @@ - diff --git a/frontend/src/app/shared/components/assets/asset-selector.component.ts b/frontend/src/app/shared/components/assets/asset-selector.component.ts index 5013516c8..6649acbbe 100644 --- a/frontend/src/app/shared/components/assets/asset-selector.component.ts +++ b/frontend/src/app/shared/components/assets/asset-selector.component.ts @@ -30,7 +30,7 @@ interface State { }) export class AssetSelectorComponent extends StatefulComponent implements OnInit { @Output() - public select = new EventEmitter>(); + public assetSelect = new EventEmitter>(); constructor(localStore: LocalStoreService, public readonly assetsState: ComponentAssetsState, @@ -63,11 +63,11 @@ export class AssetSelectorComponent extends StatefulComponent implements } public emitClose() { - this.select.emit([]); + this.assetSelect.emit([]); } public emitSelect() { - this.select.emit(Object.values(this.snapshot.selectedAssets)); + this.assetSelect.emit(Object.values(this.snapshot.selectedAssets)); } public selectTags(tags: ReadonlyArray) { diff --git a/frontend/src/app/shared/components/assets/asset.component.html b/frontend/src/app/shared/components/assets/asset.component.html index 1d316d107..38093bc9e 100644 --- a/frontend/src/app/shared/components/assets/asset.component.html +++ b/frontend/src/app/shared/components/assets/asset.component.html @@ -1,5 +1,5 @@ -
    -
    implements OnInit { public edit = new EventEmitter(); @Output() - public select = new EventEmitter(); + public selectAsset = new EventEmitter(); @Output() public selectFolder = new EventEmitter(); diff --git a/frontend/src/app/shared/components/assets/assets-list.component.html b/frontend/src/app/shared/components/assets/assets-list.component.html index 3bde35fee..97073a398 100644 --- a/frontend/src/app/shared/components/assets/assets-list.component.html +++ b/frontend/src/app/shared/components/assets/assets-list.component.html @@ -80,7 +80,7 @@ [isSelectable]="!!selectedIds" [isSelected]="!!isSelected(asset)" (loadDone)="replaceAsset($event)" - (select)="select.emit(asset)" + (selectAsset)="assetSelect.emit(asset)" (selectFolder)="selectFolder(asset)">
    diff --git a/frontend/src/app/shared/components/assets/assets-list.component.ts b/frontend/src/app/shared/components/assets/assets-list.component.ts index ed71b4eb2..5bd09240d 100644 --- a/frontend/src/app/shared/components/assets/assets-list.component.ts +++ b/frontend/src/app/shared/components/assets/assets-list.component.ts @@ -25,7 +25,7 @@ export class AssetsListComponent extends StatefulComponent { public edit = new EventEmitter(); @Output() - public select = new EventEmitter(); + public assetSelect = new EventEmitter(); @Input({ required: true }) public assetsState!: AssetsState; diff --git a/frontend/src/app/shared/components/cards/iframe-card.component.ts b/frontend/src/app/shared/components/cards/iframe-card.component.ts index c76e37800..b1870e221 100644 --- a/frontend/src/app/shared/components/cards/iframe-card.component.ts +++ b/frontend/src/app/shared/components/cards/iframe-card.component.ts @@ -5,7 +5,9 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ -import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, Input, ViewChild } from '@angular/core'; +import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, HostListener, Input, ViewChild } from '@angular/core'; +import { ApiUrlConfig, Types } from '@app/framework'; +import { AppDto, AuthService, TeamDto } from '@app/shared/internal'; @Component({ selector: 'sqx-iframe-card', @@ -14,13 +16,67 @@ import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, Input, V changeDetection: ChangeDetectionStrategy.OnPush, }) export class IFrameCardComponent implements AfterViewInit { + private readonly context: any; + private isInitialized = false; + @Input() public options: any; @ViewChild('iframe', { static: false }) public iframe!: ElementRef; + @Input() + public set team(value: TeamDto | undefined | null) { + if (value) { + this.context.teamId = value.id; + this.context.teamName = value.name; + } + } + + @Input() + public set app(value: AppDto | undefined | null) { + if (value) { + this.context.appId = value.id; + this.context.appName = value.name; + } + } + + constructor(apiUrl: ApiUrlConfig, authService: AuthService) { + this.context = { apiUrl: apiUrl.buildUrl('api'), user: authService.user }; + } + public ngAfterViewInit() { this.iframe.nativeElement.src = this.options?.src; } + + @HostListener('window:message', ['$event']) + public onWindowMessage(event: MessageEvent) { + if (event.source === this.iframe.nativeElement.contentWindow) { + const { type } = event.data; + + if (type === 'started') { + this.isInitialized = true; + + this.sendInit(); + } + } + } + + private sendInit() { + this.sendMessage('init', { context: this.context }); + } + + private sendMessage(type: string, payload: any) { + if (!this.iframe) { + return; + } + + const iframe = this.iframe.nativeElement; + + if (this.isInitialized && iframe.contentWindow && Types.isFunction(iframe.contentWindow.postMessage)) { + const message = { type, ...payload }; + + iframe.contentWindow.postMessage(message, '*'); + } + } } diff --git a/frontend/src/app/shared/components/chat-dialog.component.html b/frontend/src/app/shared/components/chat-dialog.component.html new file mode 100644 index 000000000..f0228c035 --- /dev/null +++ b/frontend/src/app/shared/components/chat-dialog.component.html @@ -0,0 +1,114 @@ + + + {{ 'chat.title' | sqxTranslate }} + + + +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +

    {{ 'chat.description' | sqxTranslate }}

    +

    {{ 'chat.describeFormat' | sqxTranslate }}

    +
    +
    +
    +
    + +
    +
    +
    +
    + {{item.text}} +
    +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    +
    +
    + {{ item.text | sqxTranslate}} +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    + {{ 'chat.answer' | sqxTranslate}} +
    + + + +
    + +
    +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    + + + + + +
    +
    +
    +
    +
    +
    + + + +
    +
    + +
    +
    + +
    +
    + +
    +
    diff --git a/frontend/src/app/shared/components/chat-dialog.component.scss b/frontend/src/app/shared/components/chat-dialog.component.scss new file mode 100644 index 000000000..15b1bfdcb --- /dev/null +++ b/frontend/src/app/shared/components/chat-dialog.component.scss @@ -0,0 +1,77 @@ +@import 'mixins'; +@import 'vars'; + +:host ::ng-deep { + .modal-body { + background-color: $color-background; + } + + p:last-child { + margin-bottom: 0; + } +} + +form { + width: 100%; +} + +textarea { + height: 300px; +} + +.flex-reverse { + flex-direction: row-reverse; +} + +.scroll-container { + flex-grow: 1; + overflow-x: hidden; + overflow-y: auto; + padding: 1.5rem; +} + +.bubble { + background-color: $color-white; + border: 0; + border-radius: $border-radius; + padding: 1rem; + position: relative; + + &-right { + &::before { + @include caret-left($color-white, 10px); + @include absolute(.5rem, null, null, -18px); + } + } + + &-left { + &::before { + @include caret-right($color-white, 10px); + @include absolute(.5rem, -18px); + } + } +} + +@keyframes blink { + 50% { + fill: transparent + } +} + +.dot { + animation: 1s blink infinite; +} + +svg { + .dot { + fill: $color-border; + } +} + +.dot:nth-child(2) { + animation-delay: 250ms; +} + +.dot:nth-child(3) { + animation-delay: 500ms; +} \ No newline at end of file diff --git a/frontend/src/app/shared/components/chat-dialog.component.ts b/frontend/src/app/shared/components/chat-dialog.component.ts new file mode 100644 index 000000000..eb368cd6b --- /dev/null +++ b/frontend/src/app/shared/components/chat-dialog.component.ts @@ -0,0 +1,120 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. + */ + +import { booleanAttribute, Component, ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core'; +import { delay } from 'rxjs/operators'; +import { AppsState, AuthService, StatefulComponent, TranslationsService } from '@app/shared/internal'; + +interface State { + // True, when running + isRunning: boolean; + + // The questions. + chatQuestion: string; + + // The answers. + chatTalk: ReadonlyArray<{ text: string; type: 'user' | 'bot' | 'system' }>; +} + +@Component({ + selector: 'sqx-chat-dialog', + styleUrls: ['./chat-dialog.component.scss'], + templateUrl: './chat-dialog.component.html', +}) +export class ChatDialogComponent extends StatefulComponent { + @Output() + public textSelect = new EventEmitter(); + + @Input({ required: true, transform: booleanAttribute }) + public showFormatHint = false; + + @ViewChild('scrollContainer', { static: false }) + public scrollContainer!: ElementRef; + + @ViewChild('input', { static: false }) + public input!: ElementRef; + + public user = this.authService.user!; + + constructor( + private readonly appsState: AppsState, + private readonly authService: AuthService, + private readonly translator: TranslationsService, + ) { + super({ + isRunning: false, + chatQuestion: '', + chatTalk: [], + }); + } + + public scrollDown() { + if (this.scrollContainer && this.scrollContainer.nativeElement) { + const height = this.scrollContainer.nativeElement.scrollHeight; + + this.scrollContainer.nativeElement.scrollTop = height; + } + } + + public setQuestion(chatQuestion: string) { + this.next({ chatQuestion }); + } + + public ask() { + const prompt = this.snapshot.chatQuestion; + + if (!prompt || prompt.length === 0) { + return; + } + + this.next(s => ({ + ...s, + chatQuestion: '', + chatTalk: [ + ...s.chatTalk, + { text: prompt, type: 'user' }, + ], + isRunning: true, + })); + + this.translator.ask(this.appsState.appName, { prompt }).pipe(delay(500)) + .subscribe({ + next: chatAnswers => { + if (chatAnswers.length === 0) { + this.next(s => ({ + ...s, + chatQuestion: '', + chatTalk: [ + ...s.chatTalk, + { text: 'i18n:chat.answersEmpty', type: 'system' }, + ], + isRunning: true, + })); + } else { + this.next(s => ({ + ...s, + chatTalk: [ + ...s.chatTalk, + ...chatAnswers.map(text => ({ text, type: 'bot' } as any)), + ], + isRunning: false, + })); + } + + setTimeout(() => { + this.input.nativeElement.focus(); + }, 100); + }, + error: () => { + this.next({ isRunning: false }); + }, + complete: () => { + this.next({ isRunning: false }); + }, + }); + } +} \ No newline at end of file diff --git a/frontend/src/app/shared/components/comments/comment.component.html b/frontend/src/app/shared/components/comments/comment.component.html index 56f16ad21..66f0cbd88 100644 --- a/frontend/src/app/shared/components/comments/comment.component.html +++ b/frontend/src/app/shared/components/comments/comment.component.html @@ -41,7 +41,7 @@
    - -
    -
    - - - - - - \ No newline at end of file diff --git a/frontend/src/app/shared/components/forms/markdown-editor.component.scss b/frontend/src/app/shared/components/forms/markdown-editor.component.scss deleted file mode 100644 index 7b55ed019..000000000 --- a/frontend/src/app/shared/components/forms/markdown-editor.component.scss +++ /dev/null @@ -1,18 +0,0 @@ -@import 'mixins'; -@import 'vars'; - -$background: #fff; - -:host ::ng-deep { - /* stylelint-disable-next-line selector-class-pattern */ - .CodeMirror { - height: 300px; - padding-bottom: 10px; - padding-top: 10px; - } -} - -.fullscreen { - @include fixed(0, 0, 0, 0); - z-index: 1040; -} \ No newline at end of file diff --git a/frontend/src/app/shared/components/forms/markdown-editor.component.ts b/frontend/src/app/shared/components/forms/markdown-editor.component.ts deleted file mode 100644 index 1db9b7889..000000000 --- a/frontend/src/app/shared/components/forms/markdown-editor.component.ts +++ /dev/null @@ -1,363 +0,0 @@ -/* - * Squidex Headless CMS - * - * @license - * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. - */ - -import { AfterViewInit, booleanAttribute, ChangeDetectionStrategy, Component, ElementRef, forwardRef, Input, Renderer2, ViewChild } from '@angular/core'; -import { NG_VALUE_ACCESSOR } from '@angular/forms'; -import { marked } from 'marked'; -import { ApiUrlConfig, AssetDto, AssetUploaderState, ContentDto, DialogModel, getContentValue, LanguageDto, ResourceLoaderService, StatefulControlComponent, Types, UploadCanceled } from '@app/shared/internal'; - -declare const SimpleMDE: any; - -export const SQX_MARKDOWN_EDITOR_CONTROL_VALUE_ACCESSOR: any = { - provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MarkdownEditorComponent), multi: true, -}; - -interface State { - // True, when the editor is shown as fullscreen. - isFullscreen: boolean; -} - -@Component({ - selector: 'sqx-markdown-editor', - styleUrls: ['./markdown-editor.component.scss'], - templateUrl: './markdown-editor.component.html', - providers: [ - SQX_MARKDOWN_EDITOR_CONTROL_VALUE_ACCESSOR, - ], - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class MarkdownEditorComponent extends StatefulControlComponent implements AfterViewInit { - private simplemde: any; - private value?: string; - - @Input() - public schemaIds?: ReadonlyArray; - - @Input() - public language!: LanguageDto; - - @Input() - public languages!: ReadonlyArray; - - @Input() - public folderId?: string; - - @Input({ transform: booleanAttribute }) - public set disabled(value: boolean | undefined | null) { - this.setDisabledState(value === true); - } - - @ViewChild('editor', { static: false }) - public editor!: ElementRef; - - @ViewChild('container', { static: false }) - public container!: ElementRef; - - @ViewChild('inner', { static: false }) - public inner!: ElementRef; - - public assetsDialog = new DialogModel(); - - public contentsDialog = new DialogModel(); - - constructor( - private readonly apiUrl: ApiUrlConfig, - private readonly assetUploader: AssetUploaderState, - private readonly renderer: Renderer2, - private readonly resourceLoader: ResourceLoaderService, - ) { - super({ isFullscreen: false }); - } - - public writeValue(obj: any) { - const newValue = Types.isString(obj) ? obj : ''; - - if (newValue === this.value) { - return; - } - - this.value = newValue; - - if (this.simplemde) { - this.simplemde.value(this.value); - } - } - - public onDisabled(isDisabled: boolean) { - if (this.simplemde) { - this.simplemde.codemirror.setOption('readOnly', isDisabled); - } - } - - private showAssetSelector = () => { - if (this.snapshot.isDisabled) { - return; - } - - this.assetsDialog.show(); - }; - - private showContentsSelector = () => { - if (this.snapshot.isDisabled) { - return; - } - - this.contentsDialog.show(); - }; - - public ngAfterViewInit() { - Promise.all([ - this.resourceLoader.loadLocalStyle('dependencies/simplemde/simplemde.min.css'), - this.resourceLoader.loadLocalStyle('dependencies/font-awesome/css/font-awesome.min.css'), - this.resourceLoader.loadLocalScript('dependencies/simplemde/simplemde.min.js'), - ]).then(() => { - const options = { - previewRender: (text: string) => { - return marked(text, { pedantic: true, mangle: false, headerIds: false }); - }, - autoDownloadFontAwesome: true, - spellChecker: false, - status: ['lines', 'words', 'cursor'], - toolbar: [ - { - name: 'bold', - action: SimpleMDE.toggleBold, - className: 'fa fa-bold', - title: 'Bold', - }, { - name: 'italic', - action: SimpleMDE.toggleItalic, - className: 'fa fa-italic', - title: 'Italic', - }, { - name: 'heading', - action: SimpleMDE.toggleHeadingSmaller, - className: 'fa fa-header', - title: 'Heading', - }, { - name: 'quote', - action: SimpleMDE.toggleBlockquote, - className: 'fa fa-quote-left', - title: 'Quote', - }, { - name: 'unordered-list', - action: SimpleMDE.toggleUnorderedList, - className: 'fa fa-list-ul', - title: 'Generic List', - }, { - name: 'ordered-list', - action: SimpleMDE.toggleOrderedList, - className: 'fa fa-list-ol', - title: 'Numbered List', - }, - '|', - { - name: 'link', - action: SimpleMDE.drawLink, - className: 'fa fa-link', - title: 'Create Link', - }, { - name: 'image', - action: SimpleMDE.drawImage, - className: 'fa fa-picture-o', - title: 'Insert Image', - }, - '|', - { - name: 'preview', - action: SimpleMDE.togglePreview, - className: 'fa fa-eye no-disable', - title: 'Toggle Preview', - }, { - name: 'fullscreen', - action: SimpleMDE.toggleFullScreen, - className: 'fa fa-arrows-alt no-disable no-mobile', - title: 'Toggle Fullscreen', - }, { - name: 'side-by-side', - action: SimpleMDE.toggleSideBySide, - className: 'fa fa-columns no-disable no-mobile', - title: 'Toggle Side by Side', - }, - '|', - { - name: 'guide', - action: 'https://simplemde.com/markdown-guide', - className: 'fa fa-question-circle', - title: 'Markdown Guide', - }, - '|', - { - name: 'assets', - action: this.showAssetSelector, - className: 'icon-assets icon-bold', - title: 'Insert Assets', - }, - ], - element: this.editor.nativeElement, - }; - - if (this.schemaIds && this.schemaIds.length > 0) { - options.toolbar.push({ - name: 'contents', - action: this.showContentsSelector, - className: 'icon-contents icon-bold', - title: 'Insert Contents', - }); - } - - this.simplemde = new SimpleMDE(options); - this.simplemde.value(this.value || ''); - this.simplemde.codemirror.setOption('readOnly', this.snapshot.isDisabled); - - this.simplemde.codemirror.on('change', () => { - const value = this.simplemde.value(); - - if (this.value !== value) { - this.value = value; - - this.callChange(value); - } - }); - - this.simplemde.codemirror.on('refresh', () => { - const isFullscreen = this.simplemde.isFullscreenActive(); - - this.toggleFullscreen(isFullscreen); - }); - - this.simplemde.codemirror.on('blur', () => { - this.callTouched(); - }); - }); - } - - public insertAssets(assets: ReadonlyArray) { - const content = this.buildAssetsMarkup(assets); - - if (content.length > 0) { - this.simplemde.codemirror.replaceSelection(content); - } - - this.assetsDialog.hide(); - } - - public insertContents(contents: ReadonlyArray) { - const content = this.buildContentsMarkup(contents); - - if (content.length > 0) { - this.simplemde.codemirror.replaceSelection(content); - } - - this.contentsDialog.hide(); - } - - public insertFiles(files: ReadonlyArray) { - const doc = this.simplemde.codemirror.getDoc(); - - for (const file of files) { - this.uploadFile(doc, file); - } - } - - private uploadFile(doc: any, file: File) { - if (this.snapshot.isDisabled) { - return; - } - - const uploadCursor = doc.getCursor(); - const uploadText = `![Uploading file...${new Date()}]()`; - - doc.replaceSelection(uploadText); - - const replaceText = (replacement: string) => { - const cursor = doc.getCursor(); - - const text = doc.getValue().replace(uploadText, replacement); - - doc.setValue(text); - - if (uploadCursor && uploadCursor.line === cursor.line) { - const offset = replacement.length - uploadText.length; - - doc.setCursor({ line: cursor.line, ch: cursor.ch + offset }); - } else { - doc.setCursor(cursor); - } - }; - - this.assetUploader.uploadFile(file, this.folderId) - .subscribe({ - next: asset => { - if (Types.is(asset, AssetDto)) { - replaceText(this.buildAssetMarkup(asset)); - } - }, - error: error => { - if (!Types.is(error, UploadCanceled)) { - replaceText('FAILED'); - } - }, - }); - } - - private toggleFullscreen(isFullscreen: boolean) { - let target = this.container.nativeElement; - - if (isFullscreen) { - target = document.body; - } - - this.renderer.appendChild(target, this.inner.nativeElement); - - this.next({ isFullscreen }); - } - - private buildAssetsMarkup(assets: ReadonlyArray) { - let markup = ''; - - for (const asset of assets) { - markup += this.buildAssetMarkup(asset); - } - - return markup; - } - - private buildContentsMarkup(contents: ReadonlyArray) { - let markup = ''; - - for (const content of contents) { - markup += this.buildContentMarkup(content); - } - - return markup; - } - - private buildContentMarkup(content: ContentDto) { - const name = - content.referenceFields - .map(f => getContentValue(content, this.language, f, false)) - .map(v => v.formatted) - .defined() - .join(', ') - || 'content'; - - return `[${name}](${this.apiUrl.buildUrl(content._links['self'].href)})`; - } - - private buildAssetMarkup(asset: AssetDto) { - const name = asset.fileNameWithoutExtension; - - if (asset.type === 'Image' || asset.mimeType === 'image/svg+xml' || asset.fileName.endsWith('.svg')) { - return `![${name}](${asset.fullUrl(this.apiUrl)} '${name}')`; - } else if (asset.type === 'Video') { - return `[${name}](${asset.fullUrl(this.apiUrl)})`; - } else { - return `[${name}](${asset.fullUrl(this.apiUrl)})`; - } - } -} diff --git a/frontend/src/app/shared/components/forms/rich-editor.component.html b/frontend/src/app/shared/components/forms/rich-editor.component.html index 01810ab03..391a7aa5b 100644 --- a/frontend/src/app/shared/components/forms/rich-editor.component.html +++ b/frontend/src/app/shared/components/forms/rich-editor.component.html @@ -1,14 +1,20 @@ -
    -
    -
    +
    + (assetSelect)="insertAssets($event)"> + + + - \ No newline at end of file + [schemaIds]="schemaIds"> + + + + \ No newline at end of file diff --git a/frontend/src/app/shared/components/forms/rich-editor.component.scss b/frontend/src/app/shared/components/forms/rich-editor.component.scss index 08f3e036d..2742d895e 100644 --- a/frontend/src/app/shared/components/forms/rich-editor.component.scss +++ b/frontend/src/app/shared/components/forms/rich-editor.component.scss @@ -1,10 +1,2 @@ @import 'mixins'; -@import 'vars'; - -.drop-container { - min-height: 401px; -} - -.editor { - height: 400px; -} \ No newline at end of file +@import 'vars'; \ No newline at end of file diff --git a/frontend/src/app/shared/components/forms/rich-editor.component.ts b/frontend/src/app/shared/components/forms/rich-editor.component.ts index 2e61a69cf..4aee803c7 100644 --- a/frontend/src/app/shared/components/forms/rich-editor.component.ts +++ b/frontend/src/app/shared/components/forms/rich-editor.component.ts @@ -7,10 +7,9 @@ import { AfterViewInit, booleanAttribute, ChangeDetectionStrategy, Component, ElementRef, EventEmitter, forwardRef, Input, OnDestroy, Output, ViewChild } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; +import { BehaviorSubject, catchError, of, switchMap } from 'rxjs'; import { ContentDto } from '@app/shared'; -import { ApiUrlConfig, AssetDto, AssetUploaderState, DialogModel, getContentValue, LanguageDto, ResourceLoaderService, StatefulControlComponent, Types, UploadCanceled } from '@app/shared/internal'; - -declare const tinymce: any; +import { ApiUrlConfig, AppsState, AssetDto, AssetsService, AssetUploaderState, DialogModel, getContentValue, LanguageDto, ResourceLoaderService, StatefulControlComponent, Types } from '@app/shared/internal'; export const SQX_RICH_EDITOR_CONTROL_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => RichEditorComponent), multi: true, @@ -26,12 +25,19 @@ export const SQX_RICH_EDITOR_CONTROL_VALUE_ACCESSOR: any = { changeDetection: ChangeDetectionStrategy.OnPush, }) export class RichEditorComponent extends StatefulControlComponent<{}, string> implements AfterViewInit, OnDestroy { - private tinyEditor: any; + private readonly assetId = new BehaviorSubject(null); + private editorWrapper: any; private value?: string; + private currentContents?: ResolvablePromise; + private currentAssets?: ResolvablePromise; + private currentChat?: ResolvablePromise; @Output() public assetPluginClick = new EventEmitter(); + @Input({ required: true }) + public hasChatBot = false; + @Input() public schemaIds?: ReadonlyArray; @@ -44,6 +50,12 @@ export class RichEditorComponent extends StatefulControlComponent<{}, string> im @Input() public folderId = ''; + @Input({ required: true }) + public classNames?: ReadonlyArray; + + @Input({ required: true }) + public mode: SquidexEditorMode = 'Html'; + @Input({ transform: booleanAttribute }) public set disabled(value: boolean | undefined | null) { this.setDisabledState(value === true); @@ -52,314 +64,209 @@ export class RichEditorComponent extends StatefulControlComponent<{}, string> im @ViewChild('editor', { static: false }) public editor!: ElementRef; + public chatDialog = new DialogModel(); + public assetsDialog = new DialogModel(); + public assetToEdit = this.assetId.pipe( + switchMap(id => { + if (id) { + return this.assetService.getAsset(this.appsState.appName, id); + } else { + return of(null); + } + }), + catchError(() => of(null))); public contentsDialog = new DialogModel(); constructor( private readonly apiUrl: ApiUrlConfig, + private readonly appsState: AppsState, private readonly assetUploader: AssetUploaderState, + private readonly assetService: AssetsService, private readonly resourceLoader: ResourceLoaderService, ) { super({}); } public ngOnDestroy() { - if (this.tinyEditor) { - this.tinyEditor.destroy(); - this.tinyEditor = null; + if (this.editorWrapper) { + this.editorWrapper.destroy?.(); + this.editorWrapper = null; } } public ngAfterViewInit() { - this.resourceLoader.loadLocalScript('dependencies/tinymce/tinymce.min.js').then(() => { - const timer = setInterval(() => { - const target = this.editor.nativeElement; - - if (document.body.contains(target)) { - tinymce.init(this.getEditorOptions(target)); - - clearInterval(timer); - } - }, 10); - }); - } - - public reset() { - this.ngOnDestroy(); - - setTimeout(() => { - this.ngAfterViewInit(); - }); - } - - private showAssetsSelector = () => { - if (this.snapshot.isDisabled) { - return; - } - - this.assetsDialog.show(); - }; - - private showContentsSelector = () => { - if (this.snapshot.isDisabled) { - return; - } - - this.contentsDialog.show(); - }; - - private getEditorOptions(target: any): any { - // eslint-disable-next-line @typescript-eslint/no-this-alias - const self = this; - - return { - ...DEFAULT_PROPS, - - images_upload_handler: (blob: any, success: (url: string) => void, failure: (message: string) => void) => { - const file = new File([blob.blob()], blob.filename(), { lastModified: new Date().getTime() }); - - self.assetUploader.uploadFile(file, this.folderId) - .subscribe({ - next: asset => { - if (Types.is(asset, AssetDto)) { - success(asset.fullUrl(self.apiUrl)); - } - }, - error: error => { - if (!Types.is(error, UploadCanceled)) { - failure('Failed'); - } - }, - }); - }, - - setup: (editor: any) => { - editor.ui.registry.addButton('assets', { - onAction: self.showAssetsSelector, - icon: 'gallery', - text: '', - tooltip: 'Insert Assets', - }); - - if (this.schemaIds && this.schemaIds.length > 0) { - editor.ui.registry.addButton('contents', { - onAction: self.showContentsSelector, - icon: 'duplicate', - text: '', - tooltip: 'Insert Contents', - }); - } - - editor.on('init', () => { - self.tinyEditor = editor; - - self.setContent(); - self.setReadOnly(); - }); - - editor.on('change', () => { - self.onValueChanged(); - }); - - editor.on('paste', (event: ClipboardEvent) => { - let hasFileDropped = false; - - if (event.clipboardData) { - for (let i = 0; i < event.clipboardData.items.length; i++) { - const file = event.clipboardData.items[i].getAsFile(); - - if (file) { - self.uploadFile(file); - - hasFileDropped = true; - } - } + this.resourceLoader.loadLocalStyle('editor/squidex-editor.css'); + this.resourceLoader.loadLocalScript('editor/squidex-editor.js').then(() => { + this.editorWrapper = new SquidexEditorWrapper(this.editor.nativeElement, { + value: this.value || '', + isDisabled: this.snapshot.isDisabled, + onSelectAIText: async () => { + if (this.snapshot.isDisabled) { + return; } - if (!hasFileDropped) { - self.onValueChanged(); - } else { - return false; - } - - return undefined; - }); - - editor.on('drop', (event: DragEvent) => { - let hasFileDropped = false; - - if (event.dataTransfer) { - for (let i = 0; i < event.dataTransfer.files.length; i++) { - const file = event.dataTransfer.files.item(i); + this.currentChat = new ResolvablePromise(); + this.chatDialog.show(); - if (file) { - self.uploadFile(file); - - hasFileDropped = true; - } - } + return await this.currentChat.promise; + }, + onSelectAssets: async () => { + if (this.snapshot.isDisabled) { + return; } - if (!hasFileDropped) { - self.onValueChanged(); + this.currentAssets = new ResolvablePromise(); + this.assetsDialog.show(); + + return await this.currentAssets.promise; + }, + onSelectContents: async () => { + if (this.snapshot.isDisabled) { + return; } - return false; - }); + this.currentContents = new ResolvablePromise(); + this.contentsDialog.show(); - editor.on('blur', () => { - self.callTouched(); - }); - }, + return await this.currentContents.promise; + }, + onUpload: (requests: UploadRequest[]) => { + return this.uploadFiles(requests); + }, + onChange: (value: string | undefined) => { + this.callChange(value); + }, + onEditContent: (schemaName, id) => { + const url = this.apiUrl.buildUrl(`/app/${this.appsState.appName}/content/${schemaName}/${id}`); - target, - }; + window.open(url, '_blank'); + }, + onEditAsset: id => { + this.assetId.next(id); + }, + appName: this.appsState.appName, + baseUrl: this.apiUrl.buildUrl(''), + canSelectAIText: this.hasChatBot, + canSelectAssets: true, + canSelectContents: !!this.schemaIds, + classNames: this.classNames, + mode: this.mode, + }); + }); } - private onValueChanged() { - const value = this.tinyEditor.getContent(); - - if (this.value !== value) { - this.value = value; + public reset() { + this.ngOnDestroy(); - this.callChange(value); - } + setTimeout(() => { + this.ngAfterViewInit(); + }); } public writeValue(obj: any) { - const newValue = Types.isString(obj) ? obj : ''; - - if (newValue == this.value) { - return; - } - - this.value = newValue; - - if (this.tinyEditor && this.tinyEditor.initialized) { - this.setContent(); + if (this.editorWrapper) { + this.editorWrapper?.setValue(obj); + } else { + this.value = obj; } } public onDisabled() { - if (this.tinyEditor && this.tinyEditor.initialized) { - this.setReadOnly(); + if (this.editorWrapper) { + this.editorWrapper?.setIsDisabled(this.snapshot.isDisabled); } } - private setContent() { - this.tinyEditor.setContent(this.value || ''); - } + public insertText(text: string | undefined | null) { + this.chatDialog.hide(); - private setReadOnly() { - this.tinyEditor.setMode(this.snapshot.isDisabled ? 'readonly' : 'design'); + if (!this.currentChat) { + return; + } + + this.currentChat.resolve(text); + this.currentChat = undefined; } public insertAssets(assets: ReadonlyArray) { - const content = this.buildAssetsMarkup(assets); + this.assetsDialog.hide(); - if (content.length > 0) { - this.tinyEditor.execCommand('mceInsertContent', false, content); + if (!this.currentAssets) { + return; } - this.assetsDialog.hide(); + const items = assets.map(a => this.buildAsset(a)); + + this.currentAssets.resolve(items); + this.currentAssets = undefined; } public insertContents(contents: ReadonlyArray) { - const content = this.buildContentsMarkup(contents); - - if (content.length > 0) { - this.tinyEditor.execCommand('mceInsertContent', false, content); - } - this.contentsDialog.hide(); - } - - public insertFiles(files: ReadonlyArray) { - for (const file of files) { - this.uploadFile(file); + if (!this.currentContents) { + return; } - } - private uploadFile(file: File) { - const uploadText = `[Uploading file...${new Date()}]`; + const items = contents.map(c => this.buildContent(c)); - this.tinyEditor.execCommand('mceInsertContent', false, uploadText); - - const replaceText = (replacement: string) => { - const content = this.tinyEditor.getContent().replace(uploadText, replacement); + this.currentContents.resolve(items); + this.currentContents = undefined; + } - this.tinyEditor.setContent(content); + private uploadFiles(requests: UploadRequest[]) { + const uploadFile = (request: UploadRequest) => { + return new Promise((resolve, reject) => { + this.assetUploader.uploadFile(request.file, this.folderId) + .subscribe({ + next: value => { + if (Types.is(value, AssetDto)) { + resolve(this.buildAsset(value)); + } else { + request.progress(value / 100); + } + }, + error: reject, + }); + }); }; - this.assetUploader.uploadFile(file, this.folderId) - .subscribe({ - next: asset => { - if (Types.is(asset, AssetDto)) { - replaceText(this.buildAssetMarkup(asset)); - } - }, - error: error => { - if (!Types.is(error, UploadCanceled)) { - replaceText('FAILED'); - } - }, - }); + return requests.map(r => () => uploadFile(r)); } - private buildAssetsMarkup(assets: ReadonlyArray) { - let markup = ''; - - for (const asset of assets) { - markup += this.buildAssetMarkup(asset); - } - - return markup; + private buildAsset(asset: AssetDto): Asset { + return { ...asset, src: asset.fullUrl(this.apiUrl) }; } - private buildContentsMarkup(contents: ReadonlyArray) { - let markup = ''; - - for (const content of contents) { - markup += this.buildContentMarkup(content); - } - - return markup; + private buildContent(content: ContentDto): Content { + return { ...content, title: buildContentTitle(content, this.language) }; } - private buildContentMarkup(content: ContentDto) { - const name = - content.referenceFields - .map(f => getContentValue(content, this.language, f, false)) - .map(v => v.formatted) - .defined() - .join(', ') - || 'content'; - - return `${name}`; + public closeAssetDialog() { + this.assetId.next(null); } +} - private buildAssetMarkup(asset: AssetDto) { - const name = asset.fileNameWithoutExtension; +function buildContentTitle(content: ContentDto, language: LanguageDto) { + const name = + content.referenceFields + .map(f => getContentValue(content, language, f, false)) + .map(v => v.formatted) + .defined() + .join(', '); - if (asset.type === 'Image' || asset.mimeType === 'image/svg+xml' || asset.fileName.endsWith('.svg')) { - return `${name}`; - } else if (asset.type === 'Video') { - return `
    \ No newline at end of file diff --git a/frontend/src/app/shared/components/search/queries/filter-node.component.ts b/frontend/src/app/shared/components/search/queries/filter-node.component.ts index 084e64b9b..8f26feb78 100644 --- a/frontend/src/app/shared/components/search/queries/filter-node.component.ts +++ b/frontend/src/app/shared/components/search/queries/filter-node.component.ts @@ -18,7 +18,7 @@ export class FilterNodeComponent { public comparison?: FilterComparison; @Output() - public change = new EventEmitter(); + public filterChange = new EventEmitter(); @Output() public remove = new EventEmitter(); diff --git a/frontend/src/app/shared/components/search/queries/query.component.html b/frontend/src/app/shared/components/search/queries/query.component.html index 2b7754a6a..479f3a6b4 100644 --- a/frontend/src/app/shared/components/search/queries/query.component.html +++ b/frontend/src/app/shared/components/search/queries/query.component.html @@ -1,18 +1,21 @@ + [statuses]="statuses">

    {{ 'search.sorting' | sqxTranslate }}

    - +
    diff --git a/frontend/src/app/shared/components/search/queries/sorting.component.ts b/frontend/src/app/shared/components/search/queries/sorting.component.ts index 029a3e71a..3106df356 100644 --- a/frontend/src/app/shared/components/search/queries/sorting.component.ts +++ b/frontend/src/app/shared/components/search/queries/sorting.component.ts @@ -16,7 +16,7 @@ import { QueryModel, QuerySorting, SORT_MODES } from '@app/shared/internal'; }) export class SortingComponent { @Output() - public change = new EventEmitter(); + public sortingChange = new EventEmitter(); @Output() public remove = new EventEmitter(); @@ -42,6 +42,6 @@ export class SortingComponent { } private emitChange() { - this.change.emit(); + this.sortingChange.emit(); } } diff --git a/frontend/src/app/shared/components/search/search-form.component.html b/frontend/src/app/shared/components/search/search-form.component.html index e840b42fe..8882a4cd5 100644 --- a/frontend/src/app/shared/components/search/search-form.component.html +++ b/frontend/src/app/shared/components/search/search-form.component.html @@ -42,7 +42,7 @@ - + {{ 'search.customQuery' | sqxTranslate }} @@ -109,7 +109,7 @@
    - + {{ 'search.nameQuery' | sqxTranslate }} diff --git a/frontend/src/app/shared/components/team-form.component.html b/frontend/src/app/shared/components/team-form.component.html index caa9005c8..89394f670 100644 --- a/frontend/src/app/shared/components/team-form.component.html +++ b/frontend/src/app/shared/components/team-form.component.html @@ -1,5 +1,5 @@ - + {{ 'teams.create' | sqxTranslate }} diff --git a/frontend/src/app/shared/components/team-form.component.ts b/frontend/src/app/shared/components/team-form.component.ts index f1b0d7524..a8a6aa0ca 100644 --- a/frontend/src/app/shared/components/team-form.component.ts +++ b/frontend/src/app/shared/components/team-form.component.ts @@ -16,7 +16,7 @@ import { ApiUrlConfig, CreateTeamForm, TeamsState } from '@app/shared/internal'; }) export class TeamFormComponent { @Output() - public close = new EventEmitter(); + public dialogClose = new EventEmitter(); public createForm = new CreateTeamForm(); @@ -27,7 +27,7 @@ export class TeamFormComponent { } public emitClose() { - this.close.emit(); + this.dialogClose.emit(); } public createTeam() { diff --git a/frontend/src/app/shared/components/tour-guide.component.ts b/frontend/src/app/shared/components/tour-guide.component.ts index c92949cb5..0efc39806 100644 --- a/frontend/src/app/shared/components/tour-guide.component.ts +++ b/frontend/src/app/shared/components/tour-guide.component.ts @@ -6,7 +6,7 @@ */ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; -import { fadeAnimation, StatefulComponent, TaskSnapshot, TourService, TourState } from '@app/shared/internal'; +import { fadeAnimation, StatefulComponent, Subscriptions, TaskSnapshot, TourService, TourState } from '@app/shared/internal'; interface State { // The when the section is collapsed. @@ -23,6 +23,8 @@ interface State { changeDetection: ChangeDetectionStrategy.OnPush, }) export class TourGuideComponent extends StatefulComponent implements OnInit { + private readonly subscriptions = new Subscriptions(); + constructor( public readonly tourState: TourState, public readonly tourService: TourService, @@ -31,13 +33,13 @@ export class TourGuideComponent extends StatefulComponent implements OnIn } public ngOnInit() { - this.own( + this.subscriptions.add( this.tourService.stepShow$ .subscribe(() => { this.next({ isCollapsed: true }); })); - this.own( + this.subscriptions.add( this.tourService.end$ .subscribe(() => { this.next({ isCollapsed: false }); diff --git a/frontend/src/app/shared/components/tour-hint.directive.ts b/frontend/src/app/shared/components/tour-hint.directive.ts index 5ecd2106f..3600d17b3 100644 --- a/frontend/src/app/shared/components/tour-hint.directive.ts +++ b/frontend/src/app/shared/components/tour-hint.directive.ts @@ -5,14 +5,19 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ -import { Directive, Input, numberAttribute, OnDestroy, OnInit } from '@angular/core'; +/* eslint-disable @angular-eslint/no-input-rename */ +/* eslint-disable @angular-eslint/directive-selector */ + +import { Directive, Input, numberAttribute, OnInit } from '@angular/core'; import { timer } from 'rxjs'; -import { FloatingPlacement, ResourceOwner, StepDefinition, TourService, TourState, Types } from '@app/shared/internal'; +import { FloatingPlacement, StepDefinition, Subscriptions, TourService, TourState, Types } from '@app/shared/internal'; @Directive({ selector: '[hintText]', }) -export class TourHintDirective extends ResourceOwner implements OnDestroy, OnInit { +export class TourHintDirective implements OnInit { + private readonly subscriptions = new Subscriptions(); + @Input('sqxTourStep') public anchorId!: string; @@ -32,7 +37,6 @@ export class TourHintDirective extends ResourceOwner implements OnDestroy, OnIni private readonly tourService: TourService, private readonly tourState: TourState, ) { - super(); } public ngOnInit() { @@ -49,7 +53,7 @@ export class TourHintDirective extends ResourceOwner implements OnDestroy, OnIni this.hintAfter : parseInt(this.hintAfter, 10); - this.own( + this.subscriptions.add( timer(after).subscribe(() => { if (this.tourState.snapshot.status === 'Started') { return; diff --git a/frontend/src/app/shared/components/watching-users.component.html b/frontend/src/app/shared/components/watching-users.component.html index 26aa5a975..8f9a04ec2 100644 --- a/frontend/src/app/shared/components/watching-users.component.html +++ b/frontend/src/app/shared/components/watching-users.component.html @@ -1,7 +1,7 @@ - - -
    - + + +
    +
    diff --git a/frontend/src/app/shared/components/watching-users.component.scss b/frontend/src/app/shared/components/watching-users.component.scss index 1a856b4a3..8ed6e6232 100644 --- a/frontend/src/app/shared/components/watching-users.component.scss +++ b/frontend/src/app/shared/components/watching-users.component.scss @@ -8,9 +8,12 @@ } .user-item { + @include circle(2.3rem); + background-color: $color-white; display: inline-block; margin-right: 0; margin-left: -1.1rem; + padding: 2px; position: relative; &:hover { @@ -19,8 +22,9 @@ .user-picture, .user-more { - @include circle(2.3rem); - border: 2px solid $color-white; + border-radius: 1000px; + border-style: solid; + border-width: 3px; } .user-more { diff --git a/frontend/src/app/shared/components/watching-users.component.ts b/frontend/src/app/shared/components/watching-users.component.ts index 7b6139217..c3f2aace2 100644 --- a/frontend/src/app/shared/components/watching-users.component.ts +++ b/frontend/src/app/shared/components/watching-users.component.ts @@ -5,9 +5,8 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; -import { timer } from 'rxjs'; -import { AppsState, CommentsService, switchSafe } from '@app/shared/internal'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { CollaborationService, Profile } from '@app/shared/internal'; @Component({ selector: 'sqx-watching-users', @@ -16,18 +15,12 @@ import { AppsState, CommentsService, switchSafe } from '@app/shared/internal'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class WatchingUsersComponent { - private appName: string; - - @Input({ required: true }) - public resource!: string; - - public users = - timer(0, 5000).pipe( - switchSafe((() => this.commentsService.getWatchingUsers(this.appName, this.resource)))); - - constructor(appsState: AppsState, - private readonly commentsService: CommentsService, + constructor( + public readonly collaboration: CollaborationService, ) { - this.appName = appsState.appName; + } + + public trackByUser(_: number, item: { user: Profile }) { + return item.user.id; } } diff --git a/frontend/src/app/shared/declarations.ts b/frontend/src/app/shared/declarations.ts index d092a0ee6..c2771b215 100644 --- a/frontend/src/app/shared/declarations.ts +++ b/frontend/src/app/shared/declarations.ts @@ -33,6 +33,7 @@ export * from './components/cards/iframe-card.component'; export * from './components/cards/random-cat-card.component'; export * from './components/cards/random-dog-card.component'; export * from './components/cards/support-card.component'; +export * from './components/chat-dialog.component'; export * from './components/comments/comment.component'; export * from './components/comments/comments.component'; export * from './components/contents/content-list-cell.directive'; @@ -42,8 +43,10 @@ export * from './components/contents/content-status.component'; export * from './components/contents/content-value-editor.component'; export * from './components/contents/content-value.component'; export * from './components/contents/translation-status.component'; +export * from './components/cursors.component'; +export * from './components/cursors.directive'; +export * from './components/focus-marker.component'; export * from './components/forms/geolocation-editor.component'; -export * from './components/forms/markdown-editor.component'; export * from './components/forms/rich-editor.component'; export * from './components/help/help-markdown.pipe'; export * from './components/help/help.component'; @@ -67,9 +70,9 @@ export * from './components/search/query-list.component'; export * from './components/search/search-form.component'; export * from './components/search/shared-queries.component'; export * from './components/table-header.component'; -export * from './components/tour-hint.directive'; -export * from './components/tour-guide.component'; export * from './components/team-form.component'; +export * from './components/tour-guide.component'; +export * from './components/tour-hint.directive'; export * from './components/watching-users.component'; export * from './guards/app-must-exist.guard'; export * from './guards/content-must-exist.guard'; diff --git a/frontend/src/app/shared/guards/app-must-exist.guard.ts b/frontend/src/app/shared/guards/app-must-exist.guard.ts index 2a8fb6f72..c87906c25 100644 --- a/frontend/src/app/shared/guards/app-must-exist.guard.ts +++ b/frontend/src/app/shared/guards/app-must-exist.guard.ts @@ -9,8 +9,8 @@ import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, Router } from '@angular/router'; import { Observable, of } from 'rxjs'; import { map, switchMap, tap } from 'rxjs/operators'; +import { UIState } from './../internal'; import { AppsState } from './../state/apps.state'; -import { UIState } from '../internal'; @Injectable() export class AppMustExistGuard { diff --git a/frontend/src/app/shared/guards/must-be-authenticated.guard.spec.ts b/frontend/src/app/shared/guards/must-be-authenticated.guard.spec.ts index f76d7a7b3..29fcd7e4d 100644 --- a/frontend/src/app/shared/guards/must-be-authenticated.guard.spec.ts +++ b/frontend/src/app/shared/guards/must-be-authenticated.guard.spec.ts @@ -6,6 +6,7 @@ */ import { Location } from '@angular/common'; +import { TestBed } from '@angular/core/testing'; import { Router } from '@angular/router'; import { firstValueFrom, of } from 'rxjs'; import { IMock, It, Mock, Times } from 'typemoq'; @@ -24,13 +25,15 @@ describe('MustBeAuthenticatedGuard', () => { uiOptions.value.redirectToLogin = false; location = Mock.ofType(); - - location.setup(x => x.path(true)) - .returns(() => '/my-path'); + location.setup(x => x.path(true)).returns(() => '/my-path'); router = Mock.ofType(); - authService = Mock.ofType(); - authGuard = new MustBeAuthenticatedGuard(authService.object, location.object, router.object, uiOptions); + + TestBed.configureTestingModule({ providers: [{ provide: UIOptions, useValue: uiOptions }] }); + TestBed.runInInjectionContext(() => { + authService = Mock.ofType(); + authGuard = new MustBeAuthenticatedGuard(authService.object, location.object, router.object); + }); }); it('should navigate to default page if not authenticated', async () => { diff --git a/frontend/src/app/shared/guards/must-be-authenticated.guard.ts b/frontend/src/app/shared/guards/must-be-authenticated.guard.ts index 5f30f2cc6..44a9db1f8 100644 --- a/frontend/src/app/shared/guards/must-be-authenticated.guard.ts +++ b/frontend/src/app/shared/guards/must-be-authenticated.guard.ts @@ -6,7 +6,7 @@ */ import { Location } from '@angular/common'; -import { Injectable } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { Router } from '@angular/router'; import { Observable } from 'rxjs'; import { map, take, tap } from 'rxjs/operators'; @@ -15,17 +15,16 @@ import { AuthService } from './../services/auth.service'; @Injectable() export class MustBeAuthenticatedGuard { + private readonly uiOptions = inject(UIOptions); + constructor( private readonly authService: AuthService, private readonly location: Location, private readonly router: Router, - private readonly uiOptions: UIOptions, ) { } public canActivate(): Observable { - const redirect = this.uiOptions.get('redirectToLogin'); - return this.authService.userChanges.pipe( take(1), tap(user => { @@ -35,7 +34,7 @@ export class MustBeAuthenticatedGuard { const redirectPath = this.location.path(true); - if (redirect) { + if (this.uiOptions.value.redirectToLogin) { this.authService.loginRedirect(redirectPath); } else { this.router.navigate([''], { queryParams: { redirectPath } }); diff --git a/frontend/src/app/shared/guards/must-be-not-authenticated.guard.spec.ts b/frontend/src/app/shared/guards/must-be-not-authenticated.guard.spec.ts index e8f78520e..73e041e60 100644 --- a/frontend/src/app/shared/guards/must-be-not-authenticated.guard.spec.ts +++ b/frontend/src/app/shared/guards/must-be-not-authenticated.guard.spec.ts @@ -6,6 +6,7 @@ */ import { Location } from '@angular/common'; +import { TestBed } from '@angular/core/testing'; import { Router } from '@angular/router'; import { firstValueFrom, of } from 'rxjs'; import { IMock, It, Mock, Times } from 'typemoq'; @@ -24,13 +25,15 @@ describe('MustBeNotAuthenticatedGuard', () => { uiOptions.value.redirectToLogin = false; location = Mock.ofType(); - - location.setup(x => x.path(true)) - .returns(() => '/my-path'); + location.setup(x => x.path(true)).returns(() => '/my-path'); router = Mock.ofType(); - authService = Mock.ofType(); - authGuard = new MustBeNotAuthenticatedGuard(authService.object, location.object, router.object, uiOptions); + + TestBed.configureTestingModule({ providers: [{ provide: UIOptions, useValue: uiOptions }] }); + TestBed.runInInjectionContext(() => { + authService = Mock.ofType(); + authGuard = new MustBeNotAuthenticatedGuard(authService.object, location.object, router.object); + }); }); it('should navigate to app page if authenticated', async () => { diff --git a/frontend/src/app/shared/guards/must-be-not-authenticated.guard.ts b/frontend/src/app/shared/guards/must-be-not-authenticated.guard.ts index 503594531..94a2237d3 100644 --- a/frontend/src/app/shared/guards/must-be-not-authenticated.guard.ts +++ b/frontend/src/app/shared/guards/must-be-not-authenticated.guard.ts @@ -6,7 +6,7 @@ */ import { Location } from '@angular/common'; -import { Injectable } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, Router } from '@angular/router'; import { Observable } from 'rxjs'; import { map, take, tap } from 'rxjs/operators'; @@ -15,16 +15,17 @@ import { AuthService } from './../services/auth.service'; @Injectable() export class MustBeNotAuthenticatedGuard { + private readonly options = inject(UIOptions); + constructor( private readonly authService: AuthService, private readonly location: Location, private readonly router: Router, - private readonly uiOptions: UIOptions, ) { } public canActivate(snapshot: ActivatedRouteSnapshot): Observable { - const redirect = this.uiOptions.get('redirectToLogin') && !snapshot.queryParams.logout; + const redirect = this.options.value.redirectToLogin && !snapshot.queryParams.logout; return this.authService.userChanges.pipe( take(1), diff --git a/frontend/src/app/shared/internal.ts b/frontend/src/app/shared/internal.ts index 79e9a953b..390e08355 100644 --- a/frontend/src/app/shared/internal.ts +++ b/frontend/src/app/shared/internal.ts @@ -15,7 +15,7 @@ export * from './services/auth.service'; export * from './services/autosave.service'; export * from './services/backups.service'; export * from './services/clients.service'; -export * from './services/comments.service'; +export * from './services/collaboration.service'; export * from './services/contents.service'; export * from './services/contributors.service'; export * from './services/help.service'; @@ -50,8 +50,8 @@ export * from './state/backups.forms'; export * from './state/backups.state'; export * from './state/clients.forms'; export * from './state/clients.state'; +export * from './state/comments'; export * from './state/comments.form'; -export * from './state/comments.state'; export * from './state/contents.forms-helpers'; export * from './state/contents.forms.visitors'; export * from './state/contents.forms'; diff --git a/frontend/src/app/shared/module.ts b/frontend/src/app/shared/module.ts index 4ed0ee531..0e6891694 100644 --- a/frontend/src/app/shared/module.ts +++ b/frontend/src/app/shared/module.ts @@ -13,7 +13,7 @@ import { MentionModule } from 'angular-mentions'; import { NgChartsModule } from 'ng2-charts'; import { NgxDocViewerModule } from 'ngx-doc-viewer'; import { SqxFrameworkModule } from '@app/framework'; -import { ApiCallsCardComponent, ApiCallsSummaryCardComponent, ApiPerformanceCardComponent, ApiTrafficCardComponent, ApiTrafficSummaryCardComponent, AppFormComponent, AppLanguagesService, AppMustExistGuard, AppsService, AppsState, AssetComponent, AssetDialogComponent, AssetFolderComponent, AssetFolderDialogComponent, AssetFolderDropdownComponent, AssetFolderDropdownItemComponent, AssetHistoryComponent, AssetPathComponent, AssetPreviewUrlPipe, AssetScriptsState, AssetSelectorComponent, AssetsListComponent, AssetsService, AssetsState, AssetTextEditorComponent, AssetUploaderComponent, AssetUploaderState, AssetUploadsCountCardComponent, AssetUploadsSizeCardComponent, AssetUploadsSizeSummaryCardComponent, AssetUrlPipe, AuthInterceptor, AuthService, AutoSaveService, BackupsService, BackupsState, buildTasks, ClientsService, ClientsState, CommentComponent, CommentsComponent, CommentsService, ContentListCellDirective, ContentListCellResizeDirective, ContentListFieldComponent, ContentListHeaderComponent, ContentListWidthDirective, ContentMustExistGuard, ContentsColumnsPipe, ContentSelectorComponent, ContentSelectorItemComponent, ContentsService, ContentsState, ContentStatusComponent, ContentValueComponent, ContentValueEditorComponent, ContributorsService, ContributorsState, FileIconPipe, FilterComparisonComponent, FilterLogicalComponent, FilterNodeComponent, FilterOperatorPipe, GeolocationEditorComponent, HelpComponent, HelpMarkdownPipe, HelpService, HistoryComponent, HistoryListComponent, HistoryMessagePipe, HistoryService, IFrameCardComponent, ImageCropperComponent, ImageFocusPointComponent, LanguagesService, LanguagesState, LoadAppsGuard, LoadLanguagesGuard, LoadSchemasGuard, LoadSettingsGuard, LoadTeamsGuard, MarkdownEditorComponent, MustBeAuthenticatedGuard, MustBeNotAuthenticatedGuard, NewsService, NotifoComponent, PlansService, PlansState, PreviewableType, QueryComponent, QueryListComponent, QueryPathComponent, RandomCatCardComponent, RandomDogCardComponent, ReferenceInputComponent, RichEditorComponent, RolesService, RolesState, RuleEventsState, RuleMustExistGuard, RuleSimulatorState, RulesService, RulesState, SavedQueriesComponent, SchemaCategoryComponent, SchemaMustExistGuard, SchemaMustExistPublishedGuard, SchemaMustNotBeSingletonGuard, SchemasService, SchemasState, SchemaTagSource, ScriptNamePipe, SearchFormComponent, SearchService, SortingComponent, StockPhotoService, SupportCardComponent, TableHeaderComponent, TASK_CONFIGURATION, TeamFormComponent, TeamMustExistGuard, TeamsService, TeamsState, TemplatesService, TemplatesState, TourGuideComponent, TourHintDirective, TourState, TranslationsService, TranslationStatusComponent, UIService, UIState, UnsetAppGuard, UnsetTeamGuard, UsagesService, UserDtoPicture, UserIdPicturePipe, UserNamePipe, UserNameRefPipe, UserPicturePipe, UserPictureRefPipe, UsersProviderService, UsersService, WatchingUsersComponent, WorkflowsService, WorkflowsState } from './declarations'; +import { ApiCallsCardComponent, ApiCallsSummaryCardComponent, ApiPerformanceCardComponent, ApiTrafficCardComponent, ApiTrafficSummaryCardComponent, AppFormComponent, AppLanguagesService, AppMustExistGuard, AppsService, AppsState, AssetComponent, AssetDialogComponent, AssetFolderComponent, AssetFolderDialogComponent, AssetFolderDropdownComponent, AssetFolderDropdownItemComponent, AssetHistoryComponent, AssetPathComponent, AssetPreviewUrlPipe, AssetScriptsState, AssetSelectorComponent, AssetsListComponent, AssetsService, AssetsState, AssetTextEditorComponent, AssetUploaderComponent, AssetUploaderState, AssetUploadsCountCardComponent, AssetUploadsSizeCardComponent, AssetUploadsSizeSummaryCardComponent, AssetUrlPipe, AuthInterceptor, AuthService, AutoSaveService, BackupsService, BackupsState, buildTasks, ChatDialogComponent, ClientsService, ClientsState, CommentComponent, CommentsComponent, ContentListCellDirective, ContentListCellResizeDirective, ContentListFieldComponent, ContentListHeaderComponent, ContentListWidthDirective, ContentMustExistGuard, ContentsColumnsPipe, ContentSelectorComponent, ContentSelectorItemComponent, ContentsService, ContentsState, ContentStatusComponent, ContentValueComponent, ContentValueEditorComponent, ContributorsService, ContributorsState, CursorsComponent, CursorsDirective, FileIconPipe, FilterComparisonComponent, FilterLogicalComponent, FilterNodeComponent, FilterOperatorPipe, FocusMarkerComponent, GeolocationEditorComponent, HelpComponent, HelpMarkdownPipe, HelpService, HistoryComponent, HistoryListComponent, HistoryMessagePipe, HistoryService, IFrameCardComponent, ImageCropperComponent, ImageFocusPointComponent, LanguagesService, LanguagesState, LoadAppsGuard, LoadLanguagesGuard, LoadSchemasGuard, LoadSettingsGuard, LoadTeamsGuard, MustBeAuthenticatedGuard, MustBeNotAuthenticatedGuard, NewsService, NotifoComponent, PlansService, PlansState, PreviewableType, QueryComponent, QueryListComponent, QueryPathComponent, RandomCatCardComponent, RandomDogCardComponent, ReferenceInputComponent, RichEditorComponent, RolesService, RolesState, RuleEventsState, RuleMustExistGuard, RuleSimulatorState, RulesService, RulesState, SavedQueriesComponent, SchemaCategoryComponent, SchemaMustExistGuard, SchemaMustExistPublishedGuard, SchemaMustNotBeSingletonGuard, SchemasService, SchemasState, SchemaTagSource, ScriptNamePipe, SearchFormComponent, SearchService, SortingComponent, StockPhotoService, SupportCardComponent, TableHeaderComponent, TASK_CONFIGURATION, TeamFormComponent, TeamMustExistGuard, TeamsService, TeamsState, TemplatesService, TemplatesState, TourGuideComponent, TourHintDirective, TourState, TranslationsService, TranslationStatusComponent, UIService, UIState, UnsetAppGuard, UnsetTeamGuard, UsagesService, UserDtoPicture, UserIdPicturePipe, UserNamePipe, UserNameRefPipe, UserPicturePipe, UserPictureRefPipe, UsersProviderService, UsersService, WatchingUsersComponent, WorkflowsService, WorkflowsState } from './declarations'; @NgModule({ imports: [ @@ -48,6 +48,7 @@ import { ApiCallsCardComponent, ApiCallsSummaryCardComponent, ApiPerformanceCard AssetUploadsSizeCardComponent, AssetUploadsSizeSummaryCardComponent, AssetUrlPipe, + ChatDialogComponent, CommentComponent, CommentsComponent, ContentListCellDirective, @@ -61,11 +62,14 @@ import { ApiCallsCardComponent, ApiCallsSummaryCardComponent, ApiPerformanceCard ContentStatusComponent, ContentValueComponent, ContentValueEditorComponent, + CursorsComponent, + CursorsDirective, FileIconPipe, FilterComparisonComponent, FilterLogicalComponent, FilterNodeComponent, FilterOperatorPipe, + FocusMarkerComponent, GeolocationEditorComponent, HelpComponent, HelpMarkdownPipe, @@ -75,7 +79,6 @@ import { ApiCallsCardComponent, ApiCallsSummaryCardComponent, ApiPerformanceCard IFrameCardComponent, ImageCropperComponent, ImageFocusPointComponent, - MarkdownEditorComponent, NotifoComponent, PreviewableType, QueryComponent, @@ -125,6 +128,7 @@ import { ApiCallsCardComponent, ApiCallsSummaryCardComponent, ApiPerformanceCard AssetUploadsSizeCardComponent, AssetUploadsSizeSummaryCardComponent, AssetUrlPipe, + ChatDialogComponent, CommentComponent, CommentsComponent, ContentListCellDirective, @@ -138,8 +142,11 @@ import { ApiCallsCardComponent, ApiCallsSummaryCardComponent, ApiPerformanceCard ContentStatusComponent, ContentValueComponent, ContentValueEditorComponent, + CursorsComponent, + CursorsDirective, DragDropModule, FileIconPipe, + FocusMarkerComponent, GeolocationEditorComponent, HelpComponent, HelpMarkdownPipe, @@ -147,7 +154,6 @@ import { ApiCallsCardComponent, ApiCallsSummaryCardComponent, ApiPerformanceCard HistoryListComponent, HistoryMessagePipe, IFrameCardComponent, - MarkdownEditorComponent, NotifoComponent, PreviewableType, QueryListComponent, @@ -194,7 +200,6 @@ export class SqxSharedModule { BackupsState, ClientsService, ClientsState, - CommentsService, ContentMustExistGuard, ContentsService, ContentsState, diff --git a/frontend/src/app/shared/services/collaboration.service.spec.ts b/frontend/src/app/shared/services/collaboration.service.spec.ts new file mode 100644 index 000000000..833848c6a --- /dev/null +++ b/frontend/src/app/shared/services/collaboration.service.spec.ts @@ -0,0 +1,177 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. + */ + +import { TestBed } from '@angular/core/testing'; +import { Mock } from 'typemoq'; +import { applyAwarenessUpdate, Awareness, encodeAwarenessUpdate } from 'y-protocols/awareness'; +import * as Y from 'yjs'; +import { AuthService, CollaborationProvider, CollaborationService, UIOptions } from '@app/shared/internal'; + +describe('CollaborationService', () => { + let service: CollaborationService; + let provider!: CollaborationProvider; + + beforeEach(() => { + TestBed.configureTestingModule({ providers: [{ provide: UIOptions, useValue: new UIOptions({}) }] }); + TestBed.runInInjectionContext(() => { + service = new CollaborationService(Mock.ofType().object); + }); + + service.providerFactory = (_, doc) => { + provider = { awareness: new Awareness(doc), doc, destroy: () => {} }; + + return provider; + }; + + service.connect('my-room'); + }); + + it('should also get map if disconnected', () => { + service.connect(null); + + let map: any = undefined; + service.getMap('map').subscribe(v => map = v); + + expect(map).toBeDefined(); + }); + + it('should also get array if disconnected', () => { + service.connect(null); + + let array: any = undefined; + service.getArray('array').subscribe(v => array = v); + + expect(array).toBeDefined(); + }); + + it('should add to map', () => { + const map = service.getMap('map'); + + let values: Record = {}; + + map.subscribe(state => { + state.valueChanges.subscribe(v => values = v); + + state.set('key1', 41); + state.set('key1', 42); + }); + + expect(values).toEqual({ key1: 42 }); + }); + + it('should remove from map', () => { + const map = service.getMap('map'); + + let values: Record = {}; + + map.subscribe(state => { + state.valueChanges.subscribe(v => values = v); + + state.set('key0', 41); + state.set('key1', 42); + state.remove('key0'); + }); + + expect(values).toEqual({ key1: 42 }); + }); + + it('should add to array', () => { + const array = service.getArray('array'); + + let items: ReadonlyArray = []; + + array.subscribe(state => { + state.itemsChanges.subscribe(i => items = i); + + state.add(1); + state.add(2); + }); + + expect(items).toEqual([ 1, 2]); + }); + + it('should replace in array', () => { + const array = service.getArray('array'); + + let items: ReadonlyArray = []; + + array.subscribe(state => { + state.itemsChanges.subscribe(i => items = i); + + state.add(1); + state.add(2); + state.set(0, 42); + }); + + expect(items).toEqual([ 42, 2]); + }); + + it('should remove from array', () => { + const array = service.getArray('array'); + + let items: ReadonlyArray = []; + + array.subscribe(state => { + state.itemsChanges.subscribe(i => items = i); + + state.add(1); + state.add(2); + state.remove(0); + }); + + expect(items).toEqual([ 2]); + }); + + it('should provide one awareness per user', () => { + let users: any[] = []; + service.userChanges.subscribe(u => users = u); + + provider.awareness.setLocalStateField('user', { id: '0', displayName: 'User0' }); + provider.awareness.setLocalStateField('key1', 101); + provider.awareness.setLocalStateField('key2', 102); + + setOtherAwareness({ + user: { id: '1', displayName: 'User1' }, + key1: 201, + key2: 202, + }); + + setOtherAwareness({ + user: { id: '1', displayName: 'User1' }, + key1: 301, + key2: 302, + }); + + setOtherAwareness({ + user: { id: '2', displayName: 'User2' }, + key1: 401, + key2: 402, + }); + + expect(users).toEqual([ + { + user: { id: '1', displayName: 'User1' }, + key1: 301, + key2: 302, + }, + { + user: { id: '2', displayName: 'User2' }, + key1: 401, + key2: 402, + }, + ]); + }); + + function setOtherAwareness(state: any) { + const otherDoc = new Y.Doc(); + const otherAwarness = new Awareness(otherDoc); + + otherAwarness.setLocalState(state); + + applyAwarenessUpdate(provider.awareness, encodeAwarenessUpdate(otherAwarness, [otherDoc.clientID], otherAwarness.getStates()), otherAwarness); + } +}); \ No newline at end of file diff --git a/frontend/src/app/shared/services/collaboration.service.ts b/frontend/src/app/shared/services/collaboration.service.ts new file mode 100644 index 000000000..bffe49598 --- /dev/null +++ b/frontend/src/app/shared/services/collaboration.service.ts @@ -0,0 +1,184 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. + */ + +import { inject, Injectable } from '@angular/core'; +import { BehaviorSubject, distinctUntilChanged, map, Observable, of, shareReplay, switchMap } from 'rxjs'; +import { Awareness } from 'y-protocols/awareness'; +import { WebsocketProvider } from 'y-websocket'; +import * as Y from 'yjs'; +import { Types, UIOptions } from '@app/framework'; +import { AuthService, Profile } from './auth.service'; + +type AwarenessState = { user: Profile; [key: string]: any }; + +export type CollaborationProvider = { awareness: Awareness; doc: Y.Doc; destroy: () => void }; + +@Injectable() +export class CollaborationService { + private readonly provider = new BehaviorSubject(null); + private readonly basePath = inject(UIOptions).value.collaborationService; + private readonly profile: Profile; + private previousName?: string | null; + + public awarenessChanges = + this.provider.pipe(map(p => p?.awareness)); + + public userChanges = + this.awarenessChanges.pipe( + switchMap(awareness => { + if (!awareness) { + return of([]); + } + + return new Observable(observer => { + const getStates = () => { + const byUser: { [userId: string]: AwarenessState } = {}; + + awareness!.getStates().forEach((state, clientId) => { + if (clientId == awareness.clientID) { + return; + } + + if (!state.user || state.user.id === this.profile.id) { + return; + } + + byUser[state.user.id] = state as any; + }); + + const sorted = Object.values(byUser).sortByString(x => x.user.displayName); + + observer.next(sorted); + }; + + getStates(); + awareness.on('change', getStates); + + return () => { + awareness.off('change', getStates); + }; + }); + }), + distinctUntilChanged(Types.equals), + shareReplay()); + + public providerFactory: (name: string, doc: Y.Doc) => CollaborationProvider; + + constructor(authService: AuthService) { + this.profile = authService.user!; + + this.providerFactory = (name, doc) => { + const websocket = new WebsocketProvider(this.basePath, `api/${name}?access_token=${this.profile.accessToken}`, doc); + + return { doc, awareness: websocket.awareness, destroy: () => websocket.destroy() }; + }; + } + + public connect(name: string | null) { + if (name === this.previousName) { + return; + } + + this.previousName = name; + this.cleanup(); + + if (!name) { + return; + } + + const yDocument = new Y.Doc(); + const yProvider = this.providerFactory(name, yDocument); + + const { id, email, displayName } = this.profile; + + yProvider.awareness?.setLocalStateField('user', { id, email, displayName }); + + this.provider.next(yProvider); + } + + private cleanup() { + this.provider.value?.destroy(); + this.provider.next(null); + } + + public getArray(name: string) { + return this.provider.pipe(map(p => new SharedArray(p?.doc.getArray(name)))); + } + + public getMap(name: string) { + return this.provider.pipe(map(p => new SharedMap(p?.doc.getMap(name)))); + } + + public updateAwareness(key: string, value: any) { + this.provider.value?.awareness.setLocalStateField(key, value); + } +} + +export class SharedMap { + private readonly value$: BehaviorSubject>>; + + public get valueChanges(): Observable>> { + return this.value$; + } + + public get state() { + return this.value$.value; + } + + constructor( + private readonly source: Y.Map | undefined, + ) { + this.value$ = new BehaviorSubject(source?.toJSON() || {}); + + source?.observeDeep(() => { + this.value$.next(source.toJSON()); + }); + } + + public set(key: string, value: T) { + this.source?.set(key, value); + } + + public remove(key: string) { + this.source?.delete(key); + } +} + +export class SharedArray { + private readonly items$: BehaviorSubject>; + + public get itemsChanges(): Observable> { + return this.items$; + } + + public get items() { + return this.items$.value; + } + + constructor( + private readonly source: Y.Array | undefined, + ) { + this.items$ = new BehaviorSubject>(source?.toJSON() || []); + + source?.observeDeep(() => { + this.items$.next(source.toJSON() || []); + }); + } + + public add(value: T) { + this.source?.insert(this.source.length, [value]); + } + + public remove(index: number, count = 1) { + this.source?.delete(index, count); + } + + public set(index: number, value: T) { + this.source?.delete(index, 1); + this.source?.insert(index, [value]); + } +} \ No newline at end of file diff --git a/frontend/src/app/shared/services/comments.service.spec.ts b/frontend/src/app/shared/services/comments.service.spec.ts deleted file mode 100644 index c37472f70..000000000 --- a/frontend/src/app/shared/services/comments.service.spec.ts +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Squidex Headless CMS - * - * @license - * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. - */ - -import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; -import { inject, TestBed } from '@angular/core/testing'; -import { ApiUrlConfig, CommentDto, CommentsDto, CommentsService, DateTime, Version } from '@app/shared/internal'; - -describe('CommentsService', () => { - const user = 'me'; - - beforeEach(() => { - TestBed.configureTestingModule({ - imports: [ - HttpClientTestingModule, - ], - providers: [ - CommentsService, - { provide: ApiUrlConfig, useValue: new ApiUrlConfig('http://service/p/') }, - ], - }); - }); - - afterEach(inject([HttpTestingController], (httpMock: HttpTestingController) => { - httpMock.verify(); - })); - - it('should make get request to get watching users', - inject([CommentsService, HttpTestingController], (commentsService: CommentsService, httpMock: HttpTestingController) => { - let userIds: ReadonlyArray; - - commentsService.getWatchingUsers('my-app', 'my-resource').subscribe(result => { - userIds = result; - }); - - const req = httpMock.expectOne('http://service/p/api/apps/my-app/watching/my-resource'); - - expect(req.request.method).toEqual('GET'); - expect(req.request.headers.get('If-Match')).toBeNull(); - expect(req.request.headers.get('X-Silent')).toBe('1'); - - req.flush(['user1', 'user2']); - - expect(userIds!).toEqual(['user1', 'user2']); - })); - - it('should make get request to get comments', - inject([CommentsService, HttpTestingController], (commentsService: CommentsService, httpMock: HttpTestingController) => { - let comments: CommentsDto; - - commentsService.getComments('my-comments', new Version('123')).subscribe(result => { - comments = result; - }); - - const req = httpMock.expectOne('http://service/p/api/my-comments?version=123'); - - expect(req.request.method).toEqual('GET'); - expect(req.request.headers.get('If-Match')).toBeNull(); - expect(req.request.headers.get('X-Silent')).toBe('1'); - - req.flush({ - createdComments: [{ - id: '123', - text: 'text1', - time: '2016-10-12T10:10', - user, - }], - updatedComments: [{ - id: '456', - text: 'text2', - time: '2017-11-12T12:12', - user, - }], - deletedComments: ['789'], - version: '9', - }); - - expect(comments!).toEqual( - new CommentsDto( - [ - new CommentDto('123', DateTime.parseISO('2016-10-12T10:10Z'), 'text1', undefined, user), - ], [ - new CommentDto('456', DateTime.parseISO('2017-11-12T12:12Z'), 'text2', undefined, user), - ], [ - '789', - ], - new Version('9')), - ); - })); - - it('should make post request to create comment', - inject([CommentsService, HttpTestingController], (commentsService: CommentsService, httpMock: HttpTestingController) => { - const dto = { text: 'text1' }; - - let comment: CommentDto; - - commentsService.postComment('my-comments', dto).subscribe(result => { - comment = result; - }); - - const req = httpMock.expectOne('http://service/p/api/my-comments'); - - expect(req.request.method).toEqual('POST'); - expect(req.request.headers.get('If-Match')).toBeNull(); - - req.flush({ - id: '123', - text: 'text1', - time: '2016-10-12T10:10', - user, - }); - - expect(comment!).toEqual(new CommentDto('123', DateTime.parseISO('2016-10-12T10:10Z'), 'text1', undefined, user)); - })); - - it('should make put request to replace comment content', - inject([CommentsService, HttpTestingController], (commentsService: CommentsService, httpMock: HttpTestingController) => { - const dto = { text: 'text1' }; - - commentsService.putComment('my-comments', '123', dto).subscribe(); - - const req = httpMock.expectOne('http://service/p/api/my-comments/123'); - - expect(req.request.method).toEqual('PUT'); - expect(req.request.headers.get('If-Match')).toBeNull(); - - req.flush({}); - })); - - it('should make delete request to delete comment', - inject([CommentsService, HttpTestingController], (commentsService: CommentsService, httpMock: HttpTestingController) => { - commentsService.deleteComment('my-comments', '123').subscribe(); - - const req = httpMock.expectOne('http://service/p/api/my-comments/123'); - - expect(req.request.method).toEqual('DELETE'); - expect(req.request.headers.get('If-Match')).toBeNull(); - - req.flush({}); - })); -}); diff --git a/frontend/src/app/shared/services/comments.service.ts b/frontend/src/app/shared/services/comments.service.ts deleted file mode 100644 index a894d1d87..000000000 --- a/frontend/src/app/shared/services/comments.service.ts +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Squidex Headless CMS - * - * @license - * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. - */ - -import { HttpClient, HttpHeaders } from '@angular/common/http'; -import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; -import { map } from 'rxjs/operators'; -import { ApiUrlConfig, DateTime, Model, pretifyError, Version } from '@app/framework'; - -export class CommentsDto extends Model { - constructor( - public readonly createdComments: ReadonlyArray, - public readonly updatedComments: ReadonlyArray, - public readonly deletedComments: ReadonlyArray, - public readonly version: Version, - ) { - super(); - } -} - -export class CommentDto extends Model { - constructor( - public readonly id: string, - public readonly time: DateTime, - public readonly text: string, - public readonly url: string | undefined, - public readonly user: string, - ) { - super(); - } -} - -export type UpsertCommentDto = Readonly<{ - // The text to comment. - text: string; - - // The url to the comment. - url?: string; -}>; - -@Injectable() -export class CommentsService { - constructor( - private readonly http: HttpClient, - private readonly apiUrl: ApiUrlConfig, - ) { - } - - public getWatchingUsers(appId: string, resource: string): Observable> { - const url = this.apiUrl.buildUrl(`api/apps/${appId}/watching/${resource}`); - - const options = { - headers: new HttpHeaders({ - 'X-Silent': '1', - }), - }; - - return this.http.get>(url, options); - } - - public getComments(commentsUrl: string, version: Version): Observable { - const url = this.apiUrl.buildUrl(`api/${commentsUrl}?version=${version.value}`); - - const options = { - headers: new HttpHeaders({ - 'X-Silent': '1', - }), - }; - - return this.http.get(url, options).pipe( - map(body => { - return parseComments(body); - }), - pretifyError('i18n:comments.loadFailed')); - } - - public postComment(commentsUrl: string, dto: UpsertCommentDto): Observable { - const url = this.apiUrl.buildUrl(`api/${commentsUrl}`); - - return this.http.post(url, dto).pipe( - map(body => { - return parseComment(body); - }), - pretifyError('i18n:comments.createFailed')); - } - - public putComment(commentsUrl: string, commentId: string, dto: UpsertCommentDto): Observable { - const url = this.apiUrl.buildUrl(`api/${commentsUrl}/${commentId}`); - - return this.http.put(url, dto).pipe( - pretifyError('i18n:comments.updateFailed')); - } - - public deleteComment(commentsUrl: string, commentId: string): Observable { - const url = this.apiUrl.buildUrl(`api/${commentsUrl}/${commentId}`); - - return this.http.delete(url).pipe( - pretifyError('i18n:comments.deleteFailed')); - } -} -function parseComments(response: any) { - return new CommentsDto( - response.createdComments.map(parseComment), - response.updatedComments.map(parseComment), - response.deletedComments, - new Version(response.version)); -} - -function parseComment(response: any) { - return new CommentDto( - response.id, - DateTime.parseISO(response.time), - response.text, - response.url, - response.user); -} - diff --git a/frontend/src/app/shared/services/help.service.spec.ts b/frontend/src/app/shared/services/help.service.spec.ts index a9183f8d2..98403102c 100644 --- a/frontend/src/app/shared/services/help.service.spec.ts +++ b/frontend/src/app/shared/services/help.service.spec.ts @@ -9,7 +9,7 @@ import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { inject, TestBed } from '@angular/core/testing'; -import { HelpService } from '@app/shared/internal'; +import { HelpService, SDKEntry } from '@app/shared/internal'; describe('HelpService', () => { beforeEach(() => { @@ -62,4 +62,44 @@ describe('HelpService', () => { expect(helpSections!).toEqual(''); })); + + it('should make get request to get sdks', + inject([HelpService, HttpTestingController], (helpService: HelpService, httpMock: HttpTestingController) => { + let sdks: Record; + + helpService.getSDKs().subscribe(result => { + sdks = result; + }); + + const req = httpMock.expectOne('https://raw.githubusercontent.com/Squidex/sdk-fern/main/sdks.json'); + + expect(req.request.method).toEqual('GET'); + expect(req.request.headers.get('If-Match')).toBeNull(); + + req.flush({ + dotnet: {}, + }); + + expect(sdks!).toEqual({ + dotnet: {} as any, + }); + })); + + it('should return empty sdks if get request fails', + inject([HelpService, HttpTestingController], (helpService: HelpService, httpMock: HttpTestingController) => { + let sdks: Record; + + helpService.getSDKs().subscribe(result => { + sdks = result; + }); + + const req = httpMock.expectOne('https://raw.githubusercontent.com/Squidex/sdk-fern/main/sdks.json'); + + expect(req.request.method).toEqual('GET'); + expect(req.request.headers.get('If-Match')).toBeNull(); + + req.error({}); + + expect(sdks!).toEqual({}); + })); }); diff --git a/frontend/src/app/shared/services/help.service.ts b/frontend/src/app/shared/services/help.service.ts index c42cb6c9b..1bc0c0d7c 100644 --- a/frontend/src/app/shared/services/help.service.ts +++ b/frontend/src/app/shared/services/help.service.ts @@ -10,6 +10,23 @@ import { Injectable } from '@angular/core'; import { Observable, of } from 'rxjs'; import { catchError } from 'rxjs/operators'; +export interface SDKEntry { + // The display name. + name: string; + + // The link to the repository. + repository: string; + + // The link to the documentation. + documentation: string; + + // The instructions as markdown. + instructions: string; + + // The SVG logo. + logo: string; +} + @Injectable() export class HelpService { constructor( @@ -23,4 +40,11 @@ export class HelpService { return this.http.get(url, { responseType: 'text' }).pipe( catchError(() => of(''))); } + + public getSDKs(): Observable> { + const url = 'https://raw.githubusercontent.com/Squidex/sdk-fern/main/sdks.json'; + + return this.http.get>(url).pipe( + catchError(() => of({}))); + } } diff --git a/frontend/src/app/shared/services/schemas.service.ts b/frontend/src/app/shared/services/schemas.service.ts index 597e3a3ca..056a86fb3 100644 --- a/frontend/src/app/shared/services/schemas.service.ts +++ b/frontend/src/app/shared/services/schemas.service.ts @@ -101,7 +101,7 @@ export function getTableFields(fields: ReadonlyArray) { } result.sort(); - + return result; } diff --git a/frontend/src/app/shared/services/schemas.types.ts b/frontend/src/app/shared/services/schemas.types.ts index 77cdd8a94..6b62c7aa2 100644 --- a/frontend/src/app/shared/services/schemas.types.ts +++ b/frontend/src/app/shared/services/schemas.types.ts @@ -179,6 +179,7 @@ export abstract class FieldPropertiesDto { export class ArrayFieldPropertiesDto extends FieldPropertiesDto { public readonly fieldType = 'Array'; + public readonly calculatedDefaultValue: 'EmptyArray' | 'Null' = 'EmptyArray'; public readonly maxItems?: number; public readonly minItems?: number; public readonly uniqueFields?: ReadonlyArray; @@ -269,6 +270,7 @@ export class ComponentFieldPropertiesDto extends FieldPropertiesDto { export class ComponentsFieldPropertiesDto extends FieldPropertiesDto { public readonly fieldType = 'Components'; + public readonly calculatedDefaultValue: 'EmptyArray' | 'Null' = 'EmptyArray'; public readonly schemaIds?: ReadonlyArray; public readonly maxItems?: number; public readonly minItems?: number; @@ -293,7 +295,7 @@ export const DATETIME_FIELD_EDITORS: ReadonlyArray = [ export class DateTimeFieldPropertiesDto extends FieldPropertiesDto { public readonly fieldType = 'DateTime'; - public readonly calculatedDefaultValue?: string; + public readonly calculatedDefaultValue?: 'Now' | 'Today'; public readonly defaultValue?: string; public readonly defaultValues?: DefaultValue; public readonly format?: string; @@ -388,6 +390,7 @@ export class ReferencesFieldPropertiesDto extends FieldPropertiesDto { public readonly maxItems?: number; public readonly minItems?: number; public readonly mustBePublished?: boolean; + public readonly query?: string; public readonly resolveReference?: boolean; public readonly schemaIds?: ReadonlyArray; @@ -430,6 +433,7 @@ export class StringFieldPropertiesDto extends FieldPropertiesDto { public readonly fieldType = 'String'; public readonly allowedValues?: ReadonlyArray; + public readonly classNames?: ReadonlyArray; public readonly contentType?: StringContentType; public readonly createEnum: boolean = false; public readonly defaultValue?: string; diff --git a/frontend/src/app/shared/state/comments.form.ts b/frontend/src/app/shared/state/comments.form.ts index 16c9fd640..0d418b5f4 100644 --- a/frontend/src/app/shared/state/comments.form.ts +++ b/frontend/src/app/shared/state/comments.form.ts @@ -7,9 +7,9 @@ import { UntypedFormControl, Validators } from '@angular/forms'; import { ExtendedFormGroup, Form } from '@app/framework'; -import { UpsertCommentDto } from './../services/comments.service'; +import { Comment } from './comments'; -export class UpsertCommentForm extends Form { +export class UpsertCommentForm extends Form { constructor() { super(new ExtendedFormGroup({ text: new UntypedFormControl('', diff --git a/frontend/src/app/shared/state/comments.state.spec.ts b/frontend/src/app/shared/state/comments.state.spec.ts deleted file mode 100644 index 77d42475a..000000000 --- a/frontend/src/app/shared/state/comments.state.spec.ts +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Squidex Headless CMS - * - * @license - * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. - */ - -import { of } from 'rxjs'; -import { IMock, Mock } from 'typemoq'; -import { CommentDto, CommentsDto, CommentsService, CommentsState, DialogService, Version } from '@app/shared/internal'; -import { TestValues } from './_test-helpers'; - -describe('CommentsState', () => { - const { - creator, - modified, - } = TestValues; - - const commentsUrl = 'my-comments'; - - const oldComments = new CommentsDto([ - new CommentDto('1', modified, 'text1', undefined, creator), - new CommentDto('2', modified, 'text2', undefined, creator), - ], [], [], new Version('1')); - - let dialogs: IMock; - let commentsService: IMock; - let commentsState: CommentsState; - - beforeEach(() => { - dialogs = Mock.ofType(); - - commentsService = Mock.ofType(); - commentsState = new CommentsState(commentsUrl, commentsService.object, dialogs.object); - }); - - beforeEach(() => { - commentsService.verifyAll(); - }); - - describe('Loading', () => { - it('should load and merge comments', () => { - const newComments = new CommentsDto([ - new CommentDto('3', modified, 'text3', undefined, creator), - ], [ - new CommentDto('2', modified, 'text2_2', undefined, creator), - ], ['1'], new Version('2')); - - commentsService.setup(x => x.getComments(commentsUrl, new Version('-1'))) - .returns(() => of(oldComments)).verifiable(); - - commentsService.setup(x => x.getComments(commentsUrl, new Version('1'))) - .returns(() => of(newComments)).verifiable(); - - commentsState.load().subscribe(); - commentsState.load().subscribe(); - - expect(commentsState.snapshot.isLoaded).toBeTruthy(); - expect(commentsState.snapshot.comments).toEqual([ - new CommentDto('2', modified, 'text2_2', undefined, creator), - new CommentDto('3', modified, 'text3', undefined, creator), - ]); - }); - }); - - describe('Updates', () => { - beforeEach(() => { - commentsService.setup(x => x.getComments(commentsUrl, new Version('-1'))) - .returns(() => of(oldComments)).verifiable(); - - commentsState.load().subscribe(); - }); - - it('should add comment to snapshot if created', () => { - const newComment = new CommentDto('3', modified, 'text3', undefined, creator); - - const request = { text: 'text3', url: 'url3' }; - - commentsService.setup(x => x.postComment(commentsUrl, request)) - .returns(() => of(newComment)).verifiable(); - - commentsState.create('text3', 'url3').subscribe(); - - expect(commentsState.snapshot.comments).toEqual([ - new CommentDto('1', modified, 'text1', undefined, creator), - new CommentDto('2', modified, 'text2', undefined, creator), - new CommentDto('3', modified, 'text3', undefined, creator), - ]); - }); - - it('should update properties if updated', () => { - const request = { text: 'text2_2' }; - - commentsService.setup(x => x.putComment(commentsUrl, '2', request)) - .returns(() => of({})).verifiable(); - - commentsState.update(oldComments.createdComments[1], 'text2_2', modified).subscribe(); - - expect(commentsState.snapshot.comments).toEqual([ - new CommentDto('1', modified, 'text1', undefined, creator), - new CommentDto('2', modified, 'text2_2', undefined, creator), - ]); - }); - - it('should remove comment from snapshot if deleted', () => { - commentsService.setup(x => x.deleteComment(commentsUrl, '2')) - .returns(() => of({})).verifiable(); - - commentsState.delete(oldComments.createdComments[1]).subscribe(); - - expect(commentsState.snapshot.comments).toEqual([ - new CommentDto('1', modified, 'text1', undefined, creator), - ]); - }); - }); -}); diff --git a/frontend/src/app/shared/state/comments.state.ts b/frontend/src/app/shared/state/comments.state.ts deleted file mode 100644 index 08fa402ff..000000000 --- a/frontend/src/app/shared/state/comments.state.ts +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Squidex Headless CMS - * - * @license - * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. - */ - -import { Observable } from 'rxjs'; -import { map, tap } from 'rxjs/operators'; -import { DateTime, debug, DialogService, LoadingState, shareSubscribed, State, Version } from '@app/framework'; -import { CommentDto, CommentsService } from './../services/comments.service'; - -interface Snapshot extends LoadingState { - // The current comments. - comments: ReadonlyArray; - - // The version of the comments state. - version: Version; -} - -export class CommentsState extends State { - public comments = - this.project(x => x.comments); - - public isLoading = - this.project(x => x.isLoading === true); - - public isLoaded = - this.project(x => x.isLoaded === true); - - public versionNumber = - this.project(x => parseInt(x.version.value, 10)); - - constructor( - private readonly commentsUrl: string, - private readonly commentsService: CommentsService, - private readonly dialogs: DialogService, - private readonly orderDescending = false, - initialVersion = -1, - ) { - super({ comments: [], version: new Version(initialVersion.toString()) }); - - debug(this, 'comments'); - } - - public load(silent = false): Observable { - return this.commentsService.getComments(this.commentsUrl, this.version).pipe( - tap(payload => { - this.next(s => { - let comments = s.comments; - - for (const created of payload.createdComments) { - if (!comments.find(x => x.id === created.id)) { - if (this.orderDescending) { - comments = [created, ...comments]; - } else { - comments = [...comments, created]; - } - } - } - - for (const updated of payload.updatedComments) { - comments = comments.replacedBy('id', updated); - } - - for (const deleted of payload.deletedComments) { - comments = comments.filter(x => x.id !== deleted); - } - - return { ...s, comments, isLoaded: true, version: payload.version }; - }, 'Loading Done'); - }), - shareSubscribed(this.dialogs, { silent })); - } - - public create(text: string, url?: string): Observable { - return this.commentsService.postComment(this.commentsUrl, { text, url }).pipe( - tap(created => { - this.next(s => { - const comments = [...s.comments, created]; - - return { ...s, comments }; - }, 'Created'); - }), - shareSubscribed(this.dialogs)); - } - - public delete(comment: CommentDto): Observable { - return this.commentsService.deleteComment(this.commentsUrl, comment.id).pipe( - tap(() => { - this.next(s => { - const comments = s.comments.removedBy('id', comment); - - return { ...s, comments }; - }, 'Deleted'); - }), - shareSubscribed(this.dialogs)); - } - - public update(comment: CommentDto, text: string, now?: DateTime): Observable { - return this.commentsService.putComment(this.commentsUrl, comment.id, { text }).pipe( - map(() => update(comment, text, now)), - tap(updated => { - this.next(s => { - const comments = s.comments.replacedBy('id', updated); - - return { ...s, comments }; - }, 'Updated'); - }), - shareSubscribed(this.dialogs)); - } - - private get version() { - return this.snapshot.version; - } -} - -const update = (comment: CommentDto, text: string, time?: DateTime) => - new CommentDto( - comment.id, - time || DateTime.now(), - text, - comment.url, - comment.user); diff --git a/frontend/src/app/shared/state/comments.ts b/frontend/src/app/shared/state/comments.ts new file mode 100644 index 000000000..a4c13781a --- /dev/null +++ b/frontend/src/app/shared/state/comments.ts @@ -0,0 +1,23 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. + */ + +export interface Comment { + // The timestamp when the comment was created. + time: string; + + // The actual text. + text: string; + + // The user token. + user: string; + + // The url. + url?: string; + + // Indicates whether this has been read. + isRead?: boolean; +} \ No newline at end of file diff --git a/frontend/src/app/shared/state/contents.forms.spec.ts b/frontend/src/app/shared/state/contents.forms.spec.ts index be39f7a1d..24b5877bc 100644 --- a/frontend/src/app/shared/state/contents.forms.spec.ts +++ b/frontend/src/app/shared/state/contents.forms.spec.ts @@ -410,11 +410,11 @@ describe('ContentForm', () => { createField({ id: 4, properties: createProperties('Array'), - partitioning: 'invariant', nested: [ createNestedField({ id: 41, properties: createProperties('String') }), createNestedField({ id: 42, properties: createProperties('String', { defaultValue: 'Default' }), isDisabled: true }), ], + partitioning: 'invariant', }), ] }); @@ -452,6 +452,18 @@ describe('ContentForm', () => { }); describe('with complex form', () => { + const arraySetup = [ + { + value: [], + defaultValue: 'EmptyArray', + + }, + { + value: undefined, + defaultValue: 'Null', + }, + ]; + it('should not enabled disabled fields', () => { const contentForm = createForm([ createField({ id: 1, properties: createProperties('String') }), @@ -471,6 +483,32 @@ describe('ContentForm', () => { expectForm(contentForm.form, 'field3.de', { invalid: false }); }); + arraySetup.forEach(test => { + it(`should create array with ${test.defaultValue} default value`, () => { + const contentForm = createForm([ + createField({ + id: 4, + properties: createProperties('Array', { calculatedDefaultValue: test.defaultValue }), + }), + ]); + + expect(contentForm.value.field4.en).toEqual(test.value); + }); + }); + + arraySetup.forEach(test => { + it(`should create components with ${test.defaultValue} default value`, () => { + const contentForm = createForm([ + createField({ + id: 4, + properties: createProperties('Components', { calculatedDefaultValue: test.defaultValue }), + }), + ]); + + expect(contentForm.value.field4.en).toEqual(test.value); + }); + }); + it('should require field based on context condition', () => { const contentForm = createForm([ createField({ id: 1, properties: createProperties('Number'), partitioning: 'invariant' }), @@ -587,11 +625,11 @@ describe('ContentForm', () => { createField({ id: 4, properties: createProperties('Array'), - partitioning: 'invariant', nested: [ createNestedField({ id: 41, properties: createProperties('Number') }), createNestedField({ id: 42, properties: createProperties('Number') }), ], + partitioning: 'invariant', }), ], [{ field: 'field4.nested42', action: 'Disable', condition: 'itemData.nested41 > 100', @@ -620,11 +658,11 @@ describe('ContentForm', () => { createField({ id: 4, properties: createProperties('Array'), - partitioning: 'invariant', nested: [ createNestedField({ id: 41, properties: createProperties('Number') }), createNestedField({ id: 42, properties: createProperties('Number') }), ], + partitioning: 'invariant', }), ], [{ field: 'field4.nested42', action: 'Hide', condition: 'itemData.nested41 > 100', @@ -653,11 +691,11 @@ describe('ContentForm', () => { createField({ id: 4, properties: createProperties('Array'), - partitioning: 'language', nested: [ createNestedField({ id: 41, properties: createProperties('Number') }), createNestedField({ id: 42, properties: createProperties('Number') }), ], + partitioning: 'language', }), ], [{ field: 'field4.nested42', action: 'Hide', condition: 'itemData.nested41 > 100', @@ -686,11 +724,7 @@ describe('ContentForm', () => { const component = createSchema({ id: 2, fields: [ - createField({ - id: 1, - properties: createProperties('String'), - partitioning: 'invariant', - }), + createField({ id: 1, properties: createProperties('String'), partitioning: 'invariant' }), ], fieldRules: [{ field: 'field1', action: 'Hide', condition: 'data.field1 > 100', @@ -804,11 +838,7 @@ describe('ContentForm', () => { }); const contentForm = createForm([ - createField({ - id: 4, - properties: createProperties('Components'), - partitioning: 'invariant', - }), + createField({ id: 4, properties: createProperties('Components'), partitioning: 'invariant' }), ], [], { [componentId]: component, }); @@ -841,11 +871,7 @@ describe('ContentForm', () => { const component1 = createSchema({ id: 1, fields: [ - createField({ - id: 11, - properties: createProperties('String'), - partitioning: 'invariant', - }), + createField({ id: 11, properties: createProperties('String'), partitioning: 'invariant' }), ], }); @@ -853,20 +879,12 @@ describe('ContentForm', () => { const component2 = createSchema({ id: 2, fields: [ - createField({ - id: 21, - properties: createProperties('String'), - partitioning: 'invariant', - }), + createField({ id: 21, properties: createProperties('String'), partitioning: 'invariant' }), ], }); const contentForm = createForm([ - createField({ - id: 4, - properties: createProperties('Component'), - partitioning: 'invariant', - }), + createField({ id: 4, properties: createProperties('Component'), partitioning: 'invariant' }), ], [], { [component1Id]: component1, [component2Id]: component2, @@ -923,20 +941,11 @@ describe('ContentForm', () => { const component = createSchema({ id: 1, fields: [ - createField({ - id: 11, - properties: createProperties('String'), - partitioning: 'invariant', - }), - ], + createField({ id: 11, properties: createProperties('String'), partitioning: 'invariant' })], }); const contentForm = createForm([ - createField({ - id: 4, - properties: createProperties('Component'), - partitioning: 'invariant', - }), + createField({ id: 4, properties: createProperties('Component'), partitioning: 'invariant' }), ], [], { [componentId]: component, }); diff --git a/frontend/src/app/shared/state/contents.forms.ts b/frontend/src/app/shared/state/contents.forms.ts index 813abb2e9..022c87f01 100644 --- a/frontend/src/app/shared/state/contents.forms.ts +++ b/frontend/src/app/shared/state/contents.forms.ts @@ -209,12 +209,7 @@ export class FieldForm extends AbstractContentForm fieldTranslationStatus(x))); - constructor( - globals: FormGlobals, - field: RootFieldDto, - fieldPath: string, - rules: RulesProvider, - ) { + constructor(globals: FormGlobals, field: RootFieldDto, fieldPath: string, rules: RulesProvider) { super(globals, field, fieldPath, FieldForm.buildForm(), false, rules); for (const { key, isOptional } of globals.partitions.getAll(field)) { @@ -345,6 +340,8 @@ export class FieldArrayForm extends AbstractContentForm this), FieldsValidators.create(field, isOptional)), isOptional, rules); + this.form.setValue(FieldDefaultValue.get(field, this.partition), { emitEvent: false }); + (this.form.template as any)['form'] = this; } diff --git a/frontend/src/app/shared/state/contents.forms.visitors.spec.ts b/frontend/src/app/shared/state/contents.forms.visitors.spec.ts index e140448d9..2ec0ce978 100644 --- a/frontend/src/app/shared/state/contents.forms.visitors.spec.ts +++ b/frontend/src/app/shared/state/contents.forms.visitors.spec.ts @@ -38,8 +38,14 @@ describe('ArrayField', () => { expect(FieldFormatter.format(field, 1)).toBe('0 Items'); }); - it('should return default value as null', () => { - expect(FieldDefaultValue.get(field, 'iv')).toBeNull(); + it('should return default value as empty array', () => { + expect(FieldDefaultValue.get(field, 'iv')).toEqual([]); + }); + + it('should return default value as undefined when configured', () => { + const field2 = createField({ properties: createProperties('Array', { calculatedDefaultValue: 'Null' }) }); + + expect(FieldDefaultValue.get(field2, 'iv')).toBeUndefined(); }); }); @@ -130,8 +136,14 @@ describe('ComponentsField', () => { expect(FieldFormatter.format(field, 1)).toBe('0 Components'); }); - it('should return default value as null', () => { - expect(FieldDefaultValue.get(field, 'iv')).toBeNull(); + it('should return default value as empty array', () => { + expect(FieldDefaultValue.get(field, 'iv')).toEqual([]); + }); + + it('should return default value as undefined when configured', () => { + const field2 = createField({ properties: createProperties('Components', { calculatedDefaultValue: 'Null' }) }); + + expect(FieldDefaultValue.get(field2, 'iv')).toBeUndefined(); }); }); diff --git a/frontend/src/app/shared/state/contents.forms.visitors.ts b/frontend/src/app/shared/state/contents.forms.visitors.ts index cf1c7b490..d3d2ae047 100644 --- a/frontend/src/app/shared/state/contents.forms.visitors.ts +++ b/frontend/src/app/shared/state/contents.forms.visitors.ts @@ -417,8 +417,20 @@ export class FieldDefaultValue implements FieldPropertiesVisitor { } } - public visitArray(_: ArrayFieldPropertiesDto): any { - return null; + public visitArray(properties: ArrayFieldPropertiesDto): any { + if (properties.calculatedDefaultValue === 'Null') { + return undefined; + } + + return []; + } + + public visitComponents(properties: ComponentsFieldPropertiesDto): any { + if (properties.calculatedDefaultValue === 'Null') { + return undefined; + } + + return []; } public visitAssets(properties: AssetsFieldPropertiesDto): any { @@ -433,10 +445,6 @@ export class FieldDefaultValue implements FieldPropertiesVisitor { return null; } - public visitComponents(_: ComponentsFieldPropertiesDto): any { - return null; - } - public visitGeolocation(_: GeolocationFieldPropertiesDto): any { return null; } diff --git a/frontend/src/app/shared/state/queries.ts b/frontend/src/app/shared/state/queries.ts index 03a3a4ae2..1b68f3e60 100644 --- a/frontend/src/app/shared/state/queries.ts +++ b/frontend/src/app/shared/state/queries.ts @@ -59,7 +59,7 @@ export class Queries { } public addShared(key: string, query: Query) { - this.uiState.setAppShared(this.getPath(key), JSON.stringify(query),); + this.uiState.setAppShared(this.getPath(key), JSON.stringify(query)); } public removeShared(saved: SavedQuery | string) { diff --git a/frontend/src/app/shared/state/resolvers.spec.ts b/frontend/src/app/shared/state/resolvers.spec.ts index 5f92e3335..5d265f273 100644 --- a/frontend/src/app/shared/state/resolvers.spec.ts +++ b/frontend/src/app/shared/state/resolvers.spec.ts @@ -5,6 +5,7 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ +import { TestBed } from '@angular/core/testing'; import { firstValueFrom, of, throwError } from 'rxjs'; import { IMock, Mock, Times } from 'typemoq'; import { UIOptions } from '@app/framework'; @@ -34,8 +35,11 @@ describe('ResolveContents', () => { ]; beforeEach(() => { - contentsService = Mock.ofType(); - contentsResolver = new ResolveContents(uiOptions, appsState.object, contentsService.object); + TestBed.configureTestingModule({ providers: [{ provide: UIOptions, useValue: uiOptions }] }); + TestBed.runInInjectionContext(() => { + contentsService = Mock.ofType(); + contentsResolver = new ResolveContents(appsState.object, contentsService.object); + }); }); it('should not resolve contents immediately', () => { diff --git a/frontend/src/app/shared/state/resolvers.ts b/frontend/src/app/shared/state/resolvers.ts index 959eeba56..6093fa60f 100644 --- a/frontend/src/app/shared/state/resolvers.ts +++ b/frontend/src/app/shared/state/resolvers.ts @@ -5,7 +5,7 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ -import { Injectable } from '@angular/core'; +import { inject, Injectable } from '@angular/core'; import { from, Observable, of, shareReplay } from 'rxjs'; import { UIOptions } from '@app/framework'; import { AssetDto, AssetsDto, AssetsService } from './../services/assets.service'; @@ -105,16 +105,13 @@ abstract class ResolverBase { private readonly schemas: { [name: string]: Observable } = {}; - private readonly itemCount; + private readonly itemCount = inject(UIOptions).value.referencesDropdownItemCount; constructor( - uiOptions: UIOptions, private readonly appsState: AppsState, private readonly contentsService: ContentsService, ) { super(); - - this.itemCount = uiOptions.get('referencesDropdownItemCount'); } public resolveAll(schema: string) { diff --git a/frontend/src/app/shared/state/schemas.forms.ts b/frontend/src/app/shared/state/schemas.forms.ts index e30b441d7..f7c46e3d2 100644 --- a/frontend/src/app/shared/state/schemas.forms.ts +++ b/frontend/src/app/shared/state/schemas.forms.ts @@ -249,6 +249,7 @@ export class EditFieldFormVisitor implements FieldPropertiesVisitor { } public visitArray() { + this.config['calculatedDefaultValue'] = new UntypedFormControl('EmptyArray'); this.config['maxItems'] = new UntypedFormControl(undefined); this.config['minItems'] = new UntypedFormControl(undefined); this.config['uniqueFields'] = new UntypedFormControl(undefined); @@ -288,6 +289,7 @@ export class EditFieldFormVisitor implements FieldPropertiesVisitor { } public visitComponents() { + this.config['calculatedDefaultValue'] = new UntypedFormControl('EmptyArray'); this.config['schemaIds'] = new UntypedFormControl(undefined); this.config['maxItems'] = new UntypedFormControl(undefined); this.config['minItems'] = new UntypedFormControl(undefined); @@ -324,12 +326,14 @@ export class EditFieldFormVisitor implements FieldPropertiesVisitor { this.config['maxItems'] = new UntypedFormControl(undefined); this.config['minItems'] = new UntypedFormControl(undefined); this.config['mustBePublished'] = new UntypedFormControl(false); + this.config['query'] = new UntypedFormControl(undefined); this.config['resolveReference'] = new UntypedFormControl(false); this.config['schemaIds'] = new UntypedFormControl(undefined); } public visitString() { this.config['allowedValues'] = new UntypedFormControl(undefined); + this.config['classNames'] = new UntypedFormControl(undefined); this.config['contentType'] = new UntypedFormControl(undefined); this.config['createEnum'] = new UntypedFormControl(undefined); this.config['defaultValue'] = new UntypedFormControl(undefined); diff --git a/frontend/src/app/shared/state/table-settings.ts b/frontend/src/app/shared/state/table-settings.ts index 6dfad2d53..838233715 100644 --- a/frontend/src/app/shared/state/table-settings.ts +++ b/frontend/src/app/shared/state/table-settings.ts @@ -5,7 +5,7 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ -import { take } from 'rxjs/operators'; +import { map, take } from 'rxjs/operators'; import { State, Types } from '@app/framework'; import { META_FIELDS, SchemaDto, TableField } from './../services/schemas.service'; import { UIState } from './ui.state'; @@ -45,8 +45,8 @@ export class TableSettings extends State { this.projectFrom(this.fields, x => x.length > 0 ? x : this.schemaDefaults); constructor( - private readonly uiState: UIState, - private readonly schema: SchemaDto, + public readonly uiState: UIState, + public readonly schema: SchemaDto, ) { super({ fields: [], sizes: {}, wrappings: {} }); @@ -143,3 +143,22 @@ export class TableSettings extends State { } } } + +export function getTableConfig(source: TableSettings) { + function sortedTableFields(fields: ReadonlyArray) { + const result: string[] = []; + + for (const field of fields) { + if (field.name && field.name.indexOf('meta') < 0) { + result.push(field.name); + } + } + + result.sort(); + return result; + } + + return source.listFields.pipe( + map(fields => sortedTableFields(fields)), + map(fields => ({ fieldNames: fields, schema: source.schema }))); +} \ No newline at end of file diff --git a/frontend/src/app/shared/state/tour.state.ts b/frontend/src/app/shared/state/tour.state.ts index 3db7fd3d3..2ef793de8 100644 --- a/frontend/src/app/shared/state/tour.state.ts +++ b/frontend/src/app/shared/state/tour.state.ts @@ -5,7 +5,7 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ -import { Inject, Injectable } from '@angular/core'; +import { inject, Inject, Injectable } from '@angular/core'; import { filter, skip, take } from 'rxjs'; import { debug, State, TourService, UIOptions } from '@app/framework'; import { TASK_CONFIGURATION, TaskConfiguration, TaskDefinition } from './tour.tasks'; @@ -32,6 +32,8 @@ interface Snapshot { @Injectable() export class TourState extends State { + private readonly isDisabled = inject(UIOptions).value.hideOnboarding; + public completedTasks = this.project(x => x.completedTasks); @@ -48,7 +50,6 @@ export class TourState extends State { @Inject(TASK_CONFIGURATION) private readonly definition: TaskConfiguration, private readonly tourService: TourService, private readonly uiState: UIState, - private readonly uiOptions: UIOptions, ) { super({}); @@ -114,10 +115,6 @@ export class TourState extends State { private disableHintCore(key: string) { this.next(s => ({ ...s, shownHints: { ...s.shownHints || {}, [key]: true } }), 'Disable Hint'); } - - private get isDisabled() { - return this.uiOptions.get('hideOnboarding'); - } } const LoadedEvent = 'Loaded'; diff --git a/frontend/src/app/shell/pages/home/home-page.component.ts b/frontend/src/app/shell/pages/home/home-page.component.ts index bcf97fd81..f31d5517f 100644 --- a/frontend/src/app/shell/pages/home/home-page.component.ts +++ b/frontend/src/app/shell/pages/home/home-page.component.ts @@ -6,7 +6,7 @@ */ import { Location } from '@angular/common'; -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { AuthService, UIOptions } from '@app/shared'; @@ -16,6 +16,8 @@ import { AuthService, UIOptions } from '@app/shared'; templateUrl: './home-page.component.html', }) export class HomePageComponent { + private readonly redirectToLogin = inject(UIOptions).value.redirectToLogin; + public showLoginError = false; constructor( @@ -23,7 +25,6 @@ export class HomePageComponent { private readonly location: Location, private readonly route: ActivatedRoute, private readonly router: Router, - private readonly uiOptions: UIOptions, ) { } @@ -32,7 +33,7 @@ export class HomePageComponent { this.route.snapshot.queryParams.redirectPath || this.location.path(); - if (this.isInternetExplorer() || this.uiOptions.get('redirectToLogin')) { + if (this.isInternetExplorer() || this.redirectToLogin) { this.authService.loginRedirect(redirectPath); return; } diff --git a/frontend/src/app/shell/pages/internal/apps-menu.component.html b/frontend/src/app/shell/pages/internal/apps-menu.component.html index 503831aa2..e9661df33 100644 --- a/frontend/src/app/shell/pages/internal/apps-menu.component.html +++ b/frontend/src/app/shell/pages/internal/apps-menu.component.html @@ -90,9 +90,9 @@ + (dialogClose)="addAppDialog.hide()"> + (dialogClose)="addTeamDialog.hide()"> \ No newline at end of file diff --git a/frontend/src/app/shell/pages/internal/apps-menu.component.ts b/frontend/src/app/shell/pages/internal/apps-menu.component.ts index 25e9837ec..bd93e9925 100644 --- a/frontend/src/app/shell/pages/internal/apps-menu.component.ts +++ b/frontend/src/app/shell/pages/internal/apps-menu.component.ts @@ -5,8 +5,6 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ -// tslint:disable: readonly-array - import { ChangeDetectionStrategy, Component } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Observable } from 'rxjs'; diff --git a/frontend/src/app/shell/pages/internal/feedback-menu.component.ts b/frontend/src/app/shell/pages/internal/feedback-menu.component.ts index bf82d7801..49c9c181c 100644 --- a/frontend/src/app/shell/pages/internal/feedback-menu.component.ts +++ b/frontend/src/app/shell/pages/internal/feedback-menu.component.ts @@ -5,7 +5,7 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ -import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core'; +import { ChangeDetectionStrategy, Component, inject, OnDestroy, OnInit } from '@angular/core'; import markerSDK, { MarkerSdk } from '@marker.io/browser'; import { UIOptions } from '@app/shared'; @@ -18,12 +18,7 @@ import { UIOptions } from '@app/shared'; export class FeedbackMenuComponent implements OnInit, OnDestroy { private widget?: MarkerSdk; - public markerProject = ''; - - constructor(uiOptions: UIOptions, - ) { - this.markerProject = uiOptions.get('markerProject'); - } + public readonly markerProject = inject(UIOptions).value.markerProject; public ngOnDestroy() { this.widget?.unload(); diff --git a/frontend/src/app/shell/pages/internal/internal-area.component.ts b/frontend/src/app/shell/pages/internal/internal-area.component.ts index d7c9153e1..9615b2a2c 100644 --- a/frontend/src/app/shell/pages/internal/internal-area.component.ts +++ b/frontend/src/app/shell/pages/internal/internal-area.component.ts @@ -5,30 +5,29 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ -import { Component, OnInit } from '@angular/core'; +import { Component, inject, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; -import { DialogService, LoadingService, Notification, ResourceOwner, UIOptions } from '@app/shared'; +import { DialogService, LoadingService, Notification, Subscriptions, UIOptions } from '@app/shared'; @Component({ selector: 'sqx-internal-area', styleUrls: ['./internal-area.component.scss'], templateUrl: './internal-area.component.html', }) -export class InternalAreaComponent extends ResourceOwner implements OnInit { - public isEmbedded = false; +export class InternalAreaComponent implements OnInit { + private readonly subscriptions = new Subscriptions(); - constructor(uiOptions: UIOptions, + public readonly isEmbedded = inject(UIOptions).value.embedded; + + constructor( public readonly loadingService: LoadingService, private readonly dialogs: DialogService, private readonly route: ActivatedRoute, ) { - super(); - - this.isEmbedded = !!uiOptions.get('embedded'); } public ngOnInit() { - this.own( + this.subscriptions.add( this.route.queryParams.subscribe(params => { const successMessage = params['successMessage']; diff --git a/frontend/src/app/shell/pages/internal/notification-dropdown.component.html b/frontend/src/app/shell/pages/internal/notification-dropdown.component.html index 524e5861b..dcfbcb686 100644 --- a/frontend/src/app/shell/pages/internal/notification-dropdown.component.html +++ b/frontend/src/app/shell/pages/internal/notification-dropdown.component.html @@ -2,19 +2,20 @@ - {{unread}} + {{unread}} - + {{ 'notifications.empty' | sqxTranslate}} - ; + public commentsUnread!: Observable; - public userToken = ''; + public userToken: string; - constructor(authService: AuthService, commentsService: CommentsService, dialogs: DialogService, - private readonly changeDetector: ChangeDetectorRef, - private readonly localStore: LocalStoreService, + constructor(authService: AuthService, + private readonly collaborations: CollaborationService, ) { - super(); - this.userToken = authService.user!.token; + } - this.versionRead = localStore.getInt(Settings.Local.NOTIFICATION_VERSION, -1); - this.versionReceived = this.versionRead; + public ngOnInit() { + this.collaborations.connect('users/collaboration'); - this.updateVersion(); + const comments$ = this.collaborations.getArray('stream'); - const commentsUrl = `users/${authService.user!.id}/notifications`; + this.commentsUnread = + comments$.pipe(switchMap(x => x.itemsChanges), + map(array => { + return array.filter(x => !x.isRead).length; + })); - this.commentsState = - new CommentsState( - commentsUrl, - commentsService, - dialogs, - true, - this.versionRead); - } + this.subscriptions.add( + comments$ + .subscribe(array => { + this.commentsArray = array; + })); - public ngOnInit() { - this.own( + this.subscriptions.add( this.modalMenu.isOpenChanges.pipe( tap(_ => { - this.updateVersion(); + this.markRead(); }), )); + } - this.own( - this.commentsState.versionNumber.pipe( - tap(version => { - this.versionReceived = version; - - this.updateVersion(); + public markRead() { + if (!this.commentsArray) { + return; + } - this.changeDetector.detectChanges(); - }))); + const toDelete = this.commentsArray.items.length - 100; - this.own(timer(0, 4000).pipe(switchMap(() => this.commentsState.load(true).pipe(onErrorResumeNextWith())))); - } + if (toDelete > 0) { + this.commentsArray.remove(0, toDelete); + } - public trackByComment(_index: number, comment: CommentDto) { - return comment.id; + this.commentsArray.items.forEach((item, i) => { + if (!item.isRead) { + this.commentsArray?.set(i, { ...item, isRead: true }); + } + }); } - private updateVersion() { - this.unread = Math.max(0, this.versionReceived - this.versionRead); - - if (this.modalMenu.isOpen) { - this.versionRead = this.versionReceived; - - this.localStore.setInt(Settings.Local.NOTIFICATION_VERSION, this.versionRead); - } + public trackByComment(index: number) { + return index; } } diff --git a/frontend/src/app/shell/pages/internal/notifications-menu.component.html b/frontend/src/app/shell/pages/internal/notifications-menu.component.html index c0686300b..439e1f4c8 100644 --- a/frontend/src/app/shell/pages/internal/notifications-menu.component.html +++ b/frontend/src/app/shell/pages/internal/notifications-menu.component.html @@ -1,4 +1,4 @@ -