diff --git a/.gitignore b/.gitignore index 345ae10b..500294f9 100644 --- a/.gitignore +++ b/.gitignore @@ -350,3 +350,7 @@ MigrationBackup/ .idea/ .DS_Store + +# Cursor local guidance (do not commit) +.cursor/rules/ +.cursor/skills/ diff --git a/Masa.Mc.sln b/Masa.Mc.sln index 5cf50b63..fcb59b75 100644 --- a/Masa.Mc.sln +++ b/Masa.Mc.sln @@ -17,10 +17,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "components", "components", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Mc.Service.Admin", "src\Services\Masa.Mc.Service\Masa.Mc.Service.Admin.csproj", "{87A8E21E-DF58-4BEA-8EA1-EF333BE4D2B3}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Web", "Web", "{F3986DD3-0372-4929-B72A-09D93196541E}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Mc.Web.Admin", "src\Web\Masa.Mc.Web.Admin\Masa.Mc.Web.Admin.csproj", "{3F0181CA-BDF5-4F56-A664-0E82DFD2A8C7}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ApiGateways", "ApiGateways", "{32774681-0D67-48A6-A379-D57015094F85}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Mc.ApiGateways.Caller", "src\ApiGateways\Caller\Masa.Mc.ApiGateways.Caller\Masa.Mc.ApiGateways.Caller.csproj", "{40685EC0-64DF-4742-B8F6-602AFAEFC0EA}" @@ -37,10 +33,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Mc.Infrastructure.Ddd. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Mc.Infrastructure.EntityFrameworkCore", "src\Infrastructure\Masa.Mc.Infrastructure.EntityFrameworkCore\Masa.Mc.Infrastructure.EntityFrameworkCore.csproj", "{FAFDC558-45A7-4FF7-BFCE-015EDF58F3AE}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Mc.Web.Admin.Server", "src\Web\Masa.Mc.Web.Admin.Server\Masa.Mc.Web.Admin.Server.csproj", "{8FA1D09B-F5B5-4B42-BF86-53512F1377B2}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Mc.Web.Admin.WebAssembly", "src\Web\Masa.Mc.Web.Admin.WebAssembly\Masa.Mc.Web.Admin.WebAssembly.csproj", "{1644695E-4B4F-4D7D-833C-7E694E758641}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Mc.Infrastructure.Common", "src\Infrastructure\Masa.Mc.Infrastructure.Common\Masa.Mc.Infrastructure.Common.csproj", "{4024A9CA-D6CA-44D7-BEA4-D96891AFC6DD}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Masa.Mc.Infrastructure.Sms", "src\Infrastructure\Masa.Mc.Infrastructure.Sms\Masa.Mc.Infrastructure.Sms.csproj", "{D965E2A5-3B97-4903-8FF6-E2E08847F16F}" @@ -97,14 +89,6 @@ Global {87A8E21E-DF58-4BEA-8EA1-EF333BE4D2B3}.Release|Any CPU.Build.0 = Release|Any CPU {87A8E21E-DF58-4BEA-8EA1-EF333BE4D2B3}.Release|x86.ActiveCfg = Release|Any CPU {87A8E21E-DF58-4BEA-8EA1-EF333BE4D2B3}.Release|x86.Build.0 = Release|Any CPU - {3F0181CA-BDF5-4F56-A664-0E82DFD2A8C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3F0181CA-BDF5-4F56-A664-0E82DFD2A8C7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3F0181CA-BDF5-4F56-A664-0E82DFD2A8C7}.Debug|x86.ActiveCfg = Debug|Any CPU - {3F0181CA-BDF5-4F56-A664-0E82DFD2A8C7}.Debug|x86.Build.0 = Debug|Any CPU - {3F0181CA-BDF5-4F56-A664-0E82DFD2A8C7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3F0181CA-BDF5-4F56-A664-0E82DFD2A8C7}.Release|Any CPU.Build.0 = Release|Any CPU - {3F0181CA-BDF5-4F56-A664-0E82DFD2A8C7}.Release|x86.ActiveCfg = Release|Any CPU - {3F0181CA-BDF5-4F56-A664-0E82DFD2A8C7}.Release|x86.Build.0 = Release|Any CPU {40685EC0-64DF-4742-B8F6-602AFAEFC0EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {40685EC0-64DF-4742-B8F6-602AFAEFC0EA}.Debug|Any CPU.Build.0 = Debug|Any CPU {40685EC0-64DF-4742-B8F6-602AFAEFC0EA}.Debug|x86.ActiveCfg = Debug|Any CPU @@ -145,22 +129,6 @@ Global {FAFDC558-45A7-4FF7-BFCE-015EDF58F3AE}.Release|Any CPU.Build.0 = Release|Any CPU {FAFDC558-45A7-4FF7-BFCE-015EDF58F3AE}.Release|x86.ActiveCfg = Release|Any CPU {FAFDC558-45A7-4FF7-BFCE-015EDF58F3AE}.Release|x86.Build.0 = Release|Any CPU - {8FA1D09B-F5B5-4B42-BF86-53512F1377B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8FA1D09B-F5B5-4B42-BF86-53512F1377B2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8FA1D09B-F5B5-4B42-BF86-53512F1377B2}.Debug|x86.ActiveCfg = Debug|Any CPU - {8FA1D09B-F5B5-4B42-BF86-53512F1377B2}.Debug|x86.Build.0 = Debug|Any CPU - {8FA1D09B-F5B5-4B42-BF86-53512F1377B2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8FA1D09B-F5B5-4B42-BF86-53512F1377B2}.Release|Any CPU.Build.0 = Release|Any CPU - {8FA1D09B-F5B5-4B42-BF86-53512F1377B2}.Release|x86.ActiveCfg = Release|Any CPU - {8FA1D09B-F5B5-4B42-BF86-53512F1377B2}.Release|x86.Build.0 = Release|Any CPU - {1644695E-4B4F-4D7D-833C-7E694E758641}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1644695E-4B4F-4D7D-833C-7E694E758641}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1644695E-4B4F-4D7D-833C-7E694E758641}.Debug|x86.ActiveCfg = Debug|Any CPU - {1644695E-4B4F-4D7D-833C-7E694E758641}.Debug|x86.Build.0 = Debug|Any CPU - {1644695E-4B4F-4D7D-833C-7E694E758641}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1644695E-4B4F-4D7D-833C-7E694E758641}.Release|Any CPU.Build.0 = Release|Any CPU - {1644695E-4B4F-4D7D-833C-7E694E758641}.Release|x86.ActiveCfg = Release|Any CPU - {1644695E-4B4F-4D7D-833C-7E694E758641}.Release|x86.Build.0 = Release|Any CPU {4024A9CA-D6CA-44D7-BEA4-D96891AFC6DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4024A9CA-D6CA-44D7-BEA4-D96891AFC6DD}.Debug|Any CPU.Build.0 = Debug|Any CPU {4024A9CA-D6CA-44D7-BEA4-D96891AFC6DD}.Debug|x86.ActiveCfg = Debug|Any CPU @@ -297,8 +265,6 @@ Global {4A1D2DFA-D091-4CD2-B9CB-D7AAA795ABD9} = {92F40AFA-8416-40BE-9893-D35E1924C69D} {FBFB499A-7022-4417-881B-68F63DBDB7F4} = {E011B243-0389-468B-B903-83445BED69A4} {87A8E21E-DF58-4BEA-8EA1-EF333BE4D2B3} = {4A1D2DFA-D091-4CD2-B9CB-D7AAA795ABD9} - {F3986DD3-0372-4929-B72A-09D93196541E} = {92F40AFA-8416-40BE-9893-D35E1924C69D} - {3F0181CA-BDF5-4F56-A664-0E82DFD2A8C7} = {F3986DD3-0372-4929-B72A-09D93196541E} {32774681-0D67-48A6-A379-D57015094F85} = {92F40AFA-8416-40BE-9893-D35E1924C69D} {40685EC0-64DF-4742-B8F6-602AFAEFC0EA} = {32774681-0D67-48A6-A379-D57015094F85} {88AD0A79-5286-4C1C-8A58-AAC9E6870CCD} = {92F40AFA-8416-40BE-9893-D35E1924C69D} @@ -307,8 +273,6 @@ Global {C47B7220-BDF3-4DFA-93FE-0F6885DB89A4} = {4660010F-BB9B-4C8E-B4F7-34AF77080EA0} {6CAC62DA-A3AF-4BFE-8E1C-0DB9D0D81CD6} = {4660010F-BB9B-4C8E-B4F7-34AF77080EA0} {FAFDC558-45A7-4FF7-BFCE-015EDF58F3AE} = {4660010F-BB9B-4C8E-B4F7-34AF77080EA0} - {8FA1D09B-F5B5-4B42-BF86-53512F1377B2} = {F3986DD3-0372-4929-B72A-09D93196541E} - {1644695E-4B4F-4D7D-833C-7E694E758641} = {F3986DD3-0372-4929-B72A-09D93196541E} {4024A9CA-D6CA-44D7-BEA4-D96891AFC6DD} = {4660010F-BB9B-4C8E-B4F7-34AF77080EA0} {D965E2A5-3B97-4903-8FF6-E2E08847F16F} = {4660010F-BB9B-4C8E-B4F7-34AF77080EA0} {C816B922-18A4-4F6A-9A7A-4D0E7F2AE129} = {4660010F-BB9B-4C8E-B4F7-34AF77080EA0} diff --git a/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageReceipts/GetSmsInboundInputDto.cs b/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageReceipts/GetSmsInboundInputDto.cs index 1c69e3e3..25335bb3 100644 --- a/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageReceipts/GetSmsInboundInputDto.cs +++ b/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageReceipts/GetSmsInboundInputDto.cs @@ -5,7 +5,11 @@ namespace Masa.Mc.Contracts.Admin.Dtos.MessageReceipts; public class GetSmsInboundInputDto : PaginatedOptionsDto { - public Guid ChannelId { get; set; } + public Guid? ChannelId { get; set; } + + public string ChannelCode { get; set; } = string.Empty; + + public SmsInboundProviders? Provider { get; set; } public string Mobile { get; set; } = string.Empty; @@ -21,10 +25,12 @@ public GetSmsInboundInputDto() { } - public GetSmsInboundInputDto(Guid channelId, string mobile, string addSerial, string smsContent, DateTimeOffset? startTime, DateTimeOffset? endTime, string sorting, int page, int pageSize) + public GetSmsInboundInputDto(Guid? channelId, string channelCode, SmsInboundProviders? provider, string mobile, string addSerial, string smsContent, DateTimeOffset? startTime, DateTimeOffset? endTime, string sorting, int page, int pageSize) : base(sorting, page, pageSize) { ChannelId = channelId; + ChannelCode = channelCode; + Provider = provider; Mobile = mobile; AddSerial = addSerial; SmsContent = smsContent; diff --git a/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageReceipts/SmsInboundDto.cs b/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageReceipts/SmsInboundDto.cs index e5c12f37..8a2ee1ca 100644 --- a/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageReceipts/SmsInboundDto.cs +++ b/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageReceipts/SmsInboundDto.cs @@ -16,4 +16,6 @@ public class SmsInboundDto : AuditEntityDto public string AddSerial { get; set; } = string.Empty; public SmsInboundProviders Provider { get; set; } + + public SmsInboundTypes InboundType { get; set; } } diff --git a/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageRecords/GetSmsInteractionHistoryInputDto.cs b/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageRecords/GetSmsInteractionHistoryInputDto.cs new file mode 100644 index 00000000..306527ea --- /dev/null +++ b/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageRecords/GetSmsInteractionHistoryInputDto.cs @@ -0,0 +1,11 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Mc.Contracts.Admin.Dtos.MessageRecords; + +public class GetSmsInteractionHistoryInputDto +{ + public string Mobile { get; set; } = string.Empty; + + public Guid ChannelId { get; set; } +} diff --git a/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageRecords/SmsInteractionHistoryDto.cs b/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageRecords/SmsInteractionHistoryDto.cs new file mode 100644 index 00000000..4df4cd6d --- /dev/null +++ b/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageRecords/SmsInteractionHistoryDto.cs @@ -0,0 +1,13 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Mc.Contracts.Admin.Dtos.MessageRecords; + +public class SmsInteractionHistoryDto +{ + public DateTimeOffset SendTime { get; set; } + + public string Content { get; set; } = string.Empty; + + public bool IsInbound { get; set; } +} diff --git a/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageRecords/SmsRecordDto.cs b/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageRecords/SmsRecordDto.cs new file mode 100644 index 00000000..23c42ac4 --- /dev/null +++ b/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageRecords/SmsRecordDto.cs @@ -0,0 +1,13 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Mc.Contracts.Admin.Dtos.MessageRecords; + +public class SmsRecordDto +{ + public Guid ChannelId { get; set; } + + public string SmsContent { get; set; } = string.Empty; + + public DateTimeOffset? SendTime { get; set; } +} diff --git a/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageTemplates/MessageTemplateUnsubscribeConfigDto.cs b/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageTemplates/MessageTemplateUnsubscribeConfigDto.cs index db965a5b..8cc02d87 100644 --- a/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageTemplates/MessageTemplateUnsubscribeConfigDto.cs +++ b/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageTemplates/MessageTemplateUnsubscribeConfigDto.cs @@ -9,13 +9,9 @@ public class MessageTemplateUnsubscribeConfigDto public string UnsubscribeKeyword { get; set; } = string.Empty; - public string UnsubscribeAutoReply { get; set; } = string.Empty; + public Guid UnsubscribeAutoReplyTemplateId { get; set; } public string ResubscribeKeyword { get; set; } = string.Empty; - public string ResubscribeAutoReply { get; set; } = string.Empty; - - public bool DebounceEnabled { get; set; } - - public int CooldownSeconds { get; set; } + public Guid ResubscribeAutoReplyTemplateId { get; set; } } diff --git a/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageTemplates/Validator/MessageTemplateUpsertDtoValidator.cs b/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageTemplates/Validator/MessageTemplateUpsertDtoValidator.cs index b971bb77..83754a6b 100644 --- a/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageTemplates/Validator/MessageTemplateUpsertDtoValidator.cs +++ b/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/MessageTemplates/Validator/MessageTemplateUpsertDtoValidator.cs @@ -8,16 +8,20 @@ public class MessageTemplateUpsertDtoValidator : AbstractValidator inputDto.DisplayName).Required("MessageTemplateDisplayNameRequired") - .Length(2, 50).WithMessage("MessageTemplateDisplayNameLength").When(x => x.ChannelType != ChannelTypes.WeixinWork && x.TemplateType != (int)WeixinWorkTemplateTypes.Text); + .Length(2, 100).WithMessage("MessageTemplateDisplayNameLength").When(x => x.ChannelType != ChannelTypes.WeixinWork && x.TemplateType != (int)WeixinWorkTemplateTypes.Text); RuleFor(inputDto => inputDto.Code).Required("MessageTemplateCodeRequired") .LetterNumberSymbol().WithMessage("MessageTemplateCodeLetterNumberSymbol") .Length(2, 50).WithMessage("MessageTemplateCodeLength"); RuleFor(inputDto => inputDto.ChannelId).Required("ChannelIdRequired"); RuleFor(inputDto => inputDto.Status).IsInEnum().WithMessage("MessageTemplateStatusRequired"); + RuleFor(inputDto => inputDto.TemplateType) + .Must(templateType => System.Enum.IsDefined(typeof(SmsTemplateTypes), templateType)) + .When(inputDto => inputDto.ChannelType == ChannelTypes.Sms) + .WithMessage("MessageTemplateTemplateTypeRequired"); RuleFor(inputDto => inputDto.AuditStatus).IsInEnum(); RuleFor(inputDto => inputDto.PerDayLimit).InclusiveBetween(0, 500).WithMessage("MessageTemplatePerDayLimitBetween"); RuleFor(inputDto => inputDto.Title).Required("TitleRequired") - .Length(2, 50).WithMessage("TitleLength") + .Length(2, 100).WithMessage("TitleLength") .When(x => x.ChannelType == ChannelTypes.Email || x.ChannelType == ChannelTypes.WebsiteMessage); RuleFor(inputDto => inputDto.Content).Required("ContentRequired"); RuleFor(inputDto => inputDto.JumpUrl).Required("JumpUrlRequired").When(x => x.IsJump); @@ -27,18 +31,17 @@ public MessageTemplateUpsertDtoValidator() RuleFor(inputDto => inputDto.UnsubscribeConfig.UnsubscribeKeyword).Required("UnsubscribeKeywordRequired") .Length(1, 20).WithMessage("UnsubscribeKeywordLength") .When(x => x.UnsubscribeConfig.Enabled); - RuleFor(inputDto => inputDto.UnsubscribeConfig.UnsubscribeAutoReply).Required("UnsubscribeAutoReplyRequired") - .Length(1, 500).WithMessage("UnsubscribeAutoReplyLength") + RuleFor(inputDto => inputDto.UnsubscribeConfig.UnsubscribeAutoReplyTemplateId) + .Must(templateId => templateId != Guid.Empty) + .WithMessage("UnsubscribeAutoReplyRequired") .When(x => x.UnsubscribeConfig.Enabled); RuleFor(inputDto => inputDto.UnsubscribeConfig.ResubscribeKeyword).Required("ResubscribeKeywordRequired") .Length(1, 20).WithMessage("ResubscribeKeywordLength") .When(x => x.UnsubscribeConfig.Enabled); - RuleFor(inputDto => inputDto.UnsubscribeConfig.ResubscribeAutoReply).Required("ResubscribeAutoReplyRequired") - .Length(1, 500).WithMessage("ResubscribeAutoReplyLength") + RuleFor(inputDto => inputDto.UnsubscribeConfig.ResubscribeAutoReplyTemplateId) + .Must(templateId => templateId != Guid.Empty) + .WithMessage("ResubscribeAutoReplyRequired") .When(x => x.UnsubscribeConfig.Enabled); - RuleFor(inputDto => inputDto.UnsubscribeConfig.CooldownSeconds) - .GreaterThan(0).WithMessage("UnsubscribeCooldownSecondsRequired") - .When(x => x.UnsubscribeConfig.Enabled && x.UnsubscribeConfig.DebounceEnabled); RuleFor(inputDto => inputDto).Must(inputDto => !inputDto.UnsubscribeConfig.Enabled || !string.Equals(inputDto.UnsubscribeConfig.UnsubscribeKeyword?.Trim(), inputDto.UnsubscribeConfig.ResubscribeKeyword?.Trim(), StringComparison.OrdinalIgnoreCase)) diff --git a/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/Unsubscriptions/AddChannelUserIdentityToUnsubscriptionBlacklistInputDto.cs b/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/Unsubscriptions/AddChannelUserIdentityToUnsubscriptionBlacklistInputDto.cs new file mode 100644 index 00000000..16acd917 --- /dev/null +++ b/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/Unsubscriptions/AddChannelUserIdentityToUnsubscriptionBlacklistInputDto.cs @@ -0,0 +1,17 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Mc.Contracts.Admin.Dtos.Unsubscriptions; + +public class AddChannelUserIdentityToUnsubscriptionBlacklistInputDto +{ + public Guid? UserId { get; set; } + + public string ChannelCode { get; set; } = string.Empty; + + public string ChannelUserIdentity { get; set; } = string.Empty; + + public string TemplateCode { get; set; } = string.Empty; + + public string Reason { get; set; } = string.Empty; +} diff --git a/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/Unsubscriptions/ChannelUserIdentityUnsubscriptionItemDto.cs b/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/Unsubscriptions/ChannelUserIdentityUnsubscriptionItemDto.cs new file mode 100644 index 00000000..c08f26f7 --- /dev/null +++ b/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/Unsubscriptions/ChannelUserIdentityUnsubscriptionItemDto.cs @@ -0,0 +1,17 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Mc.Contracts.Admin.Dtos.Unsubscriptions; + +public class ChannelUserIdentityUnsubscriptionItemDto +{ + public string ChannelUserIdentity { get; set; } = string.Empty; + + public Guid? TemplateId { get; set; } + + public string TemplateCode { get; set; } = string.Empty; + + public string TemplateName { get; set; } = string.Empty; + + public string TemplateContent { get; set; } = string.Empty; +} diff --git a/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/Unsubscriptions/RemoveChannelUserIdentityFromUnsubscriptionBlacklistInputDto.cs b/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/Unsubscriptions/RemoveChannelUserIdentityFromUnsubscriptionBlacklistInputDto.cs new file mode 100644 index 00000000..186c5684 --- /dev/null +++ b/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/Unsubscriptions/RemoveChannelUserIdentityFromUnsubscriptionBlacklistInputDto.cs @@ -0,0 +1,15 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Mc.Contracts.Admin.Dtos.Unsubscriptions; + +public class RemoveChannelUserIdentityFromUnsubscriptionBlacklistInputDto +{ + public string ChannelCode { get; set; } = string.Empty; + + public string ChannelUserIdentity { get; set; } = string.Empty; + + public string TemplateCode { get; set; } = string.Empty; + + public string Reason { get; set; } = string.Empty; +} diff --git a/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/Unsubscriptions/UnsubscriptionTimelineDto.cs b/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/Unsubscriptions/UnsubscriptionTimelineDto.cs index 364f91a5..38092b9b 100644 --- a/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/Unsubscriptions/UnsubscriptionTimelineDto.cs +++ b/src/Contracts/Masa.Mc.Contracts.Admin/Dtos/Unsubscriptions/UnsubscriptionTimelineDto.cs @@ -9,19 +9,7 @@ public class UnsubscriptionTimelineDto public UnsubscriptionTimelineActions Action { get; set; } - public UnsubscriptionSource Source { get; set; } - public string Detail { get; set; } = string.Empty; - public string Keyword { get; set; } = string.Empty; - - public string MessageId { get; set; } = string.Empty; - - public Guid? MatchedMessageRecordId { get; set; } - - public string MatchedMessageSnapshot { get; set; } = string.Empty; - - public DateTimeOffset? MatchedMessageSentAt { get; set; } - public DateTimeOffset OccurredAt { get; set; } } diff --git a/src/Domain/Masa.Mc.Domain.Shared/MessageReceipts/SmsInboundReservedKeywords.cs b/src/Domain/Masa.Mc.Domain.Shared/MessageReceipts/SmsInboundReservedKeywords.cs index 466f974d..a76972b8 100644 --- a/src/Domain/Masa.Mc.Domain.Shared/MessageReceipts/SmsInboundReservedKeywords.cs +++ b/src/Domain/Masa.Mc.Domain.Shared/MessageReceipts/SmsInboundReservedKeywords.cs @@ -6,4 +6,19 @@ namespace Masa.Mc.Domain.Shared.MessageReceipts; public static class SmsInboundReservedKeywords { public const string YunMasUnsubscribeKeyword = "R"; + + public static bool IsProviderUnsubscribeKeyword(SmsInboundProviders provider, string inboundKeyword) + { + if (string.IsNullOrWhiteSpace(inboundKeyword)) + { + return false; + } + + var normalizedKeyword = inboundKeyword.Trim(); + return provider switch + { + SmsInboundProviders.YunMas => string.Equals(normalizedKeyword, YunMasUnsubscribeKeyword, StringComparison.OrdinalIgnoreCase), + _ => false + }; + } } diff --git a/src/Domain/Masa.Mc.Domain.Shared/MessageReceipts/SmsInboundTypes.cs b/src/Domain/Masa.Mc.Domain.Shared/MessageReceipts/SmsInboundTypes.cs new file mode 100644 index 00000000..a0a1bb54 --- /dev/null +++ b/src/Domain/Masa.Mc.Domain.Shared/MessageReceipts/SmsInboundTypes.cs @@ -0,0 +1,10 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Mc.Domain.Shared.MessageReceipts; + +public enum SmsInboundTypes +{ + Other = 0, + Unsubscribe = 1 +} diff --git a/src/Domain/Masa.Mc.Domain.Shared/MessageTemplates/SmsTemplateTypes.cs b/src/Domain/Masa.Mc.Domain.Shared/MessageTemplates/SmsTemplateTypes.cs index 5ff34f44..0b73e89c 100644 --- a/src/Domain/Masa.Mc.Domain.Shared/MessageTemplates/SmsTemplateTypes.cs +++ b/src/Domain/Masa.Mc.Domain.Shared/MessageTemplates/SmsTemplateTypes.cs @@ -9,6 +9,8 @@ public enum SmsTemplateTypes Notification = 2, Promotion = 3, International = 4, - Digital=5, + Digital = 5, + Unsubscribe = 101, + Resubscribe = 102, Other = 99 } diff --git a/src/Domain/Masa.Mc.Domain.Shared/Unsubscriptions/UnsubscriptionTimelineActions.cs b/src/Domain/Masa.Mc.Domain.Shared/Unsubscriptions/UnsubscriptionTimelineActions.cs index 4f586da2..3b8d87a1 100644 --- a/src/Domain/Masa.Mc.Domain.Shared/Unsubscriptions/UnsubscriptionTimelineActions.cs +++ b/src/Domain/Masa.Mc.Domain.Shared/Unsubscriptions/UnsubscriptionTimelineActions.cs @@ -8,5 +8,6 @@ public enum UnsubscriptionTimelineActions InboundUnsubscribed = 1, ManualUnsubscribed, ManualResubscribed, - AutoResubscribed + AutoResubscribed, + OutboundMessageSent } diff --git a/src/Domain/Masa.Mc.Domain/Channels/Aggregates/ChannelType.cs b/src/Domain/Masa.Mc.Domain/Channels/Aggregates/ChannelType.cs index 198771c3..8b7242f8 100644 --- a/src/Domain/Masa.Mc.Domain/Channels/Aggregates/ChannelType.cs +++ b/src/Domain/Masa.Mc.Domain/Channels/Aggregates/ChannelType.cs @@ -26,7 +26,7 @@ public virtual SendMessageEvent GetSendMessageEvent(Guid channelId, MessageData throw new NotImplementedException(); } - public virtual SendSimpleMessageEvent GetSendSimpleMessageEvent(string channelUserIdentity, string channelCode, MessageData messageData, ExtraPropertyDictionary variables, ExtraPropertyDictionary originalVariables, string systemId) + public virtual SendSimpleMessageEvent GetSendSimpleMessageEvent(string channelUserIdentity, string channelCode, MessageData messageData, ExtraPropertyDictionary variables, string systemId) { throw new NotImplementedException(); } @@ -52,12 +52,11 @@ public override SendMessageEvent GetSendMessageEvent(Guid channelId, MessageData return new SendSmsMessageEvent(channelId, messageData, messageTaskHistory); } - public override SendSimpleMessageEvent GetSendSimpleMessageEvent(string channelUserIdentity, string channelCode, MessageData messageData, ExtraPropertyDictionary variables, ExtraPropertyDictionary originalVariables, string systemId) + public override SendSimpleMessageEvent GetSendSimpleMessageEvent(string channelUserIdentity, string channelCode, MessageData messageData, ExtraPropertyDictionary variables, string systemId) { return new SendSimpleSmsMessageEvent(channelUserIdentity, channelCode, messageData) { Variables = variables, - OriginalVariables = originalVariables, SystemId = systemId }; } diff --git a/src/Domain/Masa.Mc.Domain/Constants/MessageTemplateExceptionCodes.cs b/src/Domain/Masa.Mc.Domain/Constants/MessageTemplateExceptionCodes.cs index 792820f6..4b04894c 100644 --- a/src/Domain/Masa.Mc.Domain/Constants/MessageTemplateExceptionCodes.cs +++ b/src/Domain/Masa.Mc.Domain/Constants/MessageTemplateExceptionCodes.cs @@ -7,7 +7,8 @@ public static class MessageTemplateExceptionCodes { public const string VERIFICATION_CODE_TEMPLATE_CANNOT_ENABLE_UNSUBSCRIBE = "VerificationCodeTemplateCannotEnableUnsubscribe"; public const string UNSUBSCRIBE_KEYWORD_REQUIRED = "UnsubscribeKeywordRequired"; + public const string UNSUBSCRIBE_AUTO_REPLY_REQUIRED = "UnsubscribeAutoReplyRequired"; public const string RESUBSCRIBE_KEYWORD_REQUIRED = "ResubscribeKeywordRequired"; + public const string RESUBSCRIBE_AUTO_REPLY_REQUIRED = "ResubscribeAutoReplyRequired"; public const string UNSUBSCRIBE_KEYWORDS_MUST_BE_DIFFERENT = "UnsubscribeKeywordsMustBeDifferent"; - public const string UNSUBSCRIBE_COOLDOWN_SECONDS_REQUIRED = "UnsubscribeCooldownSecondsRequired"; } diff --git a/src/Domain/Masa.Mc.Domain/Constants/UnsubscriptionReasonConstants.cs b/src/Domain/Masa.Mc.Domain/Constants/UnsubscriptionReasonConstants.cs new file mode 100644 index 00000000..25775556 --- /dev/null +++ b/src/Domain/Masa.Mc.Domain/Constants/UnsubscriptionReasonConstants.cs @@ -0,0 +1,15 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Mc.Domain.Constants; + +public static class UnsubscriptionReasonConstants +{ + public const string INBOUND_UNSUBSCRIBE_REASON = "UnsubscriptionInboundUnsubscribeReason"; + + public const string INBOUND_RESUBSCRIBE_REASON = "UnsubscriptionInboundResubscribeReason"; + + public const string MANUAL_BLACKLIST_REASON = "UnsubscriptionManualBlacklistReason"; + + public const string MANUAL_REMOVE_BLACKLIST_REASON = "UnsubscriptionManualRemoveBlacklistReason"; +} diff --git a/src/Domain/Masa.Mc.Domain/MessageTasks/Events/SendSimpleSmsMessageEvent.cs b/src/Domain/Masa.Mc.Domain/MessageTasks/Events/SendSimpleSmsMessageEvent.cs index 8542344a..13492e4a 100644 --- a/src/Domain/Masa.Mc.Domain/MessageTasks/Events/SendSimpleSmsMessageEvent.cs +++ b/src/Domain/Masa.Mc.Domain/MessageTasks/Events/SendSimpleSmsMessageEvent.cs @@ -7,8 +7,6 @@ public record SendSimpleSmsMessageEvent: SendSimpleMessageEvent { public ExtraPropertyDictionary Variables { get; set; } - public ExtraPropertyDictionary OriginalVariables { get; set; } - public string SystemId { get; set; } = string.Empty; public SendSimpleSmsMessageEvent(string channelUserIdentity, string channelCode, MessageData messageData) diff --git a/src/Domain/Masa.Mc.Domain/MessageTemplates/Aggregates/MessageTemplate.cs b/src/Domain/Masa.Mc.Domain/MessageTemplates/Aggregates/MessageTemplate.cs index 667b48c6..5780bb1b 100644 --- a/src/Domain/Masa.Mc.Domain/MessageTemplates/Aggregates/MessageTemplate.cs +++ b/src/Domain/Masa.Mc.Domain/MessageTemplates/Aggregates/MessageTemplate.cs @@ -107,7 +107,13 @@ private void ApplyUnsubscribeConfig(MessageTemplateUnsubscribeConfig config) throw new UserFriendlyException(errorCode: MessageTemplateExceptionCodes.VERIFICATION_CODE_TEMPLATE_CANNOT_ENABLE_UNSUBSCRIBE); } - UnsubscribeConfig = config; + if (UnsubscribeConfig is null) + { + UnsubscribeConfig = config; + return; + } + + UnsubscribeConfig.Apply(config); } public void Remove() diff --git a/src/Domain/Masa.Mc.Domain/MessageTemplates/Aggregates/MessageTemplateUnsubscribeConfig.cs b/src/Domain/Masa.Mc.Domain/MessageTemplates/Aggregates/MessageTemplateUnsubscribeConfig.cs index 5b395e29..3b1a5398 100644 --- a/src/Domain/Masa.Mc.Domain/MessageTemplates/Aggregates/MessageTemplateUnsubscribeConfig.cs +++ b/src/Domain/Masa.Mc.Domain/MessageTemplates/Aggregates/MessageTemplateUnsubscribeConfig.cs @@ -12,15 +12,11 @@ public class MessageTemplateUnsubscribeConfig : ValueObject public string UnsubscribeKeyword { get; protected set; } = string.Empty; - public string UnsubscribeAutoReply { get; protected set; } = string.Empty; + public Guid UnsubscribeAutoReplyTemplateId { get; protected set; } public string ResubscribeKeyword { get; protected set; } = string.Empty; - public string ResubscribeAutoReply { get; protected set; } = string.Empty; - - public bool DebounceEnabled { get; protected set; } - - public int CooldownSeconds { get; protected set; } + public Guid ResubscribeAutoReplyTemplateId { get; protected set; } private MessageTemplateUnsubscribeConfig() { @@ -29,26 +25,22 @@ private MessageTemplateUnsubscribeConfig() public MessageTemplateUnsubscribeConfig( bool enabled, string unsubscribeKeyword, - string unsubscribeAutoReply, + Guid unsubscribeAutoReplyTemplateId, string resubscribeKeyword, - string resubscribeAutoReply, - bool debounceEnabled, - int cooldownSeconds) + Guid resubscribeAutoReplyTemplateId) { Enabled = enabled; UnsubscribeKeyword = (unsubscribeKeyword ?? string.Empty).Trim(); - UnsubscribeAutoReply = (unsubscribeAutoReply ?? string.Empty).Trim(); + UnsubscribeAutoReplyTemplateId = unsubscribeAutoReplyTemplateId; ResubscribeKeyword = (resubscribeKeyword ?? string.Empty).Trim(); - ResubscribeAutoReply = (resubscribeAutoReply ?? string.Empty).Trim(); - DebounceEnabled = debounceEnabled; - CooldownSeconds = cooldownSeconds; + ResubscribeAutoReplyTemplateId = resubscribeAutoReplyTemplateId; NormalizeAndValidate(); } public static MessageTemplateUnsubscribeConfig Disabled() { - return new MessageTemplateUnsubscribeConfig(false, string.Empty, string.Empty, string.Empty, string.Empty, false, 0); + return new MessageTemplateUnsubscribeConfig(false, string.Empty, Guid.Empty, string.Empty, Guid.Empty); } public string BuildSuffix() @@ -82,37 +74,46 @@ public SmsInboundKeywordAction ResolveInboundKeywordAction(string inboundKeyword return SmsInboundKeywordAction.None; } - public string GetAutoReplyContent(SmsInboundKeywordAction action) + public Guid GetAutoReplyTemplateId(SmsInboundKeywordAction action) { return action switch { - SmsInboundKeywordAction.Unsubscribe => UnsubscribeAutoReply, - SmsInboundKeywordAction.Resubscribe => ResubscribeAutoReply, - _ => string.Empty + SmsInboundKeywordAction.Unsubscribe => UnsubscribeAutoReplyTemplateId, + SmsInboundKeywordAction.Resubscribe => ResubscribeAutoReplyTemplateId, + _ => Guid.Empty }; } + public void Apply(MessageTemplateUnsubscribeConfig config) + { + Check.NotNull(config, nameof(config)); + + Enabled = config.Enabled; + UnsubscribeKeyword = config.UnsubscribeKeyword; + UnsubscribeAutoReplyTemplateId = config.UnsubscribeAutoReplyTemplateId; + ResubscribeKeyword = config.ResubscribeKeyword; + ResubscribeAutoReplyTemplateId = config.ResubscribeAutoReplyTemplateId; + + NormalizeAndValidate(); + } + protected override IEnumerable GetEqualityValues() { yield return Enabled; yield return UnsubscribeKeyword; - yield return UnsubscribeAutoReply; + yield return UnsubscribeAutoReplyTemplateId; yield return ResubscribeKeyword; - yield return ResubscribeAutoReply; - yield return DebounceEnabled; - yield return CooldownSeconds; + yield return ResubscribeAutoReplyTemplateId; } private void NormalizeAndValidate() { if (!Enabled) { - DebounceEnabled = false; - CooldownSeconds = 0; UnsubscribeKeyword = string.Empty; - UnsubscribeAutoReply = string.Empty; + UnsubscribeAutoReplyTemplateId = Guid.Empty; ResubscribeKeyword = string.Empty; - ResubscribeAutoReply = string.Empty; + ResubscribeAutoReplyTemplateId = Guid.Empty; return; } @@ -131,14 +132,14 @@ private void NormalizeAndValidate() throw new UserFriendlyException(errorCode: MessageTemplateExceptionCodes.UNSUBSCRIBE_KEYWORDS_MUST_BE_DIFFERENT); } - if (DebounceEnabled && CooldownSeconds <= 0) + if (UnsubscribeAutoReplyTemplateId == Guid.Empty) { - throw new UserFriendlyException(errorCode: MessageTemplateExceptionCodes.UNSUBSCRIBE_COOLDOWN_SECONDS_REQUIRED); + throw new UserFriendlyException(errorCode: MessageTemplateExceptionCodes.UNSUBSCRIBE_AUTO_REPLY_REQUIRED); } - if (!DebounceEnabled) + if (ResubscribeAutoReplyTemplateId == Guid.Empty) { - CooldownSeconds = 0; + throw new UserFriendlyException(errorCode: MessageTemplateExceptionCodes.RESUBSCRIBE_AUTO_REPLY_REQUIRED); } } } diff --git a/src/Domain/Masa.Mc.Domain/Unsubscriptions/Aggregates/Unsubscription.cs b/src/Domain/Masa.Mc.Domain/Unsubscriptions/Aggregates/Unsubscription.cs index 7f9344d4..b4e82f29 100644 --- a/src/Domain/Masa.Mc.Domain/Unsubscriptions/Aggregates/Unsubscription.cs +++ b/src/Domain/Masa.Mc.Domain/Unsubscriptions/Aggregates/Unsubscription.cs @@ -39,6 +39,92 @@ private Unsubscription() { } + public static Unsubscription CreateManualBlacklist( + Guid userId, + string channelUserIdentity, + Guid channelId, + ChannelTypes channelType, + int channelProvider, + UnsubscriptionScopeTypes scopeType, + string scopeRefId, + string reason, + DateTimeOffset occurredAt, + string timelineDetail = "") + { + var aggregate = new Unsubscription + { + Id = IdGeneratorFactory.SequentialGuidGenerator.NewId(), + UserId = userId, + ChannelUserIdentity = channelUserIdentity?.Trim() ?? string.Empty, + ChannelType = channelType, + ChannelId = channelId, + ChannelProvider = channelProvider, + ScopeType = scopeType, + ScopeRefId = scopeType is UnsubscriptionScopeTypes.Global or UnsubscriptionScopeTypes.Channel + ? string.Empty + : scopeRefId?.Trim() ?? string.Empty, + Source = UnsubscriptionSource.ManualSupport, + Status = UnsubscriptionStatus.Unsubscribed, + Keyword = string.Empty, + Reason = reason?.Trim() ?? string.Empty, + UnsubscribedAt = occurredAt, + LastInboundMessageId = string.Empty + }; + + aggregate.ValidateInvariant(); + aggregate.AppendTimeline( + UnsubscriptionTimelineActions.ManualUnsubscribed, + occurredAt, + string.IsNullOrWhiteSpace(timelineDetail) ? aggregate.Reason : timelineDetail); + return aggregate; + } + + public static Unsubscription CreateGlobalManualBlacklist( + Guid userId, + string channelUserIdentity, + Guid channelId, + ChannelTypes channelType, + int channelProvider, + string reason, + DateTimeOffset occurredAt, + string timelineDetail = "") + { + return CreateManualBlacklist( + userId, + channelUserIdentity, + channelId, + channelType, + channelProvider, + UnsubscriptionScopeTypes.Global, + string.Empty, + reason, + occurredAt, + timelineDetail); + } + + public static Unsubscription CreateChannelManualBlacklist( + Guid userId, + string channelUserIdentity, + Guid channelId, + ChannelTypes channelType, + int channelProvider, + string reason, + DateTimeOffset occurredAt, + string timelineDetail = "") + { + return CreateManualBlacklist( + userId, + channelUserIdentity, + channelId, + channelType, + channelProvider, + UnsubscriptionScopeTypes.Channel, + string.Empty, + reason, + occurredAt, + timelineDetail); + } + public static Unsubscription CreateFromSmsInbound( Guid userId, string channelUserIdentity, @@ -50,9 +136,9 @@ public static Unsubscription CreateFromSmsInbound( string reason, DateTimeOffset occurredAt, string inboundMessageId, - Guid? matchedMessageRecordId = null, - string matchedMessageSnapshot = "", - DateTimeOffset? matchedMessageSentAt = null) + string timelineDetail = "", + string outboundMessageDetail = "", + DateTimeOffset? outboundMessageSentAt = null) { var aggregate = new Unsubscription { @@ -73,16 +159,11 @@ public static Unsubscription CreateFromSmsInbound( }; aggregate.ValidateInvariant(); + aggregate.AppendOutboundTimelineIfNeeded(outboundMessageDetail, outboundMessageSentAt); aggregate.AppendTimeline( UnsubscriptionTimelineActions.InboundUnsubscribed, - UnsubscriptionSource.SmsInboundKeyword, occurredAt, - aggregate.Reason, - aggregate.Keyword, - aggregate.LastInboundMessageId, - matchedMessageRecordId, - matchedMessageSnapshot, - matchedMessageSentAt); + timelineDetail); aggregate.AddDomainEvent(new UnsubscribedBySmsInboundDomainEvent( aggregate.Id, aggregate.ChannelId, @@ -99,11 +180,9 @@ public bool TryUnsubscribeByInboundKeyword( string reason, DateTimeOffset occurredAt, string inboundMessageId, - Guid? matchedMessageRecordId, - string matchedMessageSnapshot, - DateTimeOffset? matchedMessageSentAt, - bool debounceEnabled, - int cooldownSeconds) + string timelineDetail, + string outboundMessageDetail, + DateTimeOffset? outboundMessageSentAt) { if (Status != UnsubscriptionStatus.Unsubscribed) { @@ -116,34 +195,30 @@ public bool TryUnsubscribeByInboundKeyword( return false; } - if (IsInInboundDebounceWindow(occurredAt, debounceEnabled, cooldownSeconds)) - { - return false; - } - return AppendInboundKeyword( keyword, occurredAt, normalizedMessageId, reason, - matchedMessageRecordId, - matchedMessageSnapshot, - matchedMessageSentAt); + timelineDetail, + outboundMessageDetail, + outboundMessageSentAt); } public void ResubscribeByInboundKeyword( string keyword, string reason, DateTimeOffset occurredAt, - string inboundMessageId) + string inboundMessageId, + string timelineDetail) { Resubscribe( reason, occurredAt, UnsubscriptionTimelineActions.AutoResubscribed, - UnsubscriptionSource.SmsInboundKeyword, keyword, - inboundMessageId); + inboundMessageId, + timelineDetail); } private bool AppendInboundKeyword( @@ -151,9 +226,9 @@ private bool AppendInboundKeyword( DateTimeOffset occurredAt, string inboundMessageId, string detail = "", - Guid? matchedMessageRecordId = null, - string matchedMessageSnapshot = "", - DateTimeOffset? matchedMessageSentAt = null) + string timelineDetail = "", + string outboundMessageDetail = "", + DateTimeOffset? outboundMessageSentAt = null) { if (Status != UnsubscriptionStatus.Unsubscribed) { @@ -168,16 +243,11 @@ private bool AppendInboundKeyword( Keyword = keyword?.Trim() ?? Keyword; LastInboundMessageId = normalizedMessageId; + AppendOutboundTimelineIfNeeded(outboundMessageDetail, outboundMessageSentAt); AppendTimeline( UnsubscriptionTimelineActions.InboundUnsubscribed, - UnsubscriptionSource.SmsInboundKeyword, occurredAt, - detail, - Keyword, - LastInboundMessageId, - matchedMessageRecordId, - matchedMessageSnapshot, - matchedMessageSentAt); + string.IsNullOrWhiteSpace(timelineDetail) ? detail : timelineDetail); return true; } @@ -185,9 +255,9 @@ public void Resubscribe( string reason, DateTimeOffset occurredAt, UnsubscriptionTimelineActions action = UnsubscriptionTimelineActions.ManualResubscribed, - UnsubscriptionSource source = UnsubscriptionSource.ManualSupport, string keyword = "", - string inboundMessageId = "") + string inboundMessageId = "", + string timelineDetail = "") { if (Status != UnsubscriptionStatus.Unsubscribed) { @@ -199,8 +269,9 @@ public void Resubscribe( throw new UserFriendlyException(errorCode: UnsubscriptionExceptionCodes.UNSUBSCRIPTION_REASON_REQUIRED); } + var normalizedReason = reason.Trim(); + Reason = normalizedReason; Status = UnsubscriptionStatus.Resubscribed; - Reason = reason.Trim(); ResubscribedAt = occurredAt; var normalizedMessageId = inboundMessageId?.Trim() ?? string.Empty; if (!string.IsNullOrWhiteSpace(keyword)) @@ -215,11 +286,8 @@ public void Resubscribe( AppendTimeline( action, - source, occurredAt, - Reason, - Keyword, - LastInboundMessageId); + string.IsNullOrWhiteSpace(timelineDetail) ? normalizedReason : timelineDetail); } private bool IsInboundMessageDuplicated(string inboundMessageId) @@ -228,26 +296,6 @@ private bool IsInboundMessageDuplicated(string inboundMessageId) string.Equals(LastInboundMessageId, inboundMessageId, StringComparison.Ordinal); } - private bool IsInInboundDebounceWindow(DateTimeOffset occurredAt, bool debounceEnabled, int cooldownSeconds) - { - if (!debounceEnabled || cooldownSeconds <= 0) - { - return false; - } - - var lastInboundUnsubscribeOccurredAt = Timelines - .Where(x => x.Action == UnsubscriptionTimelineActions.InboundUnsubscribed) - .OrderByDescending(x => x.OccurredAt) - .Select(x => x.OccurredAt) - .FirstOrDefault(); - if (lastInboundUnsubscribeOccurredAt == default) - { - return false; - } - - return occurredAt < lastInboundUnsubscribeOccurredAt.AddSeconds(cooldownSeconds); - } - private void ValidateInvariant() { if (string.IsNullOrWhiteSpace(ChannelUserIdentity)) @@ -255,7 +303,7 @@ private void ValidateInvariant() throw new UserFriendlyException(errorCode: UnsubscriptionExceptionCodes.CHANNEL_USER_IDENTITY_REQUIRED); } - if (string.IsNullOrWhiteSpace(ScopeRefId) && ScopeType != UnsubscriptionScopeTypes.Global) + if (ScopeType == UnsubscriptionScopeTypes.Template && string.IsNullOrWhiteSpace(ScopeRefId)) { throw new UserFriendlyException(errorCode: UnsubscriptionExceptionCodes.INVALID_UNSUBSCRIPTION_SCOPE_REFERENCE); } @@ -268,25 +316,26 @@ private void ValidateInvariant() private void AppendTimeline( UnsubscriptionTimelineActions action, - UnsubscriptionSource source, DateTimeOffset occurredAt, - string detail = "", - string keyword = "", - string messageId = "", - Guid? matchedMessageRecordId = null, - string matchedMessageSnapshot = "", - DateTimeOffset? matchedMessageSentAt = null) + string detail = "") { Timelines.Add(new UnsubscriptionTimeline( Id, action, - source, occurredAt, - detail, - keyword, - messageId, - matchedMessageRecordId, - matchedMessageSnapshot, - matchedMessageSentAt)); + detail)); + } + + private void AppendOutboundTimelineIfNeeded(string outboundMessageDetail, DateTimeOffset? outboundMessageSentAt) + { + if (string.IsNullOrWhiteSpace(outboundMessageDetail) || !outboundMessageSentAt.HasValue) + { + return; + } + + AppendTimeline( + UnsubscriptionTimelineActions.OutboundMessageSent, + outboundMessageSentAt.Value, + outboundMessageDetail); } } diff --git a/src/Domain/Masa.Mc.Domain/Unsubscriptions/Aggregates/UnsubscriptionTimeline.cs b/src/Domain/Masa.Mc.Domain/Unsubscriptions/Aggregates/UnsubscriptionTimeline.cs index c0ab7d8f..3ba7d379 100644 --- a/src/Domain/Masa.Mc.Domain/Unsubscriptions/Aggregates/UnsubscriptionTimeline.cs +++ b/src/Domain/Masa.Mc.Domain/Unsubscriptions/Aggregates/UnsubscriptionTimeline.cs @@ -9,20 +9,8 @@ public class UnsubscriptionTimeline : AuditEntity public UnsubscriptionTimelineActions Action { get; private set; } - public UnsubscriptionSource Source { get; private set; } - public string Detail { get; private set; } = string.Empty; - public string Keyword { get; private set; } = string.Empty; - - public string MessageId { get; private set; } = string.Empty; - - public Guid? MatchedMessageRecordId { get; private set; } - - public string MatchedMessageSnapshot { get; private set; } = string.Empty; - - public DateTimeOffset? MatchedMessageSentAt { get; private set; } - public DateTimeOffset OccurredAt { get; private set; } private UnsubscriptionTimeline() @@ -32,24 +20,12 @@ private UnsubscriptionTimeline() public UnsubscriptionTimeline( Guid unsubscriptionId, UnsubscriptionTimelineActions action, - UnsubscriptionSource source, DateTimeOffset occurredAt, - string detail = "", - string keyword = "", - string messageId = "", - Guid? matchedMessageRecordId = null, - string matchedMessageSnapshot = "", - DateTimeOffset? matchedMessageSentAt = null) + string detail = "") { UnsubscriptionId = unsubscriptionId; Action = action; - Source = source; OccurredAt = occurredAt; Detail = detail ?? string.Empty; - Keyword = keyword ?? string.Empty; - MessageId = messageId ?? string.Empty; - MatchedMessageRecordId = matchedMessageRecordId; - MatchedMessageSnapshot = matchedMessageSnapshot ?? string.Empty; - MatchedMessageSentAt = matchedMessageSentAt; } } diff --git a/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260627084858_SimplifyUnsubscriptionTimeline.Designer.cs b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260627084858_SimplifyUnsubscriptionTimeline.Designer.cs new file mode 100644 index 00000000..d96d7ccc --- /dev/null +++ b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260627084858_SimplifyUnsubscriptionTimeline.Designer.cs @@ -0,0 +1,1461 @@ +// +using System; +using Masa.Mc.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Masa.Mc.EntityFrameworkCore.PostgreSql.Migrations +{ + [DbContext(typeof(McDbContext))] + [Migration("20260627084858_SimplifyUnsubscriptionTimeline")] + partial class SimplifyUnsubscriptionTimeline + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Masa.BuildingBlocks.Dispatcher.IntegrationEvents.Logs.IntegrationEventLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Content") + .IsRequired() + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("EventId") + .HasColumnType("uuid"); + + b.Property("EventTypeName") + .IsRequired() + .HasColumnType("text"); + + b.Property("ExpandContent") + .IsRequired() + .HasColumnType("text"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("RowVersion") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(36) + .HasColumnType("character varying(36)") + .HasColumnName("RowVersion"); + + b.Property("State") + .HasColumnType("integer"); + + b.Property("TimesSent") + .HasColumnType("integer"); + + b.Property("TransactionId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex(new[] { "EventId", "RowVersion" }, "IX_EventId_Version"); + + b.HasIndex(new[] { "State", "ModificationTime" }, "IX_State_MTime"); + + b.HasIndex(new[] { "State", "TimesSent", "ModificationTime" }, "IX_State_TimesSent_MTime"); + + b.ToTable("IntegrationEventLog", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Apps.Aggregates.AppDeviceToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("DeviceToken") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Platform") + .HasColumnType("integer"); + + b.Property("RegisteredTime") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId", "UserId", "Platform"); + + b.ToTable("AppDeviceTokens", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Apps.Aggregates.AppVendorConfig", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Options") + .IsRequired() + .HasColumnType("text"); + + b.Property("Vendor") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId", "Vendor"); + + b.ToTable("AppVendorConfigs", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Channels.Aggregates.AppChannel", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(64) + .HasColumnType("character varying(64)") + .HasColumnName("Code"); + + b.Property("Color") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Color"); + + b.Property("DisplayName") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("DisplayName"); + + b.Property("Provider") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("Provider"); + + b.Property("Scheme") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Scheme"); + + b.Property("SchemeField") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("SchemeField"); + + b.Property("Type") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("Type"); + + b.HasKey("Id"); + + b.ToTable("Channels", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Channels.Aggregates.Channel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(64) + .HasColumnType("character varying(64)") + .HasColumnName("Code"); + + b.Property("Color") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Color"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("DisplayName") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("DisplayName"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsStatic") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Provider") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("Provider"); + + b.Property("Scheme") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Scheme"); + + b.Property("SchemeField") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("SchemeField"); + + b.Property("Type") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("Type"); + + b.HasKey("Id"); + + b.HasIndex("Code"); + + b.HasIndex("Type"); + + b.ToTable("Channels", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageInfos.Aggregates.MessageInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("MessageInfos", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageReceipts.Aggregates.SmsInbound", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AddSerial") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Provider") + .HasColumnType("integer"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("SmsContent") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("Mobile"); + + b.HasIndex("Provider"); + + b.HasIndex("SendTime"); + + b.ToTable("SmsInbounds", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageRecords.Aggregates.MessageRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("ChannelUserIdentity") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ExpectSendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("FailureReason") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("MessageEntityId") + .HasColumnType("uuid"); + + b.Property("MessageEntityType") + .HasColumnType("integer"); + + b.Property("MessageId") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("MessageTaskHistoryId") + .HasColumnType("uuid"); + + b.Property("MessageTaskId") + .HasColumnType("uuid"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Success") + .HasColumnType("boolean"); + + b.Property("SystemId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("Variables") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("MessageId"); + + b.HasIndex("MessageTaskHistoryId"); + + b.HasIndex("UserId"); + + b.ToTable("MessageRecords", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageReceiverUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelUserIdentity") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("MessageTaskHistoryId") + .HasColumnType("uuid"); + + b.Property("Platform") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("Variables") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("MessageTaskHistoryId", "ChannelUserIdentity", "Platform"); + + b.ToTable("MessageReceiverUsers", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("ChannelType") + .HasColumnType("integer"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("EntityId") + .HasColumnType("uuid"); + + b.Property("EntityType") + .HasColumnType("integer"); + + b.Property("ExpectSendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsDraft") + .HasColumnType("boolean"); + + b.Property("IsEnabled") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("ReceiverType") + .HasColumnType("integer"); + + b.Property("Receivers") + .IsRequired() + .HasColumnType("text"); + + b.Property("SchedulerJobId") + .HasColumnType("uuid"); + + b.Property("SelectReceiverType") + .HasColumnType("integer"); + + b.Property("SendRules") + .IsRequired() + .HasColumnType("text"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Sign") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Source") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("SystemId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Variables") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("Source"); + + b.ToTable("MessageTasks", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CompletionTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsTest") + .HasColumnType("boolean"); + + b.Property("MessageTaskId") + .HasColumnType("uuid"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("SchedulerTaskId") + .HasColumnType("uuid"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("TaskHistoryNo") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("WithdrawTime") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("MessageTaskId"); + + b.ToTable("MessageTaskHistorys", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AuditReason") + .IsRequired() + .HasColumnType("text"); + + b.Property("AuditStatus") + .HasColumnType("integer"); + + b.Property("AuditTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Example") + .IsRequired() + .HasColumnType("text"); + + b.Property("InvalidTime") + .HasColumnType("timestamp with time zone"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsStatic") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Options") + .IsRequired() + .HasColumnType("text"); + + b.Property("PerDayLimit") + .HasColumnType("bigint"); + + b.Property("Sign") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("TemplateId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("TemplateType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("Code"); + + b.ToTable("MessageTemplates", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplateItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("DisplayText") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("MappingCode") + .IsRequired() + .HasColumnType("text"); + + b.Property("MessageTemplateId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("MessageTemplateId"); + + b.HasIndex("Code", "MessageTemplateId"); + + b.ToTable("MessageTemplateItems", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.SmsTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AuditReason") + .IsRequired() + .HasColumnType("text"); + + b.Property("AuditStatus") + .HasColumnType("integer"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("TemplateCode") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("TemplateContent") + .IsRequired() + .HasColumnType("text"); + + b.Property("TemplateName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("TemplateType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.ToTable("SmsTemplates", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.ReceiverGroups.Aggregates.ReceiverGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.ToTable("ReceiverGroups", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.Unsubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("ChannelProvider") + .HasColumnType("integer"); + + b.Property("ChannelType") + .HasColumnType("integer"); + + b.Property("ChannelUserIdentity") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Keyword") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("LastInboundMessageId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Reason") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("ResubscribedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ScopeRefId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("ScopeType") + .HasColumnType("integer"); + + b.Property("Source") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("UnsubscribedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("ChannelType"); + + b.HasIndex("Status"); + + b.HasIndex("UserId"); + + b.HasIndex("ChannelId", "ChannelUserIdentity", "ScopeType", "ScopeRefId", "Status"); + + b.ToTable("Unsubscriptions", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.UnsubscriptionTimeline", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Action") + .HasColumnType("integer"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("Detail") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("OccurredAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UnsubscriptionId") + .HasColumnType("uuid") + .HasColumnName("UnsubscriptionId"); + + b.HasKey("Id"); + + b.HasIndex("OccurredAt"); + + b.HasIndex("UnsubscriptionId"); + + b.ToTable("UnsubscriptionTimelines", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("Content") + .IsRequired() + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsRead") + .HasColumnType("boolean"); + + b.Property("IsWithdrawn") + .HasColumnType("boolean"); + + b.Property("LinkUrl") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("MessageTaskHistoryId") + .HasColumnType("uuid"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("ReadTime") + .HasColumnType("timestamp with time zone"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("UserId", "ChannelId"); + + b.ToTable("WebsiteMessages", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessageCursor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("UpdateTime") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("WebsiteMessageCursors", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Channels.Aggregates.AppChannel", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.Channel", null) + .WithOne() + .HasForeignKey("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageInfos.Aggregates.MessageInfo", b => + { + b.OwnsOne("Masa.Mc.Domain.MessageInfos.Aggregates.MessageContent", "MessageContent", b1 => + { + b1.Property("MessageInfoId") + .HasColumnType("uuid"); + + b1.Property("Content") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Content"); + + b1.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text") + .HasColumnName("ExtraProperties"); + + b1.Property("IsJump") + .HasMaxLength(128) + .HasColumnType("boolean") + .HasColumnName("IsJump"); + + b1.Property("JumpUrl") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("JumpUrl"); + + b1.Property("Markdown") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Markdown"); + + b1.Property("Title") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Title"); + + b1.HasKey("MessageInfoId"); + + b1.ToTable("MessageInfos"); + + b1.WithOwner() + .HasForeignKey("MessageInfoId"); + }); + + b.Navigation("MessageContent") + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageRecords.Aggregates.MessageRecord", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Channel") + .WithMany() + .HasForeignKey("ChannelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Channel"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageReceiverUser", b => + { + b.HasOne("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", null) + .WithMany("ReceiverUsers") + .HasForeignKey("MessageTaskHistoryId"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTask", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Channel") + .WithMany() + .HasForeignKey("ChannelId"); + + b.Navigation("Channel"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", b => + { + b.HasOne("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTask", "MessageTask") + .WithMany() + .HasForeignKey("MessageTaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MessageTask"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", b => + { + b.OwnsOne("Masa.Mc.Domain.MessageInfos.Aggregates.MessageContent", "MessageContent", b1 => + { + b1.Property("MessageTemplateId") + .HasColumnType("uuid"); + + b1.Property("Content") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Content"); + + b1.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text") + .HasColumnName("ExtraProperties"); + + b1.Property("IsJump") + .HasMaxLength(128) + .HasColumnType("boolean") + .HasColumnName("IsJump"); + + b1.Property("JumpUrl") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("JumpUrl"); + + b1.Property("Markdown") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Markdown"); + + b1.Property("Title") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Title"); + + b1.HasKey("MessageTemplateId"); + + b1.ToTable("MessageTemplates"); + + b1.WithOwner() + .HasForeignKey("MessageTemplateId"); + }); + + b.OwnsOne("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplateUnsubscribeConfig", "UnsubscribeConfig", b1 => + { + b1.Property("MessageTemplateId") + .HasColumnType("uuid"); + + b1.Property("CooldownSeconds") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValue(0) + .HasColumnName("CooldownSeconds"); + + b1.Property("DebounceEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasColumnName("DebounceEnabled"); + + b1.Property("Enabled") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasColumnName("Enabled"); + + b1.Property("ResubscribeAutoReply") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(500) + .HasColumnType("character varying(500)") + .HasDefaultValue("") + .HasColumnName("ResubscribeAutoReply"); + + b1.Property("ResubscribeKeyword") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(20) + .HasColumnType("character varying(20)") + .HasDefaultValue("") + .HasColumnName("ResubscribeKeyword"); + + b1.Property("UnsubscribeAutoReply") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(500) + .HasColumnType("character varying(500)") + .HasDefaultValue("") + .HasColumnName("UnsubscribeAutoReply"); + + b1.Property("UnsubscribeKeyword") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(20) + .HasColumnType("character varying(20)") + .HasDefaultValue("") + .HasColumnName("UnsubscribeKeyword"); + + b1.HasKey("MessageTemplateId"); + + b1.ToTable("MessageTemplateUnsubscribeConfigs", (string)null); + + b1.WithOwner() + .HasForeignKey("MessageTemplateId"); + }); + + b.Navigation("MessageContent") + .IsRequired(); + + b.Navigation("UnsubscribeConfig"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplateItem", b => + { + b.HasOne("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", null) + .WithMany("Items") + .HasForeignKey("MessageTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.ReceiverGroups.Aggregates.ReceiverGroup", b => + { + b.OwnsMany("Masa.Mc.Domain.ReceiverGroups.Aggregates.ReceiverGroupItem", "Items", b1 => + { + b1.Property("GroupId") + .HasColumnType("uuid"); + + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b1.Property("Avatar") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b1.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b1.Property("SubjectId") + .HasColumnType("uuid"); + + b1.Property("Type") + .HasColumnType("integer"); + + b1.HasKey("GroupId", "Id"); + + b1.ToTable("ReceiverGroupItems", (string)null); + + b1.WithOwner() + .HasForeignKey("GroupId"); + }); + + b.Navigation("Items"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.UnsubscriptionTimeline", b => + { + b.HasOne("Masa.Mc.Domain.Unsubscriptions.Aggregates.Unsubscription", null) + .WithMany("Timelines") + .HasForeignKey("UnsubscriptionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessage", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Channel") + .WithMany() + .HasForeignKey("ChannelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsMany("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessageTag", "Tags", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b1.Property("ChannelId") + .HasColumnType("uuid"); + + b1.Property("CreationTime") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone"); + + b1.Property("Tag") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Tag"); + + b1.Property("UserId") + .HasColumnType("uuid"); + + b1.Property("WebsiteMessageId") + .HasColumnType("uuid"); + + b1.HasKey("Id"); + + b1.HasIndex("ChannelId"); + + b1.HasIndex("Tag"); + + b1.HasIndex("UserId"); + + b1.HasIndex("WebsiteMessageId"); + + b1.ToTable("WebsiteMessageTags", (string)null); + + b1.WithOwner() + .HasForeignKey("WebsiteMessageId"); + }); + + b.Navigation("Channel"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", b => + { + b.Navigation("ReceiverUsers"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.Unsubscription", b => + { + b.Navigation("Timelines"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260627084858_SimplifyUnsubscriptionTimeline.cs b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260627084858_SimplifyUnsubscriptionTimeline.cs new file mode 100644 index 00000000..56786141 --- /dev/null +++ b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260627084858_SimplifyUnsubscriptionTimeline.cs @@ -0,0 +1,83 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Masa.Mc.EntityFrameworkCore.PostgreSql.Migrations +{ + public partial class SimplifyUnsubscriptionTimeline : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Keyword", + table: "UnsubscriptionTimelines"); + + migrationBuilder.DropColumn( + name: "MatchedMessageRecordId", + table: "UnsubscriptionTimelines"); + + migrationBuilder.DropColumn( + name: "MatchedMessageSentAt", + table: "UnsubscriptionTimelines"); + + migrationBuilder.DropColumn( + name: "MatchedMessageSnapshot", + table: "UnsubscriptionTimelines"); + + migrationBuilder.DropColumn( + name: "MessageId", + table: "UnsubscriptionTimelines"); + + migrationBuilder.DropColumn( + name: "Source", + table: "UnsubscriptionTimelines"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Keyword", + table: "UnsubscriptionTimelines", + type: "character varying(20)", + maxLength: 20, + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "MatchedMessageRecordId", + table: "UnsubscriptionTimelines", + type: "uuid", + nullable: true); + + migrationBuilder.AddColumn( + name: "MatchedMessageSentAt", + table: "UnsubscriptionTimelines", + type: "timestamp with time zone", + nullable: true); + + migrationBuilder.AddColumn( + name: "MatchedMessageSnapshot", + table: "UnsubscriptionTimelines", + type: "character varying(2000)", + maxLength: 2000, + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "MessageId", + table: "UnsubscriptionTimelines", + type: "character varying(128)", + maxLength: 128, + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "Source", + table: "UnsubscriptionTimelines", + type: "integer", + nullable: false, + defaultValue: 0); + } + } +} diff --git a/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629063724_RefactorUnsubscriptionIndexes.Designer.cs b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629063724_RefactorUnsubscriptionIndexes.Designer.cs new file mode 100644 index 00000000..b39b156b --- /dev/null +++ b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629063724_RefactorUnsubscriptionIndexes.Designer.cs @@ -0,0 +1,1462 @@ +// +using System; +using Masa.Mc.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Masa.Mc.EntityFrameworkCore.PostgreSql.Migrations +{ + [DbContext(typeof(McDbContext))] + [Migration("20260629063724_RefactorUnsubscriptionIndexes")] + partial class RefactorUnsubscriptionIndexes + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Masa.BuildingBlocks.Dispatcher.IntegrationEvents.Logs.IntegrationEventLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Content") + .IsRequired() + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("EventId") + .HasColumnType("uuid"); + + b.Property("EventTypeName") + .IsRequired() + .HasColumnType("text"); + + b.Property("ExpandContent") + .IsRequired() + .HasColumnType("text"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("RowVersion") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(36) + .HasColumnType("character varying(36)") + .HasColumnName("RowVersion"); + + b.Property("State") + .HasColumnType("integer"); + + b.Property("TimesSent") + .HasColumnType("integer"); + + b.Property("TransactionId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex(new[] { "EventId", "RowVersion" }, "IX_EventId_Version"); + + b.HasIndex(new[] { "State", "ModificationTime" }, "IX_State_MTime"); + + b.HasIndex(new[] { "State", "TimesSent", "ModificationTime" }, "IX_State_TimesSent_MTime"); + + b.ToTable("IntegrationEventLog", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Apps.Aggregates.AppDeviceToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("DeviceToken") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Platform") + .HasColumnType("integer"); + + b.Property("RegisteredTime") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId", "UserId", "Platform"); + + b.ToTable("AppDeviceTokens", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Apps.Aggregates.AppVendorConfig", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Options") + .IsRequired() + .HasColumnType("text"); + + b.Property("Vendor") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId", "Vendor"); + + b.ToTable("AppVendorConfigs", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Channels.Aggregates.AppChannel", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(64) + .HasColumnType("character varying(64)") + .HasColumnName("Code"); + + b.Property("Color") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Color"); + + b.Property("DisplayName") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("DisplayName"); + + b.Property("Provider") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("Provider"); + + b.Property("Scheme") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Scheme"); + + b.Property("SchemeField") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("SchemeField"); + + b.Property("Type") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("Type"); + + b.HasKey("Id"); + + b.ToTable("Channels", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Channels.Aggregates.Channel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(64) + .HasColumnType("character varying(64)") + .HasColumnName("Code"); + + b.Property("Color") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Color"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("DisplayName") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("DisplayName"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsStatic") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Provider") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("Provider"); + + b.Property("Scheme") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Scheme"); + + b.Property("SchemeField") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("SchemeField"); + + b.Property("Type") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("Type"); + + b.HasKey("Id"); + + b.HasIndex("Code"); + + b.HasIndex("Type"); + + b.ToTable("Channels", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageInfos.Aggregates.MessageInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("MessageInfos", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageReceipts.Aggregates.SmsInbound", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AddSerial") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Provider") + .HasColumnType("integer"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("SmsContent") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.HasKey("Id"); + + b.HasIndex("Provider"); + + b.HasIndex("SendTime"); + + b.HasIndex("ChannelId", "SendTime"); + + b.HasIndex("Mobile", "SendTime"); + + b.ToTable("SmsInbounds", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageRecords.Aggregates.MessageRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("ChannelUserIdentity") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ExpectSendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("FailureReason") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("MessageEntityId") + .HasColumnType("uuid"); + + b.Property("MessageEntityType") + .HasColumnType("integer"); + + b.Property("MessageId") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("MessageTaskHistoryId") + .HasColumnType("uuid"); + + b.Property("MessageTaskId") + .HasColumnType("uuid"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Success") + .HasColumnType("boolean"); + + b.Property("SystemId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("Variables") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("MessageId"); + + b.HasIndex("MessageTaskHistoryId"); + + b.HasIndex("UserId"); + + b.ToTable("MessageRecords", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageReceiverUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelUserIdentity") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("MessageTaskHistoryId") + .HasColumnType("uuid"); + + b.Property("Platform") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("Variables") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("MessageTaskHistoryId", "ChannelUserIdentity", "Platform"); + + b.ToTable("MessageReceiverUsers", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("ChannelType") + .HasColumnType("integer"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("EntityId") + .HasColumnType("uuid"); + + b.Property("EntityType") + .HasColumnType("integer"); + + b.Property("ExpectSendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsDraft") + .HasColumnType("boolean"); + + b.Property("IsEnabled") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("ReceiverType") + .HasColumnType("integer"); + + b.Property("Receivers") + .IsRequired() + .HasColumnType("text"); + + b.Property("SchedulerJobId") + .HasColumnType("uuid"); + + b.Property("SelectReceiverType") + .HasColumnType("integer"); + + b.Property("SendRules") + .IsRequired() + .HasColumnType("text"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Sign") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Source") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("SystemId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Variables") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("Source"); + + b.ToTable("MessageTasks", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CompletionTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsTest") + .HasColumnType("boolean"); + + b.Property("MessageTaskId") + .HasColumnType("uuid"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("SchedulerTaskId") + .HasColumnType("uuid"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("TaskHistoryNo") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("WithdrawTime") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("MessageTaskId"); + + b.ToTable("MessageTaskHistorys", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AuditReason") + .IsRequired() + .HasColumnType("text"); + + b.Property("AuditStatus") + .HasColumnType("integer"); + + b.Property("AuditTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Example") + .IsRequired() + .HasColumnType("text"); + + b.Property("InvalidTime") + .HasColumnType("timestamp with time zone"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsStatic") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Options") + .IsRequired() + .HasColumnType("text"); + + b.Property("PerDayLimit") + .HasColumnType("bigint"); + + b.Property("Sign") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("TemplateId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("TemplateType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("Code"); + + b.ToTable("MessageTemplates", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplateItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("DisplayText") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("MappingCode") + .IsRequired() + .HasColumnType("text"); + + b.Property("MessageTemplateId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("MessageTemplateId"); + + b.HasIndex("Code", "MessageTemplateId"); + + b.ToTable("MessageTemplateItems", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.SmsTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AuditReason") + .IsRequired() + .HasColumnType("text"); + + b.Property("AuditStatus") + .HasColumnType("integer"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("TemplateCode") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("TemplateContent") + .IsRequired() + .HasColumnType("text"); + + b.Property("TemplateName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("TemplateType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.ToTable("SmsTemplates", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.ReceiverGroups.Aggregates.ReceiverGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.ToTable("ReceiverGroups", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.Unsubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("ChannelProvider") + .HasColumnType("integer"); + + b.Property("ChannelType") + .HasColumnType("integer"); + + b.Property("ChannelUserIdentity") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Keyword") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("LastInboundMessageId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Reason") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("ResubscribedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ScopeRefId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("ScopeType") + .HasColumnType("integer"); + + b.Property("Source") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("UnsubscribedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("LastInboundMessageId"); + + b.HasIndex("UserId"); + + b.HasIndex("ChannelType", "ChannelProvider", "UnsubscribedAt"); + + b.HasIndex("ChannelUserIdentity", "Status", "ScopeType"); + + b.HasIndex("ChannelId", "ChannelUserIdentity", "Status", "UnsubscribedAt"); + + b.HasIndex("ChannelId", "ChannelUserIdentity", "ScopeType", "ScopeRefId", "Status", "UnsubscribedAt"); + + b.ToTable("Unsubscriptions", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.UnsubscriptionTimeline", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Action") + .HasColumnType("integer"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("Detail") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("OccurredAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UnsubscriptionId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UnsubscriptionId", "OccurredAt"); + + b.HasIndex("OccurredAt", "Action", "UnsubscriptionId"); + + b.ToTable("UnsubscriptionTimelines", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("Content") + .IsRequired() + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsRead") + .HasColumnType("boolean"); + + b.Property("IsWithdrawn") + .HasColumnType("boolean"); + + b.Property("LinkUrl") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("MessageTaskHistoryId") + .HasColumnType("uuid"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("ReadTime") + .HasColumnType("timestamp with time zone"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("UserId", "ChannelId"); + + b.ToTable("WebsiteMessages", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessageCursor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("UpdateTime") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("WebsiteMessageCursors", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Channels.Aggregates.AppChannel", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.Channel", null) + .WithOne() + .HasForeignKey("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageInfos.Aggregates.MessageInfo", b => + { + b.OwnsOne("Masa.Mc.Domain.MessageInfos.Aggregates.MessageContent", "MessageContent", b1 => + { + b1.Property("MessageInfoId") + .HasColumnType("uuid"); + + b1.Property("Content") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Content"); + + b1.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text") + .HasColumnName("ExtraProperties"); + + b1.Property("IsJump") + .HasMaxLength(128) + .HasColumnType("boolean") + .HasColumnName("IsJump"); + + b1.Property("JumpUrl") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("JumpUrl"); + + b1.Property("Markdown") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Markdown"); + + b1.Property("Title") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Title"); + + b1.HasKey("MessageInfoId"); + + b1.ToTable("MessageInfos"); + + b1.WithOwner() + .HasForeignKey("MessageInfoId"); + }); + + b.Navigation("MessageContent") + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageRecords.Aggregates.MessageRecord", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Channel") + .WithMany() + .HasForeignKey("ChannelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Channel"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageReceiverUser", b => + { + b.HasOne("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", null) + .WithMany("ReceiverUsers") + .HasForeignKey("MessageTaskHistoryId"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTask", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Channel") + .WithMany() + .HasForeignKey("ChannelId"); + + b.Navigation("Channel"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", b => + { + b.HasOne("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTask", "MessageTask") + .WithMany() + .HasForeignKey("MessageTaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MessageTask"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", b => + { + b.OwnsOne("Masa.Mc.Domain.MessageInfos.Aggregates.MessageContent", "MessageContent", b1 => + { + b1.Property("MessageTemplateId") + .HasColumnType("uuid"); + + b1.Property("Content") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Content"); + + b1.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text") + .HasColumnName("ExtraProperties"); + + b1.Property("IsJump") + .HasMaxLength(128) + .HasColumnType("boolean") + .HasColumnName("IsJump"); + + b1.Property("JumpUrl") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("JumpUrl"); + + b1.Property("Markdown") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Markdown"); + + b1.Property("Title") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Title"); + + b1.HasKey("MessageTemplateId"); + + b1.ToTable("MessageTemplates"); + + b1.WithOwner() + .HasForeignKey("MessageTemplateId"); + }); + + b.OwnsOne("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplateUnsubscribeConfig", "UnsubscribeConfig", b1 => + { + b1.Property("MessageTemplateId") + .HasColumnType("uuid"); + + b1.Property("CooldownSeconds") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValue(0) + .HasColumnName("CooldownSeconds"); + + b1.Property("DebounceEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasColumnName("DebounceEnabled"); + + b1.Property("Enabled") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasColumnName("Enabled"); + + b1.Property("ResubscribeAutoReply") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(500) + .HasColumnType("character varying(500)") + .HasDefaultValue("") + .HasColumnName("ResubscribeAutoReply"); + + b1.Property("ResubscribeKeyword") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(20) + .HasColumnType("character varying(20)") + .HasDefaultValue("") + .HasColumnName("ResubscribeKeyword"); + + b1.Property("UnsubscribeAutoReply") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(500) + .HasColumnType("character varying(500)") + .HasDefaultValue("") + .HasColumnName("UnsubscribeAutoReply"); + + b1.Property("UnsubscribeKeyword") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(20) + .HasColumnType("character varying(20)") + .HasDefaultValue("") + .HasColumnName("UnsubscribeKeyword"); + + b1.HasKey("MessageTemplateId"); + + b1.ToTable("MessageTemplateUnsubscribeConfigs", (string)null); + + b1.WithOwner() + .HasForeignKey("MessageTemplateId"); + }); + + b.Navigation("MessageContent") + .IsRequired(); + + b.Navigation("UnsubscribeConfig"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplateItem", b => + { + b.HasOne("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", null) + .WithMany("Items") + .HasForeignKey("MessageTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.ReceiverGroups.Aggregates.ReceiverGroup", b => + { + b.OwnsMany("Masa.Mc.Domain.ReceiverGroups.Aggregates.ReceiverGroupItem", "Items", b1 => + { + b1.Property("GroupId") + .HasColumnType("uuid"); + + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b1.Property("Avatar") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b1.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b1.Property("SubjectId") + .HasColumnType("uuid"); + + b1.Property("Type") + .HasColumnType("integer"); + + b1.HasKey("GroupId", "Id"); + + b1.ToTable("ReceiverGroupItems", (string)null); + + b1.WithOwner() + .HasForeignKey("GroupId"); + }); + + b.Navigation("Items"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.UnsubscriptionTimeline", b => + { + b.HasOne("Masa.Mc.Domain.Unsubscriptions.Aggregates.Unsubscription", null) + .WithMany("Timelines") + .HasForeignKey("UnsubscriptionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessage", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Channel") + .WithMany() + .HasForeignKey("ChannelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsMany("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessageTag", "Tags", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b1.Property("ChannelId") + .HasColumnType("uuid"); + + b1.Property("CreationTime") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone"); + + b1.Property("Tag") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Tag"); + + b1.Property("UserId") + .HasColumnType("uuid"); + + b1.Property("WebsiteMessageId") + .HasColumnType("uuid"); + + b1.HasKey("Id"); + + b1.HasIndex("ChannelId"); + + b1.HasIndex("Tag"); + + b1.HasIndex("UserId"); + + b1.HasIndex("WebsiteMessageId"); + + b1.ToTable("WebsiteMessageTags", (string)null); + + b1.WithOwner() + .HasForeignKey("WebsiteMessageId"); + }); + + b.Navigation("Channel"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", b => + { + b.Navigation("ReceiverUsers"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.Unsubscription", b => + { + b.Navigation("Timelines"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629063724_RefactorUnsubscriptionIndexes.cs b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629063724_RefactorUnsubscriptionIndexes.cs new file mode 100644 index 00000000..f1257752 --- /dev/null +++ b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629063724_RefactorUnsubscriptionIndexes.cs @@ -0,0 +1,169 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Masa.Mc.EntityFrameworkCore.PostgreSql.Migrations +{ + public partial class RefactorUnsubscriptionIndexes : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_UnsubscriptionTimelines_OccurredAt", + table: "UnsubscriptionTimelines"); + + migrationBuilder.DropIndex( + name: "IX_UnsubscriptionTimelines_UnsubscriptionId", + table: "UnsubscriptionTimelines"); + + migrationBuilder.DropIndex( + name: "IX_Unsubscriptions_ChannelId", + table: "Unsubscriptions"); + + // The legacy migration created this index with a shorter truncated name ("...ScopeT~") + // while newer EF name generation may produce "...ScopeType_Sco~". Drop both variants safely. + migrationBuilder.Sql("DROP INDEX IF EXISTS \"IX_Unsubscriptions_ChannelId_ChannelUserIdentity_ScopeType_Sco~\";"); + migrationBuilder.Sql("DROP INDEX IF EXISTS \"IX_Unsubscriptions_ChannelId_ChannelUserIdentity_ScopeT~\";"); + + migrationBuilder.DropIndex( + name: "IX_Unsubscriptions_ChannelType", + table: "Unsubscriptions"); + + migrationBuilder.DropIndex( + name: "IX_Unsubscriptions_Status", + table: "Unsubscriptions"); + + migrationBuilder.DropIndex( + name: "IX_SmsInbounds_ChannelId", + table: "SmsInbounds"); + + migrationBuilder.DropIndex( + name: "IX_SmsInbounds_Mobile", + table: "SmsInbounds"); + + migrationBuilder.CreateIndex( + name: "IX_UnsubscriptionTimelines_OccurredAt_Action_UnsubscriptionId", + table: "UnsubscriptionTimelines", + columns: new[] { "OccurredAt", "Action", "UnsubscriptionId" }); + + migrationBuilder.CreateIndex( + name: "IX_UnsubscriptionTimelines_UnsubscriptionId_OccurredAt", + table: "UnsubscriptionTimelines", + columns: new[] { "UnsubscriptionId", "OccurredAt" }); + + migrationBuilder.CreateIndex( + name: "IX_Unsubscriptions_ChannelId_ChannelUserIdentity_ScopeType_Sco~", + table: "Unsubscriptions", + columns: new[] { "ChannelId", "ChannelUserIdentity", "ScopeType", "ScopeRefId", "Status", "UnsubscribedAt" }); + + migrationBuilder.CreateIndex( + name: "IX_Unsubscriptions_ChannelId_ChannelUserIdentity_Status_Unsubs~", + table: "Unsubscriptions", + columns: new[] { "ChannelId", "ChannelUserIdentity", "Status", "UnsubscribedAt" }); + + migrationBuilder.CreateIndex( + name: "IX_Unsubscriptions_ChannelType_ChannelProvider_UnsubscribedAt", + table: "Unsubscriptions", + columns: new[] { "ChannelType", "ChannelProvider", "UnsubscribedAt" }); + + migrationBuilder.CreateIndex( + name: "IX_Unsubscriptions_ChannelUserIdentity_Status_ScopeType", + table: "Unsubscriptions", + columns: new[] { "ChannelUserIdentity", "Status", "ScopeType" }); + + migrationBuilder.CreateIndex( + name: "IX_Unsubscriptions_LastInboundMessageId", + table: "Unsubscriptions", + column: "LastInboundMessageId"); + + migrationBuilder.CreateIndex( + name: "IX_SmsInbounds_ChannelId_SendTime", + table: "SmsInbounds", + columns: new[] { "ChannelId", "SendTime" }); + + migrationBuilder.CreateIndex( + name: "IX_SmsInbounds_Mobile_SendTime", + table: "SmsInbounds", + columns: new[] { "Mobile", "SendTime" }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_UnsubscriptionTimelines_OccurredAt_Action_UnsubscriptionId", + table: "UnsubscriptionTimelines"); + + migrationBuilder.DropIndex( + name: "IX_UnsubscriptionTimelines_UnsubscriptionId_OccurredAt", + table: "UnsubscriptionTimelines"); + + migrationBuilder.DropIndex( + name: "IX_Unsubscriptions_ChannelId_ChannelUserIdentity_ScopeType_Sco~", + table: "Unsubscriptions"); + + migrationBuilder.DropIndex( + name: "IX_Unsubscriptions_ChannelId_ChannelUserIdentity_Status_Unsubs~", + table: "Unsubscriptions"); + + migrationBuilder.DropIndex( + name: "IX_Unsubscriptions_ChannelType_ChannelProvider_UnsubscribedAt", + table: "Unsubscriptions"); + + migrationBuilder.DropIndex( + name: "IX_Unsubscriptions_ChannelUserIdentity_Status_ScopeType", + table: "Unsubscriptions"); + + migrationBuilder.DropIndex( + name: "IX_Unsubscriptions_LastInboundMessageId", + table: "Unsubscriptions"); + + migrationBuilder.DropIndex( + name: "IX_SmsInbounds_ChannelId_SendTime", + table: "SmsInbounds"); + + migrationBuilder.DropIndex( + name: "IX_SmsInbounds_Mobile_SendTime", + table: "SmsInbounds"); + + migrationBuilder.CreateIndex( + name: "IX_UnsubscriptionTimelines_OccurredAt", + table: "UnsubscriptionTimelines", + column: "OccurredAt"); + + migrationBuilder.CreateIndex( + name: "IX_UnsubscriptionTimelines_UnsubscriptionId", + table: "UnsubscriptionTimelines", + column: "UnsubscriptionId"); + + migrationBuilder.CreateIndex( + name: "IX_Unsubscriptions_ChannelId", + table: "Unsubscriptions", + column: "ChannelId"); + + migrationBuilder.CreateIndex( + name: "IX_Unsubscriptions_ChannelId_ChannelUserIdentity_ScopeType_Sco~", + table: "Unsubscriptions", + columns: new[] { "ChannelId", "ChannelUserIdentity", "ScopeType", "ScopeRefId", "Status" }); + + migrationBuilder.CreateIndex( + name: "IX_Unsubscriptions_ChannelType", + table: "Unsubscriptions", + column: "ChannelType"); + + migrationBuilder.CreateIndex( + name: "IX_Unsubscriptions_Status", + table: "Unsubscriptions", + column: "Status"); + + migrationBuilder.CreateIndex( + name: "IX_SmsInbounds_ChannelId", + table: "SmsInbounds", + column: "ChannelId"); + + migrationBuilder.CreateIndex( + name: "IX_SmsInbounds_Mobile", + table: "SmsInbounds", + column: "Mobile"); + } + } +} diff --git a/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629092014_RefactorUnsubscribeAutoReplyTemplateToGuid.Designer.cs b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629092014_RefactorUnsubscribeAutoReplyTemplateToGuid.Designer.cs new file mode 100644 index 00000000..f0ed2a59 --- /dev/null +++ b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629092014_RefactorUnsubscribeAutoReplyTemplateToGuid.Designer.cs @@ -0,0 +1,1454 @@ +// +using System; +using Masa.Mc.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Masa.Mc.EntityFrameworkCore.PostgreSql.Migrations +{ + [DbContext(typeof(McDbContext))] + [Migration("20260629092014_RefactorUnsubscribeAutoReplyTemplateToGuid")] + partial class RefactorUnsubscribeAutoReplyTemplateToGuid + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Masa.BuildingBlocks.Dispatcher.IntegrationEvents.Logs.IntegrationEventLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Content") + .IsRequired() + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("EventId") + .HasColumnType("uuid"); + + b.Property("EventTypeName") + .IsRequired() + .HasColumnType("text"); + + b.Property("ExpandContent") + .IsRequired() + .HasColumnType("text"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("RowVersion") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(36) + .HasColumnType("character varying(36)") + .HasColumnName("RowVersion"); + + b.Property("State") + .HasColumnType("integer"); + + b.Property("TimesSent") + .HasColumnType("integer"); + + b.Property("TransactionId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex(new[] { "EventId", "RowVersion" }, "IX_EventId_Version"); + + b.HasIndex(new[] { "State", "ModificationTime" }, "IX_State_MTime"); + + b.HasIndex(new[] { "State", "TimesSent", "ModificationTime" }, "IX_State_TimesSent_MTime"); + + b.ToTable("IntegrationEventLog", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Apps.Aggregates.AppDeviceToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("DeviceToken") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Platform") + .HasColumnType("integer"); + + b.Property("RegisteredTime") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId", "UserId", "Platform"); + + b.ToTable("AppDeviceTokens", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Apps.Aggregates.AppVendorConfig", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Options") + .IsRequired() + .HasColumnType("text"); + + b.Property("Vendor") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId", "Vendor"); + + b.ToTable("AppVendorConfigs", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Channels.Aggregates.AppChannel", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(64) + .HasColumnType("character varying(64)") + .HasColumnName("Code"); + + b.Property("Color") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Color"); + + b.Property("DisplayName") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("DisplayName"); + + b.Property("Provider") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("Provider"); + + b.Property("Scheme") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Scheme"); + + b.Property("SchemeField") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("SchemeField"); + + b.Property("Type") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("Type"); + + b.HasKey("Id"); + + b.ToTable("Channels", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Channels.Aggregates.Channel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(64) + .HasColumnType("character varying(64)") + .HasColumnName("Code"); + + b.Property("Color") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Color"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("DisplayName") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("DisplayName"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsStatic") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Provider") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("Provider"); + + b.Property("Scheme") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Scheme"); + + b.Property("SchemeField") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("SchemeField"); + + b.Property("Type") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("Type"); + + b.HasKey("Id"); + + b.HasIndex("Code"); + + b.HasIndex("Type"); + + b.ToTable("Channels", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageInfos.Aggregates.MessageInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("MessageInfos", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageReceipts.Aggregates.SmsInbound", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AddSerial") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Provider") + .HasColumnType("integer"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("SmsContent") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.HasKey("Id"); + + b.HasIndex("Provider"); + + b.HasIndex("SendTime"); + + b.HasIndex("ChannelId", "SendTime"); + + b.HasIndex("Mobile", "SendTime"); + + b.ToTable("SmsInbounds", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageRecords.Aggregates.MessageRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("ChannelUserIdentity") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ExpectSendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("FailureReason") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("MessageEntityId") + .HasColumnType("uuid"); + + b.Property("MessageEntityType") + .HasColumnType("integer"); + + b.Property("MessageId") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("MessageTaskHistoryId") + .HasColumnType("uuid"); + + b.Property("MessageTaskId") + .HasColumnType("uuid"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Success") + .HasColumnType("boolean"); + + b.Property("SystemId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("Variables") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("MessageId"); + + b.HasIndex("MessageTaskHistoryId"); + + b.HasIndex("UserId"); + + b.ToTable("MessageRecords", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageReceiverUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelUserIdentity") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("MessageTaskHistoryId") + .HasColumnType("uuid"); + + b.Property("Platform") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("Variables") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("MessageTaskHistoryId", "ChannelUserIdentity", "Platform"); + + b.ToTable("MessageReceiverUsers", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("ChannelType") + .HasColumnType("integer"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("EntityId") + .HasColumnType("uuid"); + + b.Property("EntityType") + .HasColumnType("integer"); + + b.Property("ExpectSendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsDraft") + .HasColumnType("boolean"); + + b.Property("IsEnabled") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("ReceiverType") + .HasColumnType("integer"); + + b.Property("Receivers") + .IsRequired() + .HasColumnType("text"); + + b.Property("SchedulerJobId") + .HasColumnType("uuid"); + + b.Property("SelectReceiverType") + .HasColumnType("integer"); + + b.Property("SendRules") + .IsRequired() + .HasColumnType("text"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Sign") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Source") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("SystemId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Variables") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("Source"); + + b.ToTable("MessageTasks", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CompletionTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsTest") + .HasColumnType("boolean"); + + b.Property("MessageTaskId") + .HasColumnType("uuid"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("SchedulerTaskId") + .HasColumnType("uuid"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("TaskHistoryNo") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("WithdrawTime") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("MessageTaskId"); + + b.ToTable("MessageTaskHistorys", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AuditReason") + .IsRequired() + .HasColumnType("text"); + + b.Property("AuditStatus") + .HasColumnType("integer"); + + b.Property("AuditTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Example") + .IsRequired() + .HasColumnType("text"); + + b.Property("InvalidTime") + .HasColumnType("timestamp with time zone"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsStatic") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Options") + .IsRequired() + .HasColumnType("text"); + + b.Property("PerDayLimit") + .HasColumnType("bigint"); + + b.Property("Sign") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("TemplateId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("TemplateType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("Code"); + + b.ToTable("MessageTemplates", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplateItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("DisplayText") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("MappingCode") + .IsRequired() + .HasColumnType("text"); + + b.Property("MessageTemplateId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("MessageTemplateId"); + + b.HasIndex("Code", "MessageTemplateId"); + + b.ToTable("MessageTemplateItems", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.SmsTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AuditReason") + .IsRequired() + .HasColumnType("text"); + + b.Property("AuditStatus") + .HasColumnType("integer"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("TemplateCode") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("TemplateContent") + .IsRequired() + .HasColumnType("text"); + + b.Property("TemplateName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("TemplateType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.ToTable("SmsTemplates", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.ReceiverGroups.Aggregates.ReceiverGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.ToTable("ReceiverGroups", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.Unsubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("ChannelProvider") + .HasColumnType("integer"); + + b.Property("ChannelType") + .HasColumnType("integer"); + + b.Property("ChannelUserIdentity") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Keyword") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("LastInboundMessageId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Reason") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("ResubscribedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ScopeRefId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("ScopeType") + .HasColumnType("integer"); + + b.Property("Source") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("UnsubscribedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("LastInboundMessageId"); + + b.HasIndex("UserId"); + + b.HasIndex("ChannelType", "ChannelProvider", "UnsubscribedAt"); + + b.HasIndex("ChannelUserIdentity", "Status", "ScopeType"); + + b.HasIndex("ChannelId", "ChannelUserIdentity", "Status", "UnsubscribedAt"); + + b.HasIndex("ChannelId", "ChannelUserIdentity", "ScopeType", "ScopeRefId", "Status", "UnsubscribedAt"); + + b.ToTable("Unsubscriptions", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.UnsubscriptionTimeline", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Action") + .HasColumnType("integer"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("Detail") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("OccurredAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UnsubscriptionId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UnsubscriptionId", "OccurredAt"); + + b.HasIndex("OccurredAt", "Action", "UnsubscriptionId"); + + b.ToTable("UnsubscriptionTimelines", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("Content") + .IsRequired() + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsRead") + .HasColumnType("boolean"); + + b.Property("IsWithdrawn") + .HasColumnType("boolean"); + + b.Property("LinkUrl") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("MessageTaskHistoryId") + .HasColumnType("uuid"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("ReadTime") + .HasColumnType("timestamp with time zone"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("UserId", "ChannelId"); + + b.ToTable("WebsiteMessages", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessageCursor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("UpdateTime") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("WebsiteMessageCursors", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Channels.Aggregates.AppChannel", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.Channel", null) + .WithOne() + .HasForeignKey("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageInfos.Aggregates.MessageInfo", b => + { + b.OwnsOne("Masa.Mc.Domain.MessageInfos.Aggregates.MessageContent", "MessageContent", b1 => + { + b1.Property("MessageInfoId") + .HasColumnType("uuid"); + + b1.Property("Content") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Content"); + + b1.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text") + .HasColumnName("ExtraProperties"); + + b1.Property("IsJump") + .HasMaxLength(128) + .HasColumnType("boolean") + .HasColumnName("IsJump"); + + b1.Property("JumpUrl") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("JumpUrl"); + + b1.Property("Markdown") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Markdown"); + + b1.Property("Title") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Title"); + + b1.HasKey("MessageInfoId"); + + b1.ToTable("MessageInfos"); + + b1.WithOwner() + .HasForeignKey("MessageInfoId"); + }); + + b.Navigation("MessageContent") + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageRecords.Aggregates.MessageRecord", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Channel") + .WithMany() + .HasForeignKey("ChannelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Channel"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageReceiverUser", b => + { + b.HasOne("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", null) + .WithMany("ReceiverUsers") + .HasForeignKey("MessageTaskHistoryId"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTask", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Channel") + .WithMany() + .HasForeignKey("ChannelId"); + + b.Navigation("Channel"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", b => + { + b.HasOne("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTask", "MessageTask") + .WithMany() + .HasForeignKey("MessageTaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MessageTask"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", b => + { + b.OwnsOne("Masa.Mc.Domain.MessageInfos.Aggregates.MessageContent", "MessageContent", b1 => + { + b1.Property("MessageTemplateId") + .HasColumnType("uuid"); + + b1.Property("Content") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Content"); + + b1.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text") + .HasColumnName("ExtraProperties"); + + b1.Property("IsJump") + .HasMaxLength(128) + .HasColumnType("boolean") + .HasColumnName("IsJump"); + + b1.Property("JumpUrl") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("JumpUrl"); + + b1.Property("Markdown") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Markdown"); + + b1.Property("Title") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Title"); + + b1.HasKey("MessageTemplateId"); + + b1.ToTable("MessageTemplates"); + + b1.WithOwner() + .HasForeignKey("MessageTemplateId"); + }); + + b.OwnsOne("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplateUnsubscribeConfig", "UnsubscribeConfig", b1 => + { + b1.Property("MessageTemplateId") + .HasColumnType("uuid"); + + b1.Property("CooldownSeconds") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValue(0) + .HasColumnName("CooldownSeconds"); + + b1.Property("DebounceEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasColumnName("DebounceEnabled"); + + b1.Property("Enabled") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasColumnName("Enabled"); + + b1.Property("ResubscribeAutoReplyTemplateId") + .HasColumnType("uuid") + .HasColumnName("ResubscribeAutoReplyTemplateId"); + + b1.Property("ResubscribeKeyword") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(20) + .HasColumnType("character varying(20)") + .HasDefaultValue("") + .HasColumnName("ResubscribeKeyword"); + + b1.Property("UnsubscribeAutoReplyTemplateId") + .HasColumnType("uuid") + .HasColumnName("UnsubscribeAutoReplyTemplateId"); + + b1.Property("UnsubscribeKeyword") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(20) + .HasColumnType("character varying(20)") + .HasDefaultValue("") + .HasColumnName("UnsubscribeKeyword"); + + b1.HasKey("MessageTemplateId"); + + b1.ToTable("MessageTemplateUnsubscribeConfigs", (string)null); + + b1.WithOwner() + .HasForeignKey("MessageTemplateId"); + }); + + b.Navigation("MessageContent") + .IsRequired(); + + b.Navigation("UnsubscribeConfig"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplateItem", b => + { + b.HasOne("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", null) + .WithMany("Items") + .HasForeignKey("MessageTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.ReceiverGroups.Aggregates.ReceiverGroup", b => + { + b.OwnsMany("Masa.Mc.Domain.ReceiverGroups.Aggregates.ReceiverGroupItem", "Items", b1 => + { + b1.Property("GroupId") + .HasColumnType("uuid"); + + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b1.Property("Avatar") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b1.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b1.Property("SubjectId") + .HasColumnType("uuid"); + + b1.Property("Type") + .HasColumnType("integer"); + + b1.HasKey("GroupId", "Id"); + + b1.ToTable("ReceiverGroupItems", (string)null); + + b1.WithOwner() + .HasForeignKey("GroupId"); + }); + + b.Navigation("Items"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.UnsubscriptionTimeline", b => + { + b.HasOne("Masa.Mc.Domain.Unsubscriptions.Aggregates.Unsubscription", null) + .WithMany("Timelines") + .HasForeignKey("UnsubscriptionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessage", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Channel") + .WithMany() + .HasForeignKey("ChannelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsMany("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessageTag", "Tags", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b1.Property("ChannelId") + .HasColumnType("uuid"); + + b1.Property("CreationTime") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone"); + + b1.Property("Tag") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Tag"); + + b1.Property("UserId") + .HasColumnType("uuid"); + + b1.Property("WebsiteMessageId") + .HasColumnType("uuid"); + + b1.HasKey("Id"); + + b1.HasIndex("ChannelId"); + + b1.HasIndex("Tag"); + + b1.HasIndex("UserId"); + + b1.HasIndex("WebsiteMessageId"); + + b1.ToTable("WebsiteMessageTags", (string)null); + + b1.WithOwner() + .HasForeignKey("WebsiteMessageId"); + }); + + b.Navigation("Channel"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", b => + { + b.Navigation("ReceiverUsers"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.Unsubscription", b => + { + b.Navigation("Timelines"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629092014_RefactorUnsubscribeAutoReplyTemplateToGuid.cs b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629092014_RefactorUnsubscribeAutoReplyTemplateToGuid.cs new file mode 100644 index 00000000..bcacc28b --- /dev/null +++ b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629092014_RefactorUnsubscribeAutoReplyTemplateToGuid.cs @@ -0,0 +1,60 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Masa.Mc.EntityFrameworkCore.PostgreSql.Migrations +{ + public partial class RefactorUnsubscribeAutoReplyTemplateToGuid : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "ResubscribeAutoReply", + table: "MessageTemplateUnsubscribeConfigs"); + + migrationBuilder.DropColumn( + name: "UnsubscribeAutoReply", + table: "MessageTemplateUnsubscribeConfigs"); + + migrationBuilder.AddColumn( + name: "ResubscribeAutoReplyTemplateId", + table: "MessageTemplateUnsubscribeConfigs", + type: "uuid", + nullable: true); + + migrationBuilder.AddColumn( + name: "UnsubscribeAutoReplyTemplateId", + table: "MessageTemplateUnsubscribeConfigs", + type: "uuid", + nullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "ResubscribeAutoReplyTemplateId", + table: "MessageTemplateUnsubscribeConfigs"); + + migrationBuilder.DropColumn( + name: "UnsubscribeAutoReplyTemplateId", + table: "MessageTemplateUnsubscribeConfigs"); + + migrationBuilder.AddColumn( + name: "ResubscribeAutoReply", + table: "MessageTemplateUnsubscribeConfigs", + type: "character varying(500)", + maxLength: 500, + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "UnsubscribeAutoReply", + table: "MessageTemplateUnsubscribeConfigs", + type: "character varying(500)", + maxLength: 500, + nullable: false, + defaultValue: ""); + } + } +} diff --git a/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629092250_RemoveUnsubscribeDebounceFields.Designer.cs b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629092250_RemoveUnsubscribeDebounceFields.Designer.cs new file mode 100644 index 00000000..4d379565 --- /dev/null +++ b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629092250_RemoveUnsubscribeDebounceFields.Designer.cs @@ -0,0 +1,1442 @@ +// +using System; +using Masa.Mc.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Masa.Mc.EntityFrameworkCore.PostgreSql.Migrations +{ + [DbContext(typeof(McDbContext))] + [Migration("20260629092250_RemoveUnsubscribeDebounceFields")] + partial class RemoveUnsubscribeDebounceFields + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Masa.BuildingBlocks.Dispatcher.IntegrationEvents.Logs.IntegrationEventLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Content") + .IsRequired() + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("EventId") + .HasColumnType("uuid"); + + b.Property("EventTypeName") + .IsRequired() + .HasColumnType("text"); + + b.Property("ExpandContent") + .IsRequired() + .HasColumnType("text"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("RowVersion") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(36) + .HasColumnType("character varying(36)") + .HasColumnName("RowVersion"); + + b.Property("State") + .HasColumnType("integer"); + + b.Property("TimesSent") + .HasColumnType("integer"); + + b.Property("TransactionId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex(new[] { "EventId", "RowVersion" }, "IX_EventId_Version"); + + b.HasIndex(new[] { "State", "ModificationTime" }, "IX_State_MTime"); + + b.HasIndex(new[] { "State", "TimesSent", "ModificationTime" }, "IX_State_TimesSent_MTime"); + + b.ToTable("IntegrationEventLog", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Apps.Aggregates.AppDeviceToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("DeviceToken") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Platform") + .HasColumnType("integer"); + + b.Property("RegisteredTime") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId", "UserId", "Platform"); + + b.ToTable("AppDeviceTokens", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Apps.Aggregates.AppVendorConfig", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Options") + .IsRequired() + .HasColumnType("text"); + + b.Property("Vendor") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId", "Vendor"); + + b.ToTable("AppVendorConfigs", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Channels.Aggregates.AppChannel", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(64) + .HasColumnType("character varying(64)") + .HasColumnName("Code"); + + b.Property("Color") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Color"); + + b.Property("DisplayName") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("DisplayName"); + + b.Property("Provider") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("Provider"); + + b.Property("Scheme") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Scheme"); + + b.Property("SchemeField") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("SchemeField"); + + b.Property("Type") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("Type"); + + b.HasKey("Id"); + + b.ToTable("Channels", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Channels.Aggregates.Channel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(64) + .HasColumnType("character varying(64)") + .HasColumnName("Code"); + + b.Property("Color") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Color"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("DisplayName") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("DisplayName"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsStatic") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Provider") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("Provider"); + + b.Property("Scheme") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Scheme"); + + b.Property("SchemeField") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("SchemeField"); + + b.Property("Type") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("Type"); + + b.HasKey("Id"); + + b.HasIndex("Code"); + + b.HasIndex("Type"); + + b.ToTable("Channels", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageInfos.Aggregates.MessageInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("MessageInfos", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageReceipts.Aggregates.SmsInbound", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AddSerial") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Provider") + .HasColumnType("integer"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("SmsContent") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.HasKey("Id"); + + b.HasIndex("Provider"); + + b.HasIndex("SendTime"); + + b.HasIndex("ChannelId", "SendTime"); + + b.HasIndex("Mobile", "SendTime"); + + b.ToTable("SmsInbounds", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageRecords.Aggregates.MessageRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("ChannelUserIdentity") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ExpectSendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("FailureReason") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("MessageEntityId") + .HasColumnType("uuid"); + + b.Property("MessageEntityType") + .HasColumnType("integer"); + + b.Property("MessageId") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("MessageTaskHistoryId") + .HasColumnType("uuid"); + + b.Property("MessageTaskId") + .HasColumnType("uuid"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Success") + .HasColumnType("boolean"); + + b.Property("SystemId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("Variables") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("MessageId"); + + b.HasIndex("MessageTaskHistoryId"); + + b.HasIndex("UserId"); + + b.ToTable("MessageRecords", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageReceiverUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelUserIdentity") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("MessageTaskHistoryId") + .HasColumnType("uuid"); + + b.Property("Platform") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("Variables") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("MessageTaskHistoryId", "ChannelUserIdentity", "Platform"); + + b.ToTable("MessageReceiverUsers", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("ChannelType") + .HasColumnType("integer"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("EntityId") + .HasColumnType("uuid"); + + b.Property("EntityType") + .HasColumnType("integer"); + + b.Property("ExpectSendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsDraft") + .HasColumnType("boolean"); + + b.Property("IsEnabled") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("ReceiverType") + .HasColumnType("integer"); + + b.Property("Receivers") + .IsRequired() + .HasColumnType("text"); + + b.Property("SchedulerJobId") + .HasColumnType("uuid"); + + b.Property("SelectReceiverType") + .HasColumnType("integer"); + + b.Property("SendRules") + .IsRequired() + .HasColumnType("text"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Sign") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Source") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("SystemId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Variables") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("Source"); + + b.ToTable("MessageTasks", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CompletionTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsTest") + .HasColumnType("boolean"); + + b.Property("MessageTaskId") + .HasColumnType("uuid"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("SchedulerTaskId") + .HasColumnType("uuid"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("TaskHistoryNo") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("WithdrawTime") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("MessageTaskId"); + + b.ToTable("MessageTaskHistorys", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AuditReason") + .IsRequired() + .HasColumnType("text"); + + b.Property("AuditStatus") + .HasColumnType("integer"); + + b.Property("AuditTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Example") + .IsRequired() + .HasColumnType("text"); + + b.Property("InvalidTime") + .HasColumnType("timestamp with time zone"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsStatic") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Options") + .IsRequired() + .HasColumnType("text"); + + b.Property("PerDayLimit") + .HasColumnType("bigint"); + + b.Property("Sign") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("TemplateId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("TemplateType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("Code"); + + b.ToTable("MessageTemplates", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplateItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("DisplayText") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("MappingCode") + .IsRequired() + .HasColumnType("text"); + + b.Property("MessageTemplateId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("MessageTemplateId"); + + b.HasIndex("Code", "MessageTemplateId"); + + b.ToTable("MessageTemplateItems", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.SmsTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AuditReason") + .IsRequired() + .HasColumnType("text"); + + b.Property("AuditStatus") + .HasColumnType("integer"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("TemplateCode") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("TemplateContent") + .IsRequired() + .HasColumnType("text"); + + b.Property("TemplateName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("TemplateType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.ToTable("SmsTemplates", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.ReceiverGroups.Aggregates.ReceiverGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.ToTable("ReceiverGroups", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.Unsubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("ChannelProvider") + .HasColumnType("integer"); + + b.Property("ChannelType") + .HasColumnType("integer"); + + b.Property("ChannelUserIdentity") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Keyword") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("LastInboundMessageId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Reason") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("ResubscribedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ScopeRefId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("ScopeType") + .HasColumnType("integer"); + + b.Property("Source") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("UnsubscribedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("LastInboundMessageId"); + + b.HasIndex("UserId"); + + b.HasIndex("ChannelType", "ChannelProvider", "UnsubscribedAt"); + + b.HasIndex("ChannelUserIdentity", "Status", "ScopeType"); + + b.HasIndex("ChannelId", "ChannelUserIdentity", "Status", "UnsubscribedAt"); + + b.HasIndex("ChannelId", "ChannelUserIdentity", "ScopeType", "ScopeRefId", "Status", "UnsubscribedAt"); + + b.ToTable("Unsubscriptions", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.UnsubscriptionTimeline", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Action") + .HasColumnType("integer"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("Detail") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("OccurredAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UnsubscriptionId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UnsubscriptionId", "OccurredAt"); + + b.HasIndex("OccurredAt", "Action", "UnsubscriptionId"); + + b.ToTable("UnsubscriptionTimelines", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("Content") + .IsRequired() + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsRead") + .HasColumnType("boolean"); + + b.Property("IsWithdrawn") + .HasColumnType("boolean"); + + b.Property("LinkUrl") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("MessageTaskHistoryId") + .HasColumnType("uuid"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("ReadTime") + .HasColumnType("timestamp with time zone"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("UserId", "ChannelId"); + + b.ToTable("WebsiteMessages", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessageCursor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("UpdateTime") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("WebsiteMessageCursors", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Channels.Aggregates.AppChannel", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.Channel", null) + .WithOne() + .HasForeignKey("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageInfos.Aggregates.MessageInfo", b => + { + b.OwnsOne("Masa.Mc.Domain.MessageInfos.Aggregates.MessageContent", "MessageContent", b1 => + { + b1.Property("MessageInfoId") + .HasColumnType("uuid"); + + b1.Property("Content") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Content"); + + b1.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text") + .HasColumnName("ExtraProperties"); + + b1.Property("IsJump") + .HasMaxLength(128) + .HasColumnType("boolean") + .HasColumnName("IsJump"); + + b1.Property("JumpUrl") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("JumpUrl"); + + b1.Property("Markdown") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Markdown"); + + b1.Property("Title") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Title"); + + b1.HasKey("MessageInfoId"); + + b1.ToTable("MessageInfos"); + + b1.WithOwner() + .HasForeignKey("MessageInfoId"); + }); + + b.Navigation("MessageContent") + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageRecords.Aggregates.MessageRecord", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Channel") + .WithMany() + .HasForeignKey("ChannelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Channel"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageReceiverUser", b => + { + b.HasOne("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", null) + .WithMany("ReceiverUsers") + .HasForeignKey("MessageTaskHistoryId"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTask", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Channel") + .WithMany() + .HasForeignKey("ChannelId"); + + b.Navigation("Channel"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", b => + { + b.HasOne("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTask", "MessageTask") + .WithMany() + .HasForeignKey("MessageTaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MessageTask"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", b => + { + b.OwnsOne("Masa.Mc.Domain.MessageInfos.Aggregates.MessageContent", "MessageContent", b1 => + { + b1.Property("MessageTemplateId") + .HasColumnType("uuid"); + + b1.Property("Content") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Content"); + + b1.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text") + .HasColumnName("ExtraProperties"); + + b1.Property("IsJump") + .HasMaxLength(128) + .HasColumnType("boolean") + .HasColumnName("IsJump"); + + b1.Property("JumpUrl") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("JumpUrl"); + + b1.Property("Markdown") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Markdown"); + + b1.Property("Title") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Title"); + + b1.HasKey("MessageTemplateId"); + + b1.ToTable("MessageTemplates"); + + b1.WithOwner() + .HasForeignKey("MessageTemplateId"); + }); + + b.OwnsOne("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplateUnsubscribeConfig", "UnsubscribeConfig", b1 => + { + b1.Property("MessageTemplateId") + .HasColumnType("uuid"); + + b1.Property("Enabled") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasColumnName("Enabled"); + + b1.Property("ResubscribeAutoReplyTemplateId") + .HasColumnType("uuid") + .HasColumnName("ResubscribeAutoReplyTemplateId"); + + b1.Property("ResubscribeKeyword") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(20) + .HasColumnType("character varying(20)") + .HasDefaultValue("") + .HasColumnName("ResubscribeKeyword"); + + b1.Property("UnsubscribeAutoReplyTemplateId") + .HasColumnType("uuid") + .HasColumnName("UnsubscribeAutoReplyTemplateId"); + + b1.Property("UnsubscribeKeyword") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(20) + .HasColumnType("character varying(20)") + .HasDefaultValue("") + .HasColumnName("UnsubscribeKeyword"); + + b1.HasKey("MessageTemplateId"); + + b1.ToTable("MessageTemplateUnsubscribeConfigs", (string)null); + + b1.WithOwner() + .HasForeignKey("MessageTemplateId"); + }); + + b.Navigation("MessageContent") + .IsRequired(); + + b.Navigation("UnsubscribeConfig"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplateItem", b => + { + b.HasOne("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", null) + .WithMany("Items") + .HasForeignKey("MessageTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.ReceiverGroups.Aggregates.ReceiverGroup", b => + { + b.OwnsMany("Masa.Mc.Domain.ReceiverGroups.Aggregates.ReceiverGroupItem", "Items", b1 => + { + b1.Property("GroupId") + .HasColumnType("uuid"); + + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b1.Property("Avatar") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b1.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b1.Property("SubjectId") + .HasColumnType("uuid"); + + b1.Property("Type") + .HasColumnType("integer"); + + b1.HasKey("GroupId", "Id"); + + b1.ToTable("ReceiverGroupItems", (string)null); + + b1.WithOwner() + .HasForeignKey("GroupId"); + }); + + b.Navigation("Items"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.UnsubscriptionTimeline", b => + { + b.HasOne("Masa.Mc.Domain.Unsubscriptions.Aggregates.Unsubscription", null) + .WithMany("Timelines") + .HasForeignKey("UnsubscriptionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessage", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Channel") + .WithMany() + .HasForeignKey("ChannelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsMany("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessageTag", "Tags", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b1.Property("ChannelId") + .HasColumnType("uuid"); + + b1.Property("CreationTime") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone"); + + b1.Property("Tag") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Tag"); + + b1.Property("UserId") + .HasColumnType("uuid"); + + b1.Property("WebsiteMessageId") + .HasColumnType("uuid"); + + b1.HasKey("Id"); + + b1.HasIndex("ChannelId"); + + b1.HasIndex("Tag"); + + b1.HasIndex("UserId"); + + b1.HasIndex("WebsiteMessageId"); + + b1.ToTable("WebsiteMessageTags", (string)null); + + b1.WithOwner() + .HasForeignKey("WebsiteMessageId"); + }); + + b.Navigation("Channel"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", b => + { + b.Navigation("ReceiverUsers"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.Unsubscription", b => + { + b.Navigation("Timelines"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629092250_RemoveUnsubscribeDebounceFields.cs b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629092250_RemoveUnsubscribeDebounceFields.cs new file mode 100644 index 00000000..44b8abbb --- /dev/null +++ b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629092250_RemoveUnsubscribeDebounceFields.cs @@ -0,0 +1,37 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Masa.Mc.EntityFrameworkCore.PostgreSql.Migrations +{ + public partial class RemoveUnsubscribeDebounceFields : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "CooldownSeconds", + table: "MessageTemplateUnsubscribeConfigs"); + + migrationBuilder.DropColumn( + name: "DebounceEnabled", + table: "MessageTemplateUnsubscribeConfigs"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "CooldownSeconds", + table: "MessageTemplateUnsubscribeConfigs", + type: "integer", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "DebounceEnabled", + table: "MessageTemplateUnsubscribeConfigs", + type: "boolean", + nullable: false, + defaultValue: false); + } + } +} diff --git a/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629093124_MakeUnsubscribeAutoReplyTemplateRequired.Designer.cs b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629093124_MakeUnsubscribeAutoReplyTemplateRequired.Designer.cs new file mode 100644 index 00000000..7ee0cff3 --- /dev/null +++ b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629093124_MakeUnsubscribeAutoReplyTemplateRequired.Designer.cs @@ -0,0 +1,1442 @@ +// +using System; +using Masa.Mc.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Masa.Mc.EntityFrameworkCore.PostgreSql.Migrations +{ + [DbContext(typeof(McDbContext))] + [Migration("20260629093124_MakeUnsubscribeAutoReplyTemplateRequired")] + partial class MakeUnsubscribeAutoReplyTemplateRequired + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Masa.BuildingBlocks.Dispatcher.IntegrationEvents.Logs.IntegrationEventLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Content") + .IsRequired() + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("EventId") + .HasColumnType("uuid"); + + b.Property("EventTypeName") + .IsRequired() + .HasColumnType("text"); + + b.Property("ExpandContent") + .IsRequired() + .HasColumnType("text"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("RowVersion") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(36) + .HasColumnType("character varying(36)") + .HasColumnName("RowVersion"); + + b.Property("State") + .HasColumnType("integer"); + + b.Property("TimesSent") + .HasColumnType("integer"); + + b.Property("TransactionId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex(new[] { "EventId", "RowVersion" }, "IX_EventId_Version"); + + b.HasIndex(new[] { "State", "ModificationTime" }, "IX_State_MTime"); + + b.HasIndex(new[] { "State", "TimesSent", "ModificationTime" }, "IX_State_TimesSent_MTime"); + + b.ToTable("IntegrationEventLog", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Apps.Aggregates.AppDeviceToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("DeviceToken") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Platform") + .HasColumnType("integer"); + + b.Property("RegisteredTime") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId", "UserId", "Platform"); + + b.ToTable("AppDeviceTokens", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Apps.Aggregates.AppVendorConfig", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Options") + .IsRequired() + .HasColumnType("text"); + + b.Property("Vendor") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId", "Vendor"); + + b.ToTable("AppVendorConfigs", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Channels.Aggregates.AppChannel", b => + { + b.Property("Id") + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(64) + .HasColumnType("character varying(64)") + .HasColumnName("Code"); + + b.Property("Color") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Color"); + + b.Property("DisplayName") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("DisplayName"); + + b.Property("Provider") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("Provider"); + + b.Property("Scheme") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Scheme"); + + b.Property("SchemeField") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("SchemeField"); + + b.Property("Type") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("Type"); + + b.HasKey("Id"); + + b.ToTable("Channels", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Channels.Aggregates.Channel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(64) + .HasColumnType("character varying(64)") + .HasColumnName("Code"); + + b.Property("Color") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Color"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("DisplayName") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("DisplayName"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsStatic") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Provider") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("Provider"); + + b.Property("Scheme") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Scheme"); + + b.Property("SchemeField") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("SchemeField"); + + b.Property("Type") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("integer") + .HasColumnName("Type"); + + b.HasKey("Id"); + + b.HasIndex("Code"); + + b.HasIndex("Type"); + + b.ToTable("Channels", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageInfos.Aggregates.MessageInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("MessageInfos", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageReceipts.Aggregates.SmsInbound", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AddSerial") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Provider") + .HasColumnType("integer"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("SmsContent") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.HasKey("Id"); + + b.HasIndex("Provider"); + + b.HasIndex("SendTime"); + + b.HasIndex("ChannelId", "SendTime"); + + b.HasIndex("Mobile", "SendTime"); + + b.ToTable("SmsInbounds", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageRecords.Aggregates.MessageRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("ChannelUserIdentity") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ExpectSendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("FailureReason") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("MessageEntityId") + .HasColumnType("uuid"); + + b.Property("MessageEntityType") + .HasColumnType("integer"); + + b.Property("MessageId") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("MessageTaskHistoryId") + .HasColumnType("uuid"); + + b.Property("MessageTaskId") + .HasColumnType("uuid"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Success") + .HasColumnType("boolean"); + + b.Property("SystemId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("Variables") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("MessageId"); + + b.HasIndex("MessageTaskHistoryId"); + + b.HasIndex("UserId"); + + b.ToTable("MessageRecords", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageReceiverUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelUserIdentity") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("MessageTaskHistoryId") + .HasColumnType("uuid"); + + b.Property("Platform") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.Property("Variables") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("MessageTaskHistoryId", "ChannelUserIdentity", "Platform"); + + b.ToTable("MessageReceiverUsers", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("ChannelType") + .HasColumnType("integer"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("EntityId") + .HasColumnType("uuid"); + + b.Property("EntityType") + .HasColumnType("integer"); + + b.Property("ExpectSendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsDraft") + .HasColumnType("boolean"); + + b.Property("IsEnabled") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("ReceiverType") + .HasColumnType("integer"); + + b.Property("Receivers") + .IsRequired() + .HasColumnType("text"); + + b.Property("SchedulerJobId") + .HasColumnType("uuid"); + + b.Property("SelectReceiverType") + .HasColumnType("integer"); + + b.Property("SendRules") + .IsRequired() + .HasColumnType("text"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Sign") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Source") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("SystemId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Variables") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("Source"); + + b.ToTable("MessageTasks", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CompletionTime") + .HasColumnType("timestamp with time zone"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsTest") + .HasColumnType("boolean"); + + b.Property("MessageTaskId") + .HasColumnType("uuid"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("SchedulerTaskId") + .HasColumnType("uuid"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("TaskHistoryNo") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("WithdrawTime") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("MessageTaskId"); + + b.ToTable("MessageTaskHistorys", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AuditReason") + .IsRequired() + .HasColumnType("text"); + + b.Property("AuditStatus") + .HasColumnType("integer"); + + b.Property("AuditTime") + .HasColumnType("timestamp with time zone"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Example") + .IsRequired() + .HasColumnType("text"); + + b.Property("InvalidTime") + .HasColumnType("timestamp with time zone"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsStatic") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Options") + .IsRequired() + .HasColumnType("text"); + + b.Property("PerDayLimit") + .HasColumnType("bigint"); + + b.Property("Sign") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("TemplateId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("TemplateType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("Code"); + + b.ToTable("MessageTemplates", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplateItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("DisplayText") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("MappingCode") + .IsRequired() + .HasColumnType("text"); + + b.Property("MessageTemplateId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("MessageTemplateId"); + + b.HasIndex("Code", "MessageTemplateId"); + + b.ToTable("MessageTemplateItems", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.SmsTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("AuditReason") + .IsRequired() + .HasColumnType("text"); + + b.Property("AuditStatus") + .HasColumnType("integer"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("TemplateCode") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("TemplateContent") + .IsRequired() + .HasColumnType("text"); + + b.Property("TemplateName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("TemplateType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.ToTable("SmsTemplates", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.ReceiverGroups.Aggregates.ReceiverGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.ToTable("ReceiverGroups", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.Unsubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("ChannelProvider") + .HasColumnType("integer"); + + b.Property("ChannelType") + .HasColumnType("integer"); + + b.Property("ChannelUserIdentity") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("Keyword") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("LastInboundMessageId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("Reason") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("ResubscribedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ScopeRefId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("ScopeType") + .HasColumnType("integer"); + + b.Property("Source") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("UnsubscribedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("LastInboundMessageId"); + + b.HasIndex("UserId"); + + b.HasIndex("ChannelType", "ChannelProvider", "UnsubscribedAt"); + + b.HasIndex("ChannelUserIdentity", "Status", "ScopeType"); + + b.HasIndex("ChannelId", "ChannelUserIdentity", "Status", "UnsubscribedAt"); + + b.HasIndex("ChannelId", "ChannelUserIdentity", "ScopeType", "ScopeRefId", "Status", "UnsubscribedAt"); + + b.ToTable("Unsubscriptions", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.UnsubscriptionTimeline", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Action") + .HasColumnType("integer"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("Detail") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("OccurredAt") + .HasColumnType("timestamp with time zone"); + + b.Property("UnsubscriptionId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UnsubscriptionId", "OccurredAt"); + + b.HasIndex("OccurredAt", "Action", "UnsubscriptionId"); + + b.ToTable("UnsubscriptionTimelines", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("ChannelId") + .HasColumnType("uuid"); + + b.Property("Content") + .IsRequired() + .HasColumnType("text"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("IsRead") + .HasColumnType("boolean"); + + b.Property("IsWithdrawn") + .HasColumnType("boolean"); + + b.Property("LinkUrl") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("MessageTaskHistoryId") + .HasColumnType("uuid"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("ReadTime") + .HasColumnType("timestamp with time zone"); + + b.Property("SendTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("UserId", "ChannelId"); + + b.ToTable("WebsiteMessages", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessageCursor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Creator") + .HasColumnType("uuid"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("ModificationTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Modifier") + .HasColumnType("uuid"); + + b.Property("UpdateTime") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("WebsiteMessageCursors", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Channels.Aggregates.AppChannel", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.Channel", null) + .WithOne() + .HasForeignKey("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageInfos.Aggregates.MessageInfo", b => + { + b.OwnsOne("Masa.Mc.Domain.MessageInfos.Aggregates.MessageContent", "MessageContent", b1 => + { + b1.Property("MessageInfoId") + .HasColumnType("uuid"); + + b1.Property("Content") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Content"); + + b1.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text") + .HasColumnName("ExtraProperties"); + + b1.Property("IsJump") + .HasMaxLength(128) + .HasColumnType("boolean") + .HasColumnName("IsJump"); + + b1.Property("JumpUrl") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("JumpUrl"); + + b1.Property("Markdown") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Markdown"); + + b1.Property("Title") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Title"); + + b1.HasKey("MessageInfoId"); + + b1.ToTable("MessageInfos"); + + b1.WithOwner() + .HasForeignKey("MessageInfoId"); + }); + + b.Navigation("MessageContent") + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageRecords.Aggregates.MessageRecord", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Channel") + .WithMany() + .HasForeignKey("ChannelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Channel"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageReceiverUser", b => + { + b.HasOne("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", null) + .WithMany("ReceiverUsers") + .HasForeignKey("MessageTaskHistoryId"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTask", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Channel") + .WithMany() + .HasForeignKey("ChannelId"); + + b.Navigation("Channel"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", b => + { + b.HasOne("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTask", "MessageTask") + .WithMany() + .HasForeignKey("MessageTaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MessageTask"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", b => + { + b.OwnsOne("Masa.Mc.Domain.MessageInfos.Aggregates.MessageContent", "MessageContent", b1 => + { + b1.Property("MessageTemplateId") + .HasColumnType("uuid"); + + b1.Property("Content") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Content"); + + b1.Property("ExtraProperties") + .IsRequired() + .HasColumnType("text") + .HasColumnName("ExtraProperties"); + + b1.Property("IsJump") + .HasMaxLength(128) + .HasColumnType("boolean") + .HasColumnName("IsJump"); + + b1.Property("JumpUrl") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)") + .HasColumnName("JumpUrl"); + + b1.Property("Markdown") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Markdown"); + + b1.Property("Title") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Title"); + + b1.HasKey("MessageTemplateId"); + + b1.ToTable("MessageTemplates"); + + b1.WithOwner() + .HasForeignKey("MessageTemplateId"); + }); + + b.OwnsOne("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplateUnsubscribeConfig", "UnsubscribeConfig", b1 => + { + b1.Property("MessageTemplateId") + .HasColumnType("uuid"); + + b1.Property("Enabled") + .ValueGeneratedOnAdd() + .HasColumnType("boolean") + .HasDefaultValue(false) + .HasColumnName("Enabled"); + + b1.Property("ResubscribeAutoReplyTemplateId") + .HasColumnType("uuid") + .HasColumnName("ResubscribeAutoReplyTemplateId"); + + b1.Property("ResubscribeKeyword") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(20) + .HasColumnType("character varying(20)") + .HasDefaultValue("") + .HasColumnName("ResubscribeKeyword"); + + b1.Property("UnsubscribeAutoReplyTemplateId") + .HasColumnType("uuid") + .HasColumnName("UnsubscribeAutoReplyTemplateId"); + + b1.Property("UnsubscribeKeyword") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(20) + .HasColumnType("character varying(20)") + .HasDefaultValue("") + .HasColumnName("UnsubscribeKeyword"); + + b1.HasKey("MessageTemplateId"); + + b1.ToTable("MessageTemplateUnsubscribeConfigs", (string)null); + + b1.WithOwner() + .HasForeignKey("MessageTemplateId"); + }); + + b.Navigation("MessageContent") + .IsRequired(); + + b.Navigation("UnsubscribeConfig"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplateItem", b => + { + b.HasOne("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", null) + .WithMany("Items") + .HasForeignKey("MessageTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.ReceiverGroups.Aggregates.ReceiverGroup", b => + { + b.OwnsMany("Masa.Mc.Domain.ReceiverGroups.Aggregates.ReceiverGroupItem", "Items", b1 => + { + b1.Property("GroupId") + .HasColumnType("uuid"); + + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b1.Property("Avatar") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b1.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b1.Property("SubjectId") + .HasColumnType("uuid"); + + b1.Property("Type") + .HasColumnType("integer"); + + b1.HasKey("GroupId", "Id"); + + b1.ToTable("ReceiverGroupItems", (string)null); + + b1.WithOwner() + .HasForeignKey("GroupId"); + }); + + b.Navigation("Items"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.UnsubscriptionTimeline", b => + { + b.HasOne("Masa.Mc.Domain.Unsubscriptions.Aggregates.Unsubscription", null) + .WithMany("Timelines") + .HasForeignKey("UnsubscriptionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessage", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Channel") + .WithMany() + .HasForeignKey("ChannelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsMany("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessageTag", "Tags", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b1.Property("ChannelId") + .HasColumnType("uuid"); + + b1.Property("CreationTime") + .ValueGeneratedOnAdd() + .HasColumnType("timestamp with time zone"); + + b1.Property("Tag") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)") + .HasColumnName("Tag"); + + b1.Property("UserId") + .HasColumnType("uuid"); + + b1.Property("WebsiteMessageId") + .HasColumnType("uuid"); + + b1.HasKey("Id"); + + b1.HasIndex("ChannelId"); + + b1.HasIndex("Tag"); + + b1.HasIndex("UserId"); + + b1.HasIndex("WebsiteMessageId"); + + b1.ToTable("WebsiteMessageTags", (string)null); + + b1.WithOwner() + .HasForeignKey("WebsiteMessageId"); + }); + + b.Navigation("Channel"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", b => + { + b.Navigation("ReceiverUsers"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.Unsubscription", b => + { + b.Navigation("Timelines"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629093124_MakeUnsubscribeAutoReplyTemplateRequired.cs b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629093124_MakeUnsubscribeAutoReplyTemplateRequired.cs new file mode 100644 index 00000000..5396e204 --- /dev/null +++ b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/20260629093124_MakeUnsubscribeAutoReplyTemplateRequired.cs @@ -0,0 +1,52 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Masa.Mc.EntityFrameworkCore.PostgreSql.Migrations +{ + public partial class MakeUnsubscribeAutoReplyTemplateRequired : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "UnsubscribeAutoReplyTemplateId", + table: "MessageTemplateUnsubscribeConfigs", + type: "uuid", + nullable: false, + defaultValue: new Guid("00000000-0000-0000-0000-000000000000"), + oldClrType: typeof(Guid), + oldType: "uuid", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ResubscribeAutoReplyTemplateId", + table: "MessageTemplateUnsubscribeConfigs", + type: "uuid", + nullable: false, + defaultValue: new Guid("00000000-0000-0000-0000-000000000000"), + oldClrType: typeof(Guid), + oldType: "uuid", + oldNullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "UnsubscribeAutoReplyTemplateId", + table: "MessageTemplateUnsubscribeConfigs", + type: "uuid", + nullable: true, + oldClrType: typeof(Guid), + oldType: "uuid"); + + migrationBuilder.AlterColumn( + name: "ResubscribeAutoReplyTemplateId", + table: "MessageTemplateUnsubscribeConfigs", + type: "uuid", + nullable: true, + oldClrType: typeof(Guid), + oldType: "uuid"); + } + } +} diff --git a/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/McDbContextModelSnapshot.cs b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/McDbContextModelSnapshot.cs index eea00099..197a0898 100644 --- a/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/McDbContextModelSnapshot.cs +++ b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.PostgreSql/Migrations/McDbContextModelSnapshot.cs @@ -381,14 +381,14 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.HasIndex("ChannelId"); - - b.HasIndex("Mobile"); - b.HasIndex("Provider"); b.HasIndex("SendTime"); + b.HasIndex("ChannelId", "SendTime"); + + b.HasIndex("Mobile", "SendTime"); + b.ToTable("SmsInbounds", (string)null); }); @@ -957,15 +957,17 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.HasIndex("ChannelId"); + b.HasIndex("LastInboundMessageId"); - b.HasIndex("ChannelType"); + b.HasIndex("UserId"); - b.HasIndex("Status"); + b.HasIndex("ChannelType", "ChannelProvider", "UnsubscribedAt"); - b.HasIndex("UserId"); + b.HasIndex("ChannelUserIdentity", "Status", "ScopeType"); + + b.HasIndex("ChannelId", "ChannelUserIdentity", "Status", "UnsubscribedAt"); - b.HasIndex("ChannelId", "ChannelUserIdentity", "ScopeType", "ScopeRefId", "Status"); + b.HasIndex("ChannelId", "ChannelUserIdentity", "ScopeType", "ScopeRefId", "Status", "UnsubscribedAt"); b.ToTable("Unsubscriptions", (string)null); }); @@ -990,27 +992,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasMaxLength(1000) .HasColumnType("character varying(1000)"); - b.Property("Keyword") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("character varying(20)"); - - b.Property("MatchedMessageRecordId") - .HasColumnType("uuid"); - - b.Property("MatchedMessageSentAt") - .HasColumnType("timestamp with time zone"); - - b.Property("MatchedMessageSnapshot") - .IsRequired() - .HasMaxLength(2000) - .HasColumnType("character varying(2000)"); - - b.Property("MessageId") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("character varying(128)"); - b.Property("ModificationTime") .HasColumnType("timestamp with time zone"); @@ -1020,18 +1001,14 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("OccurredAt") .HasColumnType("timestamp with time zone"); - b.Property("Source") - .HasColumnType("integer"); - b.Property("UnsubscriptionId") - .HasColumnType("uuid") - .HasColumnName("UnsubscriptionId"); + .HasColumnType("uuid"); b.HasKey("Id"); - b.HasIndex("OccurredAt"); + b.HasIndex("UnsubscriptionId", "OccurredAt"); - b.HasIndex("UnsubscriptionId"); + b.HasIndex("OccurredAt", "Action", "UnsubscriptionId"); b.ToTable("UnsubscriptionTimelines", (string)null); }); @@ -1289,31 +1266,15 @@ protected override void BuildModel(ModelBuilder modelBuilder) b1.Property("MessageTemplateId") .HasColumnType("uuid"); - b1.Property("CooldownSeconds") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(0) - .HasColumnName("CooldownSeconds"); - - b1.Property("DebounceEnabled") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false) - .HasColumnName("DebounceEnabled"); - b1.Property("Enabled") .ValueGeneratedOnAdd() .HasColumnType("boolean") .HasDefaultValue(false) .HasColumnName("Enabled"); - b1.Property("ResubscribeAutoReply") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasDefaultValue("") - .HasColumnName("ResubscribeAutoReply"); + b1.Property("ResubscribeAutoReplyTemplateId") + .HasColumnType("uuid") + .HasColumnName("ResubscribeAutoReplyTemplateId"); b1.Property("ResubscribeKeyword") .IsRequired() @@ -1323,13 +1284,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasDefaultValue("") .HasColumnName("ResubscribeKeyword"); - b1.Property("UnsubscribeAutoReply") - .IsRequired() - .ValueGeneratedOnAdd() - .HasMaxLength(500) - .HasColumnType("character varying(500)") - .HasDefaultValue("") - .HasColumnName("UnsubscribeAutoReply"); + b1.Property("UnsubscribeAutoReplyTemplateId") + .HasColumnType("uuid") + .HasColumnName("UnsubscribeAutoReplyTemplateId"); b1.Property("UnsubscribeKeyword") .IsRequired() @@ -1350,8 +1307,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("MessageContent") .IsRequired(); - b.Navigation("UnsubscribeConfig") - .IsRequired(); + b.Navigation("UnsubscribeConfig"); }); modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplateItem", b => diff --git a/src/Infrastructure/Masa.Mc.EntityFrameworkCore.SqlServer/Migrations/20260627084848_SimplifyUnsubscriptionTimeline.Designer.cs b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.SqlServer/Migrations/20260627084848_SimplifyUnsubscriptionTimeline.Designer.cs new file mode 100644 index 00000000..2e8020d4 --- /dev/null +++ b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.SqlServer/Migrations/20260627084848_SimplifyUnsubscriptionTimeline.Designer.cs @@ -0,0 +1,1461 @@ +// +using System; +using Masa.Mc.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Masa.Mc.EntityFrameworkCore.SqlServer.Migrations +{ + [DbContext(typeof(McDbContext))] + [Migration("20260627084848_SimplifyUnsubscriptionTimeline")] + partial class SimplifyUnsubscriptionTimeline + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1); + + modelBuilder.Entity("Masa.BuildingBlocks.Dispatcher.IntegrationEvents.Logs.IntegrationEventLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("EventId") + .HasColumnType("uniqueidentifier"); + + b.Property("EventTypeName") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ExpandContent") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("RowVersion") + .IsConcurrencyToken() + .IsRequired() + .HasMaxLength(36) + .HasColumnType("nvarchar(36)") + .HasColumnName("RowVersion"); + + b.Property("State") + .HasColumnType("int"); + + b.Property("TimesSent") + .HasColumnType("int"); + + b.Property("TransactionId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex(new[] { "EventId", "RowVersion" }, "IX_EventId_Version"); + + b.HasIndex(new[] { "State", "ModificationTime" }, "IX_State_MTime"); + + b.HasIndex(new[] { "State", "TimesSent", "ModificationTime" }, "IX_State_TimesSent_MTime"); + + b.ToTable("IntegrationEventLog", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Apps.Aggregates.AppDeviceToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ChannelId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Creator") + .HasColumnType("uniqueidentifier"); + + b.Property("DeviceToken") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("Modifier") + .HasColumnType("uniqueidentifier"); + + b.Property("Platform") + .HasColumnType("int"); + + b.Property("RegisteredTime") + .HasColumnType("datetimeoffset"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId", "UserId", "Platform"); + + b.ToTable("AppDeviceTokens", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Apps.Aggregates.AppVendorConfig", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ChannelId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Creator") + .HasColumnType("uniqueidentifier"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("Modifier") + .HasColumnType("uniqueidentifier"); + + b.Property("Options") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Vendor") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId", "Vendor"); + + b.ToTable("AppVendorConfigs", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Channels.Aggregates.AppChannel", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Code"); + + b.Property("Color") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("Color"); + + b.Property("DisplayName") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("DisplayName"); + + b.Property("Provider") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("int") + .HasColumnName("Provider"); + + b.Property("Scheme") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("Scheme"); + + b.Property("SchemeField") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("SchemeField"); + + b.Property("Type") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("int") + .HasColumnName("Type"); + + b.HasKey("Id"); + + b.ToTable("Channels", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Channels.Aggregates.Channel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Code"); + + b.Property("Color") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("Color"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Creator") + .HasColumnType("uniqueidentifier"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("DisplayName") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("DisplayName"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsStatic") + .HasColumnType("bit"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("Modifier") + .HasColumnType("uniqueidentifier"); + + b.Property("Provider") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("int") + .HasColumnName("Provider"); + + b.Property("Scheme") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("Scheme"); + + b.Property("SchemeField") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("SchemeField"); + + b.Property("Type") + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("int") + .HasColumnName("Type"); + + b.HasKey("Id"); + + b.HasIndex("Code"); + + b.HasIndex("Type"); + + b.ToTable("Channels", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageInfos.Aggregates.MessageInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Creator") + .HasColumnType("uniqueidentifier"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("Modifier") + .HasColumnType("uniqueidentifier"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("MessageInfos", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageReceipts.Aggregates.SmsInbound", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AddSerial") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ChannelId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Creator") + .HasColumnType("uniqueidentifier"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Mobile") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("Modifier") + .HasColumnType("uniqueidentifier"); + + b.Property("Provider") + .HasColumnType("int"); + + b.Property("SendTime") + .HasColumnType("datetimeoffset"); + + b.Property("SmsContent") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("Mobile"); + + b.HasIndex("Provider"); + + b.HasIndex("SendTime"); + + b.ToTable("SmsInbounds", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageRecords.Aggregates.MessageRecord", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ChannelId") + .HasColumnType("uniqueidentifier"); + + b.Property("ChannelUserIdentity") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Creator") + .HasColumnType("uniqueidentifier"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ExpectSendTime") + .HasColumnType("datetimeoffset"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("FailureReason") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("MessageEntityId") + .HasColumnType("uniqueidentifier"); + + b.Property("MessageEntityType") + .HasColumnType("int"); + + b.Property("MessageId") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("MessageTaskHistoryId") + .HasColumnType("uniqueidentifier"); + + b.Property("MessageTaskId") + .HasColumnType("uniqueidentifier"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("Modifier") + .HasColumnType("uniqueidentifier"); + + b.Property("SendTime") + .HasColumnType("datetimeoffset"); + + b.Property("Success") + .HasColumnType("bit"); + + b.Property("SystemId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("Variables") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("MessageId"); + + b.HasIndex("MessageTaskHistoryId"); + + b.HasIndex("UserId"); + + b.ToTable("MessageRecords", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageReceiverUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ChannelUserIdentity") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("MessageTaskHistoryId") + .HasColumnType("uniqueidentifier"); + + b.Property("Platform") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("Variables") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("MessageTaskHistoryId", "ChannelUserIdentity", "Platform"); + + b.ToTable("MessageReceiverUsers", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ChannelId") + .HasColumnType("uniqueidentifier"); + + b.Property("ChannelType") + .HasColumnType("int"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Creator") + .HasColumnType("uniqueidentifier"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("EntityId") + .HasColumnType("uniqueidentifier"); + + b.Property("EntityType") + .HasColumnType("int"); + + b.Property("ExpectSendTime") + .HasColumnType("datetimeoffset"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsDraft") + .HasColumnType("bit"); + + b.Property("IsEnabled") + .HasColumnType("bit"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("Modifier") + .HasColumnType("uniqueidentifier"); + + b.Property("ReceiverType") + .HasColumnType("int"); + + b.Property("Receivers") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SchedulerJobId") + .HasColumnType("uniqueidentifier"); + + b.Property("SelectReceiverType") + .HasColumnType("int"); + + b.Property("SendRules") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("SendTime") + .HasColumnType("datetimeoffset"); + + b.Property("Sign") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Source") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("SystemId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Variables") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("Source"); + + b.ToTable("MessageTasks", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CompletionTime") + .HasColumnType("datetimeoffset"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Creator") + .HasColumnType("uniqueidentifier"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsTest") + .HasColumnType("bit"); + + b.Property("MessageTaskId") + .HasColumnType("uniqueidentifier"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("Modifier") + .HasColumnType("uniqueidentifier"); + + b.Property("SchedulerTaskId") + .HasColumnType("uniqueidentifier"); + + b.Property("SendTime") + .HasColumnType("datetimeoffset"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TaskHistoryNo") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("WithdrawTime") + .HasColumnType("datetimeoffset"); + + b.HasKey("Id"); + + b.HasIndex("MessageTaskId"); + + b.ToTable("MessageTaskHistorys", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditReason") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("AuditStatus") + .HasColumnType("int"); + + b.Property("AuditTime") + .HasColumnType("datetimeoffset"); + + b.Property("ChannelId") + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Creator") + .HasColumnType("uniqueidentifier"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Example") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("InvalidTime") + .HasColumnType("datetimeoffset"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsStatic") + .HasColumnType("bit"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("Modifier") + .HasColumnType("uniqueidentifier"); + + b.Property("Options") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PerDayLimit") + .HasColumnType("bigint"); + + b.Property("Sign") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TemplateId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("TemplateType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("Code"); + + b.ToTable("MessageTemplates", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplateItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("DisplayText") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("MappingCode") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("MessageTemplateId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("MessageTemplateId"); + + b.HasIndex("Code", "MessageTemplateId"); + + b.ToTable("MessageTemplateItems", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.SmsTemplate", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditReason") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("AuditStatus") + .HasColumnType("int"); + + b.Property("ChannelId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Creator") + .HasColumnType("uniqueidentifier"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("Modifier") + .HasColumnType("uniqueidentifier"); + + b.Property("TemplateCode") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("TemplateContent") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("TemplateName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("TemplateType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.ToTable("SmsTemplates", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.ReceiverGroups.Aggregates.ReceiverGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Creator") + .HasColumnType("uniqueidentifier"); + + b.Property("Description") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("Modifier") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.ToTable("ReceiverGroups", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.Unsubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ChannelId") + .HasColumnType("uniqueidentifier"); + + b.Property("ChannelProvider") + .HasColumnType("int"); + + b.Property("ChannelType") + .HasColumnType("int"); + + b.Property("ChannelUserIdentity") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Creator") + .HasColumnType("uniqueidentifier"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("Keyword") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("LastInboundMessageId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("Modifier") + .HasColumnType("uniqueidentifier"); + + b.Property("Reason") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("ResubscribedAt") + .HasColumnType("datetimeoffset"); + + b.Property("ScopeRefId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ScopeType") + .HasColumnType("int"); + + b.Property("Source") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("UnsubscribedAt") + .HasColumnType("datetimeoffset"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("ChannelType"); + + b.HasIndex("Status"); + + b.HasIndex("UserId"); + + b.HasIndex("ChannelId", "ChannelUserIdentity", "ScopeType", "ScopeRefId", "Status"); + + b.ToTable("Unsubscriptions", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.UnsubscriptionTimeline", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Action") + .HasColumnType("int"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Creator") + .HasColumnType("uniqueidentifier"); + + b.Property("Detail") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("Modifier") + .HasColumnType("uniqueidentifier"); + + b.Property("OccurredAt") + .HasColumnType("datetimeoffset"); + + b.Property("UnsubscriptionId") + .HasColumnType("uniqueidentifier") + .HasColumnName("UnsubscriptionId"); + + b.HasKey("Id"); + + b.HasIndex("OccurredAt"); + + b.HasIndex("UnsubscriptionId"); + + b.ToTable("UnsubscriptionTimelines", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ChannelId") + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Creator") + .HasColumnType("uniqueidentifier"); + + b.Property("ExtraProperties") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("IsRead") + .HasColumnType("bit"); + + b.Property("IsWithdrawn") + .HasColumnType("bit"); + + b.Property("LinkUrl") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("MessageTaskHistoryId") + .HasColumnType("uniqueidentifier"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("Modifier") + .HasColumnType("uniqueidentifier"); + + b.Property("ReadTime") + .HasColumnType("datetimeoffset"); + + b.Property("SendTime") + .HasColumnType("datetimeoffset"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("ChannelId"); + + b.HasIndex("UserId", "ChannelId"); + + b.ToTable("WebsiteMessages", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessageCursor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("Creator") + .HasColumnType("uniqueidentifier"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("ModificationTime") + .HasColumnType("datetime2"); + + b.Property("Modifier") + .HasColumnType("uniqueidentifier"); + + b.Property("UpdateTime") + .HasColumnType("datetimeoffset"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("WebsiteMessageCursors", (string)null); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Channels.Aggregates.AppChannel", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.Channel", null) + .WithOne() + .HasForeignKey("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageInfos.Aggregates.MessageInfo", b => + { + b.OwnsOne("Masa.Mc.Domain.MessageInfos.Aggregates.MessageContent", "MessageContent", b1 => + { + b1.Property("MessageInfoId") + .HasColumnType("uniqueidentifier"); + + b1.Property("Content") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("Content"); + + b1.Property("ExtraProperties") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b1.Property("IsJump") + .HasMaxLength(128) + .HasColumnType("bit") + .HasColumnName("IsJump"); + + b1.Property("JumpUrl") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("JumpUrl"); + + b1.Property("Markdown") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("Markdown"); + + b1.Property("Title") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("Title"); + + b1.HasKey("MessageInfoId"); + + b1.ToTable("MessageInfos"); + + b1.WithOwner() + .HasForeignKey("MessageInfoId"); + }); + + b.Navigation("MessageContent") + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageRecords.Aggregates.MessageRecord", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Channel") + .WithMany() + .HasForeignKey("ChannelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Channel"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageReceiverUser", b => + { + b.HasOne("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", null) + .WithMany("ReceiverUsers") + .HasForeignKey("MessageTaskHistoryId"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTask", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Channel") + .WithMany() + .HasForeignKey("ChannelId"); + + b.Navigation("Channel"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", b => + { + b.HasOne("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTask", "MessageTask") + .WithMany() + .HasForeignKey("MessageTaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MessageTask"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", b => + { + b.OwnsOne("Masa.Mc.Domain.MessageInfos.Aggregates.MessageContent", "MessageContent", b1 => + { + b1.Property("MessageTemplateId") + .HasColumnType("uniqueidentifier"); + + b1.Property("Content") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("Content"); + + b1.Property("ExtraProperties") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b1.Property("IsJump") + .HasMaxLength(128) + .HasColumnType("bit") + .HasColumnName("IsJump"); + + b1.Property("JumpUrl") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("JumpUrl"); + + b1.Property("Markdown") + .IsRequired() + .HasColumnType("nvarchar(max)") + .HasColumnName("Markdown"); + + b1.Property("Title") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("Title"); + + b1.HasKey("MessageTemplateId"); + + b1.ToTable("MessageTemplates"); + + b1.WithOwner() + .HasForeignKey("MessageTemplateId"); + }); + + b.OwnsOne("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplateUnsubscribeConfig", "UnsubscribeConfig", b1 => + { + b1.Property("MessageTemplateId") + .HasColumnType("uniqueidentifier"); + + b1.Property("CooldownSeconds") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(0) + .HasColumnName("CooldownSeconds"); + + b1.Property("DebounceEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("DebounceEnabled"); + + b1.Property("Enabled") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("Enabled"); + + b1.Property("ResubscribeAutoReply") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)") + .HasDefaultValue("") + .HasColumnName("ResubscribeAutoReply"); + + b1.Property("ResubscribeKeyword") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)") + .HasDefaultValue("") + .HasColumnName("ResubscribeKeyword"); + + b1.Property("UnsubscribeAutoReply") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)") + .HasDefaultValue("") + .HasColumnName("UnsubscribeAutoReply"); + + b1.Property("UnsubscribeKeyword") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)") + .HasDefaultValue("") + .HasColumnName("UnsubscribeKeyword"); + + b1.HasKey("MessageTemplateId"); + + b1.ToTable("MessageTemplateUnsubscribeConfigs", (string)null); + + b1.WithOwner() + .HasForeignKey("MessageTemplateId"); + }); + + b.Navigation("MessageContent") + .IsRequired(); + + b.Navigation("UnsubscribeConfig"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplateItem", b => + { + b.HasOne("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", null) + .WithMany("Items") + .HasForeignKey("MessageTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.ReceiverGroups.Aggregates.ReceiverGroup", b => + { + b.OwnsMany("Masa.Mc.Domain.ReceiverGroups.Aggregates.ReceiverGroupItem", "Items", b1 => + { + b1.Property("GroupId") + .HasColumnType("uniqueidentifier"); + + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b1.Property("Avatar") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b1.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b1.Property("SubjectId") + .HasColumnType("uniqueidentifier"); + + b1.Property("Type") + .HasColumnType("int"); + + b1.HasKey("GroupId", "Id"); + + b1.ToTable("ReceiverGroupItems", (string)null); + + b1.WithOwner() + .HasForeignKey("GroupId"); + }); + + b.Navigation("Items"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.UnsubscriptionTimeline", b => + { + b.HasOne("Masa.Mc.Domain.Unsubscriptions.Aggregates.Unsubscription", null) + .WithMany("Timelines") + .HasForeignKey("UnsubscriptionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessage", b => + { + b.HasOne("Masa.Mc.Domain.Channels.Aggregates.AppChannel", "Channel") + .WithMany() + .HasForeignKey("ChannelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsMany("Masa.Mc.Domain.WebsiteMessages.Aggregates.WebsiteMessageTag", "Tags", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b1.Property("ChannelId") + .HasColumnType("uniqueidentifier"); + + b1.Property("CreationTime") + .ValueGeneratedOnAdd() + .HasColumnType("datetime2"); + + b1.Property("Tag") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("Tag"); + + b1.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b1.Property("WebsiteMessageId") + .HasColumnType("uniqueidentifier"); + + b1.HasKey("Id"); + + b1.HasIndex("ChannelId"); + + b1.HasIndex("Tag"); + + b1.HasIndex("UserId"); + + b1.HasIndex("WebsiteMessageId"); + + b1.ToTable("WebsiteMessageTags", (string)null); + + b1.WithOwner() + .HasForeignKey("WebsiteMessageId"); + }); + + b.Navigation("Channel"); + + b.Navigation("Tags"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTasks.Aggregates.MessageTaskHistory", b => + { + b.Navigation("ReceiverUsers"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplate", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("Masa.Mc.Domain.Unsubscriptions.Aggregates.Unsubscription", b => + { + b.Navigation("Timelines"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Infrastructure/Masa.Mc.EntityFrameworkCore.SqlServer/Migrations/20260627084848_SimplifyUnsubscriptionTimeline.cs b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.SqlServer/Migrations/20260627084848_SimplifyUnsubscriptionTimeline.cs new file mode 100644 index 00000000..a870ee47 --- /dev/null +++ b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.SqlServer/Migrations/20260627084848_SimplifyUnsubscriptionTimeline.cs @@ -0,0 +1,83 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Masa.Mc.EntityFrameworkCore.SqlServer.Migrations +{ + public partial class SimplifyUnsubscriptionTimeline : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Keyword", + table: "UnsubscriptionTimelines"); + + migrationBuilder.DropColumn( + name: "MatchedMessageRecordId", + table: "UnsubscriptionTimelines"); + + migrationBuilder.DropColumn( + name: "MatchedMessageSentAt", + table: "UnsubscriptionTimelines"); + + migrationBuilder.DropColumn( + name: "MatchedMessageSnapshot", + table: "UnsubscriptionTimelines"); + + migrationBuilder.DropColumn( + name: "MessageId", + table: "UnsubscriptionTimelines"); + + migrationBuilder.DropColumn( + name: "Source", + table: "UnsubscriptionTimelines"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Keyword", + table: "UnsubscriptionTimelines", + type: "nvarchar(20)", + maxLength: 20, + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "MatchedMessageRecordId", + table: "UnsubscriptionTimelines", + type: "uniqueidentifier", + nullable: true); + + migrationBuilder.AddColumn( + name: "MatchedMessageSentAt", + table: "UnsubscriptionTimelines", + type: "datetimeoffset", + nullable: true); + + migrationBuilder.AddColumn( + name: "MatchedMessageSnapshot", + table: "UnsubscriptionTimelines", + type: "nvarchar(2000)", + maxLength: 2000, + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "MessageId", + table: "UnsubscriptionTimelines", + type: "nvarchar(128)", + maxLength: 128, + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "Source", + table: "UnsubscriptionTimelines", + type: "int", + nullable: false, + defaultValue: 0); + } + } +} diff --git a/src/Infrastructure/Masa.Mc.EntityFrameworkCore.SqlServer/Migrations/MCDbContextModelSnapshot.cs b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.SqlServer/Migrations/MCDbContextModelSnapshot.cs index 729c0c47..709472fd 100644 --- a/src/Infrastructure/Masa.Mc.EntityFrameworkCore.SqlServer/Migrations/MCDbContextModelSnapshot.cs +++ b/src/Infrastructure/Masa.Mc.EntityFrameworkCore.SqlServer/Migrations/MCDbContextModelSnapshot.cs @@ -990,27 +990,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasMaxLength(1000) .HasColumnType("nvarchar(1000)"); - b.Property("Keyword") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("nvarchar(20)"); - - b.Property("MatchedMessageRecordId") - .HasColumnType("uniqueidentifier"); - - b.Property("MatchedMessageSentAt") - .HasColumnType("datetimeoffset"); - - b.Property("MatchedMessageSnapshot") - .IsRequired() - .HasMaxLength(2000) - .HasColumnType("nvarchar(2000)"); - - b.Property("MessageId") - .IsRequired() - .HasMaxLength(128) - .HasColumnType("nvarchar(128)"); - b.Property("ModificationTime") .HasColumnType("datetime2"); @@ -1020,9 +999,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("OccurredAt") .HasColumnType("datetimeoffset"); - b.Property("Source") - .HasColumnType("int"); - b.Property("UnsubscriptionId") .HasColumnType("uniqueidentifier") .HasColumnName("UnsubscriptionId"); @@ -1350,8 +1326,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("MessageContent") .IsRequired(); - b.Navigation("UnsubscribeConfig") - .IsRequired(); + b.Navigation("UnsubscribeConfig"); }); modelBuilder.Entity("Masa.Mc.Domain.MessageTemplates.Aggregates.MessageTemplateItem", b => diff --git a/src/Infrastructure/Masa.Mc.EntityFrameworkCore/McDbContextModelBuilderExtensions.cs b/src/Infrastructure/Masa.Mc.EntityFrameworkCore/McDbContextModelBuilderExtensions.cs index fb2305c0..71f0f63b 100644 --- a/src/Infrastructure/Masa.Mc.EntityFrameworkCore/McDbContextModelBuilderExtensions.cs +++ b/src/Infrastructure/Masa.Mc.EntityFrameworkCore/McDbContextModelBuilderExtensions.cs @@ -52,11 +52,11 @@ public static void ConfigureMC(this ModelBuilder builder) ub.HasKey(x => x.MessageTemplateId); ub.Property(x => x.Enabled).HasColumnName(nameof(MessageTemplateUnsubscribeConfig.Enabled)).HasDefaultValue(false); ub.Property(x => x.UnsubscribeKeyword).HasColumnName(nameof(MessageTemplateUnsubscribeConfig.UnsubscribeKeyword)).HasMaxLength(20).HasDefaultValue(string.Empty); - ub.Property(x => x.UnsubscribeAutoReply).HasColumnName(nameof(MessageTemplateUnsubscribeConfig.UnsubscribeAutoReply)).HasMaxLength(500).HasDefaultValue(string.Empty); + ub.Property(x => x.UnsubscribeAutoReplyTemplateId) + .HasColumnName(nameof(MessageTemplateUnsubscribeConfig.UnsubscribeAutoReplyTemplateId)); ub.Property(x => x.ResubscribeKeyword).HasColumnName(nameof(MessageTemplateUnsubscribeConfig.ResubscribeKeyword)).HasMaxLength(20).HasDefaultValue(string.Empty); - ub.Property(x => x.ResubscribeAutoReply).HasColumnName(nameof(MessageTemplateUnsubscribeConfig.ResubscribeAutoReply)).HasMaxLength(500).HasDefaultValue(string.Empty); - ub.Property(x => x.DebounceEnabled).HasColumnName(nameof(MessageTemplateUnsubscribeConfig.DebounceEnabled)).HasDefaultValue(false); - ub.Property(x => x.CooldownSeconds).HasColumnName(nameof(MessageTemplateUnsubscribeConfig.CooldownSeconds)).HasDefaultValue(0); + ub.Property(x => x.ResubscribeAutoReplyTemplateId) + .HasColumnName(nameof(MessageTemplateUnsubscribeConfig.ResubscribeAutoReplyTemplateId)); }); b.Navigation(x => x.UnsubscribeConfig).IsRequired(false); }); @@ -198,10 +198,10 @@ public static void ConfigureMC(this ModelBuilder builder) b.Property(x => x.SmsContent).IsRequired().HasMaxLength(1000); b.Property(x => x.AddSerial).HasMaxLength(64); b.Property(x => x.Provider).IsRequired(); - b.HasIndex(x => x.ChannelId); - b.HasIndex(x => x.Mobile); b.HasIndex(x => x.SendTime); b.HasIndex(x => x.Provider); + b.HasIndex(x => new { x.ChannelId, x.SendTime }); + b.HasIndex(x => new { x.Mobile, x.SendTime }); }); builder.Entity(b => @@ -214,10 +214,11 @@ public static void ConfigureMC(this ModelBuilder builder) b.Property(x => x.LastInboundMessageId).HasMaxLength(128); b.HasIndex(x => x.UserId); - b.HasIndex(x => x.ChannelId); - b.HasIndex(x => x.ChannelType); - b.HasIndex(x => x.Status); - b.HasIndex(x => new { x.ChannelId, x.ChannelUserIdentity, x.ScopeType, x.ScopeRefId, x.Status }); + b.HasIndex(x => new { x.ChannelType, x.ChannelProvider, x.UnsubscribedAt }); + b.HasIndex(x => new { x.ChannelId, x.ChannelUserIdentity, x.ScopeType, x.ScopeRefId, x.Status, x.UnsubscribedAt }); + b.HasIndex(x => new { x.ChannelId, x.ChannelUserIdentity, x.Status, x.UnsubscribedAt }); + b.HasIndex(x => new { x.ChannelUserIdentity, x.Status, x.ScopeType }); + b.HasIndex(x => x.LastInboundMessageId); b.HasMany(x => x.Timelines).WithOne().HasForeignKey(x => x.UnsubscriptionId).IsRequired(); }); @@ -225,13 +226,10 @@ public static void ConfigureMC(this ModelBuilder builder) builder.Entity(b => { b.ToTable(MCConsts.DbTablePrefix + "UnsubscriptionTimelines", MCConsts.DbSchema); - b.Property(x => x.UnsubscriptionId).HasColumnName("UnsubscriptionId"); b.Property(x => x.Detail).HasMaxLength(1000); - b.Property(x => x.Keyword).HasMaxLength(20); - b.Property(x => x.MessageId).HasMaxLength(128); - b.Property(x => x.MatchedMessageSnapshot).HasMaxLength(2000); - b.HasIndex(x => x.UnsubscriptionId); - b.HasIndex(x => x.OccurredAt); + b.HasIndex(x => new { x.UnsubscriptionId, x.OccurredAt }); + b.HasIndex(x => new { x.OccurredAt, x.Action, x.UnsubscriptionId }); }); } + } diff --git a/src/Infrastructure/Masa.Mc.EntityFrameworkCore/Repositories/UnsubscriptionRepository.cs b/src/Infrastructure/Masa.Mc.EntityFrameworkCore/Repositories/UnsubscriptionRepository.cs index 6c75ef17..f0480a61 100644 --- a/src/Infrastructure/Masa.Mc.EntityFrameworkCore/Repositories/UnsubscriptionRepository.cs +++ b/src/Infrastructure/Masa.Mc.EntityFrameworkCore/Repositories/UnsubscriptionRepository.cs @@ -21,7 +21,6 @@ public UnsubscriptionRepository(McDbContext context, IUnitOfWork unitOfWork) .Include(x => x.Timelines) .Where(x => x.ChannelId == channelId && - x.ChannelType == ChannelTypes.Sms && x.ChannelUserIdentity == channelUserIdentity && x.ScopeType == scopeType && x.ScopeRefId == scopeRefId && diff --git a/src/Services/Masa.Mc.Service/Application/MessageReceipts/MessageReceiptCommandHandler.cs b/src/Services/Masa.Mc.Service/Application/MessageReceipts/MessageReceiptCommandHandler.cs index 81289791..37acc4c0 100644 --- a/src/Services/Masa.Mc.Service/Application/MessageReceipts/MessageReceiptCommandHandler.cs +++ b/src/Services/Masa.Mc.Service/Application/MessageReceipts/MessageReceiptCommandHandler.cs @@ -201,6 +201,63 @@ private async Task TryHandleSmsInboundUnsubscriptionAsync( return; } + if (await TryHandleChannelLevelInboundUnsubscriptionAsync( + command, + inboundEntity, + sendTime, + inboundKeyword, + cancellationToken)) + { + return; + } + + await TryHandleTemplateLevelInboundUnsubscriptionAsync( + command, + inboundEntity, + sendTime, + inboundKeyword, + cancellationToken); + } + + private async Task TryHandleChannelLevelInboundUnsubscriptionAsync( + ReceiveSmsInboundCommand command, + SmsInbound inboundEntity, + DateTimeOffset sendTime, + string inboundKeyword, + CancellationToken cancellationToken) + { + if (!SmsInboundReservedKeywords.IsProviderUnsubscribeKeyword(command.Provider, inboundKeyword)) + { + return false; + } + + var lastMessageRecord = await TryGetLatestInboundRelatedRecordAsync(command.ChannelId, command.Input.Mobile, cancellationToken); + if (lastMessageRecord is null) + { + return true; + } + + await _channelUnsubscriptionDomainService.HandleSmsInboundProviderReservedUnsubscribeAsync( + lastMessageRecord.UserId, + lastMessageRecord.ChannelUserIdentity, + command.ChannelId, + (int)command.Provider, + inboundKeyword, + sendTime, + inboundEntity.Id.ToString("N"), + string.Empty, + lastMessageRecord.SendTime, + cancellationToken); + return true; + } + + private async Task TryHandleTemplateLevelInboundUnsubscriptionAsync( + ReceiveSmsInboundCommand command, + SmsInbound inboundEntity, + DateTimeOffset sendTime, + string inboundKeyword, + CancellationToken cancellationToken) + { var context = await TryGetInboundTemplateContextAsync(command.ChannelId, command.Input.Mobile, cancellationToken); if (context is null) { @@ -227,40 +284,70 @@ private async Task TryHandleSmsInboundUnsubscriptionAsync( inboundKeyword, sendTime, inboundEntity.Id.ToString("N"), - lastTemplateRecord.Id, matchedMessageSnapshot, lastTemplateRecord.SendTime, - unsubscribeConfig.DebounceEnabled, - unsubscribeConfig.CooldownSeconds, cancellationToken); if (handledAction == SmsInboundKeywordAction.None) { return; } + var autoReplyTemplateId = unsubscribeConfig.GetAutoReplyTemplateId(handledAction); await _smsInboundAutoReplyService.TrySendAutoReplyAsync( command.ChannelId, command.Provider, lastTemplateRecord.ChannelUserIdentity, - unsubscribeConfig.GetAutoReplyContent(handledAction), + lastTemplateRecord.UserId, + autoReplyTemplateId, cancellationToken); } + private async Task TryGetLatestInboundRelatedRecordAsync( + Guid channelId, + string channelUserIdentity, + CancellationToken cancellationToken) + { + var messageRecordQuery = await _repository.GetQueryableAsync(); + return await messageRecordQuery + .Where(x => + x.ChannelId == channelId && + x.ChannelUserIdentity == channelUserIdentity) + .OrderByDescending(x => x.SendTime) + .ThenByDescending(x => x.CreationTime) + .FirstOrDefaultAsync(cancellationToken); + } + private async Task<(MessageRecord LastTemplateRecord, MessageTemplate Template)?> TryGetInboundTemplateContextAsync( Guid channelId, string channelUserIdentity, CancellationToken cancellationToken) { + var excludedTemplateTypes = new[] + { + (int)SmsTemplateTypes.VerificationCode, + (int)SmsTemplateTypes.Unsubscribe, + (int)SmsTemplateTypes.Resubscribe + }; + + var availableTemplateIdsQuery = _messageTemplateRepository.AsNoTracking() + .Where(x => + x.ChannelId == channelId && + !excludedTemplateTypes.Contains(x.TemplateType)) + .Select(x => x.Id); + var messageRecordQuery = await _repository.GetQueryableAsync(); var lastTemplateRecord = await messageRecordQuery .Where(x => x.ChannelId == channelId && x.ChannelUserIdentity == channelUserIdentity && - x.MessageEntityType == MessageEntityTypes.Template) + x.Success == true && + x.MessageEntityType == MessageEntityTypes.Template && + x.MessageEntityId != default && + availableTemplateIdsQuery.Contains(x.MessageEntityId)) .OrderByDescending(x => x.SendTime) .ThenByDescending(x => x.CreationTime) .FirstOrDefaultAsync(cancellationToken); - if (lastTemplateRecord == null || lastTemplateRecord.MessageEntityId == default) + if (lastTemplateRecord == null) { return null; } diff --git a/src/Services/Masa.Mc.Service/Application/MessageReceipts/MessageReceiptQueryHandler.cs b/src/Services/Masa.Mc.Service/Application/MessageReceipts/MessageReceiptQueryHandler.cs index 1937745e..ca3e6273 100644 --- a/src/Services/Masa.Mc.Service/Application/MessageReceipts/MessageReceiptQueryHandler.cs +++ b/src/Services/Masa.Mc.Service/Application/MessageReceipts/MessageReceiptQueryHandler.cs @@ -16,6 +16,18 @@ public MessageReceiptQueryHandler(IMcQueryContext context) public async Task GetListSmsInboundAsync(GetListSmsInboundQuery query) { var input = query.Input; + if (!input.ChannelId.HasValue && !string.IsNullOrWhiteSpace(input.ChannelCode)) + { + var channelCode = input.ChannelCode.Trim(); + input.ChannelId = (await _context.ChannelQueryQueries.FirstOrDefaultAsync(x => x.Code == channelCode))?.Id; + } + + if (!input.ChannelId.HasValue && !string.IsNullOrWhiteSpace(input.ChannelCode)) + { + query.Result = new PaginatedListDto(0, 0, new List()); + return; + } + var condition = CreateSmsInboundPredicate(input); var resultList = await _context.SmsInboundQueries.GetPaginatedListAsync(condition, new() { @@ -27,16 +39,38 @@ public async Task GetListSmsInboundAsync(GetListSmsInboundQuery query) } }); - query.Result = new PaginatedListDto(resultList.Total, resultList.TotalPages, resultList.Result.Adapt>()); + var inboundDtos = resultList.Result.Adapt>(); + if (inboundDtos.Any()) + { + var inboundMessageIds = inboundDtos + .Select(x => x.Id.ToString("N")) + .ToList(); + var unsubscribedInboundIds = await _context.UnsubscriptionQueries + .Where(x => inboundMessageIds.Contains(x.LastInboundMessageId)) + .Select(x => x.LastInboundMessageId) + .Distinct() + .ToListAsync(); + var unsubscribedInboundIdSet = unsubscribedInboundIds.ToHashSet(StringComparer.OrdinalIgnoreCase); + foreach (var item in inboundDtos) + { + item.InboundType = unsubscribedInboundIdSet.Contains(item.Id.ToString("N")) + ? SmsInboundTypes.Unsubscribe + : SmsInboundTypes.Other; + } + } + + query.Result = new PaginatedListDto(resultList.Total, resultList.TotalPages, inboundDtos); } private static Expression> CreateSmsInboundPredicate(GetSmsInboundInputDto input) { - Expression> condition = x => x.ChannelId == input.ChannelId; + Expression> condition = x => true; + condition = condition.And(input.ChannelId.HasValue, x => x.ChannelId == input.ChannelId!.Value); condition = condition.And(!string.IsNullOrWhiteSpace(input.Mobile), x => x.Mobile == input.Mobile); condition = condition.And(!string.IsNullOrWhiteSpace(input.AddSerial), x => x.AddSerial == input.AddSerial); condition = condition.And(!string.IsNullOrWhiteSpace(input.SmsContent), x => x.SmsContent.Contains(input.SmsContent)); + condition = condition.And(input.Provider.HasValue, x => x.Provider == input.Provider!.Value); condition = condition.And(input.StartTime.HasValue, x => x.SendTime >= input.StartTime!.Value); condition = condition.And(input.EndTime.HasValue, x => x.SendTime <= input.EndTime!.Value); diff --git a/src/Services/Masa.Mc.Service/Application/MessageReceipts/SmsInboundAutoReplySendRequest.cs b/src/Services/Masa.Mc.Service/Application/MessageReceipts/SmsInboundAutoReplySendRequest.cs new file mode 100644 index 00000000..ddeeea60 --- /dev/null +++ b/src/Services/Masa.Mc.Service/Application/MessageReceipts/SmsInboundAutoReplySendRequest.cs @@ -0,0 +1,14 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Mc.Service.Admin.Application.MessageReceipts; + +public record SmsInboundAutoReplySendRequest( + Guid ChannelId, + SmsInboundProviders Provider, + string ChannelUserIdentity, + Guid UserId, + Guid AutoReplyTemplateEntityId, + string AutoReplyTemplateId, + string AutoReplyTemplateName, + string AutoReplyContent); diff --git a/src/Services/Masa.Mc.Service/Application/MessageReceipts/SmsInboundAutoReplyService.cs b/src/Services/Masa.Mc.Service/Application/MessageReceipts/SmsInboundAutoReplyService.cs index 1f751790..4c97abe8 100644 --- a/src/Services/Masa.Mc.Service/Application/MessageReceipts/SmsInboundAutoReplyService.cs +++ b/src/Services/Masa.Mc.Service/Application/MessageReceipts/SmsInboundAutoReplyService.cs @@ -6,16 +6,31 @@ namespace Masa.Mc.Service.Admin.Application.MessageReceipts; public class SmsInboundAutoReplyService : ITransientDependency { private readonly IChannelRepository _channelRepository; + private readonly IMessageTemplateRepository _messageTemplateRepository; + private readonly IMessageRecordRepository _messageRecordRepository; + private readonly MessageTemplateDomainService _messageTemplateDomainService; private readonly SmsSenderFactory _smsSenderFactory; + private readonly IHostEnvironment _hostEnvironment; + private readonly II18n _i18n; private readonly ILogger _logger; public SmsInboundAutoReplyService( IChannelRepository channelRepository, + IMessageTemplateRepository messageTemplateRepository, + IMessageRecordRepository messageRecordRepository, + MessageTemplateDomainService messageTemplateDomainService, SmsSenderFactory smsSenderFactory, + IHostEnvironment hostEnvironment, + II18n i18n, ILogger logger) { _channelRepository = channelRepository; + _messageTemplateRepository = messageTemplateRepository; + _messageRecordRepository = messageRecordRepository; + _messageTemplateDomainService = messageTemplateDomainService; _smsSenderFactory = smsSenderFactory; + _hostEnvironment = hostEnvironment; + _i18n = i18n; _logger = logger; } @@ -23,21 +38,130 @@ public async Task TrySendAutoReplyAsync( Guid channelId, SmsInboundProviders provider, string channelUserIdentity, - string autoReplyContent, + Guid userId, + Guid autoReplyTemplateId, CancellationToken cancellationToken = default) { - if (string.IsNullOrWhiteSpace(autoReplyContent) || string.IsNullOrWhiteSpace(channelUserIdentity)) + if (autoReplyTemplateId == Guid.Empty) + { + return; + } + + var messageTemplate = await _messageTemplateRepository.FindAsync( + x => x.ChannelId == channelId && x.Id == autoReplyTemplateId, + cancellationToken: cancellationToken); + if (messageTemplate is null) { return; } - var channel = await _channelRepository.AsNoTracking() - .FirstOrDefaultAsync(x => x.Id == channelId, cancellationToken); + var autoReplyContent = messageTemplate?.MessageContent?.Content?.Trim(); + if (string.IsNullOrWhiteSpace(autoReplyContent)) + { + return; + } + + var request = new SmsInboundAutoReplySendRequest( + channelId, + provider, + channelUserIdentity, + userId, + messageTemplate.Id, + messageTemplate.TemplateId, + messageTemplate.DisplayName, + autoReplyContent); + + await TrySendAutoReplyInternalAsync(request, messageTemplate, cancellationToken); + } + + private async Task TrySendAutoReplyInternalAsync( + SmsInboundAutoReplySendRequest request, + MessageTemplate? messageTemplate, + CancellationToken cancellationToken = default) + { + ArgumentNullException.ThrowIfNull(request); + + if (!TryGetSendPayload(request, out var channelUserIdentity, out var autoReplyContent)) + { + return; + } + + var messageRecord = CreateMessageRecord(request); + if (await TryHandleSendUpperLimitAsync(messageTemplate, channelUserIdentity, messageRecord)) + { + return; + } + + var channelId = request.ChannelId; + var provider = request.Provider; + var channel = await _channelRepository.AsNoTracking().FirstOrDefaultAsync(x => x.Id == channelId, cancellationToken); if (channel is null) { return; } + if (await TryHandleNonProductionAsync(provider, channelId, channelUserIdentity, messageRecord)) + { + return; + } + + await SendAutoReplyInProductionAsync(channel, provider, channelUserIdentity, autoReplyContent, messageRecord); + } + + private static bool TryGetSendPayload( + SmsInboundAutoReplySendRequest request, + out string channelUserIdentity, + out string autoReplyContent) + { + channelUserIdentity = request.ChannelUserIdentity; + autoReplyContent = request.AutoReplyContent; + return !string.IsNullOrWhiteSpace(autoReplyContent) && !string.IsNullOrWhiteSpace(channelUserIdentity); + } + + private async Task TryHandleSendUpperLimitAsync( + MessageTemplate? messageTemplate, + string channelUserIdentity, + MessageRecord messageRecord) + { + if (messageTemplate == null || + await _messageTemplateDomainService.CheckSendUpperLimitAsync(messageTemplate, channelUserIdentity)) + { + return false; + } + + messageRecord.SetResult(false, _i18n.T("DailySendingLimit"), DateTimeOffset.UtcNow, string.Empty); + await _messageRecordRepository.AddAsync(messageRecord); + return true; + } + + private async Task TryHandleNonProductionAsync( + SmsInboundProviders provider, + Guid channelId, + string channelUserIdentity, + MessageRecord messageRecord) + { + if (_hostEnvironment.IsProduction()) + { + return false; + } + + messageRecord.SetResult(true, _i18n.T("InboundAutoReplySkippedInNonProduction"), DateTimeOffset.UtcNow, string.Empty); + _logger.LogInformation( + "Skip inbound auto reply real send in non-production. Provider: {Provider}, ChannelId: {ChannelId}, Target: {Target}", + provider, + channelId, + channelUserIdentity); + await _messageRecordRepository.AddAsync(messageRecord); + return true; + } + + private async Task SendAutoReplyInProductionAsync( + Channel channel, + SmsInboundProviders provider, + string channelUserIdentity, + string autoReplyContent, + MessageRecord messageRecord) + { var smsProvider = (SmsProviders)provider; var options = _smsSenderFactory.GetOptions(smsProvider, channel.ExtraProperties); var smsAsyncLocal = _smsSenderFactory.GetProviderAsyncLocal(smsProvider); @@ -58,11 +182,37 @@ public async Task TrySendAutoReplyAsync( { _logger.LogWarning("Inbound auto reply failed: {Message}", response.Message); } + + messageRecord.SetResult( + response.Success ? (smsSender.SupportsReceipt ? null : true) : false, + response.Success ? string.Empty : (response.Message ?? string.Empty), + DateTimeOffset.UtcNow, + response.MsgId ?? string.Empty); } } catch (Exception ex) { + messageRecord.SetResult(false, ex.Message, DateTimeOffset.UtcNow, string.Empty); _logger.LogError(ex, "Send inbound auto reply failed"); } + + await _messageRecordRepository.AddAsync(messageRecord); + } + + private static MessageRecord CreateMessageRecord(SmsInboundAutoReplySendRequest request) + { + var messageRecord = new MessageRecord( + request.UserId, + request.ChannelUserIdentity, + request.ChannelId, + Guid.Empty, + Guid.Empty, + new ExtraPropertyDictionary(), + request.AutoReplyTemplateName ?? string.Empty, + DateTimeOffset.UtcNow, + string.Empty); + messageRecord.SetMessageEntity(MessageEntityTypes.Template, request.AutoReplyTemplateEntityId); + messageRecord.SetDataValue(nameof(MessageTemplate.TemplateId), request.AutoReplyTemplateId ?? string.Empty); + return messageRecord; } } diff --git a/src/Services/Masa.Mc.Service/Application/MessageRecords/EventHandler/RetrySmsMessageEventHandler.cs b/src/Services/Masa.Mc.Service/Application/MessageRecords/EventHandler/RetrySmsMessageEventHandler.cs index 4922531e..04a4275f 100644 --- a/src/Services/Masa.Mc.Service/Application/MessageRecords/EventHandler/RetrySmsMessageEventHandler.cs +++ b/src/Services/Masa.Mc.Service/Application/MessageRecords/EventHandler/RetrySmsMessageEventHandler.cs @@ -9,6 +9,7 @@ public class RetrySmsMessageEventHandler private readonly IChannelRepository _channelRepository; private readonly IMessageRecordRepository _messageRecordRepository; private readonly MessageTemplateDomainService _messageTemplateDomainService; + private readonly UnsubscriptionDomainService _channelUnsubscriptionDomainService; private readonly IMessageTemplateRepository _repository; private readonly II18n _i18n; private readonly ITemplateRenderer _templateRenderer; @@ -17,6 +18,7 @@ public RetrySmsMessageEventHandler(SmsSenderFactory smsSenderFactory , IChannelRepository channelRepository , IMessageRecordRepository messageRecordRepository , MessageTemplateDomainService messageTemplateDomainService + , UnsubscriptionDomainService channelUnsubscriptionDomainService , IMessageTemplateRepository repository , II18n i18n , ITemplateRenderer templateRenderer) @@ -25,6 +27,7 @@ public RetrySmsMessageEventHandler(SmsSenderFactory smsSenderFactory _channelRepository = channelRepository; _messageRecordRepository = messageRecordRepository; _messageTemplateDomainService = messageTemplateDomainService; + _channelUnsubscriptionDomainService = channelUnsubscriptionDomainService; _repository = repository; _i18n = i18n; _templateRenderer = templateRenderer; @@ -47,10 +50,21 @@ public async Task HandleEventAsync(RetrySmsMessageEvent eto) using (smsAsyncLoca.Change(options)) { var variables = messageRecord.Variables; - var messageTemplate = await _repository.FindAsync(x => x.Id == messageRecord.MessageEntityId, false); + var messageTemplate = await _repository.FindAsync(x => x.Id == messageRecord.MessageEntityId); + if (messageTemplate?.GetUnsubscribeConfig().Enabled == true && + await _channelUnsubscriptionDomainService.IsSmsTemplateUnsubscribedAsync( + messageRecord.ChannelId, + messageRecord.ChannelUserIdentity, + messageTemplate.Id)) + { + messageRecord.SetResult(false, Masa.Mc.Service.Admin.Application.MessageTasks.EventHandler.SmsSendBlockResultHelper.GetUnsubscriptionBlockedMessage(_i18n)); + await _messageRecordRepository.UpdateAsync(messageRecord); + return; + } + if (!await _messageTemplateDomainService.CheckSendUpperLimitAsync(messageTemplate, messageRecord.ChannelUserIdentity)) { - messageRecord.SetResult(false, _i18n.T("DailySendingLimit")); + messageRecord.SetResult(false, Masa.Mc.Service.Admin.Application.MessageTasks.EventHandler.SmsSendBlockResultHelper.GetDailySendingLimitMessage(_i18n)); await _messageRecordRepository.UpdateAsync(messageRecord); return; } @@ -64,7 +78,7 @@ public async Task HandleEventAsync(RetrySmsMessageEvent eto) try { var response = await smsSender.SendAsync(smsMessage) as SmsSendResponse; - if (response.Success) + if (response?.Success is true) { messageRecord.SetResult(smsSender.SupportsReceipt ? null : true, string.Empty, DateTimeOffset.UtcNow, response.MsgId); } diff --git a/src/Services/Masa.Mc.Service/Application/MessageRecords/MessageRecordQueryHandler.cs b/src/Services/Masa.Mc.Service/Application/MessageRecords/MessageRecordQueryHandler.cs index 5a8c4de5..c9ddf2e8 100644 --- a/src/Services/Masa.Mc.Service/Application/MessageRecords/MessageRecordQueryHandler.cs +++ b/src/Services/Masa.Mc.Service/Application/MessageRecords/MessageRecordQueryHandler.cs @@ -9,16 +9,19 @@ public class MessageRecordQueryHandler private readonly IAuthClient _authClient; private readonly II18n _i18n; private readonly IDataFilter _dataFilter; + private readonly ITemplateRenderer _templateRenderer; public MessageRecordQueryHandler(IMcQueryContext context , IAuthClient authClient , II18n i18n - , IDataFilter dataFilter) + , IDataFilter dataFilter + , ITemplateRenderer templateRenderer) { _context = context; _authClient = authClient; _i18n = i18n; _dataFilter = dataFilter; + _templateRenderer = templateRenderer; } [EventHandler] @@ -54,6 +57,171 @@ public async Task GetListAsync(GetListMessageRecordQuery query) query.Result = result; } + [EventHandler] + public async Task GetSmsRecordsByMobileAsync(GetSmsRecordsByMobileQuery query) + { + var mobile = query.Mobile?.Trim(); + if (string.IsNullOrWhiteSpace(mobile)) + { + query.Result = new PaginatedListDto(0, 0, new()); + return; + } + + using var dataFilter = _dataFilter.Disable(); + Guid? channelId = null; + if (!string.IsNullOrWhiteSpace(query.ChannelCode)) + { + var channelCode = query.ChannelCode.Trim(); + channelId = await _context.ChannelQueryQueries + .AsNoTracking() + .Where(x => x.Type == ChannelTypes.Sms && x.Code == channelCode) + .Select(x => (Guid?)x.Id) + .FirstOrDefaultAsync(); + if (!channelId.HasValue) + { + query.Result = new PaginatedListDto(0, 0, new()); + return; + } + } + + var condition = CreateSmsOutboundRecordPredicate(mobile, channelId); + var resultList = await _context.MessageRecordQueries + .AsNoTracking() + .GetPaginatedListAsync(condition, new() + { + Page = query.Page, + PageSize = query.PageSize, + Sorting = new Dictionary + { + [nameof(MessageRecordQueryModel.SendTime)] = true + } + }); + if (!resultList.Result.Any()) + { + query.Result = new PaginatedListDto(0, 0, new()); + return; + } + + var records = resultList.Result + .Select(x => new + { + ChannelId = x.ChannelId!.Value, + x.SendTime, + x.MessageEntityId, + x.Variables, + x.DisplayName + }) + .ToList(); + + var templateIds = records + .Select(x => x.MessageEntityId) + .Distinct() + .ToList(); + var templateContents = templateIds.Any() + ? await _context.MessageTemplateQueries + .AsNoTracking() + .Where(x => templateIds.Contains(x.Id)) + .ToDictionaryAsync(x => x.Id, x => x.Content) + : new Dictionary(); + + var items = records + .Select(x => new SmsRecordDto + { + ChannelId = x.ChannelId, + SmsContent = ResolveSmsContent( + x.MessageEntityId, + x.Variables, + x.DisplayName, + templateContents), + SendTime = x.SendTime + }) + .ToList(); + query.Result = new PaginatedListDto(resultList.Total, resultList.TotalPages, items); + } + + [EventHandler] + public async Task GetSmsInteractionHistoryAsync(GetSmsInteractionHistoryQuery query) + { + var mobile = query.Mobile?.Trim(); + if (string.IsNullOrWhiteSpace(mobile) || query.ChannelId == Guid.Empty) + { + query.Result = new(); + return; + } + + using var dataFilter = _dataFilter.Disable(); + + var startTime = DateTimeOffset.UtcNow.AddMonths(-1); + var outboundRecords = await _context.MessageRecordQueries + .AsNoTracking() + .Where(CreateSmsOutboundRecordPredicate(mobile, query.ChannelId)) + .Where(x => x.SendTime.HasValue && x.SendTime.Value >= startTime) + .Select(x => new + { + x.SendTime, + x.MessageEntityId, + x.Variables, + x.DisplayName + }) + .ToListAsync(); + + var templateIds = outboundRecords + .Select(x => x.MessageEntityId) + .Distinct() + .ToList(); + var templateContents = templateIds.Any() + ? await _context.MessageTemplateQueries + .AsNoTracking() + .Where(x => templateIds.Contains(x.Id)) + .ToDictionaryAsync(x => x.Id, x => x.Content) + : new Dictionary(); + + var outboundItems = outboundRecords + .Where(x => x.SendTime.HasValue) + .Select(x => new SmsInteractionHistoryDto + { + SendTime = x.SendTime!.Value, + Content = ResolveSmsContent( + x.MessageEntityId, + x.Variables, + x.DisplayName, + templateContents), + IsInbound = false + }) + .ToList(); + + var inboundQuery = _context.SmsInboundQueries + .AsNoTracking() + .Where(x => x.Mobile == mobile && x.ChannelId == query.ChannelId && x.SendTime >= startTime); + + var inboundItems = await inboundQuery + .Select(x => new SmsInteractionHistoryDto + { + SendTime = x.SendTime, + Content = x.SmsContent, + IsInbound = true + }) + .ToListAsync(); + + query.Result = inboundItems + .Concat(outboundItems) + .Where(x => !string.IsNullOrWhiteSpace(x.Content)) + .OrderByDescending(x => x.SendTime) + .ToList(); + } + + private static Expression> CreateSmsOutboundRecordPredicate( + string mobile, + Guid? channelId) + { + Expression> condition = x => + x.ChannelUserIdentity == mobile && + x.MessageEntityType == MessageEntityTypes.Template && + x.ChannelId.HasValue; + condition = condition.And(channelId.HasValue, x => x.ChannelId == channelId!.Value); + return condition; + } + private async Task>> CreateFilteredPredicate(GetMessageRecordInputDto inputDto) { Expression> condition = x => true; @@ -97,4 +265,19 @@ private async Task FillUserInfo(List dtos) item.User.FillChannelUserIdentity(item.ChannelUserIdentity, item.Channel.Type); } } + + private string ResolveSmsContent( + Guid messageEntityId, + ExtraPropertyDictionary? variables, + string displayName, + IReadOnlyDictionary templateContents) + { + if (templateContents.TryGetValue(messageEntityId, out var templateContent) && + !string.IsNullOrWhiteSpace(templateContent)) + { + return _templateRenderer.Render(templateContent, variables ?? new()); + } + + return displayName; + } } diff --git a/src/Services/Masa.Mc.Service/Application/MessageRecords/Queries/GetSmsInteractionHistoryQuery.cs b/src/Services/Masa.Mc.Service/Application/MessageRecords/Queries/GetSmsInteractionHistoryQuery.cs new file mode 100644 index 00000000..622d9a7d --- /dev/null +++ b/src/Services/Masa.Mc.Service/Application/MessageRecords/Queries/GetSmsInteractionHistoryQuery.cs @@ -0,0 +1,9 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Mc.Service.Admin.Application.MessageRecords.Queries; + +public record GetSmsInteractionHistoryQuery(string Mobile, Guid ChannelId) : Query> +{ + public override List Result { get; set; } = new(); +} diff --git a/src/Services/Masa.Mc.Service/Application/MessageRecords/Queries/GetSmsRecordsByMobileQuery.cs b/src/Services/Masa.Mc.Service/Application/MessageRecords/Queries/GetSmsRecordsByMobileQuery.cs new file mode 100644 index 00000000..fd40a104 --- /dev/null +++ b/src/Services/Masa.Mc.Service/Application/MessageRecords/Queries/GetSmsRecordsByMobileQuery.cs @@ -0,0 +1,9 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Mc.Service.Admin.Application.MessageRecords.Queries; + +public record GetSmsRecordsByMobileQuery(string Mobile, string ChannelCode, int Page, int PageSize) : Query> +{ + public override PaginatedListDto Result { get; set; } = new(); +} diff --git a/src/Services/Masa.Mc.Service/Application/MessageTasks/EventHandler/SendSimpleMessageEventHandler.cs b/src/Services/Masa.Mc.Service/Application/MessageTasks/EventHandler/SendSimpleMessageEventHandler.cs index 858e12ba..8fa4ae56 100644 --- a/src/Services/Masa.Mc.Service/Application/MessageTasks/EventHandler/SendSimpleMessageEventHandler.cs +++ b/src/Services/Masa.Mc.Service/Application/MessageTasks/EventHandler/SendSimpleMessageEventHandler.cs @@ -48,7 +48,7 @@ public async Task HandleEventAsync(SendSimpleSmsMessageEvent eto) var messageEntityId = eto.MessageData.GetDataValue(nameof(MessageTemplate.Id)); MessageTemplate? messageTemplate = null; - var messageRecord = new MessageRecord(Guid.Empty, eto.ChannelUserIdentity, channel.Id, Guid.Empty, Guid.Empty, eto.OriginalVariables, eto.MessageData.MessageContent.Title, DateTimeOffset.UtcNow, eto.SystemId); + var messageRecord = new MessageRecord(Guid.Empty, eto.ChannelUserIdentity, channel.Id, Guid.Empty, Guid.Empty, eto.Variables, eto.MessageData.MessageContent.Title, DateTimeOffset.UtcNow, eto.SystemId); messageRecord.SetMessageEntity(eto.MessageData.MessageType, messageEntityId); messageRecord.SetDataValue(nameof(MessageTemplate.Sign), sign); messageRecord.SetDataValue(nameof(MessageTemplate.TemplateId), templateId); @@ -56,7 +56,7 @@ public async Task HandleEventAsync(SendSimpleSmsMessageEvent eto) if (eto.MessageData.MessageType == MessageEntityTypes.Template) { - messageTemplate = await _messageTemplateRepository.FindAsync(x => x.Id == messageEntityId, false); + messageTemplate = await _messageTemplateRepository.FindAsync(x => x.Id == messageEntityId); if (messageTemplate?.GetUnsubscribeConfig().Enabled == true && await _channelUnsubscriptionDomainService.IsSmsTemplateUnsubscribedAsync(channel.Id, eto.ChannelUserIdentity, messageEntityId)) { @@ -74,11 +74,7 @@ await _channelUnsubscriptionDomainService.IsSmsTemplateUnsubscribedAsync(channel } } - var text = smsSender.SupportsTemplate ? JsonSerializer.Serialize(eto.Variables) : eto.MessageData.MessageContent.Content; - if (!smsSender.SupportsTemplate && messageTemplate?.GetUnsubscribeConfig().Enabled == true) - { - text = messageTemplate.AppendUnsubscribeSuffix(text); - } + var text = BuildSmsMessageText(eto, smsSender, messageTemplate); var smsMessage = new SmsMessage(eto.ChannelUserIdentity, text); smsMessage.Properties.Add("SignName", sign); @@ -107,4 +103,25 @@ await _channelUnsubscriptionDomainService.IsSmsTemplateUnsubscribedAsync(channel } } + private string BuildSmsMessageText(SendSimpleSmsMessageEvent eto, ISmsSender smsSender, MessageTemplate? template) + { + string text = string.Empty; + if (smsSender.SupportsTemplate) + { + var variables = template is null ? eto.Variables : _messageTemplateDomainService.ConvertVariables(template, eto.Variables); + text = JsonSerializer.Serialize(variables); + } + else + { + text = eto.MessageData.MessageContent.Content; + + if (template?.GetUnsubscribeConfig().Enabled == true) + { + text = template.AppendUnsubscribeSuffix(text); + } + } + + return text; + } + } diff --git a/src/Services/Masa.Mc.Service/Application/MessageTasks/EventHandler/SendSmsMessageEventHandler.cs b/src/Services/Masa.Mc.Service/Application/MessageTasks/EventHandler/SendSmsMessageEventHandler.cs index ed5f0912..27e4edf2 100644 --- a/src/Services/Masa.Mc.Service/Application/MessageTasks/EventHandler/SendSmsMessageEventHandler.cs +++ b/src/Services/Masa.Mc.Service/Application/MessageTasks/EventHandler/SendSmsMessageEventHandler.cs @@ -45,7 +45,7 @@ public async Task ResolveAsync(SendSmsMessageEvent eto) var channelId = eto.ChannelId; var taskHistory = eto.MessageTaskHistory; - var messageTemplate = await _templateRepository.FindAsync(x => x.Id == taskHistory.MessageTask.EntityId, false); + var messageTemplate = await _templateRepository.FindAsync(x => x.Id == taskHistory.MessageTask.EntityId); var messageRecords = new List(); foreach (var item in taskHistory.ReceiverUsers) @@ -82,6 +82,7 @@ public async Task CheckAsync(SendSmsMessageEvent eto) var unsubscriptionEnabled = eto.MessageTemplate.GetUnsubscribeConfig().Enabled; var channelUserIdentitys = eto.MessageRecords.Select(x => x.ChannelUserIdentity).Distinct().ToList(); var checkChannelUserIdentitys = await _messageTemplateDomainService.CheckSendUpperLimitAsync(eto.MessageTemplate, channelUserIdentitys); + var exceededUpperLimitIdentitySet = checkChannelUserIdentitys.ToHashSet(); foreach (var messageRecord in eto.MessageRecords) { @@ -90,13 +91,13 @@ public async Task CheckAsync(SendSmsMessageEvent eto) messageRecord.ChannelUserIdentity, templateId)) { - messageRecord.SetResult(false, _i18n.T("MessageBlockedByUnsubscription")); + messageRecord.SetResult(false, SmsSendBlockResultHelper.GetUnsubscriptionBlockedMessage(_i18n)); continue; } - if (checkChannelUserIdentitys.Contains(messageRecord.ChannelUserIdentity)) + if (exceededUpperLimitIdentitySet.Contains(messageRecord.ChannelUserIdentity)) { - messageRecord.SetResult(false, _i18n.T("DailySendingLimit")); + messageRecord.SetResult(false, SmsSendBlockResultHelper.GetDailySendingLimitMessage(_i18n)); continue; } diff --git a/src/Services/Masa.Mc.Service/Application/MessageTasks/EventHandler/SmsSendBlockResultHelper.cs b/src/Services/Masa.Mc.Service/Application/MessageTasks/EventHandler/SmsSendBlockResultHelper.cs new file mode 100644 index 00000000..83db6666 --- /dev/null +++ b/src/Services/Masa.Mc.Service/Application/MessageTasks/EventHandler/SmsSendBlockResultHelper.cs @@ -0,0 +1,17 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Mc.Service.Admin.Application.MessageTasks.EventHandler; + +internal static class SmsSendBlockResultHelper +{ + public static string GetUnsubscriptionBlockedMessage(II18n i18n) + { + return i18n.T("MessageBlockedByUnsubscription"); + } + + public static string GetDailySendingLimitMessage(II18n i18n) + { + return i18n.T("DailySendingLimit"); + } +} diff --git a/src/Services/Masa.Mc.Service/Application/MessageTasks/MessageTaskCommandHandler.cs b/src/Services/Masa.Mc.Service/Application/MessageTasks/MessageTaskCommandHandler.cs index 4c3d88be..bd0ea539 100644 --- a/src/Services/Masa.Mc.Service/Application/MessageTasks/MessageTaskCommandHandler.cs +++ b/src/Services/Masa.Mc.Service/Application/MessageTasks/MessageTaskCommandHandler.cs @@ -206,7 +206,7 @@ public async Task ResendAsync(ResendMessageTaskCommand command) [EventHandler] public async Task SendSimpleMessageAsync(SendSimpleTemplateMessageCommand command) { - var template = await _messageTemplateRepository.FindAsync(x => x.Code == command.InputDto.TemplateCode); + var template = await _messageTemplateRepository.FindAsync(x => x.Code == command.InputDto.TemplateCode, false); MasaArgumentException.ThrowIfNull(template, _i18n.T("MessageTemplate")); var messageData = new MessageData(template.MessageContent, MessageEntityTypes.Template); @@ -217,10 +217,9 @@ public async Task SendSimpleMessageAsync(SendSimpleTemplateMessageCommand comman messageData.SetDataValue(BusinessConsts.MESSAGE_TYPE, template.TemplateType.ToString()); messageData.SetDataValue(nameof(MessageTemplate.Id), template.Id.ToString()); - var variables = _messageTemplateDomainService.ConvertVariables(template, command.InputDto.Variables); var channelType = Enumeration.FromValue((int)command.InputDto.ChannelType); - var eto = channelType.GetSendSimpleMessageEvent(command.InputDto.ChannelUserIdentity, command.InputDto.ChannelCode, messageData, variables, command.InputDto.Variables, command.InputDto.SystemId); + var eto = channelType.GetSendSimpleMessageEvent(command.InputDto.ChannelUserIdentity, command.InputDto.ChannelCode, messageData, command.InputDto.Variables, command.InputDto.SystemId); await _eventBus.PublishAsync(eto); } diff --git a/src/Services/Masa.Mc.Service/Application/QueryModels/MessageTemplateUnsubscribeConfigQueryModel.cs b/src/Services/Masa.Mc.Service/Application/QueryModels/MessageTemplateUnsubscribeConfigQueryModel.cs index dc8108aa..0dd3e838 100644 --- a/src/Services/Masa.Mc.Service/Application/QueryModels/MessageTemplateUnsubscribeConfigQueryModel.cs +++ b/src/Services/Masa.Mc.Service/Application/QueryModels/MessageTemplateUnsubscribeConfigQueryModel.cs @@ -9,13 +9,9 @@ public class MessageTemplateUnsubscribeConfigQueryModel public string UnsubscribeKeyword { get; set; } = string.Empty; - public string UnsubscribeAutoReply { get; set; } = string.Empty; + public Guid UnsubscribeAutoReplyTemplateId { get; set; } public string ResubscribeKeyword { get; set; } = string.Empty; - public string ResubscribeAutoReply { get; set; } = string.Empty; - - public bool DebounceEnabled { get; set; } - - public int CooldownSeconds { get; set; } + public Guid ResubscribeAutoReplyTemplateId { get; set; } } diff --git a/src/Services/Masa.Mc.Service/Application/QueryModels/UnsubscriptionTimelineQueryModel.cs b/src/Services/Masa.Mc.Service/Application/QueryModels/UnsubscriptionTimelineQueryModel.cs index d18623c9..a3a032b4 100644 --- a/src/Services/Masa.Mc.Service/Application/QueryModels/UnsubscriptionTimelineQueryModel.cs +++ b/src/Services/Masa.Mc.Service/Application/QueryModels/UnsubscriptionTimelineQueryModel.cs @@ -9,19 +9,7 @@ public class UnsubscriptionTimelineQueryModel : Masa.BuildingBlocks.Ddd.Domain.E public UnsubscriptionTimelineActions Action { get; set; } - public UnsubscriptionSource Source { get; set; } - public string Detail { get; set; } = string.Empty; - public string Keyword { get; set; } = string.Empty; - - public string MessageId { get; set; } = string.Empty; - - public Guid? MatchedMessageRecordId { get; set; } - - public string MatchedMessageSnapshot { get; set; } = string.Empty; - - public DateTimeOffset? MatchedMessageSentAt { get; set; } - public DateTimeOffset OccurredAt { get; set; } } diff --git a/src/Services/Masa.Mc.Service/Application/Unsubscriptions/AddChannelUserIdentityToUnsubscriptionBlacklistCommand.cs b/src/Services/Masa.Mc.Service/Application/Unsubscriptions/AddChannelUserIdentityToUnsubscriptionBlacklistCommand.cs new file mode 100644 index 00000000..208b472f --- /dev/null +++ b/src/Services/Masa.Mc.Service/Application/Unsubscriptions/AddChannelUserIdentityToUnsubscriptionBlacklistCommand.cs @@ -0,0 +1,6 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Mc.Service.Admin.Application.Unsubscriptions; + +public record AddChannelUserIdentityToUnsubscriptionBlacklistCommand(AddChannelUserIdentityToUnsubscriptionBlacklistInputDto Input) : Command; diff --git a/src/Services/Masa.Mc.Service/Application/Unsubscriptions/MessageTemplateLookupItem.cs b/src/Services/Masa.Mc.Service/Application/Unsubscriptions/MessageTemplateLookupItem.cs new file mode 100644 index 00000000..5e10e1c7 --- /dev/null +++ b/src/Services/Masa.Mc.Service/Application/Unsubscriptions/MessageTemplateLookupItem.cs @@ -0,0 +1,10 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Mc.Service.Admin.Application.Unsubscriptions; + +internal sealed record MessageTemplateLookupItem( + Guid Id, + string Code, + string DisplayName, + string Content); diff --git a/src/Services/Masa.Mc.Service/Application/Unsubscriptions/Queries/GetChannelUserIdentityUnsubscriptionsQuery.cs b/src/Services/Masa.Mc.Service/Application/Unsubscriptions/Queries/GetChannelUserIdentityUnsubscriptionsQuery.cs new file mode 100644 index 00000000..7b9ced68 --- /dev/null +++ b/src/Services/Masa.Mc.Service/Application/Unsubscriptions/Queries/GetChannelUserIdentityUnsubscriptionsQuery.cs @@ -0,0 +1,9 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Mc.Service.Admin.Application.Unsubscriptions.Queries; + +public record GetChannelUserIdentityUnsubscriptionsQuery(string ChannelCode, string ChannelUserIdentity) : Query> +{ + public override List Result { get; set; } = new(); +} diff --git a/src/Services/Masa.Mc.Service/Application/Unsubscriptions/RemoveChannelUserIdentityFromUnsubscriptionBlacklistCommand.cs b/src/Services/Masa.Mc.Service/Application/Unsubscriptions/RemoveChannelUserIdentityFromUnsubscriptionBlacklistCommand.cs new file mode 100644 index 00000000..605cf205 --- /dev/null +++ b/src/Services/Masa.Mc.Service/Application/Unsubscriptions/RemoveChannelUserIdentityFromUnsubscriptionBlacklistCommand.cs @@ -0,0 +1,6 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Mc.Service.Admin.Application.Unsubscriptions; + +public record RemoveChannelUserIdentityFromUnsubscriptionBlacklistCommand(RemoveChannelUserIdentityFromUnsubscriptionBlacklistInputDto Input) : Command; diff --git a/src/Services/Masa.Mc.Service/Application/Unsubscriptions/UnsubscriptionCommandHandler.cs b/src/Services/Masa.Mc.Service/Application/Unsubscriptions/UnsubscriptionCommandHandler.cs new file mode 100644 index 00000000..99857667 --- /dev/null +++ b/src/Services/Masa.Mc.Service/Application/Unsubscriptions/UnsubscriptionCommandHandler.cs @@ -0,0 +1,180 @@ +// Copyright (c) MASA Stack All rights reserved. +// Licensed under the Apache License. See LICENSE.txt in the project root for license information. + +namespace Masa.Mc.Service.Admin.Application.Unsubscriptions; + +public class UnsubscriptionCommandHandler +{ + private readonly UnsubscriptionDomainService _unsubscriptionDomainService; + private readonly IUserContext _userContext; + private readonly IAuthClient _authClient; + private readonly IChannelRepository _channelRepository; + private readonly IMessageTemplateRepository _messageTemplateRepository; + + public UnsubscriptionCommandHandler( + UnsubscriptionDomainService unsubscriptionDomainService, + IUserContext userContext, + IAuthClient authClient, + IChannelRepository channelRepository, + IMessageTemplateRepository messageTemplateRepository) + { + _unsubscriptionDomainService = unsubscriptionDomainService; + _userContext = userContext; + _authClient = authClient; + _channelRepository = channelRepository; + _messageTemplateRepository = messageTemplateRepository; + } + + [EventHandler] + public async Task AddChannelUserIdentityToBlacklistAsync(AddChannelUserIdentityToUnsubscriptionBlacklistCommand command) + { + var channel = await ResolveChannelAsync(command.Input.ChannelCode); + var templateId = await ResolveTemplateIdAsync(channel.Id, command.Input.TemplateCode); + var operatorName = await ResolveCurrentOperatorDisplayNameAsync(); + + var channelType = (ChannelTypes)Enum.Parse(typeof(ChannelTypes), channel.Type.Id.ToString()); + var (targetUserId, targetChannelUserIdentity) = await ResolveTargetUserAsync( + channelType, + command.Input.UserId, + command.Input.ChannelUserIdentity); + await _unsubscriptionDomainService.AddChannelUserIdentityToBlacklistAsync( + targetUserId, + channel.Id, + channelType, + channel.Provider, + targetChannelUserIdentity, + templateId, + command.Input.Reason, + operatorName); + } + + [EventHandler] + public async Task RemoveChannelUserIdentityFromBlacklistAsync(RemoveChannelUserIdentityFromUnsubscriptionBlacklistCommand command) + { + var channel = await ResolveChannelAsync(command.Input.ChannelCode); + var templateId = await ResolveTemplateIdAsync(channel.Id, command.Input.TemplateCode); + var operatorName = await ResolveCurrentOperatorDisplayNameAsync(); + + var channelType = (ChannelTypes)Enum.Parse(typeof(ChannelTypes), channel.Type.Id.ToString()); + await _unsubscriptionDomainService.RemoveChannelUserIdentityFromBlacklistAsync( + _userContext.GetUserId(), + channel.Id, + channelType, + channel.Provider, + command.Input.ChannelUserIdentity, + templateId, + command.Input.Reason, + operatorName); + } + + private async Task ResolveChannelAsync(string channelCode) + { + var normalizedChannelCode = channelCode?.Trim(); + if (string.IsNullOrWhiteSpace(normalizedChannelCode)) + { + throw new UserFriendlyException(errorCode: UserFriendlyExceptionCodes.CHANNEL_REQUIRED); + } + + var channel = await _channelRepository.FindAsync(x => x.Code == normalizedChannelCode); + MasaArgumentException.ThrowIfNull(channel, nameof(Channel)); + return channel!; + } + + private async Task ResolveTemplateIdAsync(Guid channelId, string templateCode) + { + var normalizedTemplateCode = templateCode?.Trim(); + if (string.IsNullOrWhiteSpace(normalizedTemplateCode)) + { + return null; + } + + var template = await _messageTemplateRepository.FindAsync(x => + x.ChannelId == channelId && + x.Code == normalizedTemplateCode); + if (template is null) + { + throw new UserFriendlyException(errorCode: UserFriendlyExceptionCodes.MESSAGE_TEMPLATE_NOT_EXIST); + } + + return template.Id; + } + + private async Task ResolveTargetUserIdAsync(ChannelTypes channelType, string channelUserIdentity) + { + var normalizedChannelUserIdentity = channelUserIdentity?.Trim(); + if (string.IsNullOrWhiteSpace(normalizedChannelUserIdentity)) + { + throw new UserFriendlyException(errorCode: UnsubscriptionExceptionCodes.CHANNEL_USER_IDENTITY_REQUIRED); + } + + if (channelType == ChannelTypes.WebsiteMessage && Guid.TryParse(normalizedChannelUserIdentity, out var websiteUserId)) + { + return websiteUserId; + } + + UserModel? user = channelType switch + { + ChannelTypes.Sms => await _authClient.UserService.GetByPhoneNumberAsync(normalizedChannelUserIdentity), + ChannelTypes.Email => await _authClient.UserService.GetByEmailAsync(normalizedChannelUserIdentity), + _ => null + }; + + if (user is not null && user.Id != Guid.Empty) + { + return user.Id; + } + + throw new UserFriendlyException(errorCode: UnsubscriptionExceptionCodes.CHANNEL_USER_IDENTITY_REQUIRED); + } + + private async Task<(Guid userId, string channelUserIdentity)> ResolveTargetUserAsync( + ChannelTypes channelType, + Guid? inputUserId, + string inputChannelUserIdentity) + { + if (inputUserId.HasValue && inputUserId.Value != Guid.Empty) + { + var users = await _authClient.UserService.GetListByIdsAsync(new[] { inputUserId.Value }); + var user = users.FirstOrDefault(x => x.Id == inputUserId.Value); + if (user is null) + { + throw new UserFriendlyException(errorCode: UnsubscriptionExceptionCodes.CHANNEL_USER_IDENTITY_REQUIRED); + } + + var resolvedChannelUserIdentity = ResolveChannelUserIdentityByUser(channelType, user); + if (string.IsNullOrWhiteSpace(resolvedChannelUserIdentity)) + { + throw new UserFriendlyException(errorCode: UnsubscriptionExceptionCodes.CHANNEL_USER_IDENTITY_REQUIRED); + } + + return (inputUserId.Value, resolvedChannelUserIdentity.Trim()); + } + + var targetUserId = await ResolveTargetUserIdAsync(channelType, inputChannelUserIdentity); + return (targetUserId, inputChannelUserIdentity.Trim()); + } + + private static string ResolveChannelUserIdentityByUser(ChannelTypes channelType, UserModel user) + { + return channelType switch + { + ChannelTypes.Sms => user.PhoneNumber ?? string.Empty, + ChannelTypes.Email => user.Email ?? string.Empty, + ChannelTypes.WebsiteMessage => user.Id.ToString(), + _ => string.Empty + }; + } + + private async Task ResolveCurrentOperatorDisplayNameAsync() + { + var operatorId = _userContext.GetUserId(); + if (operatorId == Guid.Empty) + { + return "-"; + } + + var users = await _authClient.UserService.GetListByIdsAsync(new[] { operatorId }); + var operatorName = users.FirstOrDefault()?.RealDisplayName?.Trim(); + return string.IsNullOrWhiteSpace(operatorName) ? "-" : operatorName; + } +} diff --git a/src/Services/Masa.Mc.Service/Application/Unsubscriptions/UnsubscriptionQueryHandler.cs b/src/Services/Masa.Mc.Service/Application/Unsubscriptions/UnsubscriptionQueryHandler.cs index a79aeea2..c75d28a1 100644 --- a/src/Services/Masa.Mc.Service/Application/Unsubscriptions/UnsubscriptionQueryHandler.cs +++ b/src/Services/Masa.Mc.Service/Application/Unsubscriptions/UnsubscriptionQueryHandler.cs @@ -57,6 +57,88 @@ public async Task GetAsync(GetUnsubscriptionQuery query) query.Result = dto; } + [EventHandler] + public async Task GetChannelUserIdentityUnsubscriptionsAsync(GetChannelUserIdentityUnsubscriptionsQuery query) + { + var normalizedChannelCode = query.ChannelCode?.Trim(); + var normalizedChannelUserIdentity = query.ChannelUserIdentity?.Trim(); + if (string.IsNullOrWhiteSpace(normalizedChannelCode) || string.IsNullOrWhiteSpace(normalizedChannelUserIdentity)) + { + query.Result = new(); + return; + } + + var channel = await _context.ChannelQueryQueries + .AsNoTracking() + .Where(x => x.Code == normalizedChannelCode) + .Select(x => new + { + x.Id, + x.Type, + x.Provider + }) + .FirstOrDefaultAsync(); + if (channel is null) + { + query.Result = new(); + return; + } + + var activeUnsubscriptions = await _context.UnsubscriptionQueries + .AsNoTracking() + .Where(x => + x.ChannelId == channel.Id && + x.ChannelType == channel.Type && + x.ChannelProvider == channel.Provider && + x.ChannelUserIdentity == normalizedChannelUserIdentity && + x.Status == UnsubscriptionStatus.Unsubscribed) + .OrderByDescending(x => x.UnsubscribedAt) + .ToListAsync(); + if (!activeUnsubscriptions.Any()) + { + query.Result = new(); + return; + } + + var templateIds = activeUnsubscriptions + .Where(x => x.ScopeType == UnsubscriptionScopeTypes.Template) + .Select(x => Guid.TryParse(x.ScopeRefId, out var templateId) ? templateId : Guid.Empty) + .Where(x => x != Guid.Empty) + .Distinct() + .ToList(); + var templateDict = templateIds.Any() + ? await _context.MessageTemplateQueries + .AsNoTracking() + .Where(x => templateIds.Contains(x.Id)) + .Select(x => new MessageTemplateLookupItem(x.Id, x.Code, x.DisplayName, x.Content)) + .ToDictionaryAsync(x => x.Id) + : new Dictionary(); + + query.Result = activeUnsubscriptions + .Select(item => + { + var templateId = item.ScopeType == UnsubscriptionScopeTypes.Template && + Guid.TryParse(item.ScopeRefId, out var parsedTemplateId) + ? parsedTemplateId + : (Guid?)null; + MessageTemplateLookupItem? template = null; + if (templateId.HasValue) + { + templateDict.TryGetValue(templateId.Value, out template); + } + + return new ChannelUserIdentityUnsubscriptionItemDto + { + ChannelUserIdentity = item.ChannelUserIdentity, + TemplateId = templateId, + TemplateCode = template?.Code ?? string.Empty, + TemplateName = template?.DisplayName ?? string.Empty, + TemplateContent = template?.Content ?? string.Empty + }; + }) + .ToList(); + } + private static Expression> CreatePredicate(GetUnsubscriptionInputDto input) { var condition = CreateUnsubscriptionScopePredicate(input); @@ -163,10 +245,12 @@ private async Task FillUserDisplayNamesAsync(List dtos) item.UserDisplayName = userDisplayName; } - if (users.TryGetValue(item.Modifier, out var modifierName)) + var operatorUserId = item.Modifier != Guid.Empty ? item.Modifier : item.UserId; + if (operatorUserId != Guid.Empty && users.TryGetValue(operatorUserId, out var modifierName)) { item.ModifierName = modifierName; } } } + } diff --git a/src/Services/Masa.Mc.Service/Application/Unsubscriptions/UnsubscriptionTimelineQueryHandler.cs b/src/Services/Masa.Mc.Service/Application/Unsubscriptions/UnsubscriptionTimelineQueryHandler.cs index e761fbf4..23756044 100644 --- a/src/Services/Masa.Mc.Service/Application/Unsubscriptions/UnsubscriptionTimelineQueryHandler.cs +++ b/src/Services/Masa.Mc.Service/Application/Unsubscriptions/UnsubscriptionTimelineQueryHandler.cs @@ -33,10 +33,10 @@ on timeline.UnsubscriptionId equals unsubscription.Id ChannelId = unsubscription.ChannelId, ScopeType = unsubscription.ScopeType, ScopeRefId = unsubscription.ScopeRefId, - Source = timeline.Source, + Source = unsubscription.Source, Action = timeline.Action, Status = unsubscription.Status, - Keyword = timeline.Keyword, + Keyword = unsubscription.Keyword, Detail = timeline.Detail, OccurredAt = timeline.OccurredAt, Operator = timeline.Creator == Guid.Empty ? unsubscription.Modifier : timeline.Creator @@ -77,14 +77,14 @@ private static Expression> CreateUnsubscrip condition = condition.And(input.UserId.HasValue, x => x.UserId == input.UserId); condition = condition.And(!string.IsNullOrWhiteSpace(input.ChannelUserIdentity), x => x.ChannelUserIdentity.Contains(input.ChannelUserIdentity)); condition = condition.And(!string.IsNullOrWhiteSpace(input.ScopeRefId), x => x.ScopeRefId == input.ScopeRefId); + condition = condition.And(!string.IsNullOrWhiteSpace(input.Keyword), x => x.Keyword.Contains(input.Keyword)); + condition = condition.And(input.Source.HasValue, x => x.Source == input.Source); return condition; } private static Expression> CreateTimelinePredicate(GetUnsubscriptionHistoryInputDto input) { Expression> condition = _ => true; - condition = condition.And(!string.IsNullOrWhiteSpace(input.Keyword), x => x.Keyword.Contains(input.Keyword)); - condition = condition.And(input.Source.HasValue, x => x.Source == input.Source); condition = condition.And(input.StartTime.HasValue, x => x.OccurredAt >= input.StartTime); condition = condition.And(input.EndTime.HasValue, x => x.OccurredAt <= input.EndTime); condition = condition.And(input.Action.HasValue, x => x.Action == input.Action); diff --git a/src/Services/Masa.Mc.Service/Assets/I18n/en-US.json b/src/Services/Masa.Mc.Service/Assets/I18n/en-US.json index 606abd3b..0fb905e4 100644 --- a/src/Services/Masa.Mc.Service/Assets/I18n/en-US.json +++ b/src/Services/Masa.Mc.Service/Assets/I18n/en-US.json @@ -8,6 +8,7 @@ "ReceiverGroup": "ReceiverGroup", "WebsiteMessage": "WebsiteMessage", "DailySendingLimit": "The maximum number of times to send per day has been reached", + "InboundAutoReplySkippedInNonProduction": "Skipped inbound auto reply SMS send in non-production environment", "NoValidData": "no valid data detected", "PhoneCannotEmpty": "Phone number cannot be empty", "EmailCannotEmpty": "Email cannot be empty", @@ -33,17 +34,21 @@ "TemplateIdCannotRepeated": "Template id cannot be repeated", "UnsubscribeKeywordRequired": "Please enter unsubscribe keyword", "UnsubscribeKeywordLength": "Unsubscribe keyword length must be between 1 and 20", - "UnsubscribeAutoReplyRequired": "Please enter unsubscribe auto reply", - "UnsubscribeAutoReplyLength": "Unsubscribe auto reply length must be between 1 and 500", + "UnsubscribeAutoReplyRequired": "Please select unsubscribe template", + "UnsubscribeAutoReplyLength": "Unsubscribe template ID length must be between 1 and 128", "ResubscribeKeywordRequired": "Please enter resubscribe keyword", "ResubscribeKeywordLength": "Resubscribe keyword length must be between 1 and 20", - "ResubscribeAutoReplyRequired": "Please enter resubscribe auto reply", - "ResubscribeAutoReplyLength": "Resubscribe auto reply length must be between 1 and 500", + "ResubscribeAutoReplyRequired": "Please select resubscribe template", + "ResubscribeAutoReplyLength": "Resubscribe template ID length must be between 1 and 128", "UnsubscribeKeywordsMustBeDifferent": "Unsubscribe and resubscribe keywords must be different", "UnsubscribeKeywordCannotUseProviderReservedKeyword": "Unsubscribe keyword cannot use provider reserved keywords", "UnsubscribeCooldownSecondsRequired": "Cooldown seconds must be greater than 0 when debounce is enabled", "VerificationCodeTemplateCannotEnableUnsubscribe": "Verification code templates cannot enable unsubscribe", "MessageBlockedByUnsubscription": "Blocked because the user has unsubscribed", + "UnsubscriptionInboundUnsubscribeReason": "Unsubscribed by inbound keyword", + "UnsubscriptionInboundResubscribeReason": "Resubscribed by inbound keyword", + "UnsubscriptionManualBlacklistReason": "Manually added to unsubscription blacklist", + "UnsubscriptionManualRemoveBlacklistReason": "Manually removed from unsubscription blacklist", "ReceiverGroupNameCannotRepeated": "ReceiverGroup name cannot be repeated", "SyncSmsTemplateErrorMessage": "SMS template synchronization failed. Please check whether the channel information is correct", "ClientIdNotBound": "Client Id not bound", diff --git a/src/Services/Masa.Mc.Service/Assets/I18n/zh-CN.json b/src/Services/Masa.Mc.Service/Assets/I18n/zh-CN.json index 1ceef64b..42cd1c55 100644 --- a/src/Services/Masa.Mc.Service/Assets/I18n/zh-CN.json +++ b/src/Services/Masa.Mc.Service/Assets/I18n/zh-CN.json @@ -7,7 +7,8 @@ "MessageTaskHistory": "消æ¯ä»»åŠ¡åŽ†å²", "ReceiverGroup": "收件人组", "WebsiteMessage": "站内信", - "DailySendingLimit": "已达到æ¯å¤©å‘é€çš„æœ€å¤§æ¬¡æ•°", + "DailySendingLimit": "已达到æ¯å¤©å‘é€çš„æœ€å¤§æ¬¡æ•°", + "InboundAutoReplySkippedInNonProduction": "éžæ­£å¼çŽ¯å¢ƒå·²è·³è¿‡è‡ªåŠ¨å›žå¤çŸ­ä¿¡å‘é€", "NoValidData": "未检测到有效数æ®", "PhoneCannotEmpty": "电è¯å·ç ä¸èƒ½ä¸ºç©º", "EmailCannotEmpty": "邮箱ä¸èƒ½ä¸ºç©º", @@ -34,17 +35,21 @@ "TemplateIdCannotRepeated": "模æ¿ä¸èƒ½é‡å¤", "UnsubscribeKeywordRequired": "请输入退订关键è¯", "UnsubscribeKeywordLength": "退订关键è¯é•¿åº¦éœ€åœ¨1到20之间", - "UnsubscribeAutoReplyRequired": "请输入退订自动回å¤å†…容", - "UnsubscribeAutoReplyLength": "退订自动回å¤é•¿åº¦éœ€åœ¨1到500之间", +"UnsubscribeAutoReplyRequired": "请选择退订模æ¿", +"UnsubscribeAutoReplyLength": "退订模æ¿ID长度需在1到128之间", "ResubscribeKeywordRequired": "请输入æ¢å¤é€€è®¢å…³é”®è¯", "ResubscribeKeywordLength": "æ¢å¤é€€è®¢å…³é”®è¯é•¿åº¦éœ€åœ¨1到20之间", - "ResubscribeAutoReplyRequired": "请输入æ¢å¤é€€è®¢è‡ªåŠ¨å›žå¤å†…容", - "ResubscribeAutoReplyLength": "æ¢å¤é€€è®¢è‡ªåŠ¨å›žå¤é•¿åº¦éœ€åœ¨1到500之间", +"ResubscribeAutoReplyRequired": "请选择æ¢å¤æ¨¡æ¿", +"ResubscribeAutoReplyLength": "æ¢å¤æ¨¡æ¿ID长度需在1到128之间", "UnsubscribeKeywordsMustBeDifferent": "退订关键è¯ä¸Žæ¢å¤é€€è®¢å…³é”®è¯ä¸èƒ½ç›¸åŒ", "UnsubscribeKeywordCannotUseProviderReservedKeyword": "退订关键è¯ä¸èƒ½ä½¿ç”¨æ¸ é“厂商ä¿ç•™å…³é”®è¯", "UnsubscribeCooldownSecondsRequired": "å¼€å¯é˜²æŠ–åŽå†·å´æ—¶é—´å¿…须大于0ç§’", "VerificationCodeTemplateCannotEnableUnsubscribe": "验è¯ç æ¨¡æ¿ä¸å…许开å¯é€€è®¢", "MessageBlockedByUnsubscription": "因用户退订被拦截", + "UnsubscriptionInboundUnsubscribeReason": "用户上行关键字退订", + "UnsubscriptionInboundResubscribeReason": "用户上行关键字æ¢å¤é€€è®¢", + "UnsubscriptionManualBlacklistReason": "åŽå°æ‰‹åŠ¨æ‹‰å…¥é€€è®¢é»‘åå•", + "UnsubscriptionManualRemoveBlacklistReason": "åŽå°æ‰‹åŠ¨ç§»é™¤é€€è®¢é»‘åå•", "ReceiverGroupNameCannotRepeated": "消æ¯ç»„åç§°ä¸èƒ½é‡å¤", "SyncSmsTemplateErrorMessage": "短信模æ¿åŒæ­¥å¤±è´¥ï¼Œè¯·æ£€æŸ¥æ¸ é“ä¿¡æ¯æ˜¯å¦æ­£ç¡®", "ClientIdNotBound": "设备Id未绑定", diff --git a/src/Services/Masa.Mc.Service/Domain/Unsubscriptions/Services/UnsubscriptionDomainService.cs b/src/Services/Masa.Mc.Service/Domain/Unsubscriptions/Services/UnsubscriptionDomainService.cs index 3e20a678..35503713 100644 --- a/src/Services/Masa.Mc.Service/Domain/Unsubscriptions/Services/UnsubscriptionDomainService.cs +++ b/src/Services/Masa.Mc.Service/Domain/Unsubscriptions/Services/UnsubscriptionDomainService.cs @@ -5,16 +5,16 @@ namespace Masa.Mc.Service.Admin.Domain.Unsubscriptions.Services; public class UnsubscriptionDomainService : DomainService { - private const string INBOUND_UNSUBSCRIBE_REASON = "用户上行关键字退订"; - private const string INBOUND_RESUBSCRIBE_REASON = "用户上行关键字æ¢å¤é€€è®¢"; - private readonly IUnsubscriptionRepository _repository; + private readonly II18n _i18n; public UnsubscriptionDomainService( IDomainEventBus eventBus, - IUnsubscriptionRepository repository) : base(eventBus) + IUnsubscriptionRepository repository, + II18n i18n) : base(eventBus) { _repository = repository; + _i18n = i18n; } public async Task HandleSmsInboundKeywordAsync( @@ -27,11 +27,8 @@ public async Task HandleSmsInboundKeywordAsync( string keyword, DateTimeOffset occurredAt, string inboundMessageId, - Guid? matchedMessageRecordId, string matchedMessageSnapshot, DateTimeOffset? matchedMessageSentAt, - bool debounceEnabled, - int cooldownSeconds, CancellationToken cancellationToken = default) { if (action == SmsInboundKeywordAction.Unsubscribe) @@ -41,15 +38,13 @@ public async Task HandleSmsInboundKeywordAsync( channelUserIdentity, channelId, channelProvider, - templateId, + UnsubscriptionScopeTypes.Template, + templateId.ToString("N"), keyword, occurredAt, inboundMessageId, - matchedMessageRecordId, matchedMessageSnapshot, matchedMessageSentAt, - debounceEnabled, - cooldownSeconds, cancellationToken); return handled ? SmsInboundKeywordAction.Unsubscribe : SmsInboundKeywordAction.None; } @@ -70,45 +65,71 @@ public async Task HandleSmsInboundKeywordAsync( return SmsInboundKeywordAction.None; } + public async Task HandleSmsInboundProviderReservedUnsubscribeAsync( + Guid userId, + string channelUserIdentity, + Guid channelId, + int channelProvider, + string keyword, + DateTimeOffset occurredAt, + string inboundMessageId, + string matchedMessageSnapshot, + DateTimeOffset? matchedMessageSentAt, + CancellationToken cancellationToken = default) + { + return await HandleInboundUnsubscribeAsync( + userId, + channelUserIdentity, + channelId, + channelProvider, + UnsubscriptionScopeTypes.Channel, + string.Empty, + keyword, + occurredAt, + inboundMessageId, + matchedMessageSnapshot, + matchedMessageSentAt, + cancellationToken); + } + private async Task HandleInboundUnsubscribeAsync( Guid userId, string channelUserIdentity, Guid channelId, int channelProvider, - Guid templateId, + UnsubscriptionScopeTypes scopeType, + string scopeRefId, string keyword, DateTimeOffset occurredAt, string inboundMessageId, - Guid? matchedMessageRecordId, string matchedMessageSnapshot, DateTimeOffset? matchedMessageSentAt, - bool debounceEnabled, - int cooldownSeconds, CancellationToken cancellationToken = default) { - var scopeRefId = templateId.ToString("N"); var active = await _repository.FindActiveAsync( channelId, channelUserIdentity, - UnsubscriptionScopeTypes.Template, + scopeType, scopeRefId, cancellationToken); if (active is null) { + var timelineDetail = BuildInboundTimelineDetail(keyword, UnsubscriptionReasonConstants.INBOUND_UNSUBSCRIBE_REASON); + var outboundMessageDetail = BuildOutboundTimelineDetail(matchedMessageSnapshot); var aggregate = Unsubscription.CreateFromSmsInbound( userId, channelUserIdentity, channelId, channelProvider, - UnsubscriptionScopeTypes.Template, + scopeType, scopeRefId, keyword, - INBOUND_UNSUBSCRIBE_REASON, + LocalizeReason(UnsubscriptionReasonConstants.INBOUND_UNSUBSCRIBE_REASON), occurredAt, inboundMessageId, - matchedMessageRecordId, - matchedMessageSnapshot, + timelineDetail, + outboundMessageDetail, matchedMessageSentAt); await _repository.AddAsync(aggregate, cancellationToken); @@ -117,14 +138,12 @@ private async Task HandleInboundUnsubscribeAsync( var changed = active.TryUnsubscribeByInboundKeyword( keyword, - INBOUND_UNSUBSCRIBE_REASON, + LocalizeReason(UnsubscriptionReasonConstants.INBOUND_UNSUBSCRIBE_REASON), occurredAt, inboundMessageId, - matchedMessageRecordId, - matchedMessageSnapshot, - matchedMessageSentAt, - debounceEnabled, - cooldownSeconds); + BuildInboundTimelineDetail(keyword, UnsubscriptionReasonConstants.INBOUND_UNSUBSCRIBE_REASON), + BuildOutboundTimelineDetail(matchedMessageSnapshot), + matchedMessageSentAt); if (!changed) { return false; @@ -156,9 +175,10 @@ private async Task HandleInboundResubscribeAsync( active.ResubscribeByInboundKeyword( keyword, - INBOUND_RESUBSCRIBE_REASON, + LocalizeReason(UnsubscriptionReasonConstants.INBOUND_RESUBSCRIBE_REASON), occurredAt, - inboundMessageId); + inboundMessageId, + BuildInboundTimelineDetail(keyword, UnsubscriptionReasonConstants.INBOUND_RESUBSCRIBE_REASON)); await _repository.UpdateAsync(active, cancellationToken); return true; @@ -184,4 +204,184 @@ public async Task IsSmsTemplateUnsubscribedAsync( return aggregate is not null; } + + public async Task IsChannelUserIdentityUnsubscribedAsync( + string channelUserIdentity, + CancellationToken cancellationToken = default) + { + if (string.IsNullOrWhiteSpace(channelUserIdentity)) + { + return false; + } + + var existing = await _repository.FindAsync( + x => x.ChannelUserIdentity == channelUserIdentity.Trim() && + (x.ScopeType == UnsubscriptionScopeTypes.Channel || x.ScopeType == UnsubscriptionScopeTypes.Global) && + x.Status == UnsubscriptionStatus.Unsubscribed, + cancellationToken); + return existing is not null; + } + + public async Task AddChannelUserIdentityToBlacklistAsync( + Guid userId, + Guid channelId, + ChannelTypes channelType, + int channelProvider, + string channelUserIdentity, + Guid? templateId, + string reason, + string operatorName, + CancellationToken cancellationToken = default) + { + if (channelId == Guid.Empty) + { + throw new UserFriendlyException(errorCode: UserFriendlyExceptionCodes.CHANNEL_REQUIRED); + } + + if (string.IsNullOrWhiteSpace(channelUserIdentity)) + { + throw new UserFriendlyException(errorCode: UnsubscriptionExceptionCodes.CHANNEL_USER_IDENTITY_REQUIRED); + } + + var normalizedChannelUserIdentity = channelUserIdentity.Trim(); + var hasTemplateScope = templateId.HasValue && templateId.Value != Guid.Empty; + var scopeType = hasTemplateScope ? UnsubscriptionScopeTypes.Template : UnsubscriptionScopeTypes.Channel; + var scopeRefId = hasTemplateScope ? templateId!.Value.ToString("N") : string.Empty; + var active = await _repository.FindAsync( + x => x.ChannelId == channelId && + x.ChannelType == channelType && + x.ChannelProvider == channelProvider && + x.ChannelUserIdentity == normalizedChannelUserIdentity && + (hasTemplateScope + ? x.ScopeType == scopeType && x.ScopeRefId == scopeRefId + : x.ScopeType == UnsubscriptionScopeTypes.Channel || x.ScopeType == UnsubscriptionScopeTypes.Global) && + x.Status == UnsubscriptionStatus.Unsubscribed, + cancellationToken); + if (active is not null) + { + return; + } + + var localizedReason = string.IsNullOrWhiteSpace(reason) + ? LocalizeReason(UnsubscriptionReasonConstants.MANUAL_BLACKLIST_REASON) + : reason; + var timelineDetail = BuildManualUnsubscribedTimelineDetail(operatorName, localizedReason); + var aggregate = hasTemplateScope + ? Unsubscription.CreateManualBlacklist( + userId, + normalizedChannelUserIdentity, + channelId, + channelType, + channelProvider, + scopeType, + scopeRefId, + localizedReason, + DateTimeOffset.UtcNow, + timelineDetail) + : Unsubscription.CreateChannelManualBlacklist( + userId, + normalizedChannelUserIdentity, + channelId, + channelType, + channelProvider, + localizedReason, + DateTimeOffset.UtcNow, + timelineDetail); + await _repository.AddAsync(aggregate, cancellationToken); + } + + public async Task RemoveChannelUserIdentityFromBlacklistAsync( + Guid operatorId, + Guid channelId, + ChannelTypes channelType, + int channelProvider, + string channelUserIdentity, + Guid? templateId, + string reason, + string operatorName, + CancellationToken cancellationToken = default) + { + if (channelId == Guid.Empty) + { + throw new UserFriendlyException(errorCode: UserFriendlyExceptionCodes.CHANNEL_REQUIRED); + } + + if (string.IsNullOrWhiteSpace(channelUserIdentity)) + { + throw new UserFriendlyException(errorCode: UnsubscriptionExceptionCodes.CHANNEL_USER_IDENTITY_REQUIRED); + } + + var normalizedChannelUserIdentity = channelUserIdentity.Trim(); + var hasTemplateScope = templateId.HasValue && templateId.Value != Guid.Empty; + var scopeType = hasTemplateScope ? UnsubscriptionScopeTypes.Template : UnsubscriptionScopeTypes.Channel; + var scopeRefId = hasTemplateScope ? templateId!.Value.ToString("N") : string.Empty; + var active = await _repository.FindAsync( + x => x.ChannelId == channelId && + x.ChannelType == channelType && + x.ChannelProvider == channelProvider && + x.ChannelUserIdentity == normalizedChannelUserIdentity && + (hasTemplateScope + ? x.ScopeType == scopeType && x.ScopeRefId == scopeRefId + : x.ScopeType == UnsubscriptionScopeTypes.Channel || x.ScopeType == UnsubscriptionScopeTypes.Global) && + x.Status == UnsubscriptionStatus.Unsubscribed, + cancellationToken); + if (active is null) + { + return; + } + + var localizedReason = string.IsNullOrWhiteSpace(reason) + ? LocalizeReason(UnsubscriptionReasonConstants.MANUAL_REMOVE_BLACKLIST_REASON) + : reason; + active.Resubscribe( + localizedReason, + DateTimeOffset.UtcNow, + timelineDetail: BuildManualResubscribedTimelineDetail(operatorName, localizedReason)); + await _repository.UpdateAsync(active, cancellationToken); + } + + private string LocalizeReason(string reasonKey) + { + return _i18n.T(reasonKey); + } + + private string BuildInboundTimelineDetail(string keyword, string fallbackReasonKey) + { + var normalizedKeyword = keyword?.Trim(); + if (string.IsNullOrWhiteSpace(normalizedKeyword)) + { + return fallbackReasonKey == UnsubscriptionReasonConstants.INBOUND_RESUBSCRIBE_REASON + ? "收到上行(æ¢å¤é€€è®¢ï¼‰" + : "收到上行(退订)"; + } + + return $"收到上行“{normalizedKeyword}â€"; + } + + private string BuildOutboundTimelineDetail(string messageSnapshot) + { + var normalizedSnapshot = messageSnapshot?.Trim(); + if (string.IsNullOrWhiteSpace(normalizedSnapshot)) + { + return string.Empty; + } + + return $"å‘é€äº†â€œ{normalizedSnapshot}â€"; + } + + private string BuildManualUnsubscribedTimelineDetail(string operatorName, string reason) + { + return $"{NormalizeOperatorName(operatorName)}手动拉黑/ 原因:{reason?.Trim() ?? string.Empty}"; + } + + private string BuildManualResubscribedTimelineDetail(string operatorName, string reason) + { + return $"{NormalizeOperatorName(operatorName)}手动æ¢å¤/ æ¢å¤åŽŸå› ï¼š {reason?.Trim() ?? string.Empty}"; + } + + private static string NormalizeOperatorName(string operatorName) + { + var normalized = operatorName?.Trim(); + return string.IsNullOrWhiteSpace(normalized) ? "-" : normalized; + } } diff --git a/src/Services/Masa.Mc.Service/Infrastructure/EntityFrameworkCore/McQueryContext.cs b/src/Services/Masa.Mc.Service/Infrastructure/EntityFrameworkCore/McQueryContext.cs index 6dd838c6..c7b37517 100644 --- a/src/Services/Masa.Mc.Service/Infrastructure/EntityFrameworkCore/McQueryContext.cs +++ b/src/Services/Masa.Mc.Service/Infrastructure/EntityFrameworkCore/McQueryContext.cs @@ -61,11 +61,11 @@ protected override void OnModelCreatingExecuting(ModelBuilder builder) ub.HasKey("MessageTemplateId"); ub.Property(x => x.Enabled).HasColumnName(nameof(MessageTemplateUnsubscribeConfigQueryModel.Enabled)); ub.Property(x => x.UnsubscribeKeyword).HasColumnName(nameof(MessageTemplateUnsubscribeConfigQueryModel.UnsubscribeKeyword)); - ub.Property(x => x.UnsubscribeAutoReply).HasColumnName(nameof(MessageTemplateUnsubscribeConfigQueryModel.UnsubscribeAutoReply)); + ub.Property(x => x.UnsubscribeAutoReplyTemplateId) + .HasColumnName(nameof(MessageTemplateUnsubscribeConfigQueryModel.UnsubscribeAutoReplyTemplateId)); ub.Property(x => x.ResubscribeKeyword).HasColumnName(nameof(MessageTemplateUnsubscribeConfigQueryModel.ResubscribeKeyword)); - ub.Property(x => x.ResubscribeAutoReply).HasColumnName(nameof(MessageTemplateUnsubscribeConfigQueryModel.ResubscribeAutoReply)); - ub.Property(x => x.DebounceEnabled).HasColumnName(nameof(MessageTemplateUnsubscribeConfigQueryModel.DebounceEnabled)); - ub.Property(x => x.CooldownSeconds).HasColumnName(nameof(MessageTemplateUnsubscribeConfigQueryModel.CooldownSeconds)); + ub.Property(x => x.ResubscribeAutoReplyTemplateId) + .HasColumnName(nameof(MessageTemplateUnsubscribeConfigQueryModel.ResubscribeAutoReplyTemplateId)); }); b.Navigation(x => x.UnsubscribeConfig).IsRequired(false); }); @@ -186,4 +186,5 @@ private void ApplyProviderSpecificConfigurations(ModelBuilder builder) } } } + } diff --git a/src/Services/Masa.Mc.Service/Services/MessageRecordService.cs b/src/Services/Masa.Mc.Service/Services/MessageRecordService.cs index e7b71885..6d8df5ef 100644 --- a/src/Services/Masa.Mc.Service/Services/MessageRecordService.cs +++ b/src/Services/Masa.Mc.Service/Services/MessageRecordService.cs @@ -35,4 +35,28 @@ public async Task RetryAsync(IEventBus eventBus, RetryMessageRecordInputDto inpu var command = new RetryMessageRecordCommand(inputDto); await eventBus.PublishAsync(command); } + + [RoutePattern("sms-records", StartWithBaseUri = true, HttpMethod = "Get")] + public async Task> GetSmsRecordsAsync( + IEventBus eventBus, + [FromQuery] string mobile, + [FromQuery] string channelCode = "", + [FromQuery] int page = 1, + [FromQuery] int pagesize = 10) + { + var query = new GetSmsRecordsByMobileQuery(mobile, channelCode, page, pagesize); + await eventBus.PublishAsync(query); + return query.Result; + } + + [RoutePattern("sms-interaction-history", StartWithBaseUri = true, HttpMethod = "Get")] + public async Task> GetSmsInteractionHistoryAsync( + IEventBus eventBus, + [FromQuery] string mobile, + [FromQuery] Guid channelId) + { + var query = new GetSmsInteractionHistoryQuery(mobile, channelId); + await eventBus.PublishAsync(query); + return query.Result; + } } diff --git a/src/Services/Masa.Mc.Service/Services/SmsInboundService.cs b/src/Services/Masa.Mc.Service/Services/SmsInboundService.cs index dae0124d..5d094373 100644 --- a/src/Services/Masa.Mc.Service/Services/SmsInboundService.cs +++ b/src/Services/Masa.Mc.Service/Services/SmsInboundService.cs @@ -14,12 +14,14 @@ public SmsInboundService() : base("api/sms-inbound") } [RoutePattern("", StartWithBaseUri = true, HttpMethod = "Get")] - public async Task> GetListAsync(IEventBus eventBus, [FromQuery] Guid channelId, + public async Task> GetListAsync(IEventBus eventBus, [FromQuery] Guid? channelId, + [FromQuery] string? channelCode, + [FromQuery] SmsInboundProviders? provider, [FromQuery] DateTimeOffset? startTime, [FromQuery] DateTimeOffset? endTime, [FromQuery] string mobile = "", [FromQuery] string addSerial = "", [FromQuery] string smsContent = "", [FromQuery] string sorting = "", [FromQuery] int page = 1, [FromQuery] int pagesize = 10) { - var input = new GetSmsInboundInputDto(channelId, mobile, addSerial, smsContent, startTime, endTime, sorting, page, pagesize); + var input = new GetSmsInboundInputDto(channelId, channelCode ?? string.Empty, provider, mobile, addSerial, smsContent, startTime, endTime, sorting, page, pagesize); var query = new GetListSmsInboundQuery(input); await eventBus.PublishAsync(query); return query.Result; diff --git a/src/Services/Masa.Mc.Service/Services/UnsubscriptionService.cs b/src/Services/Masa.Mc.Service/Services/UnsubscriptionService.cs index 751c9b6f..8f08d24c 100644 --- a/src/Services/Masa.Mc.Service/Services/UnsubscriptionService.cs +++ b/src/Services/Masa.Mc.Service/Services/UnsubscriptionService.cs @@ -49,47 +49,40 @@ public async Task> GetListAsync( return query.Result; } - [RoutePattern("history", StartWithBaseUri = true, HttpMethod = "Get")] - public async Task> GetHistoryListAsync( - IEventBus eventBus, - [FromQuery] Guid? channelId, - [FromQuery] Guid? userId, - [FromQuery] UnsubscriptionSource? source, - [FromQuery] UnsubscriptionTimelineActions? action, - [FromQuery] DateTimeOffset? startTime, - [FromQuery] DateTimeOffset? endTime, - [FromQuery] string filter = "", - [FromQuery] string channelUserIdentity = "", - [FromQuery] string scopeRefId = "", - [FromQuery] string keyword = "", - [FromQuery] string sorting = "", - [FromQuery] int page = 1, - [FromQuery] int pagesize = 10) + [RoutePattern("{id}", StartWithBaseUri = true, HttpMethod = "Get")] + public async Task GetAsync(IEventBus eventBus, Guid id) { - var input = new GetUnsubscriptionHistoryInputDto( - channelId, - userId, - filter, - channelUserIdentity, - scopeRefId, - keyword, - source, - action, - startTime, - endTime, - sorting, - page, - pagesize); - var query = new GetUnsubscriptionHistoryListQuery(input); + var query = new GetUnsubscriptionQuery(id); await eventBus.PublishAsync(query); return query.Result; } - [RoutePattern("{id}", StartWithBaseUri = true, HttpMethod = "Get")] - public async Task GetAsync(IEventBus eventBus, Guid id) + [RoutePattern("channel-user-identities", StartWithBaseUri = true, HttpMethod = "Get")] + public async Task> GetChannelUserIdentityUnsubscriptionsAsync( + IEventBus eventBus, + [FromQuery] string channelCode, + [FromQuery] string channelUserIdentity) { - var query = new GetUnsubscriptionQuery(id); + var query = new GetChannelUserIdentityUnsubscriptionsQuery(channelCode, channelUserIdentity); await eventBus.PublishAsync(query); return query.Result; } + + [RoutePattern("channel-user-identities/unsubscriptions", StartWithBaseUri = true, HttpMethod = "Post")] + public async Task AddChannelUserIdentityToBlacklistAsync( + IEventBus eventBus, + [FromBody] AddChannelUserIdentityToUnsubscriptionBlacklistInputDto input) + { + var command = new AddChannelUserIdentityToUnsubscriptionBlacklistCommand(input); + await eventBus.PublishAsync(command); + } + + [RoutePattern("channel-user-identities/unsubscriptions", StartWithBaseUri = true, HttpMethod = "Delete")] + public async Task RemoveChannelUserIdentityFromBlacklistAsync( + IEventBus eventBus, + [FromBody] RemoveChannelUserIdentityFromUnsubscriptionBlacklistInputDto input) + { + var command = new RemoveChannelUserIdentityFromUnsubscriptionBlacklistCommand(input); + await eventBus.PublishAsync(command); + } } diff --git a/src/Services/Masa.Mc.Service/_Imports.cs b/src/Services/Masa.Mc.Service/_Imports.cs index 5ea690e9..121efcce 100644 --- a/src/Services/Masa.Mc.Service/_Imports.cs +++ b/src/Services/Masa.Mc.Service/_Imports.cs @@ -82,6 +82,7 @@ global using Masa.Mc.Domain.Channels.Aggregates; global using Masa.Mc.Domain.Channels.Events; global using Masa.Mc.Domain.Channels.Repositories; +global using Masa.Mc.Domain.Constants; global using Masa.Mc.Domain.Consts; global using Masa.Mc.Domain.MessageInfos.Aggregates; global using Masa.Mc.Domain.MessageInfos.Repositories; diff --git a/src/Web/Masa.Mc.Web.Admin.Server/Certificates/7348307__lonsid.cn.pfx b/src/Web/Masa.Mc.Web.Admin.Server/Certificates/7348307__lonsid.cn.pfx deleted file mode 100644 index 5a014fef..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.Server/Certificates/7348307__lonsid.cn.pfx and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.Server/Dockerfile b/src/Web/Masa.Mc.Web.Admin.Server/Dockerfile deleted file mode 100644 index c6c32f31..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM registry.cn-hangzhou.aliyuncs.com/masa/dotnet_sdk:6.0.100 AS publish -WORKDIR /src -COPY . . -ENV CSPROJ="src/Web/Masa.Mc.Web.Admin.Server/Masa.Mc.Web.Admin.Server.csproj" -RUN dotnet restore $CSPROJ && dotnet publish $CSPROJ -c Release -o /app/publish - - -FROM registry.cn-hangzhou.aliyuncs.com/masa/dotnet_aspnet:6.0.4 -WORKDIR /app -COPY --from=publish /app/publish . -COPY ["src/Web/Masa.Mc.Web.Admin/wwwroot/i18n","wwwroot/i18n"] -ENV ASPNETCORE_URLS=https://0.0.0.0:443 -EXPOSE 80 -EXPOSE 443 -ENTRYPOINT ["dotnet", "Masa.Mc.Web.Admin.Server.dll"] \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin.Server/Masa.Mc.Web.Admin.Server.csproj b/src/Web/Masa.Mc.Web.Admin.Server/Masa.Mc.Web.Admin.Server.csproj deleted file mode 100644 index 041da8ba..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/Masa.Mc.Web.Admin.Server.csproj +++ /dev/null @@ -1,37 +0,0 @@ - - - - net6.0 - enable - enable - ..\..\..\docker-compose.dcproj - d1f0bc4d-1731-474c-8478-296e92befe3d - Linux - ..\..\.. - false - false - - - - - - - - - - - - - - - PreserveNewest - - - - - - PreserveNewest - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.Server/Pages/Error.cshtml b/src/Web/Masa.Mc.Web.Admin.Server/Pages/Error.cshtml deleted file mode 100644 index 7d873c6f..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/Pages/Error.cshtml +++ /dev/null @@ -1,43 +0,0 @@ -@page -@model Masa.Mc.Web.Admin.Pages.ErrorModel - - - - - - - - Error - - - - -
-
-

Error.

-

An error occurred while processing your request.

- - @if (Model.ShowRequestId) - { -

- Request ID: @Model.RequestId -

- } - -

Development Mode

-

- Swapping to the Development environment displays detailed information about the error - that occurred. -

-

- The Development environment shouldn't be enabled for deployed applications. - It can result in displaying sensitive information from exceptions to end users. - For local debugging, enable the Development environment by setting the - ASPNETCORE_ENVIRONMENT environment variable to Development - and restarting the app. -

-
-
- - - diff --git a/src/Web/Masa.Mc.Web.Admin.Server/Pages/Error.cshtml.cs b/src/Web/Masa.Mc.Web.Admin.Server/Pages/Error.cshtml.cs deleted file mode 100644 index ae7ece82..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/Pages/Error.cshtml.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.RazorPages; -using System.Diagnostics; - -namespace Masa.Mc.Web.Admin.Pages -{ - [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] - [IgnoreAntiforgeryToken] - public class ErrorModel : PageModel - { - public string? RequestId { get; set; } - - public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); - - private readonly ILogger _logger; - - public ErrorModel(ILogger logger) - { - _logger = logger; - } - - public void OnGet() - { - RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; - } - } -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin.Server/Pages/Login.cshtml b/src/Web/Masa.Mc.Web.Admin.Server/Pages/Login.cshtml deleted file mode 100644 index bbe89852..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/Pages/Login.cshtml +++ /dev/null @@ -1,2 +0,0 @@ -@page -@model Masa.Mc.Web.Admin.Server.Pages.LoginModel diff --git a/src/Web/Masa.Mc.Web.Admin.Server/Pages/Login.cshtml.cs b/src/Web/Masa.Mc.Web.Admin.Server/Pages/Login.cshtml.cs deleted file mode 100644 index f03bee22..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/Pages/Login.cshtml.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Server.Pages; - -public class LoginModel : PageModel -{ - public async Task OnGetAsync(string redirectUri) - { - // just to remove compiler warning - await Task.CompletedTask; - - if (string.IsNullOrWhiteSpace(redirectUri)) - { - redirectUri = Url.Content("~/"); - } - - // If user is already logged in, we can redirect directly... - if (HttpContext.User.Identity != null && HttpContext.User.Identity.IsAuthenticated) - { - Response.Redirect(redirectUri); - } - - return Challenge( - new AuthenticationProperties - { - RedirectUri = redirectUri - }, - OpenIdConnectDefaults.AuthenticationScheme); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin.Server/Pages/Logout.cshtml b/src/Web/Masa.Mc.Web.Admin.Server/Pages/Logout.cshtml deleted file mode 100644 index f9f74c22..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/Pages/Logout.cshtml +++ /dev/null @@ -1,2 +0,0 @@ -@page -@model Masa.Mc.Web.Admin.Server.Pages.LogoutModel diff --git a/src/Web/Masa.Mc.Web.Admin.Server/Pages/Logout.cshtml.cs b/src/Web/Masa.Mc.Web.Admin.Server/Pages/Logout.cshtml.cs deleted file mode 100644 index 61616ca5..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/Pages/Logout.cshtml.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Authentication.Cookies; -using Microsoft.AspNetCore.Authentication.OpenIdConnect; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.RazorPages; - -namespace Masa.Mc.Web.Admin.Server.Pages; - -public class LogoutModel : PageModel -{ - public async Task OnGetAsync() - { - if (User.Identity != null && User.Identity.IsAuthenticated == true) - { - // delete local authentication cookie - await HttpContext.SignOutAsync(); - } - - return SignOut( - new AuthenticationProperties - { - RedirectUri = "/" - }, - OpenIdConnectDefaults.AuthenticationScheme, - CookieAuthenticationDefaults.AuthenticationScheme); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin.Server/Pages/_Host.cshtml b/src/Web/Masa.Mc.Web.Admin.Server/Pages/_Host.cshtml deleted file mode 100644 index d437a902..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/Pages/_Host.cshtml +++ /dev/null @@ -1,15 +0,0 @@ -@page "/" -@namespace Masa.Mc.Web.Admin.Pages -@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers -@{ - Layout = "_Layout"; - - var tokens = new TokenProvider - { - AccessToken = await HttpContext.GetTokenAsync(OpenIdConnectParameterNames.AccessToken), - RefreshToken = await HttpContext.GetTokenAsync(OpenIdConnectParameterNames.RefreshToken), - IdToken = await HttpContext.GetTokenAsync(OpenIdConnectParameterNames.IdToken) - }; -} - - diff --git a/src/Web/Masa.Mc.Web.Admin.Server/Pages/_Layout.cshtml b/src/Web/Masa.Mc.Web.Admin.Server/Pages/_Layout.cshtml deleted file mode 100644 index 507f6603..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/Pages/_Layout.cshtml +++ /dev/null @@ -1,50 +0,0 @@ -@using Microsoft.AspNetCore.Components.Web -@namespace Masa.Mc.Web.Admin.Server.Pages -@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers - - - - - - - - Masa.Mc.Web.Admin - - - - - - - - - - - - - - - - - - - @RenderBody() - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.Server/Program.cs b/src/Web/Masa.Mc.Web.Admin.Server/Program.cs deleted file mode 100644 index 7a592dbb..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/Program.cs +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -var builder = WebApplication.CreateBuilder(args); - -ValidatorOptions.Global.LanguageManager = new MasaLanguageManager(); -GlobalValidationOptions.SetDefaultCulture("zh-CN"); - -await builder.Services.AddMasaStackConfigAsync(MasaStackProject.MC, MasaStackApp.WEB); -var masaStackConfig = builder.Services.GetMasaStackConfig(); - -if (!builder.Environment.IsDevelopment()) -{ - builder.WebHost.UseKestrel(option => - { - option.ConfigureHttpsDefaults(options => - { - options.ServerCertificate = X509Certificate2.CreateFromPemFile("./ssl/tls.crt", "./ssl/tls.key"); - options.CheckCertificateRevocation = false; - }); - }); -} - -// Add services to the container. -builder.Services.AddRazorPages(); -builder.Services.AddServerSideBlazor(); -builder.Services.AddBlazorDownloadFile(); - -builder.Services.AddResponseCompression(opts => -{ - opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat( - new[] { "application/octet-stream" }); -}); -var authBaseAddress = masaStackConfig.GetAuthServiceDomain(); -var mcBaseAddress = builder.Services.GetMasaConfiguration().ConfigurationApi.GetDefault().GetValue("AppSettings:McClient:Url"); - -if (string.IsNullOrEmpty(mcBaseAddress)) -{ - mcBaseAddress = masaStackConfig.GetMcServiceDomain(); -} - -await builder.Services.AddMasaStackComponentsAsync(MasaStackProject.MC, "wwwroot/i18n", authBaseAddress); - -builder.Services.AddHttpContextAccessor(); -builder.Services.AddGlobalForServer(); -builder.Services.AddScoped(); -builder.Services.AddSingleton(); -TypeAdapterConfig.GlobalSettings.Scan(Assembly.GetExecutingAssembly(), Assembly.Load("Masa.Mc.Contracts.Admin"), Assembly.Load("Masa.Mc.Web.Admin")); -MasaOpenIdConnectOptions masaOpenIdConnectOptions = new MasaOpenIdConnectOptions -{ - Authority = masaStackConfig.GetSsoDomain(), - ClientId = masaStackConfig.GetWebId(MasaStackProject.MC), - Scopes = new List { "offline_access" } -}; ; - -IdentityModelEventSource.ShowPII = true; -builder.Services.AddMasaOpenIdConnect(masaOpenIdConnectOptions); - -builder.Services.AddMcApiGateways(option => -{ - option.McServiceBaseAddress = mcBaseAddress; - option.AuthorityEndpoint = masaOpenIdConnectOptions.Authority; - option.ClientId = masaOpenIdConnectOptions.ClientId; - option.ClientSecret = masaOpenIdConnectOptions.ClientSecret; -}); - -StaticWebAssetsLoader.UseStaticWebAssets(builder.Environment, builder.Configuration); - -var app = builder.Build(); - -// Configure the HTTP request pipeline. -if (app.Environment.IsDevelopment()) -{ - app.UseDeveloperExceptionPage(); -} -else -{ - app.UseExceptionHandler("/Error"); - // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. - app.UseHsts(); -} - -app.UseHttpsRedirection(); - -app.UseStaticFiles(); - -app.UseRouting(); - -app.UseAuthentication(); -app.UseAuthorization(); - -app.MapControllers(); -app.MapBlazorHub(); -app.MapFallbackToPage("/_Host"); -app.Run(); \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin.Server/Properties/launchSettings.json b/src/Web/Masa.Mc.Web.Admin.Server/Properties/launchSettings.json deleted file mode 100644 index 85c423d3..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/Properties/launchSettings.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:9877", - "sslPort": 44650 - } - }, - "profiles": { - "Masa.Mc.Web.Admin": { - "commandName": "Project", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development", - "MASA_CLUSTER": "Default", - "DCC_SECRET": "masastack.com", - "ADMIN_PWD": "admin123", - "DOMAIN_NAME": "masastack.com", - "MASA_NAMESPACE": "masastack", - "TLS_NAME": "masastack", - "MASA_VERSION": "1.0-Prev", - "IS_DEMO": "false", - "MASA_ENVIRONMENT": "Development", - "OTLP_URL": "http://otel-collector.masastack:9013", - "ELASTIC": "{\"Nodes\": [\"http://es-ydy-new.lonsid.cn:9200\"],\"Index\": \"auth_user_development\"}", - "REDIS": "{\"RedisHost\": \"10.130.0.19\", \"RedisPort\": 2135, \"RedisDb\": 3,\"RedisPassword\": \"Hzss@123\"}", - "CONNECTIONSTRING": "{\"Server\": \"10.130.0.19\", \"Port\": 2415,\"Database\":\"mc-dev\",\"UserId\": \"ss\",\"Password\":\"Hzss@123\"}", - "MASA_STACK": "[{\"id\":\"pm\",\"service\":{\"id\":\"pm-service-dev\",\"domain\":\"http://pm-service-dev.masastack.com\"},\"web\":{\"id\":\"pm-web-dev\",\"domain\":\"https://pm-dev.masastack.com\"}},{\"id\":\"dcc\",\"service\":{\"id\":\"dcc-service-dev\",\"domain\":\"http://dcc-service-dev.masastack.com\"},\"web\":{\"id\":\"dcc-web-dev\",\"domain\":\"https://dcc-dev.masastack.com\"}},{\"id\":\"tsc\",\"service\":{\"id\":\"tsc-service-dev\",\"domain\":\"http://tsc-service-dev.masastack.com\"},\"web\":{\"id\":\"tsc-web-dev\",\"domain\":\"https://tsc-dev.masastack.com\"}},{\"id\":\"alert\",\"service\":{\"id\":\"alert-service-dev\",\"domain\":\"http://alert-service-dev.masastack.com\"},\"web\":{\"id\":\"alert-web-dev\",\"domain\":\"https://alert-dev.masastack.com\"}},{\"id\":\"scheduler\",\"service\":{\"id\":\"scheduler-service-dev\",\"domain\":\"http://scheduler-service-dev.masastack.com\"},\"worker\":{\"id\":\"scheduler-worker-dev\",\"domain\":\"http://scheduler-worker-dev.masastack.com\"},\"web\":{\"id\":\"scheduler-web-dev\",\"domain\":\"https://scheduler-dev.masastack.com\"}},{\"id\":\"mc\",\"service\":{\"id\":\"mc-service-dev\",\"domain\":\"http://mc-service-dev.masastack.com\"},\"web\":{\"id\":\"mc-web-dev\",\"domain\":\"https://mc-dev.masastack.com\"}},{\"id\":\"auth\",\"service\":{\"id\":\"auth-service-dev\",\"domain\":\"http://auth-service-dev.masastack.com\"},\"web\":{\"id\":\"auth-web-dev\",\"domain\":\"https://auth-dev.masastack.com\"},\"sso\":{\"id\":\"auth-sso-dev\",\"domain\":\"https://auth-sso-dev.masastack.com\"}}]" - }, - "applicationUrl": "https://localhost:19500;http://localhost:19510", - "dotnetRunMessages": true - }, - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "Docker": { - "commandName": "Docker", - "launchBrowser": true, - "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}", - "publishAllPorts": true, - "useSSL": true - } - } -} diff --git a/src/Web/Masa.Mc.Web.Admin.Server/_Imports.cs b/src/Web/Masa.Mc.Web.Admin.Server/_Imports.cs deleted file mode 100644 index a6375fe3..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/_Imports.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -// System Namespaces -global using System.Reflection; -global using System.Security.Cryptography.X509Certificates; - -// Microsoft Namespaces -global using Microsoft.AspNetCore.Authentication; -global using Microsoft.AspNetCore.Authentication.OpenIdConnect; -global using Microsoft.AspNetCore.Mvc; -global using Microsoft.AspNetCore.Mvc.RazorPages; -global using Microsoft.AspNetCore.ResponseCompression; -global using Microsoft.AspNetCore.Hosting.StaticWebAssets; -global using Microsoft.IdentityModel.Logging; -global using Microsoft.IdentityModel.Protocols.OpenIdConnect; - -// Third-party Libraries -global using BlazorDownloadFile; -global using FluentValidation; -global using FluentValidation.Resources; -global using Mapster; - -// MASA Building Blocks and Contrib Packages -global using Masa.Contrib.StackSdks.Caller; -global using Masa.Contrib.StackSdks.Config; -global using Masa.Contrib.Configuration.ConfigurationApi.Dcc; -global using Masa.Stack.Components.Extensions.OpenIdConnect; - -// MASA MC Contracts, Infrastructure, Domain, Services, and Application -global using Masa.Mc.ApiGateways.Caller; -global using Masa.Mc.Contracts.Admin.Dtos.Channels.Validator; - -// MASA Stack Components -global using Masa.Stack.Components; \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin.Server/appsettings.Develop.json b/src/Web/Masa.Mc.Web.Admin.Server/appsettings.Develop.json deleted file mode 100644 index f362ebef..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/appsettings.Develop.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Error" - } - }, - "AllowedHosts": "*", - "AppId": "mc-develop" -} - \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin.Server/appsettings.Development.json b/src/Web/Masa.Mc.Web.Admin.Server/appsettings.Development.json deleted file mode 100644 index 003f4b42..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/appsettings.Development.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Error" - } - }, - "AllowedHosts": "*", - "AppId": "mc-develop" -} diff --git a/src/Web/Masa.Mc.Web.Admin.Server/appsettings.Staging.json b/src/Web/Masa.Mc.Web.Admin.Server/appsettings.Staging.json deleted file mode 100644 index bb6b7d3d..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/appsettings.Staging.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Error" - } - }, - "AllowedHosts": "*", - "AppId": "mc-staging" -} - \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin.Server/appsettings.json b/src/Web/Masa.Mc.Web.Admin.Server/appsettings.json deleted file mode 100644 index f2f78acf..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/appsettings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Error" - } - }, - "AllowedHosts": "*", - "AppId": "mc-ui-demo" -} diff --git a/src/Web/Masa.Mc.Web.Admin.Server/ssl/tls.crt b/src/Web/Masa.Mc.Web.Admin.Server/ssl/tls.crt deleted file mode 100644 index 1198c59b..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/ssl/tls.crt +++ /dev/null @@ -1,39 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIGvzCCBaegAwIBAgIQDst0LJnPKMFkgmyOgbSX+jANBgkqhkiG9w0BAQsFADBf -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMR4wHAYDVQQDExVHZW9UcnVzdCBDTiBSU0EgQ0EgRzEw -HhcNMjIwMzAzMDAwMDAwWhcNMjMwMzE0MjM1OTU5WjCBiTELMAkGA1UEBhMCQ04x -EjAQBgNVBAgMCea1meaxn+ecgTESMBAGA1UEBwwJ5rip5bee5biCMTwwOgYDVQQK -DDPmtZnmsZ/mnJfor5flvrflgaXlurfppa7msLTorr7lpIfogqHku73mnInpmZDl -hazlj7gxFDASBgNVBAMMCyoubG9uc2lkLmNuMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEAtbKBcjdZEBM6LMREx/vWuAa81uJpe6IvwKEajHoZ5NRK1CyM -L+VYBeKYhgRmBzgjJW0M16kk094/fgpAfclGswDryDnWGiuiaX2NXOroiPYFcyWX -UnEWYqsdrowbiUvFgPkXWwUwo8/RsV1nC/BiqNhduxLuQti0QkzOBeeurcunaShu -s9qbEjQeBkUUgmH4rK4U+ABv6RvwDfB1JLFFmruc3Wgndv0udylK67p9x7cXE0Wz -OhLQtI3+W5Vg8K2XXX/2AZOs+8jFkxG2x/EUQs4BKBYOvXqULLheFmut/pPxdxlb -2FNpMBq8qb0/U6oCkj2rO433EVvFzKvyx9nAGwIDAQABo4IDSjCCA0YwHwYDVR0j -BBgwFoAUkZ9eMRWuEJ+tYMH3wcyqSDQvDCYwHQYDVR0OBBYEFK/ICh/pYf/R8k57 -H6EKb+MbzgeiMCEGA1UdEQQaMBiCCyoubG9uc2lkLmNugglsb25zaWQuY24wDgYD -VR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjB1BgNV -HR8EbjBsMDSgMqAwhi5odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vR2VvVHJ1c3RD -TlJTQUNBRzEuY3JsMDSgMqAwhi5odHRwOi8vY3JsNC5kaWdpY2VydC5jb20vR2Vv -VHJ1c3RDTlJTQUNBRzEuY3JsMD4GA1UdIAQ3MDUwMwYGZ4EMAQICMCkwJwYIKwYB -BQUHAgEWG2h0dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzBvBggrBgEFBQcBAQRj -MGEwIQYIKwYBBQUHMAGGFWh0dHA6Ly9vY3NwLmRjb2NzcC5jbjA8BggrBgEFBQcw -AoYwaHR0cDovL2NybC5kaWdpY2VydC1jbi5jb20vR2VvVHJ1c3RDTlJTQUNBRzEu -Y3J0MAkGA1UdEwQCMAAwggF9BgorBgEEAdZ5AgQCBIIBbQSCAWkBZwB1AK33vvp8 -/xDIi509nB4+GGq0Zyldz7EMJMqFhjTr3IKKAAABf05aVi0AAAQDAEYwRAIgfqBq -PZpvMHW4aGsR/yucGiC7KeyYu+i7xg7k9gP5wYwCIDw1deL5sim38D6kU6BfkgV2 -YXlXv4TIQ2bLyELEcQ1SAHcANc8ZG7+xbFe/D61MbULLu7YnICZR6j/hKu+oA8M7 -1kwAAAF/TlpWMAAABAMASDBGAiEAwu1ZmZw5+99t+ilr1BryrezjJrolcU+l7a+3 -pK4G44QCIQDaROzJaidunAchCoQdQvkD7sobvJIqrcGi9RwTym2ckQB1ALNzdwfh -hFD4Y4bWBancEQlKeS2xZwwLh9zwAw55NqWaAAABf05aVmUAAAQDAEYwRAIgSM0e -5ypEiVCjJxKsG8zehtL4poEJGWNMnAAdvjhOa48CIACiIljn0KSsANPQgy51yM8y -NF6XS/NoFyAEwNIvf3P8MA0GCSqGSIb3DQEBCwUAA4IBAQCEFau//Q03vuchkVGl -sX+MSYTP0tJK3bXCCKcgrYo2ptoEFE9DJOcPcSF+Drw71G66mfPlT0v9Yvn1WyPg -81KGvBgBv2NHlQFsHy/dyxC1afUmj4E37pd9oI+KJ6yl++G8H1TN+T4PSU+WAneX -JQHmq3+xC3rcEUhqkoojIfT1nnXVKjf9KeHzKBgZwMnz7capvOBQ3pFp5oTDvt+2 -WEHM/pxnwuV+P8D7lJCx3O4DjP5Ww47FPTkq00Q5EzWQ+wy5w3ab3DPjsTmQJyZG -pOTxuh4GDCzfGWLG6uzsdCMOHcF5qxVZuw1MiY/TzJJ0CN9gTBjArE7/SfFi9qrf -HoS9 ------END CERTIFICATE----- \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin.Server/ssl/tls.key b/src/Web/Masa.Mc.Web.Admin.Server/ssl/tls.key deleted file mode 100644 index cee682ee..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/ssl/tls.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC1soFyN1kQEzos -xETH+9a4BrzW4ml7oi/AoRqMehnk1ErULIwv5VgF4piGBGYHOCMlbQzXqSTT3j9+ -CkB9yUazAOvIOdYaK6JpfY1c6uiI9gVzJZdScRZiqx2ujBuJS8WA+RdbBTCjz9Gx -XWcL8GKo2F27Eu5C2LRCTM4F566ty6dpKG6z2psSNB4GRRSCYfisrhT4AG/pG/AN -8HUksUWau5zdaCd2/S53KUrrun3HtxcTRbM6EtC0jf5blWDwrZddf/YBk6z7yMWT -EbbH8RRCzgEoFg69epQsuF4Wa63+k/F3GVvYU2kwGrypvT9TqgKSPas7jfcRW8XM -q/LH2cAbAgMBAAECggEAI8KitHqNNls6Z2YnjV6U93on/3jnPtSAZn6urXg4kW9w -3Mp5utF+HgZnc3T5KbGURUDttqJNI7/JqkJVSAxttDxZq3oql9L/r5hs0p1PL+mP -0AZVfn3QZJH+EQT1RHPbxtL/lEP0u0DjKe/SoKhqmoWfCPskVpa0/5mDMOlU2VJ3 -ARdQcFlaUyq66sfEo+sTa+RYBlbtRUfyCW6HBlLBeowWpGjridULTMS9WQUA2wIw -wSFofg374aB8TdYsv5lsU+innHUQ/PK/5+8j7btUXGpsl8d8bvkym8w6Jsf9RC+P -NyGlG3nit7xakWMO6B+J8PMV5BzX0+lFr8mnfg+RwQKBgQDrshNmVxg0MkT/L6+7 -Eb0S4HfdGLxOtneWsgkPtUjp5Bax6S0uGY9KOpce7Vxw417r6yhDjQxf7Gr/ejme -diawv5hvtYortPHu6WMMRhDPC3d1ycs6b+UhkD6QE/YLU4ceezDolc4eJuhsTDMp -ro4JxzTz6X28Zq0BDni9OVso2wKBgQDFWZNKXHc/KPN5q0Xh6oMSN25v8mtx5xG4 -lrCysZKoHpK2ziwHtaOJPZejMPDxRjXbe7+GxNekV8ESEPPeEiB9ie2v0LZs5zhk -CAFpevRDwKVO4TaXPmXkWyRQSXNNa7Du6k5monPdBSVyZg+wxwyWxIYLep3cRyqf -m4eu/OTJwQKBgQDVO48XiHYKSuxnHiJTEPJIkLGAYq+CWswIltthzbXAfK0XmghY -66DaG/W6ci2up9WphF8x9fqbEc2fgll8hhHs1/m2Hrx5XEOAzL7iTMVKO2qBMuZc -4PygB9rCCH0RtCjLJ9KQqW8HklW2HJ4w+I3iRMogXT5240Fjck9Dig9x/wKBgQCR -FIfua8mSWhWbxWira46N7sg2bh3E750ceVNPGrH4+/jZgPnndQXTV79JTipjBT2E -rBWiCsWI4KZkFKhjAip2f9aHoMTrjJPtHeGD3MsDn/Um5vQN/eZEGSi6CTVFnjzF -duTKGPVab3UXA6bXS42arMDqYWr5zCuuiFUYNHwxQQKBgQC9D+dpMfDaFpjxYyi9 -PK2rnzGeYvkN/I6bx/JqwZEKwiYbdTGmVcdi8HVY09051lB2GTnD6E4WcEuQ0j8N -D6a9v8sraRGEeByfvoZOzkplpnORsRJdN9ZmGhZ8R+fXX4piC+et+Ei8oCxviNJA -F3SNL0UoerZ8xuM5Z+lZaIpzew== ------END PRIVATE KEY----- \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/css/error.css b/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/css/error.css deleted file mode 100644 index c65334c7..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/css/error.css +++ /dev/null @@ -1,45 +0,0 @@ -.text-danger { - --bs-text-opacity: 1; - color: rgba(var(--bs-danger-rgb),var(--bs-text-opacity)) !important -} - -.valid.modified:not([type=checkbox]) { - outline: 1px solid #26b050; -} - -.invalid { - outline: 1px solid red; -} - -.validation-message { - color: red; -} - -#blazor-error-ui { - background: lightyellow; - bottom: 0; - box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); - display: none; - left: 0; - padding: 0.6rem 1.25rem 0.7rem 1.25rem; - position: fixed; - width: 100%; - z-index: 1000; -} - - #blazor-error-ui .dismiss { - cursor: pointer; - position: absolute; - right: 0.75rem; - top: 0.5rem; - } - -.blazor-error-boundary { - background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121; - padding: 1rem 1rem 1rem 3.7rem; - color: white; -} - - .blazor-error-boundary::after { - content: "An error has occurred." - } diff --git a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/favicon.ico b/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/favicon.ico deleted file mode 100644 index 63e859b4..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/favicon.ico and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/1.svg b/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/1.svg deleted file mode 100644 index a47f78f5..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/1.svg +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/10.svg b/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/10.svg deleted file mode 100644 index 082ab6ea..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/10.svg +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/11.svg b/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/11.svg deleted file mode 100644 index ed6e9b2a..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/11.svg +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/12.svg b/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/12.svg deleted file mode 100644 index 74fb5900..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/12.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/13.svg b/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/13.svg deleted file mode 100644 index 93b28c41..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/13.svg +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/14.svg b/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/14.svg deleted file mode 100644 index fd688f93..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/14.svg +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/2.svg b/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/2.svg deleted file mode 100644 index f4a8944d..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/2.svg +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/3.svg b/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/3.svg deleted file mode 100644 index b2e10605..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/3.svg +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/4.svg b/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/4.svg deleted file mode 100644 index 58e0cfe7..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/4.svg +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/7.svg b/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/7.svg deleted file mode 100644 index 6cefecfb..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/7.svg +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/8.svg b/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/8.svg deleted file mode 100644 index 6f2032cb..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/8.svg +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/9.svg b/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/9.svg deleted file mode 100644 index cb45b1e5..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/img/avatar/9.svg +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/nav/nav.json b/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/nav/nav.json deleted file mode 100644 index 852d382c..00000000 --- a/src/Web/Masa.Mc.Web.Admin.Server/wwwroot/nav/nav.json +++ /dev/null @@ -1,58 +0,0 @@ -[ - { - "Id": 1, - "Title": "Permission.ChannelManagement", - "Icon": "mdi-cellphone", - "Href": "channels/channelManagement" - }, - { - "Id": 2, - "Title": "Permission.MessageManagement", - "Icon": "mdi-animation", - "Children": [ - { - "Id": 3, - "Title": "Permission.SendMessage", - "Icon": "mdi-circle", - "Href": "messageTasks/sendMessage" - }, - { - "Id": 4, - "Title": "Permission.MessageRecord", - "Icon": "mdi-circle", - "Href": "messageRecords/messageRecordManagement" - } - ] - }, - { - "Id": 5, - "Title": "Permission.MessageTemplateManagement", - "Icon": "mdi-image-filter-none", - "Children": [ - { - "Id": 6, - "Title": "Sms", - "Icon": "mdi-circle", - "Href": "messageTemplates/smsTemplateManagement" - }, - { - "Id": 7, - "Title": "Email", - "Icon": "mdi-circle", - "Href": "messageTemplates/emailTemplateManagement" - }, - { - "Id": 8, - "Title": "WebsiteMessage", - "Icon": "mdi-circle", - "Href": "messageTemplates/websiteMessageTemplateManagement" - } - ] - }, - { - "Id": 9, - "Title": "Permission.ReceiverGroupManagement", - "Icon": "mdi-account-group", - "Href": "receiverGroups/receiverGroupManagement" - } -] diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/Masa.Mc.Web.Admin.WebAssembly.csproj b/src/Web/Masa.Mc.Web.Admin.WebAssembly/Masa.Mc.Web.Admin.WebAssembly.csproj deleted file mode 100644 index c1b4d78a..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/Masa.Mc.Web.Admin.WebAssembly.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - net6.0 - enable - enable - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/Program.cs b/src/Web/Masa.Mc.Web.Admin.WebAssembly/Program.cs deleted file mode 100644 index 00321f05..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/Program.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Masa.Mc.Web.Admin; -using Masa.Mc.Web.Admin.WebAssembly; -using Microsoft.AspNetCore.Components.Authorization; -using Microsoft.AspNetCore.Components.Web; -using Microsoft.AspNetCore.Components.WebAssembly.Hosting; - -var builder = WebAssemblyHostBuilder.CreateDefault(args); - -builder.Services.AddAuthorizationCore(); -builder.Services.AddScoped(); - -await builder.Services.AddGlobalForWasmAsync(builder.HostEnvironment.BaseAddress); - -builder.RootComponents.Add(typeof(App), "#app"); -builder.RootComponents.Add("head::after"); -builder.Services.AddMasaBlazor(builder => -{ - builder.UseTheme(option => - { - option.Primary = "#4318FF"; - option.Accent = "#4318FF"; - }); -}); - -await builder.Build().RunAsync(); diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/Properties/launchSettings.json b/src/Web/Masa.Mc.Web.Admin.WebAssembly/Properties/launchSettings.json deleted file mode 100644 index cdbf583f..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/Properties/launchSettings.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:9877", - "sslPort": 44650 - } - }, - "profiles": { - "Masa.Mc.Web.Admin": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", - "applicationUrl": "https://localhost:7362;http://localhost:5362", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - } - } -} diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/TestAuthStateProvider.cs b/src/Web/Masa.Mc.Web.Admin.WebAssembly/TestAuthStateProvider.cs deleted file mode 100644 index 221b710e..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/TestAuthStateProvider.cs +++ /dev/null @@ -1,14 +0,0 @@ -using Microsoft.AspNetCore.Components.Authorization; -using System.Security.Claims; - -namespace Masa.Mc.Web.Admin.WebAssembly -{ - public class TestAuthStateProvider : AuthenticationStateProvider - { - public async override Task GetAuthenticationStateAsync() - { - var anonymous = new ClaimsIdentity(); - return await Task.FromResult(new AuthenticationState(new ClaimsPrincipal(anonymous))); - } - } -} diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/css/app.css b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/css/app.css deleted file mode 100644 index 18df7679..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/css/app.css +++ /dev/null @@ -1,33 +0,0 @@ -#blazor-error-ui { - background: lightyellow; - bottom: 0; - box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); - display: none; - left: 0; - padding: 0.6rem 1.25rem 0.7rem 1.25rem; - position: fixed; - width: 100%; - z-index: 1000; -} - -#blazor-error-ui .dismiss { - cursor: pointer; - position: absolute; - right: 0.75rem; - top: 0.5rem; -} - -.modal-overlay { - position: fixed; - top: 0; - bottom: 0; - left: 0; - right: 0; - background-color: #F0F3FA; - z-index: 2000; - display: flex; - align-items: center; - justify-content: center; - flex-direction: column; - --sk-color: #4318FF; -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/css/spinkit.min.css b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/css/spinkit.min.css deleted file mode 100644 index 248e1c3e..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/css/spinkit.min.css +++ /dev/null @@ -1 +0,0 @@ -:root{--sk-size:40px;--sk-color:#333}.sk-center{margin:auto}.sk-plane{width:var(--sk-size);height:var(--sk-size);background-color:var(--sk-color);animation:sk-plane 1.2s infinite ease-in-out}@keyframes sk-plane{0%{transform:perspective(120px) rotateX(0) rotateY(0)}50%{transform:perspective(120px) rotateX(-180.1deg) rotateY(0)}100%{transform:perspective(120px) rotateX(-180deg) rotateY(-179.9deg)}}.sk-chase{width:var(--sk-size);height:var(--sk-size);position:relative;animation:sk-chase 2.5s infinite linear both}.sk-chase-dot{width:100%;height:100%;position:absolute;left:0;top:0;animation:sk-chase-dot 2.0s infinite ease-in-out both}.sk-chase-dot:before{content:'';display:block;width:25%;height:25%;background-color:var(--sk-color);border-radius:100%;animation:sk-chase-dot-before 2.0s infinite ease-in-out both}.sk-chase-dot:nth-child(1){animation-delay:-1.1s}.sk-chase-dot:nth-child(2){animation-delay:-1.0s}.sk-chase-dot:nth-child(3){animation-delay:-0.9s}.sk-chase-dot:nth-child(4){animation-delay:-0.8s}.sk-chase-dot:nth-child(5){animation-delay:-0.7s}.sk-chase-dot:nth-child(6){animation-delay:-0.6s}.sk-chase-dot:nth-child(1):before{animation-delay:-1.1s}.sk-chase-dot:nth-child(2):before{animation-delay:-1.0s}.sk-chase-dot:nth-child(3):before{animation-delay:-0.9s}.sk-chase-dot:nth-child(4):before{animation-delay:-0.8s}.sk-chase-dot:nth-child(5):before{animation-delay:-0.7s}.sk-chase-dot:nth-child(6):before{animation-delay:-0.6s}@keyframes sk-chase{100%{transform:rotate(360deg)}}@keyframes sk-chase-dot{80%,100%{transform:rotate(360deg)}}@keyframes sk-chase-dot-before{50%{transform:scale(0.4)}100%,0%{transform:scale(1.0)}}.sk-bounce{width:var(--sk-size);height:var(--sk-size);position:relative}.sk-bounce-dot{width:100%;height:100%;border-radius:50%;background-color:var(--sk-color);opacity:.6;position:absolute;top:0;left:0;animation:sk-bounce 2s infinite cubic-bezier(0.455,0.03,0.515,0.955)}.sk-bounce-dot:nth-child(2){animation-delay:-1.0s}@keyframes sk-bounce{0%,100%{transform:scale(0)}45%,55%{transform:scale(1)}}.sk-wave{width:var(--sk-size);height:var(--sk-size);display:flex;justify-content:space-between}.sk-wave-rect{background-color:var(--sk-color);height:100%;width:15%;animation:sk-wave 1.2s infinite ease-in-out}.sk-wave-rect:nth-child(1){animation-delay:-1.2s}.sk-wave-rect:nth-child(2){animation-delay:-1.1s}.sk-wave-rect:nth-child(3){animation-delay:-1.0s}.sk-wave-rect:nth-child(4){animation-delay:-0.9s}.sk-wave-rect:nth-child(5){animation-delay:-0.8s}@keyframes sk-wave{0%,40%,100%{transform:scaleY(0.4)}20%{transform:scaleY(1)}}.sk-pulse{width:var(--sk-size);height:var(--sk-size);background-color:var(--sk-color);border-radius:100%;animation:sk-pulse 1.2s infinite cubic-bezier(0.455,0.03,0.515,0.955)}@keyframes sk-pulse{0%{transform:scale(0)}100%{transform:scale(1);opacity:0}}.sk-flow{width:calc(var(--sk-size) * 1.3);height:calc(var(--sk-size) * 1.3);display:flex;justify-content:space-between}.sk-flow-dot{width:25%;height:25%;background-color:var(--sk-color);border-radius:50%;animation:sk-flow 1.4s cubic-bezier(0.455,0.03,0.515,0.955) 0s infinite both}.sk-flow-dot:nth-child(1){animation-delay:-0.30s}.sk-flow-dot:nth-child(2){animation-delay:-0.15s}@keyframes sk-flow{0%,80%,100%{transform:scale(0.3)}40%{transform:scale(1)}}.sk-swing{width:var(--sk-size);height:var(--sk-size);position:relative;animation:sk-swing 1.8s infinite linear}.sk-swing-dot{width:45%;height:45%;position:absolute;top:0;left:0;right:0;margin:auto;background-color:var(--sk-color);border-radius:100%;animation:sk-swing-dot 2s infinite ease-in-out}.sk-swing-dot:nth-child(2){top:auto;bottom:0;animation-delay:-1s}@keyframes sk-swing{100%{transform:rotate(360deg)}}@keyframes sk-swing-dot{0%,100%{transform:scale(0.2)}50%{transform:scale(1)}}.sk-circle{width:var(--sk-size);height:var(--sk-size);position:relative}.sk-circle-dot{width:100%;height:100%;position:absolute;left:0;top:0}.sk-circle-dot:before{content:'';display:block;width:15%;height:15%;background-color:var(--sk-color);border-radius:100%;animation:sk-circle 1.2s infinite ease-in-out both}.sk-circle-dot:nth-child(1){transform:rotate(30deg)}.sk-circle-dot:nth-child(2){transform:rotate(60deg)}.sk-circle-dot:nth-child(3){transform:rotate(90deg)}.sk-circle-dot:nth-child(4){transform:rotate(120deg)}.sk-circle-dot:nth-child(5){transform:rotate(150deg)}.sk-circle-dot:nth-child(6){transform:rotate(180deg)}.sk-circle-dot:nth-child(7){transform:rotate(210deg)}.sk-circle-dot:nth-child(8){transform:rotate(240deg)}.sk-circle-dot:nth-child(9){transform:rotate(270deg)}.sk-circle-dot:nth-child(10){transform:rotate(300deg)}.sk-circle-dot:nth-child(11){transform:rotate(330deg)}.sk-circle-dot:nth-child(1):before{animation-delay:-1.1s}.sk-circle-dot:nth-child(2):before{animation-delay:-1s}.sk-circle-dot:nth-child(3):before{animation-delay:-0.9s}.sk-circle-dot:nth-child(4):before{animation-delay:-0.8s}.sk-circle-dot:nth-child(5):before{animation-delay:-0.7s}.sk-circle-dot:nth-child(6):before{animation-delay:-0.6s}.sk-circle-dot:nth-child(7):before{animation-delay:-0.5s}.sk-circle-dot:nth-child(8):before{animation-delay:-0.4s}.sk-circle-dot:nth-child(9):before{animation-delay:-0.3s}.sk-circle-dot:nth-child(10):before{animation-delay:-0.2s}.sk-circle-dot:nth-child(11):before{animation-delay:-0.1s}@keyframes sk-circle{0%,80%,100%{transform:scale(0)}40%{transform:scale(1)}}.sk-circle-fade{width:var(--sk-size);height:var(--sk-size);position:relative}.sk-circle-fade-dot{width:100%;height:100%;position:absolute;left:0;top:0}.sk-circle-fade-dot:before{content:'';display:block;width:15%;height:15%;background-color:var(--sk-color);border-radius:100%;animation:sk-circle-fade 1.2s infinite ease-in-out both}.sk-circle-fade-dot:nth-child(1){transform:rotate(30deg)}.sk-circle-fade-dot:nth-child(2){transform:rotate(60deg)}.sk-circle-fade-dot:nth-child(3){transform:rotate(90deg)}.sk-circle-fade-dot:nth-child(4){transform:rotate(120deg)}.sk-circle-fade-dot:nth-child(5){transform:rotate(150deg)}.sk-circle-fade-dot:nth-child(6){transform:rotate(180deg)}.sk-circle-fade-dot:nth-child(7){transform:rotate(210deg)}.sk-circle-fade-dot:nth-child(8){transform:rotate(240deg)}.sk-circle-fade-dot:nth-child(9){transform:rotate(270deg)}.sk-circle-fade-dot:nth-child(10){transform:rotate(300deg)}.sk-circle-fade-dot:nth-child(11){transform:rotate(330deg)}.sk-circle-fade-dot:nth-child(1):before{animation-delay:-1.1s}.sk-circle-fade-dot:nth-child(2):before{animation-delay:-1.0s}.sk-circle-fade-dot:nth-child(3):before{animation-delay:-0.9s}.sk-circle-fade-dot:nth-child(4):before{animation-delay:-0.8s}.sk-circle-fade-dot:nth-child(5):before{animation-delay:-0.7s}.sk-circle-fade-dot:nth-child(6):before{animation-delay:-0.6s}.sk-circle-fade-dot:nth-child(7):before{animation-delay:-0.5s}.sk-circle-fade-dot:nth-child(8):before{animation-delay:-0.4s}.sk-circle-fade-dot:nth-child(9):before{animation-delay:-0.3s}.sk-circle-fade-dot:nth-child(10):before{animation-delay:-0.2s}.sk-circle-fade-dot:nth-child(11):before{animation-delay:-0.1s}@keyframes sk-circle-fade{0%,39%,100%{opacity:0;transform:scale(0.6)}40%{opacity:1;transform:scale(1)}}.sk-grid{width:var(--sk-size);height:var(--sk-size)}.sk-grid-cube{width:33.33%;height:33.33%;background-color:var(--sk-color);float:left;animation:sk-grid 1.3s infinite ease-in-out}.sk-grid-cube:nth-child(1){animation-delay:.2s}.sk-grid-cube:nth-child(2){animation-delay:.3s}.sk-grid-cube:nth-child(3){animation-delay:.4s}.sk-grid-cube:nth-child(4){animation-delay:.1s}.sk-grid-cube:nth-child(5){animation-delay:.2s}.sk-grid-cube:nth-child(6){animation-delay:.3s}.sk-grid-cube:nth-child(7){animation-delay:0s}.sk-grid-cube:nth-child(8){animation-delay:.1s}.sk-grid-cube:nth-child(9){animation-delay:.2s}@keyframes sk-grid{0%,70%,100%{transform:scale3D(1,1,1)}35%{transform:scale3D(0,0,1)}}.sk-fold{width:var(--sk-size);height:var(--sk-size);position:relative;transform:rotateZ(45deg)}.sk-fold-cube{float:left;width:50%;height:50%;position:relative;transform:scale(1.1)}.sk-fold-cube:before{content:'';position:absolute;top:0;left:0;width:100%;height:100%;background-color:var(--sk-color);animation:sk-fold 2.4s infinite linear both;transform-origin:100% 100%}.sk-fold-cube:nth-child(2){transform:scale(1.1) rotateZ(90deg)}.sk-fold-cube:nth-child(4){transform:scale(1.1) rotateZ(180deg)}.sk-fold-cube:nth-child(3){transform:scale(1.1) rotateZ(270deg)}.sk-fold-cube:nth-child(2):before{animation-delay:.3s}.sk-fold-cube:nth-child(4):before{animation-delay:.6s}.sk-fold-cube:nth-child(3):before{animation-delay:.9s}@keyframes sk-fold{0%,10%{transform:perspective(140px) rotateX(-180deg);opacity:0}25%,75%{transform:perspective(140px) rotateX(0);opacity:1}90%,100%{transform:perspective(140px) rotateY(180deg);opacity:0}}.sk-wander{width:var(--sk-size);height:var(--sk-size);position:relative}.sk-wander-cube{background-color:var(--sk-color);width:20%;height:20%;position:absolute;top:0;left:0;--sk-wander-distance:calc(var(--sk-size) * 0.75);animation:sk-wander 2.0s ease-in-out -2.0s infinite both}.sk-wander-cube:nth-child(2){animation-delay:-0.5s}.sk-wander-cube:nth-child(3){animation-delay:-1.0s}@keyframes sk-wander{0%{transform:rotate(0)}25%{transform:translateX(var(--sk-wander-distance)) rotate(-90deg) scale(0.6)}50%{transform:translateX(var(--sk-wander-distance)) translateY(var(--sk-wander-distance)) rotate(-179deg)}50.1%{transform:translateX(var(--sk-wander-distance)) translateY(var(--sk-wander-distance)) rotate(-180deg)}75%{transform:translateX(0) translateY(var(--sk-wander-distance)) rotate(-270deg) scale(0.6)}100%{transform:rotate(-360deg)}} diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/decode.min.js b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/decode.min.js deleted file mode 100644 index faf2e423..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/decode.min.js +++ /dev/null @@ -1,2605 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - brotli/decode.min.js at master · google/brotli - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - -
- - - -
- - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - -
- -
- - - google  /   - brotli  /   - -
- - - - Type # for issues and pull requests, > for commands, and ? for help - - - Type # for issues, pull requests, and projects, > for commands, and ? for help - - - Type # for issues, pull requests, and projects, / for files, and > for commands - - -
- -
-
- We’ve encountered an error and some results aren't available at this time. Type a new search or try again later. -
-
- - No results matched your search - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - Search for issues and pull requests - - # - - - - Search for issues, pull requests, discussions, and projects - - # - - - - Search for organizations, repositories, and users - - @ - - - - Search for projects - - ! - - - - Search for files - - / - - - - Activate command mode - - > - - - - Search your issues, pull requests, and discussions - - # author:@me - - - - Search your issues, pull requests, and discussions - - # author:@me - - - - Filter to pull requests - - # is:pr - - - - Filter to issues - - # is:issue - - - - Filter to discussions - - # is:discussion - - - - Filter to projects - - # is:project - - - - Filter to open issues, pull requests, and discussions - - # is:open - - - - - - - - - - - - - - - - -
-
-
- -
- - - - - - - - - - -
- - - - -
-
-
- - - - - - - - - - - - - - - - -
- -
- -
-

- - - / - - brotli - - - Public -

- -
- -
    - -
  • - -
    - - - - - - - Watch - - - 347 - - - -
    -
    -

    Messages

    - -
    - -
    -
    - - - - - - - - -
    - - -
    - - - - - Get push messages on iOS or Android. - -
    -
    -
    -
    - - -
    -
    -
    - - - -
  • - -
  • -
    -
    - Fork - 1k - - -
    - -

    Fork brotli

    -
    - -
    - - - - - -

    If this dialog fails to load, you can visit the fork page directly.

    -
    -
    - -
    -
    -
    - -
  • - -
  • - -
    -
    - -
    -
    - -
    -
    - - - - - -
    - -
    -
    - - - - - - - -
    - -
    -
    -
    -
    -
    -
  • - -
  • - - -
  • -
- -
- -
-
- - - - -
- - - -
-
- - Open in github.dev - Open in a new github.dev tab - - - - - - - -
- - - - - Permalink - - -
- -
-
- - - master - - - - -
-
-
- Switch branches/tags - -
- - - -
- -
- -
- - -
- -
- - - - - - - - - - - - - - - - -
- - -
-
-
-
- -
- -
- - - - Go to file - - -
- - - - -
-
-
- - - - -
- -
-
-
 
-
- -
-
 
- Cannot retrieve contributors at this time -
-
- - - - - - - - - - - -
- -
- - -
- - 1 lines (1 sloc) - - 146 KB -
- -
- - - - -
- - - - - - - - - - - - - - - -
- -
-
- -
-
- -
- -
-
- - - -
- - -
- - - - - - - - - -
export let BrotliDecode=(()=>{function f(f){this.data=f,this.offset=0}let w=Int32Array.from([256,402,436,468,500,534,566,598,630,662,694,726,758,790,822,854,886,920,952,984,1016,1048,1080]),b=Int32Array.from([1,2,3,4,0,5,17,6,16,7,8,9,10,11,12,13,14,15]),j=Int32Array.from([0,3,2,1,0,0,0,0,0,0,3,3,3,3,3,3]),l=Int32Array.from([0,0,0,0,-1,1,-2,2,-3,3,-1,1,-2,2,-3,3]),m=Int32Array.from([131072,131076,131075,196610,131072,131076,131075,262145,131072,131076,131075,196610,131072,131076,131075,262149]),p=Int32Array.from([1,5,9,13,17,25,33,41,49,65,81,97,113,145,177,209,241,305,369,497,753,1265,2289,4337,8433,16625]),q=Int32Array.from([2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,7,8,9,10,11,12,13,24]),o=Int16Array.from([0,0,0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,7,8,9,10,12,14,24]),n=Int16Array.from([0,0,0,0,0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,7,8,9,10,24]),g=new Int16Array(2816);function k(f){let w=-1,b=16;for(;b>0;)f>>>b!=0&&(w+=b,f>>>=b),b>>=1;return w+f}function s(f,w,b){return 16+w+2*(b<<f)}function v(f,w,b){if(f<b+(2<<w))throw"maxDistance is too small";let j=4+(f-b>>w),l=k(j)-1;return((l-1<<1|j>>l&1)-1<<w)+(1<<w)+b+16}function t(f,w){if(0!=f.j)throw"State MUST be uninitialized";f.l=new Int32Array(3091),f.l[0]=7,f.m=3;let b=v(2147483644,3,120);f.p=new Int8Array(b),f.q=new Int32Array(b),f.input=w,function(f){f.o=new Int8Array(4160),f.g=0,f.k=new Int16Array(2080),f.s=32,f.v=2048,f.t=0,E(f)}(f),f.j=1}function e(f){if(f.s>=16&&(f.g=f.k[f.v++]<<16|f.g>>>16,f.s-=16),0!=_(f,1)){let w=_(f,3);return 0==w?1:_(f,w)+(1<<w)}return 0}function d(f,w,b){let j=f[w],l=b.g>>>b.s;j+=255&l;let m=f[j]>>16,p=65535&f[j];return m<=8?(b.s+=m,p):(j+=p,j+=(l&(1<<m)-1)>>>8,b.s+=8+(f[j]>>16),65535&f[j])}function H(f,w,b){b.s>=16&&(b.g=b.k[b.v++]<<16|b.g>>>16,b.s-=16);let j=d(f,w,b),l=q[j];return b.s>=16&&(b.g=b.k[b.v++]<<16|b.g>>>16,b.s-=16),p[j]+(l<=16?_(b,l):X(b,l))}function a(f,w){let b=f[w];for(;w>0;w--)f[w]=f[w-1];f[0]=b}function u(f,w,j,l,p){let q=new Int32Array(f),o=new Int32Array(18),n=32,g=0;for(let f=w;f<18&&n>0;f++){let w=b[f];p.s>=16&&(p.g=p.k[p.v++]<<16|p.g>>>16,p.s-=16);let j=p.g>>>p.s&15;p.s+=m[j]>>16;let l=65535&m[j];o[w]=l,0!=l&&(n-=32>>l,g++)}if(0!=n&&1!=g)throw"Corrupted Huffman code histogram";return function(f,w,b,j){let l=0,m=8,p=0,q=0,o=32768,n=new Int32Array(33);for(c(n,n.length-1,5,f,18);l<w&&o>0;){j.v>2030&&C(j),j.s>=16&&(j.g=j.k[j.v++]<<16|j.g>>>16,j.s-=16);let f=j.g>>>j.s&31;j.s+=n[f]>>16;let g=65535&n[f];if(g<16)p=0,b[l++]=g,0!=g&&(m=g,o-=32768>>g);else{let f=g-14,n=0;16==g&&(n=m),q!=n&&(p=0,q=n);let k=p;p>0&&(p-=2,p<<=f),j.s>=16&&(j.g=j.k[j.v++]<<16|j.g>>>16,j.s-=16),p+=_(j,f)+3;let s=p-k;if(l+s>w)throw"symbol + repeatDelta > numSymbols";for(let f=0;f<s;f++)b[l++]=q;0!=q&&(o-=s<<15-q)}}if(0!=o)throw"Unused space";b.fill(0,l,w)}(o,f,q,p),c(j,l,8,q,f)}function z(f,w,b,j,l){l.v>2030&&C(l),l.s>=16&&(l.g=l.k[l.v++]<<16|l.g>>>16,l.s-=16);let m=_(l,2);return 1==m?function(f,w,b,j,l){let m=new Int32Array(w),p=new Int32Array(4),q=1+k(f-1),o=_(l,2)+1;for(let f=0;f<o;f++){l.s>=16&&(l.g=l.k[l.v++]<<16|l.g>>>16,l.s-=16);let b=_(l,q);if(b>=w)throw"Can't readHuffmanCode";p[f]=b}!function(f,w){for(let b=0;b<w-1;++b)for(let j=b+1;j<w;++j)if(f[b]==f[j])throw"Duplicate simple Huffman code symbol"}(p,o);let n=o;switch(4==o&&(n+=_(l,1)),n){case 1:m[p[0]]=1;break;case 2:m[p[0]]=1,m[p[1]]=1;break;case 3:m[p[0]]=1,m[p[1]]=2,m[p[2]]=2;break;case 4:m[p[0]]=2,m[p[1]]=2,m[p[2]]=2,m[p[3]]=2;break;case 5:m[p[0]]=1,m[p[1]]=2,m[p[2]]=3,m[p[3]]=3}return c(b,j,8,m,w)}(f,w,b,j,l):u(w,m,b,j,l)}function h(f,b,j){j.v>2030&&C(j);let l=e(j)+1;if(1==l)return b.fill(0,0,f),l;j.s>=16&&(j.g=j.k[j.v++]<<16|j.g>>>16,j.s-=16);let m=0;0!=_(j,1)&&(m=_(j,4)+1);let p=l+m,q=w[p+31>>5],o=new Int32Array(q+1),n=o.length-1;z(p,p,o,n,j);for(let w=0;w<f;){j.v>2030&&C(j),j.s>=16&&(j.g=j.k[j.v++]<<16|j.g>>>16,j.s-=16);let l=d(o,n,j);if(0==l)b[w]=0,w++;else if(l<=m){j.s>=16&&(j.g=j.k[j.v++]<<16|j.g>>>16,j.s-=16);let m=(1<<l)+_(j,l);for(;0!=m;){if(w>=f)throw"Corrupted context map";b[w]=0,w++,m--}}else b[w]=l-m,w++}return j.s>=16&&(j.g=j.k[j.v++]<<16|j.g>>>16,j.s-=16),1==_(j,1)&&function(f,w){let b=new Int32Array(256);for(let f=0;f<256;f++)b[f]=f;for(let j=0;j<w;j++){let w=255&f[j];f[j]=b[w],0!=w&&a(b,w)}}(b,f),l}function i(f,w,b){let j=f.H,l=4+2*w;f.s>=16&&(f.g=f.k[f.v++]<<16|f.g>>>16,f.s-=16);let m=d(f.l,2*w,f),p=H(f.l,2*w+1,f);return 1==m?m=j[l+1]+1:0==m?m=j[l]:m-=2,m>=b&&(m-=b),j[l]=j[l+1],j[l+1]=m,p}function r(f){f.u=i(f,0,f.h);let w=f.H[5];f.i=w<<6,f.I=255&f.R[f.i];let b=f.K[w];f.T=b<<9,f.W=f.T+256}function I(f){f.B=i(f,1,f.Y),f.S=f.H[7]}function R(f){f.A=i(f,2,f.V),f.D=f.H[9]<<2}function K(f){if(0!=f.F)return f.P=10,void(f.j=12);f.U=new Int32Array(0),f.C=new Int32Array(0),f.J=new Int32Array(0),f.v>2030&&C(f),function(f){if(f.s>=16&&(f.g=f.k[f.v++]<<16|f.g>>>16,f.s-=16),f.F=_(f,1),f._=0,f.X=0,f.M=0,0!=f.F&&0!=_(f,1))return;let w=_(f,2)+4;if(7==w){if(f.M=1,0!=_(f,1))throw"Corrupted reserved bit";let w=_(f,2);if(0==w)return;for(let b=0;b<w;b++){f.s>=16&&(f.g=f.k[f.v++]<<16|f.g>>>16,f.s-=16);let j=_(f,8);if(0==j&&b+1==w&&w>1)throw"Exuberant nibble";f._|=j<<8*b}}else for(let b=0;b<w;b++){f.s>=16&&(f.g=f.k[f.v++]<<16|f.g>>>16,f.s-=16);let j=_(f,4);if(0==j&&b+1==w&&w>4)throw"Exuberant nibble";f._|=j<<4*b}f._++,0==f.F&&(f.X=_(f,1))}(f),0==f._&&0==f.M||(0!=f.X||0!=f.M?(G(f),f.j=0!=f.M?5:6):f.j=3,0==f.M&&(f.G+=f._,f.G>1<<30&&(f.G=1<<30),f.O<f.Z&&function(f){let w=f.Z;if(w>f.G){let b=f.G;for(;w>>1>b;)w>>=1;0==f.F&&w<16384&&f.Z>=16384&&(w=16384)}if(w<=f.O)return;let b=new Int8Array(w+37);0!=f.L.length&&b.set(f.L.subarray(0,0+f.O),0),f.L=b,f.O=w}(f)))}function T(f,w,b){let j=f.l[2*w];if(b<=1)return f.l[2*w+1]=j,f.l[2*w+2]=j,1<<28;let l=b+2;j+=z(l,l,f.l,2*w,f),f.l[2*w+1]=j;return j+=z(26,26,f.l,2*w+1,f),f.l[2*w+2]=j,H(f.l,2*w+1,f)}function y(f){f.h=e(f)+1,f.u=T(f,0,f.h),f.Y=e(f)+1,f.B=T(f,1,f.Y),f.V=e(f)+1,f.A=T(f,2,f.V),f.v>2030&&C(f),f.s>=16&&(f.g=f.k[f.v++]<<16|f.g>>>16,f.s-=16),f.N=_(f,2),f.$=_(f,4)<<f.N,f.K=new Int8Array(f.h);for(let w=0;w<f.h;){let b=ff(w+96,f.h);for(;w<b;++w)f.s>=16&&(f.g=f.k[f.v++]<<16|f.g>>>16,f.s-=16),f.K[w]=_(f,2);f.v>2030&&C(f)}f.R=new Int8Array(f.h<<6);let w=h(f.h<<6,f.R,f);f.ff=1;for(let w=0;w<f.h<<6;w++)if(f.R[w]!=w>>6){f.ff=0;break}f.wf=new Int8Array(f.V<<2);let b=h(f.V<<2,f.wf,f);f.U=Y(256,256,w,f),f.C=Y(704,704,f.Y,f);let j=s(f.N,f.$,24),l=j;1==f.bf&&(j=s(f.N,f.$,62),l=v(2147483644,f.N,f.$)),f.J=Y(j,l,b,f),function(f,w){let b=f.p,j=f.q,l=f.N,m=f.$,p=1<<l,q=1,o=0,n=16;for(let f=0;f<m;++f)b[n]=0,j[n]=f+1,++n;for(;n<w;){let f=m+((2+o<<q)-4<<l)+1;for(let w=0;w<p;++w)b[n]=q,j[n]=f+w,++n;q+=o,o^=1}}(f,l),f.i=0,f.D=0,f.T=512*f.K[0],f.W=f.T+256,f.I=0,f.S=0,f.H[4]=1,f.H[5]=0,f.H[6]=1,f.H[7]=0,f.H[8]=1,f.H[9]=0}function W(f){let w=f.L;if(f._<=0)return M(f),void(f.j=2);let b=ff(f.O-f.jf,f._);if(function(f,w,b,j){if(0!=(7&f.s))throw"Unaligned copyBytes";for(;32!=f.s&&0!=j;)w[b++]=f.g>>>f.s,f.s+=8,j--;if(0==j)return;let l=ff(x(f),j>>1);if(l>0){let m=f.v<<1,p=l<<1;w.set(f.o.subarray(m,m+p),b),b+=p,j-=p,f.v+=l}if(0==j)return;if(x(f)>0){for(f.s>=16&&(f.g=f.k[f.v++]<<16|f.g>>>16,f.s-=16);0!=j;)w[b++]=f.g>>>f.s,f.s+=8,j--;return void J(f,0)}for(;j>0;){let l=wf(f.input,w,b,j);if(-1==l)throw"Unexpected end of input";b+=l,j-=l}}(f,w,f.jf,b),f._-=b,f.jf+=b,f.jf==f.O)return f.P=6,void(f.j=12);M(f),f.j=2}function B(f){let w=ff(f.lf-f.mf,f.pf-f.qf);return 0!=w&&(f.nf.set(f.L.subarray(f.qf,f.qf+w),f.gf+f.mf),f.mf+=w,f.qf+=w),f.mf<f.lf?1:0}function Y(f,b,j,l){let m=w[b+31>>5],p=new Int32Array(j+j*m),q=j;for(let w=0;w<j;++w)p[w]=q,q+=z(f,b,p,w,l);return p}function S(f){let w=f.O;return 0!=f.kf&&(w=ff(w,f.qf+f.lf-f.mf)),w}function A(f,w){if(f.sf>2147483644)throw"Invalid backward reference";let b=f.sf-f.maxDistance-1-f.vf;if(b<0)!function(f,w,b){-1==f.tf&&function(f){f.ef=new Int8Array(256);let w=8;for(;f.vf-1>>>w!=0;)w++;w-=8,f.tf=w;let b=0,j=0;for(;b<f.vf;){for(;f.df[j+1]<b;)j++;f.ef[b>>>w]=j,b+=1<<w}}(f);let j=f.ef[w>>>f.tf];for(;w>=f.df[j+1];)j++;if(f.vf>w+b)throw"Invalid backward reference";f.m=f.m+1&3,f.H[f.m]=f.sf,f._-=b,f.Hf=j,f.af=w-f.df[j],f.uf=b,f.zf=0}(f,-b-1,f.hf),f.j=14;else{let j=L,l=f.hf;if(l>31)throw"Invalid backward reference";let m=$[l];if(0==m)throw"Invalid backward reference";let p=N[l],q=b>>>m;p+=(b&(1<<m)-1)*l;let o=F;if(q>=o.if)throw"Invalid backward reference";let n=function(f,w,b,j,l,m,p){let q=w,o=m.rf,n=m.If,g=m.Rf,k=3*p,s=o[k],v=o[k+1],t=o[k+2],e=g[s],d=g[s+1],H=g[t],a=g[t+1],u=v-11,z=v-0;(u<1||u>9)&&(u=0);(z<1||z>9)&&(z=0);for(;e!=d;)f[q++]=n[e++];u>l&&(u=l);j+=u,l-=u;let h=l-=z;for(;h>0;)f[q++]=b[j++],h--;if(10==v||11==v){let w=q-l;for(10==v&&(l=1);l>0;){let b=255&f[w];b<192?(b>=97&&b<=122&&(f[w]^=32),w+=1,l-=1):b<224?(f[w+1]^=32,w+=2,l-=2):(f[w+2]^=5,w+=3,l-=3)}}else if(21==v||22==v){let w=q-l,b=m.Kf[p],j=16777216-(32768&b)+(32767&b);for(;l>0;){let b=1,m=255&f[w];if(m<128)j+=m,f[w]=127&j;else if(m<192);else if(m<224)if(l>=2){let l=f[w+1];j+=63&l|(31&m)<<6,f[w]=192|j>>6&31,f[w+1]=192&l|63&j,b=2}else b=l;else if(m<240)if(l>=3){let l=f[w+1],p=f[w+2];j+=63&p|(63&l)<<6|(15&m)<<12,f[w]=224|j>>12&15,f[w+1]=192&l|j>>6&63,f[w+2]=192&p|63&j,b=3}else b=l;else if(m<248)if(l>=4){let l=f[w+1],p=f[w+2],q=f[w+3];j+=63&q|(63&p)<<6|(63&l)<<12|(7&m)<<18,f[w]=240|j>>18&7,f[w+1]=192&l|j>>12&63,f[w+2]=192&p|j>>6&63,f[w+3]=192&q|63&j,b=4}else b=l;w+=b,l-=b,21==v&&(l=0)}}for(;H!=a;)f[q++]=n[H++];return q-w}(f.L,f.jf,j,p,l,o,q);if(f.jf+=n,f._-=n,f.jf>=w)return f.P=4,void(f.j=12);f.j=4}}function V(f,w){let b=f.jf,j=b;for(;f.uf!=f.zf;){let j=w-b,n=f.df[f.Hf+1]-f.df[f.Hf]-f.af,g=f.uf-f.zf;if(g>n&&(g=n),g>j&&(g=j),l=f.L,m=b,p=f.Tf[f.Hf],q=f.af,o=f.af+g,l.set(p.slice(q,o),m),b+=g,f.af+=g,f.zf+=g,g==n&&(f.Hf++,f.af=0),b>=w)break}var l,m,p,q,o;return b-j}function D(f){if(0==f.j)throw"Can't decompress until initialized";if(11==f.j)throw"Can't decompress after close";if(1==f.j){let w=function(f){let w=f.bf;if(f.bf=0,f.s>=16&&(f.g=f.k[f.v++]<<16|f.g>>>16,f.s-=16),0==_(f,1))return 16;let b=_(f,3);return 0!=b?17+b:(b=_(f,3),0!=b?1==b?0==w?-1:(f.bf=1,1==_(f,1)?-1:(b=_(f,6),b<10||b>30?-1:b)):8+b:17)}(f);if(-1==w)throw"Invalid 'windowBits' code";f.Z=1<<w,f.yf=f.Z-16,f.j=2}let w=S(f),b=f.O-1,m=f.L;for(;10!=f.j;)switch(f.j){case 2:if(f._<0)throw"Invalid metablock length";K(f),w=S(f),b=f.O-1,m=f.L;continue;case 3:y(f),f.j=4;case 4:if(f._<=0){f.j=2;continue}f.v>2030&&C(f),0==f.B&&I(f),f.B--,f.s>=16&&(f.g=f.k[f.v++]<<16|f.g>>>16,f.s-=16);let p=d(f.C,f.S,f)<<2,q=g[p],o=g[p+1],n=g[p+2];f.Wf=g[p+3],f.s>=16&&(f.g=f.k[f.v++]<<16|f.g>>>16,f.s-=16);let k=255&q;f.Bf=o+(k<=16?_(f,k):X(f,k)),f.s>=16&&(f.g=f.k[f.v++]<<16|f.g>>>16,f.s-=16);let s=q>>8;f.hf=n+(s<=16?_(f,s):X(f,s)),f.Yf=0,f.j=7;case 7:if(0!=f.ff){for(;f.Yf<f.Bf;)if(f.v>2030&&C(f),0==f.u&&r(f),f.u--,f.s>=16&&(f.g=f.k[f.v++]<<16|f.g>>>16,f.s-=16),m[f.jf]=d(f.U,f.I,f),f.jf++,f.Yf++,f.jf>=w){f.P=7,f.j=12;break}}else{let j=255&m[f.jf-1&b],l=255&m[f.jf-2&b];for(;f.Yf<f.Bf;){f.v>2030&&C(f),0==f.u&&r(f);let b=O[f.T+j]|O[f.W+l],p=255&f.R[f.i+b];if(f.u--,l=j,f.s>=16&&(f.g=f.k[f.v++]<<16|f.g>>>16,f.s-=16),j=d(f.U,p,f),m[f.jf]=j,f.jf++,f.Yf++,f.jf>=w){f.P=7,f.j=12;break}}}if(7!=f.j)continue;if(f._-=f.Bf,f._<=0){f.j=4;continue}let v=f.Wf;if(v<0)f.sf=f.H[f.m];else{f.v>2030&&C(f),0==f.A&&R(f),f.A--,f.s>=16&&(f.g=f.k[f.v++]<<16|f.g>>>16,f.s-=16);let w=255&f.wf[f.D+v];if(v=d(f.J,w,f),v<16){let w=f.m+j[v]&3;if(f.sf=f.H[w]+l[v],f.sf<0)throw"Negative distance"}else{let w,b=f.p[v];f.s+b<=32?w=_(f,b):(f.s>=16&&(f.g=f.k[f.v++]<<16|f.g>>>16,f.s-=16),w=b<=16?_(f,b):X(f,b)),f.sf=f.q[v]+(w<<f.N)}}if(f.maxDistance!=f.yf&&f.jf<f.yf?f.maxDistance=f.jf:f.maxDistance=f.yf,f.sf>f.maxDistance){f.j=9;continue}if(v>0&&(f.m=f.m+1&3,f.H[f.m]=f.sf),f.hf>f._)throw"Invalid backward reference";f.Yf=0,f.j=8;case 8:let t=f.jf-f.sf&b,e=f.jf,H=f.hf-f.Yf,a=t+H,u=e+H;if(a<b&&u<b){if(H<12||a>e&&u>t)for(let f=0;f<H;f+=4)m[e++]=m[t++],m[e++]=m[t++],m[e++]=m[t++],m[e++]=m[t++];else m.copyWithin(e,t,a);f.Yf+=H,f._-=H,f.jf+=H}else for(;f.Yf<f.hf;)if(m[f.jf]=m[f.jf-f.sf&b],f._--,f.jf++,f.Yf++,f.jf>=w){f.P=8,f.j=12;break}8==f.j&&(f.j=4);continue;case 9:A(f,w);continue;case 14:if(f.jf+=V(f,w),f.jf>=w)return f.P=14,void(f.j=12);f.j=4;continue;case 5:for(;f._>0;)f.v>2030&&C(f),f.s>=16&&(f.g=f.k[f.v++]<<16|f.g>>>16,f.s-=16),_(f,8),f._--;f.j=2;continue;case 6:W(f);continue;case 12:f.pf=ff(f.jf,f.O),f.j=13;case 13:if(0==B(f))return;f.jf>=f.yf&&(f.maxDistance=f.yf),f.jf>=f.O&&(f.jf>f.O&&m.copyWithin(0,f.O,f.jf),f.jf&=b,f.qf=0),f.j=f.P;continue;default:throw"Unexpected state "+f.j}if(10==f.j){if(f._<0)throw"Invalid metablock length";G(f),J(f,1)}}!function(f){let w=new Int16Array(24),b=new Int16Array(24);b[0]=2;for(let f=0;f<23;++f)w[f+1]=w[f]+(1<<o[f]),b[f+1]=b[f]+(1<<n[f]);for(let j=0;j<704;++j){let l=j>>>6,m=-4;l>=2&&(l-=2,m=0);let p=(170064>>>2*l&3)<<3|j>>>3&7,q=(156228>>>2*l&3)<<3|7&j,g=b[q],k=m+(g>4?3:g-2),s=4*j;f[s+0]=o[p]|n[q]<<8,f[s+1]=w[p],f[s+2]=b[q],f[s+3]=k}}(g);let F=new function(f,w,b){this.if=0,this.rf=new Int32Array(0),this.If=new Int8Array(0),this.Rf=new Int32Array(0),this.Kf=new Int16Array(0),this.if=f,this.rf=new Int32Array(3*f),this.Kf=new Int16Array(f),this.If=new Int8Array(w),this.Rf=new Int32Array(b+1)}(121,167,50);function Q(f,w){let b=1<<w-1;for(;0!=(f&b);)b>>=1;return(f&b-1)+b}function P(f,w,b,j,l){do{f[w+(j-=b)]=l}while(j>0)}function U(f,w,b){let j=1<<w-b;for(;w<15&&(j-=f[w],!(j<=0));)w++,j<<=1;return w-b}function c(f,w,b,j,l){let m,p,q=f[w],o=new Int32Array(l),n=new Int32Array(16),g=new Int32Array(16);for(p=0;p<l;p++)n[j[p]]++;g[1]=0;for(let f=1;f<15;f++)g[f+1]=g[f]+n[f];for(p=0;p<l;p++)0!=j[p]&&(o[g[j[p]]++]=p);let k=b,s=1<<k,v=s;if(1==g[15]){for(m=0;m<v;m++)f[q+m]=o[0];return v}m=0,p=0;for(let w=1,j=2;w<=b;w++,j<<=1)for(;n[w]>0;n[w]--)P(f,q+m,j,s,w<<16|o[p++]),m=Q(m,w);let t=v-1,e=-1,d=q;for(let w=b+1,j=2;w<=15;w++,j<<=1)for(;n[w]>0;n[w]--)(m&t)!=e&&(d+=s,k=U(n,w,b),s=1<<k,v+=s,e=m&t,f[q+e]=k+b<<16|d-q-e),P(f,d+(m>>b),j,s,w-b<<16|o[p++]),m=Q(m,w);return v}function C(f){if(0!=f.t){if(x(f)>=-2)return;throw"No more input"}let w=f.v<<1,b=4096-w;for(f.o.copyWithin(0,w,4096),f.v=0;b<4096;){let w=4096-b,j=wf(f.input,f.o,b,w);if(j<=0){f.t=1,f.Sf=b,b+=1;break}b+=j}!function(f,w){let b=f.o,j=w>>1,l=f.k;for(let f=0;f<j;++f)l[f]=255&b[2*f]|(255&b[2*f+1])<<8}(f,b)}function J(f,w){if(0==f.t)return;let b=(f.v<<1)+(f.s+7>>3)-4;if(b>f.Sf)throw"Read after end";if(0!=w&&b!=f.Sf)throw"Unused bytes after end"}function _(f,w){let b=f.g>>>f.s&(1<<w)-1;return f.s+=w,b}function X(f,w){let b=_(f,16);return f.g=f.k[f.v++]<<16|f.g>>>16,f.s-=16,b|_(f,w-16)<<16}function E(f){f.v>2030&&C(f),J(f,0),f.g=f.k[f.v++]<<16|f.g>>>16,f.s-=16,f.g=f.k[f.v++]<<16|f.g>>>16,f.s-=16}function M(f){32==f.s&&E(f)}function G(f){let w=32-f.s&7;if(0!=w){if(0!=_(f,w))throw"Corrupted padding bits"}}function x(f){let w=2048;return 0!=f.t&&(w=f.Sf+1>>1),w-f.v}!function(f,w,b,j,l){let m=j.length,p=1,q=0;for(let b=0;b<m;++b){let l=j.charCodeAt(b);35==l?w[p++]=q:f[q++]=l}for(let f=0;f<363;++f)b[f]=l.charCodeAt(f)-32}(F.If,F.Rf,F.rf,'# #s #, #e #.# the #.com/#\xc2\xa0# of # and # in # to #"#">#\n#]# for # a # that #. # with #\'# from # by #. The # on # as # is #ing #\n\t#:#ed #(# at #ly #="# of the #. This #,# not #er #al #=\'#ful #ive #less #est #ize #ous #'," !! ! , *! &! \" ! ) * * - ! # ! #!*! + ,$ ! - % . / # 0 1 . \" 2 3!* 4% ! # / 5 6 7 8 0 1 & $ 9 + : ; < ' != > ?! 4 @ 4 2 & A *# ( B C& ) % ) !*# *-% A +! *. D! %' & E *6 F G% ! *A *% H! D I!+! J!+ K +- *4! A L!*4 M N +6 O!*% +.! K *G P +%( ! G *D +D Q +# *K!*G!+D!+# +G +A +4!+% +K!+4!*D!+K!*K");let O=new Int32Array(2048);function Z(){this.L=new Int8Array(0),this.K=new Int8Array(0),this.R=new Int8Array(0),this.wf=new Int8Array(0),this.p=new Int8Array(0),this.nf=new Int8Array(0),this.o=new Int8Array(0),this.k=new Int16Array(0),this.Af=new Int32Array(0),this.H=new Int32Array(0),this.l=new Int32Array(0),this.U=new Int32Array(0),this.C=new Int32Array(0),this.J=new Int32Array(0),this.q=new Int32Array(0),this.j=0,this.P=0,this.g=0,this.s=0,this.v=0,this.Sf=0,this.t=0,this._=0,this.F=0,this.X=0,this.M=0,this.u=0,this.h=0,this.B=0,this.Y=0,this.A=0,this.V=0,this.jf=0,this.maxDistance=0,this.m=0,this.ff=0,this.I=0,this.S=0,this.Yf=0,this.Bf=0,this.i=0,this.D=0,this.T=0,this.W=0,this.Wf=0,this.$=0,this.N=0,this.sf=0,this.hf=0,this.yf=0,this.Z=0,this.O=0,this.G=0,this.gf=0,this.lf=0,this.mf=0,this.qf=0,this.pf=0,this.kf=0,this.bf=0,this.Vf=0,this.vf=0,this.Hf=0,this.af=0,this.uf=0,this.zf=0,this.Tf=new Array(0),this.df=new Int32Array(0),this.tf=0,this.ef=new Int8Array(0),this.input=null,this.L=new Int8Array(0),this.H=new Int32Array(10),this.H[0]=16,this.H[1]=15,this.H[2]=11,this.H[3]=4}!function(f,w,b){for(let w=0;w<256;++w)f[w]=63&w,f[512+w]=w>>2,f[1792+w]=2+(w>>6);for(let b=0;b<128;++b)f[1024+b]=4*(w.charCodeAt(b)-32);for(let w=0;w<64;++w)f[1152+w]=1&w,f[1216+w]=2+(1&w);let j=1280;for(let w=0;w<19;++w){let l=3&w,m=b.charCodeAt(w)-32;for(let w=0;w<m;++w)f[j++]=l}for(let w=0;w<16;++w)f[1792+w]=1,f[2032+w]=6;f[1792]=0,f[2047]=7;for(let w=0;w<256;++w)f[1536+w]=f[1792+w]<<3}(O," !! ! \"#$##%#$&'##(#)#++++++++++((&*'##,---,---,-----,-----,-----&#'###.///.///./////./////./////&#'# ","A/* ': & : $ \x81 @");let L=null,N=new Int32Array(32),$=new Int32Array(32);{let f=new Int8Array(122784),w=new Int32Array(25);!function(f,w,b,j,l,m){let p=function(f){let w=f.length,b=new Int8Array(w);for(let j=0;j<w;++j)b[j]=f.charCodeAt(j);return b}(w+b);if(p.length!=f.length)throw"Corrupted brotli dictionary";let q=0,o=j.length;for(let f=0;f<o;f+=2){let w=j.charCodeAt(f)-36,b=j.charCodeAt(f+1)-36;for(let f=0;f<w;++f)p[q]^=3,q++;for(let f=0;f<b;++f)p[q]^=236,q++}for(let f=0;f<m.length;++f)l[f]=m.charCodeAt(f)-65;f.set(p)}(f,'wjnfgltmojefofewab`h`lgfgbwbpkltlmozpjwf`jwzlsfmivpwojhfeqfftlqhwf{wzfbqlufqalgzolufelqnallhsobzojufojmfkfosklnfpjgfnlqftlqgolmdwkfnujftejmgsbdfgbzpevookfbgwfqnfb`kbqfbeqlnwqvfnbqhbaofvslmkjdkgbwfobmgmftpfufmmf{w`bpfalwkslpwvpfgnbgfkbmgkfqftkbwmbnfOjmhaoldpjyfabpfkfognbhfnbjmvpfq$*#(klogfmgptjwkMftpqfbgtfqfpjdmwbhfkbufdbnfpffm`boosbwktfoosovpnfmvejonsbqwiljmwkjpojpwdllgmffgtbzptfpwilapnjmgboploldlqj`kvpfpobpwwfbnbqnzellghjmdtjoofbpwtbqgafpwejqfSbdfhmltbtbz-smdnlufwkbmolbgdjufpfoemlwfnv`keffgnbmzql`hj`lmlm`follhkjgfgjfgKlnfqvofklpwbib{jmel`ovaobtpofppkboeplnfpv`kylmf233&lmfp`bqfWjnfqb`faovfelvqtffheb`fklsfdbufkbqgolpwtkfmsbqhhfswsbpppkjsqllnKWNOsobmWzsfglmfpbufhffseobdojmhplogejufwllhqbwfwltmivnswkvpgbqh`bqgejofefbqpwbzhjoowkbweboobvwlfufq-`lnwbohpklsulwfgffsnlgfqfpwwvqmalqmabmgefooqlpfvqo+phjmqlof`lnfb`wpbdfpnffwdlog-isdjwfnubqzefowwkfmpfmggqlsUjft`lsz2-3!?,b=pwlsfopfojfpwlvqsb`h-djesbpw`pp<dqbznfbm%dw8qjgfpklwobwfpbjgqlbgubq#effoilkmqj`hslqwebpw$VB.gfbg?,a=sllqajoowzsfV-P-tllgnvpw1s{8JmelqbmhtjgftbmwtbooofbgX3^8sbvotbufpvqf\'+$ tbjwnbppbqnpdlfpdbjmobmdsbjg"..#ol`hvmjwqllwtbohejqntjef{no!plmdwfpw13s{hjmgqltpwlloelmwnbjopbefpwbqnbsp`lqfqbjmeoltabazpsbmpbzp7s{85s{8bqwpellwqfbotjhjkfbwpwfswqjslqd,obhftfbhwlogElqn`bpwebmpabmhufqzqvmpivozwbph2s{8dlbodqftpoltfgdfjg>!pfwp6s{8-ip<73s{je#+pllmpfbwmlmfwvafyfqlpfmwqffgeb`wjmwldjewkbqn2;s{`bnfkjooalogyllnuljgfbpzqjmdejoosfbhjmjw`lpw0s{8ib`hwbdpajwpqloofgjwhmftmfbq?"..dqltIPLMgvwzMbnfpbofzlv#olwpsbjmibyy`logfzfpejpkttt-qjphwbapsqfu23s{qjpf16s{Aovfgjmd033/abooelqgfbqmtjogal{-ebjqob`hufqpsbjqivmfwf`kje+"sj`hfujo\'+! tbqnolqgglfpsvoo/333jgfbgqbtkvdfpslwevmgavqmkqfe`foohfzpwj`hklvqolppevfo21s{pvjwgfboQPP!bdfgdqfzDFW!fbpfbjnpdjqobjgp;s{8mbuzdqjgwjsp :::tbqpobgz`bqp*8#~sks<kfoowbootklnyk9\t),\x0e\t#233kboo-\t\tB4s{8svpk`kbw3s{8`qft),?,kbpk46s{eobwqbqf#%%#wfoo`bnslmwlobjgnjppphjswfmwejmfnbofdfwpsolw733/\x0e\t\x0e\t`lloeffw-sks?aq=fqj`nlpwdvjgafoogfp`kbjqnbwkbwln,jnd% ;1ov`h`fmw3338wjmzdlmfkwnopfoogqvdEQFFmlgfmj`h<jg>olpfmvooubpwtjmgQPP#tfbqqfozaffmpbnfgvhfmbpb`bsftjpkdvoeW109kjwppolwdbwfhj`haovqwkfz26s{$$*8*8!=npjftjmpajqgplqwafwbpffhW2;9lqgpwqffnboo53s{ebqn\x0elupalzpX3^-$*8!SLPWafbqhjgp*8~~nbqzwfmg+VH*rvbgyk9\n.pjy....sqls$*8\x0eojewW2:9uj`fbmgzgfaw=QPPsllomf`haoltW259gllqfuboW249ofwpebjolqbosloomlub`lopdfmf#\x0elxplewqlnfwjooqlpp?k0=slvqebgfsjmh?wq=njmj*\x7f"+njmfyk9\x04abqpkfbq33*8njoh#..=jqlmeqfggjphtfmwpljosvwp,ip,klozW119JPAMW139bgbnpffp?k1=iplm$/#$`lmwW129#QPPollsbpjbnllm?,s=plvoOJMFelqw`bqwW279?k2=;3s{"..?:s{8W379njhf975Ymj`fjm`kZlqhqj`fyk9\b$**8svqfnbdfsbqbwlmfalmg904Y\\le\\$^*8333/yk9\vwbmhzbqgaltoavpk965YIbub03s{\t\x7f~\t&@0&907YifeeF[SJ`bpkujpbdloepmltyk9\x05rvfq-`pppj`hnfbwnjm-ajmggfookjqfsj`pqfmw905YKWWS.132elwltloeFMG#{al{967YALGZgj`h8\t~\tf{jw906Yubqpafbw$~*8gjfw:::8bmmf~~?,Xj^-Obmdhn.^tjqfwlzpbggppfbobof{8\t\n~f`klmjmf-lqd336*wlmziftppbmgofdpqlle333*#133tjmfdfbqgldpallwdbqz`vwpwzofwfnswjlm-{no`l`hdbmd\'+$-63s{Sk-Gnjp`bobmolbmgfphnjofqzbmvmj{gjp`*8~\tgvpw`ojs*-\t\t43s{.133GUGp4^=?wbsfgfnlj((*tbdffvqlskjolswpklofEBRpbpjm.15WobapsfwpVQO#avoh`llh8~\x0e\tKFBGX3^*baaqivbm+2:;ofpkwtjm?,j=plmzdvzpev`hsjsf\x7f.\t"331*mgltX2^8X^8\tOld#pbow\x0e\t\n\nabmdwqjnabwk*x\x0e\t33s{\t~*8hl9\0effpbg=\x0ep9,,#X^8wloosovd+*x\tx\x0e\t#-ip$133sgvboalbw-ISD*8\t~rvlw*8\t\t$*8\t\x0e\t~\x0e1327132613251324132;132:13131312131113101317131613151314131;131:130313021301130013071306130513041320132113221323133:133;133413351336133713301331133213332:::2::;2::42::52::62::72::02::12::22::32:;:2:;;2:;42:;52:;62:;72:;02:;12:;22:;32:4:2:4;2:442:452:462:472:402:412:422:432:5:2:5;2:542:552:562:572:502:512:522:532:6:2:6;2:642:652:662:672:602:612:622:632333231720:73333::::`lnln/Mpfpwffpwbsfqlwlglkb`f`bgbb/]lajfmg/Abbp/Aujgb`bpllwqlelqlplollwqb`vbogjilpjgldqbmwjslwfnbgfafbodlrv/Efpwlmbgbwqfpsl`l`bpbabilwlgbpjmlbdvbsvfpvmlpbmwfgj`fovjpfoobnbzlylmbbnlqsjpllaqb`oj`foolgjlpklqb`bpj<[<\\<Q<\\<R<P=l<\\=l=o=n<\\<Q<Y<S<R<R=n<T<[<Q<R<X<R=n<R<Z<Y<R<Q<T=i<q<\\<Y<Y<]=g<P=g<~=g=m<R<^=g<^<R<q<R<R<]<s<R<W<T<Q<T<L<H<q<Y<p=g=n=g<r<Q<T<P<X<\\<{<\\<x<\\<q=o<r<]=n<Y<t<[<Y<U<Q=o<P<P<N=g=o<Z5m5f4O5j5i4K5i4U5o5h4O5d4]4C5f4K5m5e5k5d5h5i5h5o4K5d5h5k4D4_4K5h4I5j5k5f4O5f5n4C5k5h4G5i4D5k5h5d5h5f4D5h4K5f4D5o4X5f4K5i4O5i5j4F4D5f5h5j4A4D5k5i5i4X5d4Xejqpwujgflojdkwtlqognfgjbtkjwf`olpfaob`hqjdkwpnbooallhpsob`fnvpj`ejfoglqgfqsljmwubovfofufowbaofalbqgklvpfdqlvstlqhpzfbqppwbwfwlgbztbwfqpwbqwpwzofgfbwksltfqsklmfmjdkwfqqlqjmsvwbalvwwfqnpwjwofwllopfufmwol`bowjnfpobqdftlqgpdbnfppklqwpsb`fel`vp`ofbqnlgfoaol`hdvjgfqbgjlpkbqftlnfmbdbjmnlmfzjnbdfmbnfpzlvmdojmfpobwfq`lolqdqffmeqlmw%bns8tbw`kelq`fsqj`fqvofpafdjmbewfqujpjwjppvfbqfbpafoltjmgf{wlwboklvqpobafosqjmwsqfppavjowojmhppsffgpwvgzwqbgfelvmgpfmpfvmgfqpkltmelqnpqbmdfbggfgpwjoonlufgwbhfmbalufeobpkej{fglewfmlwkfqujftp`kf`hofdboqjufqjwfnprvj`hpkbsfkvnbmf{jpwdljmdnlujfwkjqgabpj`sfb`fpwbdftjgwkoldjmjgfbptqlwfsbdfpvpfqpgqjufpwlqfaqfbhplvwkulj`fpjwfpnlmwktkfqfavjogtkj`kfbqwkelqvnwkqffpslqwsbqwz@oj`holtfqojufp`obppobzfqfmwqzpwlqzvpbdfplvmg`lvqwzlvq#ajqwkslsvswzsfpbssozJnbdfafjmdvssfqmlwfpfufqzpkltpnfbmpf{wqbnbw`kwqb`hhmltmfbqozafdbmpvsfqsbsfqmlqwkofbqmdjufmmbnfgfmgfgWfqnpsbqwpDqlvsaqbmgvpjmdtlnbmebopfqfbgzbvgjlwbhfptkjof-`ln,ojufg`bpfpgbjoz`kjogdqfbwivgdfwklpfvmjwpmfufqaqlbg`lbpw`lufqbssofejofp`z`ofp`fmfsobmp`oj`htqjwfrvffmsjf`ffnbjoeqbnflogfqsklwlojnjw`b`kf`jujop`boffmwfqwkfnfwkfqfwlv`kalvmgqlzbobphfgtklofpjm`fpwl`h#mbnfebjwkkfbqwfnswzleefqp`lsfltmfgnjdkwboavnwkjmhaollgbqqbznbilqwqvpw`bmlmvmjlm`lvmwubojgpwlmfPwzofOldjmkbsszl``vqofew9eqfpkrvjwfejonpdqbgfmffgpvqabmejdkwabpjpklufqbvwl8qlvwf-kwnonj{fgejmboZlvq#pojgfwlsj`aqltmbolmfgqbtmpsojwqfb`kQjdkwgbwfpnbq`krvlwfdllgpOjmhpglvawbpzm`wkvnaboolt`kjfezlvwkmlufo23s{8pfqufvmwjokbmgp@kf`hPsb`frvfqzibnfpfrvbowtj`f3/333Pwbqwsbmfoplmdpqlvmgfjdkwpkjewtlqwkslpwpofbgptffhpbuljgwkfpfnjofpsobmfpnbqwboskbsobmwnbqhpqbwfpsobzp`objnpbofpwf{wppwbqptqlmd?,k0=wkjmd-lqd,nvowjkfbqgSltfqpwbmgwlhfmplojg+wkjpaqjmdpkjsppwbeewqjfg`boopevoozeb`wpbdfmwWkjp#,,..=bgnjmfdzswFufmw26s{8Fnbjowqvf!`qlpppsfmwaoldpal{!=mlwfgofbuf`kjmbpjyfpdvfpw?,k7=qlalwkfbuzwqvf/pfufmdqbmg`qjnfpjdmpbtbqfgbm`fskbpf=?"..fm\\VP% 0:8133s{\\mbnfobwjmfmilzbib{-bwjlmpnjwkV-P-#klogpsfwfqjmgjbmbu!=`kbjmp`lqf`lnfpgljmdsqjlqPkbqf2::3pqlnbmojpwpibsbmeboopwqjboltmfqbdqff?,k1=bavpfbofqwlsfqb!.,,T`bqgpkjoopwfbnpSklwlwqvwk`ofbm-sks<pbjmwnfwboolvjpnfbmwsqlleaqjfeqlt!=dfmqfwqv`hollhpUbovfEqbnf-mfw,..=\t?wqz#x\tubq#nbhfp`lpwpsobjmbgvowrvfpwwqbjmobalqkfosp`bvpfnbdj`nlwlqwkfjq163s{ofbpwpwfsp@lvmw`lvogdobpppjgfpevmgpklwfobtbqgnlvwknlufpsbqjpdjufpgvw`kwf{bpeqvjwmvoo/\x7f\x7fX^8wls!=\t?"..SLPW!l`fbm?aq,=eollqpsfbhgfswk#pjyfabmhp`bw`k`kbqw13s{8bojdmgfboptlvog63s{8vqo>!sbqhpnlvpfNlpw#---?,bnlmdaqbjmalgz#mlmf8abpfg`bqqzgqbewqfefqsbdf\\klnf-nfwfqgfobzgqfbnsqlufiljmw?,wq=gqvdp?"..#bsqjojgfboboofmf{b`welqwk`lgfpoldj`Ujft#pffnpaobmhslqwp#+133pbufg\\ojmhdlbopdqbmwdqffhklnfpqjmdpqbwfg03s{8tklpfsbqpf+*8!#Aol`hojmv{ilmfpsj{fo$*8!=*8je+.ofewgbujgklqpfEl`vpqbjpfal{fpWqb`hfnfmw?,fn=abq!=-pq`>wltfqbow>!`baofkfmqz17s{8pfwvsjwbozpkbqsnjmlqwbpwftbmwpwkjp-qfpfwtkffodjqop,`pp,233&8`ovappwveeajaofulwfp#2333hlqfb~*8\x0e\tabmgprvfvf>#x~8;3s{8`hjmdx\x0e\t\n\nbkfbg`ol`hjqjpkojhf#qbwjlpwbwpElqn!zbkll*X3^8Balvwejmgp?,k2=gfavdwbphpVQO#>`foop~*+*821s{8sqjnfwfoopwvqmp3{533-isd!psbjmafb`kwb{fpnj`qlbmdfo..=?,djewppwfuf.ojmhalgz-~*8\t\nnlvmw#+2::EBR?,qldfqeqbmh@obpp1;s{8effgp?k2=?p`lwwwfpwp11s{8gqjmh*#\x7f\x7f#oftjppkboo 30:8#elq#olufgtbpwf33s{8ib9\x0fnpjnlm?elmwqfsoznffwpvmwfq`kfbswjdkwAqbmg*#">#gqfpp`ojspqllnplmhfznlajonbjm-Mbnf#sobwfevmmzwqffp`ln,!2-isdtnlgfsbqbnPWBQWofew#jggfm/#132*8\t~\telqn-ujqvp`kbjqwqbmptlqpwSbdfpjwjlmsbw`k?"..\tl.`b`ejqnpwlvqp/333#bpjbmj((*xbglaf$*X3^jg>23alwk8nfmv#-1-nj-smd!hfujm`lb`k@kjogaqv`f1-isdVQO*(-isd\x7fpvjwfpoj`fkbqqz213!#ptffwwq=\x0e\tmbnf>gjfdlsbdf#ptjpp..=\t\t eee8!=Old-`ln!wqfbwpkffw*#%%#27s{8poffsmwfmwejofgib9\x0fojg>!`Mbnf!tlqpfpklwp.al{.gfowb\t%ow8afbqp97;Y?gbwb.qvqbo?,b=#psfmgabhfqpklsp>#!!8sks!=`wjlm20s{8aqjbmkfoolpjyf>l>&1E#iljmnbzaf?jnd#jnd!=/#eipjnd!#!*X3^NWlsAWzsf!mftozGbmph`yf`kwqbjohmltp?,k6=ebr!=yk.`m23*8\t.2!*8wzsf>aovfpwqvozgbujp-ip$8=\x0e\t?"pwffo#zlv#k1=\x0e\telqn#ifpvp233&#nfmv-\x0e\t\n\x0e\ttbofpqjphpvnfmwggjmda.ojhwfb`kdje!#ufdbpgbmphffpwjpkrjspvlnjplaqfgfpgffmwqfwlglpsvfgfb/]lpfpw/Mwjfmfkbpwblwqlpsbqwfglmgfmvfulkb`fqelqnbnjpnlnfilqnvmglbrv/Ag/Abpp/_olbzvgbef`kbwlgbpwbmwlnfmlpgbwlplwqbppjwjlnv`klbklqbovdbqnbzlqfpwlpklqbpwfmfqbmwfpelwlpfpwbpsb/Apmvfubpbovgelqlpnfgjlrvjfmnfpfpslgfq`kjofpfq/Muf`fpgf`jqilp/Efpwbqufmwbdqvslkf`klfoolpwfmdlbnjdl`lpbpmjufodfmwfnjpnbbjqfpivojlwfnbpkb`jbebulqivmjlojaqfsvmwlavfmlbvwlqbaqjoavfmbwf{wlnbqylpbafqojpwbovfdl`/_nlfmfqlivfdlsfq/Vkbafqfpwlzmvm`bnvifqubolqevfqbojaqldvpwbjdvboulwlp`bplpdv/Absvfglplnlpbujplvpwfggfafmml`kfavp`bebowbfvqlppfqjfgj`kl`vqpl`obuf`bpbpof/_msobylobqdllaqbpujpwbbslzlivmwlwqbwbujpwl`qfbq`bnslkfnlp`jm`l`bqdlsjplplqgfmkb`fm/Mqfbgjp`lsfgql`fq`bsvfgbsbsfonfmlq/Vwjo`obqlilqdf`boofslmfqwbqgfmbgjfnbq`bpjdvffoobppjdol`l`kfnlwlpnbgqf`obpfqfpwlmj/]lrvfgbsbpbqabm`lkjilpujbifsbaol/Epwfujfmfqfjmlgfibqelmgl`bmbomlqwfofwqb`bvpbwlnbqnbmlpovmfpbvwlpujoobufmglsfpbqwjslpwfmdbnbq`loofubsbgqfvmjglubnlpylmbpbnalpabmgbnbqjbbavplnv`kbpvajqqjlibujujqdqbgl`kj`bboo/Ailufmgj`kbfpwbmwbofppbojqpvfolsfplpejmfpoobnbavp`l/Epwboofdbmfdqlsobybkvnlqsbdbqivmwbglaofjpobpalopbab/]lkbaobov`kb/mqfbgj`fmivdbqmlwbpuboofboo/M`bqdbglolqbabilfpw/Edvpwlnfmwfnbqjlejqnb`lpwlej`kbsobwbkldbqbqwfpofzfpbrvfonvpflabpfpsl`lpnjwbg`jfol`kj`lnjfgldbmbqpbmwlfwbsbgfafpsobzbqfgfppjfwf`lqwf`lqfbgvgbpgfpflujfilgfpfbbdvbp%rvlw8glnbjm`lnnlmpwbwvpfufmwpnbpwfqpzpwfnb`wjlmabmmfqqfnlufp`qloovsgbwfdolabonfgjvnejowfqmvnafq`kbmdfqfpvowsvaoj`p`qffm`kllpfmlqnbowqbufojppvfpplvq`fwbqdfwpsqjmdnlgvofnlajofptjw`ksklwlpalqgfqqfdjlmjwpfoepl`jbob`wjuf`lovnmqf`lqgelooltwjwof=fjwkfqofmdwkebnjozeqjfmgobzlvwbvwklq`qfbwfqfujftpvnnfqpfqufqsobzfgsobzfqf{sbmgsloj`zelqnbwglvaofsljmwppfqjfpsfqplmojujmdgfpjdmnlmwkpelq`fpvmjrvftfjdkwsflsoffmfqdzmbwvqfpfbq`kejdvqfkbujmd`vpwlnleepfwofwwfqtjmgltpvanjwqfmgfqdqlvspvsolbgkfbowknfwklgujgflpp`klloevwvqfpkbgltgfabwfubovfpLaif`wlwkfqpqjdkwpofbdvf`kqlnfpjnsofmlwj`fpkbqfgfmgjmdpfbplmqfslqwlmojmfprvbqfavwwlmjnbdfpfmbaofnlujmdobwfpwtjmwfqEqbm`fsfqjlgpwqlmdqfsfbwOlmglmgfwbjoelqnfggfnbmgpf`vqfsbppfgwlddofsob`fpgfuj`fpwbwj``jwjfppwqfbnzfooltbwwb`hpwqffweojdkwkjggfmjmel!=lsfmfgvpfevouboofz`bvpfpofbgfqpf`qfwpf`lmggbnbdfpslqwpf{`fswqbwjmdpjdmfgwkjmdpfeef`wejfogppwbwfpleej`fujpvbofgjwlqulovnfQfslqwnvpfvnnlujfpsbqfmwb``fppnlpwoznlwkfq!#jg>!nbqhfwdqlvmg`kbm`fpvqufzafelqfpznalonlnfmwpsff`knlwjlmjmpjgfnbwwfq@fmwfqlaif`wf{jpwpnjggofFvqlsfdqltwkofdb`znbmmfqfmlvdk`bqffqbmptfqlqjdjmslqwbo`ojfmwpfof`wqbmgln`olpfgwlsj`p`lnjmdebwkfqlswjlmpjnsozqbjpfgfp`bsf`klpfm`kvq`kgfejmfqfbplm`lqmfqlvwsvwnfnlqzjeqbnfsloj`fnlgfopMvnafqgvqjmdleefqppwzofphjoofgojpwfg`boofgpjoufqnbqdjmgfofwfafwwfqaqltpfojnjwpDolabopjmdoftjgdfw`fmwfqavgdfwmltqbs`qfgjw`objnpfmdjmfpbefwz`klj`fpsjqjw.pwzofpsqfbgnbhjmdmffgfgqvppjbsofbpff{wfmwP`qjswaqlhfmbooltp`kbqdfgjujgfeb`wlqnfnafq.abpfgwkflqz`lmejdbqlvmgtlqhfgkfosfg@kvq`kjnsb`wpklvogbotbzpoldl!#alwwlnojpw!=*xubq#sqfej{lqbmdfKfbgfq-svpk+`lvsofdbqgfmaqjgdfobvm`kQfujftwbhjmdujpjlmojwwofgbwjmdAvwwlmafbvwzwkfnfpelqdlwPfbq`kbm`klqbonlpwolbgfg@kbmdfqfwvqmpwqjmdqfolbgNlajofjm`lnfpvssozPlvq`flqgfqpujftfg%maps8`lvqpfBalvw#jpobmg?kwno#`llhjfmbnf>!bnbylmnlgfqmbguj`fjm?,b=9#Wkf#gjboldklvpfpAFDJM#Nf{j`lpwbqwp`fmwqfkfjdkwbggjmdJpobmgbppfwpFnsjqfP`kllofeelqwgjqf`wmfbqoznbmvboPfof`w-\t\tLmfiljmfgnfmv!=SkjojsbtbqgpkbmgofjnslqwLeej`fqfdbqgphjoopmbwjlmPslqwpgfdqfftffhoz#+f-d-afkjmggl`wlqolddfgvmjwfg?,a=?,afdjmpsobmwpbppjpwbqwjpwjppvfg033s{\x7f`bmbgbbdfm`zp`kfnfqfnbjmAqbyjopbnsofoldl!=afzlmg.p`bofb``fswpfqufgnbqjmfEllwfq`bnfqb?,k2=\t\\elqn!ofbufppwqfpp!#,=\x0e\t-dje!#lmolbgolbgfqL{elqgpjpwfqpvqujuojpwfmefnbofGfpjdmpjyf>!bssfbowf{w!=ofufopwkbmhpkjdkfqelq`fgbmjnbobmzlmfBeqj`bbdqffgqf`fmwSflsof?aq#,=tlmgfqsqj`fpwvqmfg\x7f\x7f#x~8nbjm!=jmojmfpvmgbztqbs!=ebjofg`fmpvpnjmvwfafb`lmrvlwfp263s{\x7ffpwbwfqfnlwffnbjo!ojmhfgqjdkw8pjdmboelqnbo2-kwnopjdmvssqjm`feolbw9-smd!#elqvn-B``fppsbsfqpplvmgpf{wfmgKfjdkwpojgfqVWE.;!%bns8#Afelqf-#TjwkpwvgjlltmfqpnbmbdfsqlejwiRvfqzbmmvbosbqbnpalvdkwebnlvpdlldofolmdfqj((*#xjpqbfopbzjmdgf`jgfklnf!=kfbgfqfmpvqfaqbm`ksjf`fpaol`h8pwbwfgwls!=?qb`jmdqfpjyf..%dw8sb`jwzpf{vboavqfbv-isd!#23/333lawbjmwjwofpbnlvmw/#Jm`-`lnfgznfmv!#ozqj`pwlgbz-jmgffg`lvmwz\\oldl-EbnjozollhfgNbqhfwopf#jeSobzfqwvqhfz*8ubq#elqfpwdjujmdfqqlqpGlnbjm~fopfxjmpfqwAold?,ellwfqoldjm-ebpwfqbdfmwp?algz#23s{#3sqbdnbeqjgbzivmjlqgloobqsob`fg`lufqpsovdjm6/333#sbdf!=alpwlm-wfpw+bubwbqwfpwfg\\`lvmwelqvnpp`kfnbjmgf{/ejoofgpkbqfpqfbgfqbofqw+bssfbqPvanjwojmf!=algz!=\t)#WkfWklvdkpffjmdifqpfzMftp?,ufqjezf{sfqwjmivqztjgwk>@llhjfPWBQW#b`qlpp\\jnbdfwkqfbgmbwjufsl`hfwal{!=\tPzpwfn#Gbujg`bm`fqwbaofpsqlufgBsqjo#qfboozgqjufqjwfn!=nlqf!=albqgp`lolqp`bnsvpejqpw#\x7f\x7f#X^8nfgjb-dvjwbqejmjpktjgwk9pkltfgLwkfq#-sks!#bppvnfobzfqptjoplmpwlqfpqfojfeptfgfm@vpwlnfbpjoz#zlvq#Pwqjmd\t\tTkjowbzolq`ofbq9qfplqweqfm`kwklvdk!*#(#!?algz=avzjmdaqbmgpNfnafqmbnf!=lssjmdpf`wlq6s{8!=upsb`fslpwfqnbilq#`leeffnbqwjmnbwvqfkbssfm?,mbu=hbmpbpojmh!=Jnbdfp>ebopftkjof#kpsb`f3%bns8#\t\tJm##sltfqSlophj.`lolqilqgbmAlwwlnPwbqw#.`lvmw1-kwnomftp!=32-isdLmojmf.qjdkwnjoofqpfmjlqJPAM#33/333#dvjgfpubovf*f`wjlmqfsbjq-{no!##qjdkwp-kwno.aol`hqfdF{s9klufqtjwkjmujqdjmsklmfp?,wq=\x0evpjmd#\t\nubq#=$*8\t\n?,wg=\t?,wq=\tabkbpbaqbpjodbofdlnbdzbqslophjpqsphj4]4C5d\bTA\nzk\vBl\bQ\x7f\vUm\x05Gx\bSM\nmC\bTA\twQ\nd}\bW@\bTl\bTF\ti@\tcT\vBM\v|j\x04BV\tqw\tcC\bWI\npa\tfM\n{Z\x05{X\bTF\bVV\bVK\t\x7fm\x04kF\t[]\bPm\bTv\nsI\vpg\t[I\bQp\x04mx\v_W\n^M\npe\vQ}\vGu\nel\npe\x04Ch\x04BV\bTA\tSo\nzk\vGL\vxD\nd[\x05Jz\x05MY\bQp\x04li\nfl\npC\x05{B\x05Nt\vwT\ti_\bTg\x04QQ\n|p\vXN\bQS\vxD\x04QC\bWZ\tpD\vVS\bTW\x05Nt\x04Yh\nzu\x04Kj\x05N}\twr\tHa\n_D\tj`\vQ}\vWp\nxZ\x04{c\tji\tBU\nbD\x04a|\tTn\tpV\nZd\nmC\vEV\x05{X\tc}\tTo\bWl\bUd\tIQ\tcg\vxs\nXW\twR\vek\tc}\t]y\tJn\nrp\neg\npV\nz\\\x05{W\npl\nz\\\nzU\tPc\t`{\bV@\nc|\bRw\ti_\bVb\nwX\tHv\x04Su\bTF\v_W\vWs\vsI\x05m\x7f\nTT\ndc\tUS\t}f\tiZ\bWz\tc}\x04MD\tBe\tiD\v@@\bTl\bPv\t}t\x04Sw\x04M`\vnU\tkW\ved\nqo\vxY\tA|\bTz\vy`\x04BR\x04BM\tia\x04XU\nyu\x04n^\tfL\tiI\nXW\tfD\bWz\bW@\tyj\t\x7fm\tav\tBN\vb\\\tpD\bTf\nY[\tJn\bQy\t[^\vWc\vyu\x04Dl\x04CJ\vWj\vHR\t`V\vuW\tQy\np@\vGu\x05pl\x04Jm\bW[\nLP\nxC\n`m\twQ\x05ui\x05\x7fR\nbI\twQ\tBZ\tWV\x04BR\npg\tcg\x05ti\x04CW\n_y\tRg\bQa\vQB\vWc\nYb\x05le\ngE\x04Su\nL[\tQ\x7f\tea\tdj\v]W\nb~\x04M`\twL\bTV\bVH\nt\x7f\npl\t|b\x05s_\bU|\bTa\x04oQ\x05lv\x04Sk\x04M`\bTv\vK}\nfl\tcC\x04oQ\x04BR\tHk\t|d\bQp\tHK\tBZ\vHR\bPv\vLx\vEZ\bT\x7f\bTv\tiD\x05oD\x05MU\vwB\x04Su\x05k`\x04St\ntC\tPl\tKg\noi\tjY\vxY\x04h}\nzk\bWZ\t\x7fm\ve`\tTB\tfE\nzk\t`z\x04Yh\nV|\tHK\tAJ\tAJ\bUL\tp\\\tql\nYc\x04Kd\nfy\x04Yh\t[I\vDg\x04Jm\n]n\nlb\bUd\n{Z\tlu\tfs\x04oQ\bTW\x04Jm\vwB\tea\x04Yh\x04BC\tsb\tTn\nzU\n_y\vxY\tQ]\ngw\x04mt\tO\\\ntb\bWW\bQy\tmI\tV[\ny\\\naB\vRb\twQ\n]Q\x04QJ\bWg\vWa\bQj\ntC\bVH\nYm\vxs\bVK\nel\bWI\vxY\x04Cq\ntR\vHV\bTl\bVw\tay\bQa\bVV\t}t\tdj\nr|\tp\\\twR\n{i\nTT\t[I\ti[\tAJ\vxs\v_W\td{\vQ}\tcg\tTz\tA|\tCj\vLm\x05N}\x05m\x7f\nbK\tdZ\tp\\\t`V\tsV\np@\tiD\twQ\vQ}\bTf\x05ka\x04Jm\v@@\bV`\tzp\n@N\x04Sw\tiI\tcg\noi\x04Su\bVw\x04lo\x04Cy\tc}\vb\\\tsU\x04BA\bWI\bTf\nxS\tVp\nd|\bTV\vbC\tNo\x05Ju\nTC\t|`\n{Z\tD]\bU|\tc}\x05lm\bTl\tBv\tPl\tc}\bQp\t\x7fm\nLk\tkj\n@N\x04Sb\x04KO\tj_\tp\\\nzU\bTl\bTg\bWI\tcf\x04XO\bWW\ndz\x04li\tBN\nd[\bWO\x04MD\vKC\tdj\tI_\bVV\ny\\\vLm\x05xl\txB\tkV\vb\\\vJW\vVS\tVx\vxD\td{\x04MD\bTa\t|`\vPz\x04R}\vWs\x04BM\nsI\x04CN\bTa\x04Jm\npe\ti_\npV\nrh\tRd\tHv\n~A\nxR\vWh\vWk\nxS\vAz\vwX\nbI\x04oQ\tfw\nqI\nV|\nun\x05z\x7f\vpg\td\\\voA\x05{D\ti_\x05xB\bT\x7f\t`V\x05qr\tTT\x04g]\x04CA\vuR\tVJ\tT`\npw\vRb\tI_\nCx\x04Ro\vsI\x04Cj\x04Kh\tBv\tWV\x04BB\x05oD\x05{D\nhc\x04Km\v^R\tQE\n{I\np@\nc|\x05Gt\tc}\x04Dl\nzU\x05qN\tsV\x05k}\tHh\v|j\nqo\x05u|\tQ]\vek\x05\x7fZ\x04M`\x04St\npe\tdj\bVG\veE\t\x7fm\vWc\x04|I\n[W\tfL\bT\x7f\tBZ\x04Su\vKa\x04Cq\x05Nt\x04Y[\nqI\bTv\tfM\ti@\t}f\x04B\\\tQy\vBl\bWg\x04XD\x05kc\vx[\bVV\tQ]\t\x7fa\tPy\vxD\nfI\t}f\x05oD\tdj\tSG\x05ls\t~D\x04CN\n{Z\t\\v\n_D\nhc\vx_\x04C[\tAJ\nLM\tVx\x04CI\tbj\tc^\tcF\ntC\x04Sx\twr\x04XA\bU\\\t|a\vK\\\bTV\bVj\nd|\tfs\x04CX\ntb\bRw\tVx\tAE\tA|\bT\x7f\x05Nt\vDg\tVc\bTl\x04d@\npo\t\x7fM\tcF\npe\tiZ\tBo\bSq\nfH\x04l`\bTx\bWf\tHE\vF{\tcO\tfD\nlm\vfZ\nlm\veU\tdG\x04BH\bTV\tSi\x05MW\nwX\nz\\\t\\c\x04CX\nd}\tl}\bQp\bTV\tF~\bQ\x7f\t`i\ng@\x05nO\bUd\bTl\nL[\twQ\tji\ntC\t|J\nLU\naB\vxY\x04Kj\tAJ\x05uN\ti[\npe\x04Sk\vDg\vx]\bVb\bVV\nea\tkV\nqI\bTa\x04Sk\nAO\tpD\ntb\nts\nyi\bVg\ti_\v_W\nLk\x05Nt\tyj\tfM\x04R\x7f\tiI\bTl\vwX\tsV\vMl\nyu\tAJ\bVj\x04KO\tWV\vA}\vW\x7f\nrp\tiD\v|o\x05lv\vsI\x04BM\td~\tCU\bVb\x04eV\npC\vwT\tj`\tc}\vxs\vps\vvh\tWV\vGg\vAe\vVK\v]W\trg\vWc\x05F`\tBr\vb\\\tdZ\bQp\nqI\x04kF\nLk\vAR\bWI\bTg\tbs\tdw\n{L\n_y\tiZ\bTA\tlg\bVV\bTl\tdk\n`k\ta{\ti_\x05{A\x05wj\twN\v@@\bTe\ti_\n_D\twL\nAH\viK\vek\n[]\tp_\tyj\bTv\tUS\t[r\n{I\nps\x05Gt\vVK\npl\x04S}\vWP\t|d\x04MD\vHV\bT\x7f\x04R}\x04M`\bTV\bVH\x05lv\x04Ch\bW[\x04Ke\tR{\v^R\tab\tBZ\tVA\tB`\nd|\nhs\x04Ke\tBe\x04Oi\tR{\td\\\x05nB\bWZ\tdZ\tVJ\x05Os\t\x7fm\x04uQ\vhZ\x04Q@\x04QQ\nfI\bW[\x04B\\\x04li\nzU\nMd\x04M`\nxS\bVV\n\\}\vxD\t\x7fm\bTp\x04IS\nc|\tkV\x05i~\tV{\vhZ\t|b\bWt\n@R\voA\vnU\bWI\tea\tB`\tiD\tc}\tTz\x04BR\vQB\x05Nj\tCP\t[I\bTv\t`W\x05uN\vpg\vpg\vWc\tiT\tbs\twL\tU_\tc\\\t|h\vKa\tNr\tfL\nq|\nzu\nz\\\tNr\bUg\t|b\x04m`\bTv\nyd\nrp\bWf\tUX\x04BV\nzk\nd}\twQ\t}f\x04Ce\ved\bTW\bSB\nxU\tcn\bTb\ne\x7f\ta\\\tSG\bU|\npV\nN\\\x04Kn\vnU\tAt\tpD\v^R\vIr\x04b[\tR{\tdE\vxD\vWK\vWA\bQL\bW@\x04Su\bUd\nDM\tPc\x04CA\x04Dl\x04oQ\tHs\x05wi\x04ub\n\x7fa\bQp\x05Ob\nLP\bTl\x04Y[\vK}\tAJ\bQ\x7f\x04n^\vsA\bSM\nqM\bWZ\n^W\vz{\x04S|\tfD\bVK\bTv\bPv\x04BB\tCP\x04dF\tid\vxs\x04mx\vws\tcC\ntC\tyc\x05M`\vW\x7f\nrh\bQp\vxD\x04\\o\nsI\x04_k\nzu\x04kF\tfD\x04Xs\x04XO\tjp\bTv\x04BS\x05{B\tBr\nzQ\nbI\tc{\x04BD\x04BV\x05nO\bTF\tca\x05Jd\tfL\tPV\tI_\nlK\x04`o\twX\npa\tgu\bP}\x05{^\bWf\n{I\tBN\npa\x04Kl\vpg\tcn\tfL\vvh\x04Cq\bTl\vnU\bSq\x04Cm\twR\bUJ\npe\nyd\nYg\x04Cy\vKW\tfD\nea\x04oQ\tj_\tBv\x04nM\vID\bTa\nzA\x05pl\n]n\bTa\tR{\tfr\n_y\bUg\x05{X\x05kk\vxD\x04|I\x05xl\nfy\x04Ce\vwB\nLk\vd]\noi\n}h\tQ]\npe\bVw\x04Hk\x04OQ\nzk\tAJ\npV\bPv\ny\\\tA{\x04Oi\bSB\x04XA\veE\tjp\nq}\tiD\x05qN\v^R\t\x7fm\tiZ\tBr\bVg\noi\n\\X\tU_\nc|\vHV\bTf\tTn\x04\\N\x04\\N\nuB\x05lv\nyu\tTd\bTf\bPL\v]W\tdG\nA`\nw^\ngI\npe\tdw\nz\\\x05ia\bWZ\tcF\x04Jm\n{Z\bWO\x04_k\x04Df\x04RR\td\\\bVV\vxs\x04BN\x05ti\x04lm\tTd\t]y\vHV\tSo\v|j\x04XX\tA|\vZ^\vGu\bTW\x05M`\x04kF\vhZ\vVK\tdG\vBl\tay\nxU\x05qE\x05nO\bVw\nqI\x04CX\ne\x7f\tPl\bWO\vLm\tdL\x05uH\x04Cm\tdT\x04fn\vwB\x05ka\vnU\n@M\nyT\tHv\t\\}\x04Kh\td~\x04Yh\x05k}\neR\td\\\bWI\t|b\tHK\tiD\bTW\x05MY\npl\bQ_\twr\vAx\tHE\bTg\bSq\x05vp\vb\\\bWO\nOl\nsI\nfy\vID\t\\c\n{Z\n^~\npe\nAO\tTT\vxv\x04k_\bWO\v|j\vwB\tQy\ti@\tPl\tHa\tdZ\x05k}\x04ra\tUT\vJc\ved\np@\tQN\nd|\tkj\tHk\x04M`\noi\twr\td\\\nlq\no_\nlb\nL[\tac\x04BB\x04BH\x04Cm\npl\tIQ\bVK\vxs\n`e\viK\npa\x04Oi\tUS\bTp\tfD\nPG\x05kk\x04XA\nz\\\neg\vWh\twR\x05qN\nqS\tcn\x04lo\nxS\n^W\tBU\nt\x7f\tHE\tp\\\tfF\tfw\bVV\bW@\tak\vVK\x05ls\tVJ\bVV\veE\x04\\o\nyX\nYm\x04M`\x05lL\nd|\nzk\tA{\x05sE\twQ\x04XT\nt\x7f\tPl\t]y\vwT\x05{p\x04MD\vb\\\tQ]\x04Kj\tJn\nAH\vRb\tBU\tHK\t\\c\nfI\x05m\x7f\nqM\n@R\tSo\noi\x04BT\tHv\n_y\x04Kh\tBZ\t]i\bUJ\tV{\x04Sr\nbI\vGg\ta_\bTR\nfI\nfl\t[K\tII\x04S|\vuW\tiI\bWI\nqI\v|j\x04BV\bVg\bWZ\x04kF\vx]\bTA\tab\tfr\ti@\tJd\tJd\vps\nAO\bTa\x05xu\tiD\nzk\t|d\t|`\bW[\tlP\tdG\bVV\vw}\vqO\ti[\bQ\x7f\bTz\vVF\twN\x05ts\tdw\bTv\neS\ngi\tNr\x05yS\npe\bVV\bSq\n`m\tyj\tBZ\vWX\bSB\tc\\\nUR\t[J\tc_\x04nM\bWQ\vAx\nMd\tBr\x05ui\vxY\bSM\vWc\v|j\vxs\t}Q\tBO\bPL\bWW\tfM\nAO\tPc\veU\x04e^\bTg\nqI\tac\bPv\tcF\x04oQ\tQ\x7f\vhZ\x05ka\nz\\\tiK\tBU\n`k\tCP\x04S|\x04M`\n{I\tS{\x04_O\tBZ\x04Zi\x04Sk\tps\tp\\\nYu\n]s\nxC\bWt\nbD\tkV\vGu\x05yS\nqA\t[r\neK\x04M`\tdZ\x05lL\bUg\bTl\nbD\tUS\vb\\\tpV\ncc\x04S\\\tct\t`z\bPL\vWs\nA`\neg\bSq\x05uE\x04CR\vDg\t`W\vz{\vWc\x04Sk\x04Sk\tbW\bUg\tea\nxZ\tiI\tUX\tVJ\nqn\tS{\vRb\bTQ\npl\x05Gt\vuW\x05uj\npF\nqI\tfL\t[I\tia\x04XO\nyu\vDg\ved\tq{\x04VG\bQ\x7f\x05ka\tVj\tkV\txB\nd|\np@\tQN\tPc\tps\x04]j\tkV\toU\bTp\nzU\x05nB\vB]\ta{\bV@\n]n\x04m`\tcz\tR{\x04m`\bQa\vwT\bSM\x05MY\x05qN\tdj\x05~s\vQ}\x05MY\vMB\tBv\twR\bRg\vQ}\tql\vKC\nrm\x05xu\x04CC\vwB\vvh\tBq\x04Xq\npV\ti_\x05Ob\x05uE\nbd\nqo\v{i\nC~\tBL\veE\x05uH\bVj\x04Ey\x04Gz\vzR\v{i\tcf\n{Z\n]n\x04XA\vGu\vnU\thS\vGI\nCc\tHE\bTA\tHB\x04BH\x04Cj\nCc\bTF\tHE\nXI\tA{\bQ\x7f\tc\\\vmO\vWX\nfH\np@\x05MY\bTF\nlK\tBt\nzU\tTT\x04Km\vwT\npV\ndt\vyI\tVx\tQ\x7f\tRg\tTd\nzU\bRS\nLM\twA\x04nM\tTn\ndS\t]g\nLc\vwB\t}t\t[I\tCP\x04kX\vFm\vhZ\x05m\x7f\ti[\np@\vQ}\vW\x7f\t|d\nMO\nMd\tf_\tfD\tcJ\tHz\vRb\tio\tPy\x04Y[\nxU\tct\v@@\tww\bPv\x04BM\x04FF\ntb\x05v|\vKm\tBq\tBq\x04Kh\x04`o\nZd\x04XU\ti]\t|`\tSt\x04B\\\bQ\x7f\v_W\tTJ\nqI\t|a\tA{\vuP\x04MD\tPl\nxR\tfL\vws\tc{\td\\\bV`\neg\tHK\x05kc\nd|\bVV\ny\\\x05kc\ti]\bVG\t`V\tss\tI_\tAE\tbs\tdu\nel\tpD\vW\x7f\nqs\x05lv\bSM\x04Zi\vVK\x05ia\vQB\tQ\x7f\n{Z\bPt\vKl\nlK\nhs\ndS\bVK\x05mf\nd^\tkV\tcO\nc|\bVH\t\\]\bTv\bSq\tmI\vDg\tVJ\tcn\ny\\\bVg\bTv\nyX\bTF\t]]\bTp\noi\nhs\veU\nBf\tdj\x05Mr\n|p\t\\g\t]r\bVb\x05{D\nd[\x04XN\tfM\tO\\\x05s_\tcf\tiZ\x04XN\vWc\tqv\n`m\tU^\x05oD\nd|\vGg\tdE\vwf\x04lo\x04u}\nd|\x05oQ\t`i\x04Oi\vxD\ndZ\nCx\x04Yw\nzk\ntb\ngw\tyj\tB`\nyX\vps\ntC\vpP\vqw\bPu\bPX\tDm\npw\x05Nj\tss\taG\vxs\bPt\noL\x04Gz\tOk\ti@\ti]\x04eC\tIQ\tii\tdj\v@J\t|d\x05uh\bWZ\veU\vnU\bTa\tcC\x04g]\nzk\x04Yh\bVK\nLU\np@\ntb\ntR\tCj\vNP\ti@\bP{\n\\}\n{c\nwX\tfL\bVG\tc{\t|`\tAJ\t|C\tfD\x05ln\t|d\tbs\nqI\x05{B\vAx\np@\nzk\vRb\x05Os\vWS\x04e^\vD_\tBv\vWd\bVb\vxs\veE\bRw\n]n\n|p\vg|\tfw\x05kc\bTI\x05ka\n\\T\x04Sp\tju\vps\npe\x05u|\vGr\bVe\tCU\x04]M\x04XU\vxD\bTa\tIQ\vWq\tCU\tam\tdj\bSo\x04Sw\vnU\x04Ch\tQ]\x05s_\bPt\tfS\bTa\t\\}\n@O\x04Yc\tUZ\bTx\npe\vnU\nzU\t|}\tiD\nz\\\bSM\vxD\x04BR\nzQ\tQN\x04]M\x04Yh\nLP\vFm\vLX\x05vc\vql\x05ka\tHK\bVb\ntC\nCy\bTv\nuV\x04oQ\t`z\t[I\tB`\vRb\tyj\tsb\vWs\bTl\tkV\ved\ne\x7f\x05lL\vxN\t\x7fm\nJn\tjY\vxD\bVb\bSq\vyu\twL\vXL\bTA\tpg\tAt\tnD\x04XX\twR\npl\nhw\x05yS\nps\tcO\bW[\v|j\x04XN\tsV\tp\\\tBe\nb~\nAJ\n]e\x05k`\x05qN\tdw\tWV\tHE\vEV\x05Jz\tid\tB`\tzh\x05E]\tfD\bTg\x05qN\bTa\tja\x04Cv\bSM\nhc\bUe\x05t_\tie\x04g]\twQ\nPn\bVB\tjw\bVg\vbE\tBZ\vRH\bP{\tjp\n\\}\ta_\tcC\t|a\vD]\tBZ\ti[\tfD\vxW\no_\td\\\n_D\ntb\t\\c\tAJ\nlK\x04oQ\x04lo\vLx\vM@\bWZ\x04Kn\vpg\nTi\nIv\n|r\v@}\x05Jz\x05Lm\x05Wh\x05k}\x05ln\vxD\n]s\x04gc\vps\tBr\bTW\vBM\x05tZ\nBY\x04DW\tjf\vSW\x04C}\nqo\tdE\tmv\tIQ\bPP\bUb\x05lv\x04BC\nzQ\t[I\vgl\nig\bUs\x04BT\vbC\bSq\tsU\tiW\nJn\tSY\tHK\trg\npV\vID\v|j\x04KO\t`S\t|a`vbmglfmujbqnbgqjgavp`bqjmj`jlwjfnslslqrvf`vfmwbfpwbglsvfgfmivfdlp`lmwqbfpw/Mmmlnaqfwjfmfmsfqejonbmfqbbnjdlp`jvgbg`fmwqlbvmrvfsvfgfpgfmwqlsqjnfqsqf`jlpfd/Vmavfmlpuloufqsvmwlppfnbmbkba/Abbdlpwlmvfulpvmjglp`bqolpfrvjslmj/]lpnv`klpbodvmb`lqqfljnbdfmsbqwjqbqqjabnbq/Abklnaqffnsoflufqgbg`bnajlnv`kbpevfqlmsbpbglo/Amfbsbqf`fmvfubp`vqplpfpwbabrvjfqlojaqlp`vbmwlb``fplnjdvfoubqjlp`vbwqlwjfmfpdqvslppfq/Mmfvqlsbnfgjlpeqfmwfb`fq`bgfn/Mplefqwb`l`kfpnlgfoljwbojbofwqbpbod/Vm`lnsqb`vbofpf{jpwf`vfqslpjfmglsqfmpboofdbqujbifpgjmfqlnvq`jbslgq/Msvfpwlgjbqjlsvfaolrvjfqfnbmvfosqlsjl`qjpjp`jfqwlpfdvqlnvfqwfevfmwf`fqqbqdqbmgffef`wlsbqwfpnfgjgbsqlsjbleqf`fwjfqqbf.nbjoubqjbpelqnbpevwvqllaifwlpfdvjqqjfpdlmlqnbpnjpnlp/Vmj`l`bnjmlpjwjlpqby/_mgfajglsqvfabwlofglwfm/Abifp/Vpfpsfql`l`jmblqjdfmwjfmgb`jfmwl`/Mgjykbaobqpfq/Abobwjmbevfqybfpwjoldvfqqbfmwqbq/E{jwlo/_sfybdfmgbu/Agflfujwbqsbdjmbnfwqlpibujfqsbgqfpe/M`jo`bafyb/Mqfbppbojgbfmu/Alibs/_mbavplpajfmfpwf{wlpoofubqsvfgbmevfqwf`ln/Vm`obpfpkvnbmlwfmjglajoablvmjgbgfpw/Mpfgjwbq`qfbgl<X<W=c=k=n<R<V<\\<V<T<W<T=a=n<R<^=m<Y<Y<_<R<S=l<T=n<\\<V<Y=e<Y=o<Z<Y<v<\\<V<]<Y<[<]=g<W<R<Q<T<~=m<Y<S<R<X<A=n<R=n<R<P=k<Y<P<Q<Y=n<W<Y=n=l<\\<[<R<Q<\\<_<X<Y<P<Q<Y<x<W=c<s=l<T<Q<\\=m<Q<T=i=n<Y<P<V=n<R<_<R<X<^<R=n=n<\\<P<M<D<|<P<\\=c<K=n<R<^<\\=m<^<\\<P<Y<P=o<N<\\<V<X<^<\\<Q<\\<P=a=n<T=a=n=o<~<\\<P=n<Y=i<S=l<R=n=o=n<Q<\\<X<X<Q=c<~<R=n=n=l<T<Q<Y<U<~<\\=m<Q<T<P=m<\\<P=n<R=n=l=o<]<r<Q<T<P<T=l<Q<Y<Y<r<r<r<W<T=j=a=n<\\<r<Q<\\<Q<Y<P<X<R<P<P<R<U<X<^<Y<R<Q<R=m=o<X\fHy\fIk\fHU\fId\fHy\fIl\fHT\fIk\fHy\fHR\fHy\fIg\fHx\fH\\\fHF\fH\\\fHD\fIk\fHc\fHy\fHy\fHS\fHA\fIl\fHk\fHT\fHy\fH\\\fHH\fIg\fHU\fIg\fHj\fHF\fHU\fIl\fHC\fHU\fHC\fHR\fHH\fHy\fHI\fHRibdqbm\fHj\fHp\fHp\fIg\fHi\fH@\fHJ\fIg\fH{\fHd\fHp\fHR\fH{\fHc\fHU\fHB\fHk\fHD\fHY\fHU\fHC\fIk\fHI\fIk\fHI\fIl\fHt\fH\\\fHp\fH@\fHJ\fIl\fHy\fHd\fHp\fIl\fHY\fIk\fHD\fHd\fHD\fHc\fHU\fH\\\fHe\fHT\fHB\fIk\fHy\fHB\fHY\fIg\fH^\fIk\fHT\fH@\fHB\fHd\fHJ\fIk\fH\x7f\fH\\\fHj\fHB\fH@\fHT\fHA\fH\\\fH@\fHD\fHv\fH^\fHB\fHD\fHj\fH{\fHT\fIl\fH^\fIl4U5h5e4I5h5e5k4\\4K4N4B4]4U4C4C4K5h5e5k4\\5k4Y5d4]4V5f4]5o4K5j5d5h4K4D5f5j4U4]4Z4\\5h5o5k5j4K5f5d5i5n4K5h4U5h5f4K5j4K5h5o5j4A4F5e5n4D5h5d4A4E4K4B4]5m5n4[4U4D4C4]5o5j4I4\\4K5o5i4K4K4A4C4I5h4K5m5f5k4D4U4Z5o5f5m4D4A4G5d5i5j5d5k5d4O5j4K4@4C4K5h5k4K4_5h5i4U5j4C5h5f4_4U4D4]4Y5h5e5i5j4\\4D5k4K4O5j5k5i4G5h5o5j4F4K5h4K4A5f4G5i4Y4]4X4]4A4A5d5h5d5m5f4K4\\4K5h5o5h5i4]4E4K5j4F4K5h5m4O4D5d4B4K4Y4O5j4F4K5j5k4K5h5f4U4Z5d5d5n4C4K4D5j4B5f4]4D5j4F5h5o5i4X4K4M5d5k5f4K4D5d5n4Y4Y5d5i4K4]5n5i4O4A4C5j4A5j4U4C5i4]4O5f4K4A4E5o4F4D4C5d5j5f4@4D5i5j5k4F4A4F4@5k4E4_5j4E5f4F5i5o4]4E4V4^4E5j5m4_4D5f4F5h5h5k5h5j4K4F5h5o5n5h4D5h5i4K4U5j5k4O5d5h4X5f4M5j5d4]4O5i4K5m5f5o4D5o5h4\\4K4F4]4F4D4D4O5j5k5i4_4K5j5o4D5f4U5m5n4C4A4_5j5h5k5i4X4U4]4O5k5h4X5k4]5n4[4]4[5h4Dsqlejofpfquj`fgfebvowkjnpfoegfwbjop`lmwfmwpvsslqwpwbqwfgnfppbdfpv``fppebpkjlm?wjwof=`lvmwqzb``lvmw`qfbwfgpwlqjfpqfpvowpqvmmjmdsql`fpptqjwjmdlaif`wpujpjaoftfo`lnfbqwj`ofvmhmltmmfwtlqh`lnsbmzgzmbnj`aqltpfqsqjub`zsqlaofnPfquj`fqfpsf`wgjpsobzqfrvfpwqfpfquftfapjwfkjpwlqzeqjfmgplswjlmptlqhjmdufqpjlmnjoojlm`kbmmfotjmglt-bggqfppujpjwfgtfbwkfq`lqqf`wsqlgv`wfgjqf`welqtbqgzlv#`bmqfnlufgpvaif`w`lmwqlobq`kjuf`vqqfmwqfbgjmdojaqbqzojnjwfgnbmbdfqevqwkfqpvnnbqznb`kjmfnjmvwfpsqjubwf`lmwf{wsqldqbnpl`jfwzmvnafqptqjwwfmfmbaofgwqjddfqplvq`fpolbgjmdfofnfmwsbqwmfqejmboozsfqef`wnfbmjmdpzpwfnphffsjmd`vowvqf%rvlw8/ilvqmbosqlif`wpvqeb`fp%rvlw8f{sjqfpqfujftpabobm`fFmdojpk@lmwfmwwkqlvdkSofbpf#lsjmjlm`lmwb`wbufqbdfsqjnbqzujoobdfPsbmjpkdboofqzgf`ojmfnffwjmdnjppjlmslsvobqrvbojwznfbpvqfdfmfqbopsf`jfppfppjlmpf`wjlmtqjwfqp`lvmwfqjmjwjboqfslqwpejdvqfpnfnafqpklogjmdgjpsvwffbqojfqf{sqfppgjdjwbosj`wvqfBmlwkfqnbqqjfgwqbeej`ofbgjmd`kbmdfg`fmwqbouj`wlqzjnbdfp,qfbplmppwvgjfpefbwvqfojpwjmdnvpw#afp`kllopUfqpjlmvpvboozfsjplgfsobzjmddqltjmdlaujlvplufqobzsqfpfmwb`wjlmp?,vo=\x0e\ttqbssfqboqfbgz`fqwbjmqfbojwzpwlqbdfbmlwkfqgfphwlsleefqfgsbwwfqmvmvpvboGjdjwbo`bsjwboTfapjwfebjovqf`lmmf`wqfgv`fgBmgqljggf`bgfpqfdvobq#%bns8#bmjnbopqfofbpfBvwlnbwdfwwjmdnfwklgpmlwkjmdSlsvobq`bswjlmofwwfqp`bswvqfp`jfm`foj`fmpf`kbmdfpFmdobmg>2%bns8Kjpwlqz#>#mft#@fmwqbovsgbwfgPsf`jboMfwtlqhqfrvjqf`lnnfmwtbqmjmd@loofdfwlloabqqfnbjmpaf`bvpffof`wfgGfvwp`kejmbm`ftlqhfqprvj`hozafwtffmf{b`wozpfwwjmdgjpfbpfPl`jfwztfbslmpf{kjajw%ow8"..@lmwqlo`obppfp`lufqfglvwojmfbwwb`hpgfuj`fp+tjmgltsvqslpfwjwof>!Nlajof#hjoojmdpkltjmdJwbojbmgqlssfgkfbujozfeef`wp.2$^*8\t`lmejqn@vqqfmwbgubm`fpkbqjmdlsfmjmdgqbtjmdajoojlmlqgfqfgDfqnbmzqfobwfg?,elqn=jm`ovgftkfwkfqgfejmfgP`jfm`f`bwboldBqwj`ofavwwlmpobqdfpwvmjelqnilvqmfzpjgfabq@kj`bdlklojgbzDfmfqbosbppbdf/%rvlw8bmjnbwfeffojmdbqqjufgsbppjmdmbwvqboqlvdkoz-\t\tWkf#avw#mlwgfmpjwzAqjwbjm@kjmfpfob`h#lewqjavwfJqfobmg!#gbwb.eb`wlqpqf`fjufwkbw#jpOjaqbqzkvpabmgjm#eb`wbeebjqp@kbqofpqbgj`boaqlvdkwejmgjmdobmgjmd9obmd>!qfwvqm#ofbgfqpsobmmfgsqfnjvnsb`hbdfBnfqj`bFgjwjlm^%rvlw8Nfppbdfmffg#wlubovf>!`lnsof{ollhjmdpwbwjlmafojfufpnboofq.nlajofqf`lqgptbmw#wlhjmg#leEjqfel{zlv#bqfpjnjobqpwvgjfgnb{jnvnkfbgjmdqbsjgoz`ojnbwfhjmdglnfnfqdfgbnlvmwpelvmgfgsjlmffqelqnvobgzmbpwzklt#wl#Pvsslqwqfufmvff`lmlnzQfpvowpaqlwkfqplogjfqobqdfoz`boojmd-%rvlw8B``lvmwFgtbqg#pfdnfmwQlafqw#feelqwpSb`jej`ofbqmfgvs#tjwkkfjdkw9tf#kbufBmdfofpmbwjlmp\\pfbq`kbssojfgb`rvjqfnbppjufdqbmwfg9#ebopfwqfbwfgajddfpwafmfejwgqjujmdPwvgjfpnjmjnvnsfqkbspnlqmjmdpfoojmdjp#vpfgqfufqpfubqjbmw#qlof>!njppjmdb`kjfufsqlnlwfpwvgfmwplnflmff{wqfnfqfpwlqfalwwln9fuloufgboo#wkfpjwfnbsfmdojpktbz#wl##Bvdvpwpznalop@lnsbmznbwwfqpnvpj`bobdbjmpwpfqujmd~*+*8\x0e\tsbznfmwwqlvaof`lm`fsw`lnsbqfsbqfmwpsobzfqpqfdjlmpnlmjwlq#$$Wkf#tjmmjmdf{solqfbgbswfgDboofqzsqlgv`fbajojwzfmkbm`f`bqffqp*-#Wkf#`loof`wPfbq`k#bm`jfmwf{jpwfgellwfq#kbmgofqsqjmwfg`lmplofFbpwfqmf{slqwptjmgltp@kbmmfojoofdbomfvwqbopvddfpw\\kfbgfqpjdmjmd-kwno!=pfwwofgtfpwfqm`bvpjmd.tfahjw`objnfgIvpwj`f`kbswfquj`wjnpWklnbp#nlyjoobsqlnjpfsbqwjfpfgjwjlmlvwpjgf9ebopf/kvmgqfgLoznsj`\\avwwlmbvwklqpqfb`kfg`kqlmj`gfnbmgppf`lmgpsqlwf`wbglswfgsqfsbqfmfjwkfqdqfbwozdqfbwfqlufqboojnsqluf`lnnbmgpsf`jbopfbq`k-tlqpkjsevmgjmdwklvdkwkjdkfpwjmpwfbgvwjojwzrvbqwfq@vowvqfwfpwjmd`ofbqozf{slpfgAqltpfqojafqbo~#`bw`kSqlif`wf{bnsofkjgf+*8EolqjgbbmptfqpbooltfgFnsfqlqgfefmpfpfqjlvpeqffglnPfufqbo.avwwlmEvqwkfqlvw#le#">#mvoowqbjmfgGfmnbqhuljg+3*,boo-ipsqfufmwQfrvfpwPwfskfm\t\tTkfm#lapfquf?,k1=\x0e\tNlgfqm#sqlujgf!#bow>!alqgfqp-\t\tElq#\t\tNbmz#bqwjpwpsltfqfgsfqelqnej`wjlmwzsf#lenfgj`bowj`hfwplsslpfg@lvm`jotjwmfppivpwj`fDflqdf#Afodjvn---?,b=wtjwwfqmlwbaoztbjwjmdtbqebqf#Lwkfq#qbmhjmdskqbpfpnfmwjlmpvqujufp`klobq?,s=\x0e\t#@lvmwqzjdmlqfgolpp#leivpw#bpDflqdjbpwqbmdf?kfbg=?pwlssfg2$^*8\x0e\tjpobmgpmlwbaofalqgfq9ojpw#le`bqqjfg233/333?,k0=\t#pfufqboaf`lnfppfof`w#tfggjmd33-kwnonlmbq`klee#wkfwfb`kfqkjdkoz#ajloldzojef#lelq#fufmqjpf#le%qbrvl8sovplmfkvmwjmd+wklvdkGlvdobpiljmjmd`jq`ofpElq#wkfBm`jfmwUjfwmbnufkj`ofpv`k#bp`qzpwboubovf#>Tjmgltpfmilzfgb#pnboobppvnfg?b#jg>!elqfjdm#Boo#qjklt#wkfGjpsobzqfwjqfgkltfufqkjggfm8abwwofppffhjmd`bajmfwtbp#mlwollh#bw`lmgv`wdfw#wkfIbmvbqzkbssfmpwvqmjmdb9klufqLmojmf#Eqfm`k#ob`hjmdwzsj`bof{wqb`wfmfnjfpfufm#jedfmfqbwgf`jgfgbqf#mlw,pfbq`kafojfep.jnbdf9ol`bwfgpwbwj`-oldjm!=`lmufqwujlofmwfmwfqfgejqpw!=`jq`vjwEjmobmg`kfnjpwpkf#tbp23s{8!=bp#pv`kgjujgfg?,psbm=tjoo#afojmf#leb#dqfbwnzpwfqz,jmgf{-eboojmdgvf#wl#qbjotbz`loofdfnlmpwfqgfp`fmwjw#tjwkmv`ofbqIftjpk#sqlwfpwAqjwjpkeoltfqpsqfgj`wqfelqnpavwwlm#tkl#tbpof`wvqfjmpwbmwpvj`jgfdfmfqj`sfqjlgpnbqhfwpPl`jbo#ejpkjmd`lnajmfdqbskj`tjmmfqp?aq#,=?az#wkf#MbwvqboSqjub`z`llhjfplvw`lnfqfploufPtfgjpkaqjfeozSfqpjbmpl#nv`k@fmwvqzgfsj`wp`lovnmpklvpjmdp`qjswpmf{w#wlafbqjmdnbssjmdqfujpfgiRvfqz+.tjgwk9wjwof!=wllowjsPf`wjlmgfpjdmpWvqhjpkzlvmdfq-nbw`k+~*+*8\t\tavqmjmdlsfqbwfgfdqffpplvq`f>Qj`kbqg`olpfozsobpwj`fmwqjfp?,wq=\x0e\t`lolq9 vo#jg>!slppfppqloojmdskzpj`pebjojmdf{f`vwf`lmwfpwojmh#wlGfebvow?aq#,=\t9#wqvf/`kbqwfqwlvqjpn`obppj`sql`ffgf{sobjm?,k2=\x0e\tlmojmf-<{no#ufkfosjmdgjbnlmgvpf#wkfbjqojmffmg#..=*-bwwq+qfbgfqpklpwjmd eeeeeeqfbojyfUjm`fmwpjdmbop#pq`>!,Sqlgv`wgfpsjwfgjufqpfwfoojmdSvaoj`#kfog#jmIlpfsk#wkfbwqfbeef`wp?pwzof=b#obqdfglfpm$wobwfq/#Fofnfmwebuj`lm`qfbwlqKvmdbqzBjqslqwpff#wkfpl#wkbwNj`kbfoPzpwfnpSqldqbnp/#bmg##tjgwk>f%rvlw8wqbgjmdofew!=\tsfqplmpDlogfm#Beebjqpdqbnnbqelqnjmdgfpwqlzjgfb#le`bpf#lelogfpw#wkjp#jp-pq`#>#`bqwllmqfdjpwq@lnnlmpNvpojnpTkbw#jpjm#nbmznbqhjmdqfufbopJmgffg/frvbooz,pklt\\blvwgllqfp`bsf+Bvpwqjbdfmfwj`pzpwfn/Jm#wkf#pjwwjmdKf#boplJpobmgpB`bgfnz\t\n\n?"..Gbmjfo#ajmgjmdaol`h!=jnslpfgvwjojyfBaqbkbn+f{`fswxtjgwk9svwwjmd*-kwno+\x7f\x7f#X^8\tGBWBX#)hjw`kfmnlvmwfgb`wvbo#gjbof`wnbjmoz#\\aobmh$jmpwboof{sfqwpje+wzsfJw#bopl%`lsz8#!=Wfqnpalqm#jmLswjlmpfbpwfqmwbohjmd`lm`fqmdbjmfg#lmdljmdivpwjez`qjwj`peb`wlqzjwp#ltmbppbvowjmujwfgobpwjmdkjp#ltmkqfe>!,!#qfo>!gfufols`lm`fqwgjbdqbngloobqp`ovpwfqsks<jg>bo`lklo*8~*+*8vpjmd#b=?psbm=ufppfopqfujuboBggqfppbnbwfvqbmgqljgboofdfgjoomfpptbohjmd`fmwfqprvbojeznbw`kfpvmjejfgf{wjm`wGfefmpfgjfg#jm\t\n?"..#`vpwlnpojmhjmdOjwwof#Allh#lefufmjmdnjm-ip<bqf#wkfhlmwbhwwlgbz$p-kwno!#wbqdfw>tfbqjmdBoo#Qjd8\t~*+*8qbjpjmd#Bopl/#`qv`jbobalvw!=gf`obqf..=\t?p`ejqfel{bp#nv`kbssojfpjmgf{/#p/#avw#wzsf#>#\t\x0e\t?"..wltbqgpQf`lqgpSqjubwfElqfjdmSqfnjfq`klj`fpUjqwvboqfwvqmp@lnnfmwSltfqfgjmojmf8slufqwz`kbnafqOjujmd#ulovnfpBmwklmzoldjm!#QfobwfgF`lmlnzqfb`kfp`vwwjmddqbujwzojef#jm@kbswfq.pkbgltMlwbaof?,wg=\x0e\t#qfwvqmpwbgjvntjgdfwpubqzjmdwqbufopkfog#aztkl#bqftlqh#jmeb`vowzbmdvobqtkl#kbgbjqslqwwltm#le\t\tPlnf#$`oj`h$`kbqdfphfztlqgjw#tjoo`jwz#le+wkjp*8Bmgqft#vmjrvf#`kf`hfglq#nlqf033s{8#qfwvqm8qpjlm>!sovdjmptjwkjm#kfqpfoePwbwjlmEfgfqboufmwvqfsvaojpkpfmw#wlwfmpjlmb`wqfpp`lnf#wlejmdfqpGvhf#lesflsof/f{soljwtkbw#jpkbqnlmzb#nbilq!9!kwwsjm#kjp#nfmv!=\tnlmwkozleej`fq`lvm`jodbjmjmdfufm#jmPvnnbqzgbwf#leolzbowzejwmfppbmg#tbpfnsfqlqpvsqfnfPf`lmg#kfbqjmdQvppjbmolmdfpwBoafqwbobwfqbopfw#le#pnboo!=-bssfmggl#tjwkefgfqboabmh#leafmfbwkGfpsjwf@bsjwbodqlvmgp*/#bmg#sfq`fmwjw#eqln`olpjmd`lmwbjmJmpwfbgejewffmbp#tfoo-zbkll-qfpslmgejdkwfqlap`vqfqfeof`wlqdbmj`>#Nbwk-fgjwjmdlmojmf#sbggjmdb#tkloflmfqqlqzfbq#lefmg#le#abqqjfqtkfm#jwkfbgfq#klnf#leqfpvnfgqfmbnfgpwqlmd=kfbwjmdqfwbjmp`olvgeqtbz#le#Nbq`k#2hmltjmdjm#sbqwAfwtffmofpplmp`olpfpwujqwvboojmhp!=`qlppfgFMG#..=ebnlvp#btbqgfgOj`fmpfKfbowk#ebjqoz#tfbowkznjmjnboBeqj`bm`lnsfwfobafo!=pjmdjmdebqnfqpAqbpjo*gjp`vppqfsob`fDqfdlqzelmw#`lsvqpvfgbssfbqpnbhf#vsqlvmgfgalwk#leaol`hfgpbt#wkfleej`fp`lolvqpje+gl`vtkfm#kffmelq`fsvpk+evBvdvpw#VWE.;!=Ebmwbpzjm#nlpwjmivqfgVpvboozebqnjmd`olpvqflaif`w#gfefm`fvpf#le#Nfgj`bo?algz=\tfujgfmwaf#vpfghfz@lgfpj{wffmJpobnj` 333333fmwjqf#tjgfoz#b`wjuf#+wzsflelmf#`bm`lolq#>psfbhfqf{wfmgpSkzpj`pwfqqbjm?walgz=evmfqboujftjmdnjggof#`qj`hfwsqlskfwpkjewfggl`wlqpQvppfoo#wbqdfw`lnsb`wbodfaqbpl`jbo.avoh#lenbm#bmg?,wg=\t#kf#ofew*-ubo+*ebopf*8oldj`boabmhjmdklnf#wlmbnjmd#Bqjylmb`qfgjwp*8\t~*8\telvmgfqjm#wvqm@loojmpafelqf#Avw#wkf`kbqdfgWjwof!=@bswbjmpsfoofgdlggfppWbd#..=Bggjmd9avw#tbpQf`fmw#sbwjfmwab`h#jm>ebopf%Ojm`lomtf#hmlt@lvmwfqIvgbjpnp`qjsw#bowfqfg$^*8\t##kbp#wkfvm`ofbqFufmw$/alwk#jmmlw#boo\t\t?"..#sob`jmdkbqg#wl#`fmwfqplqw#le`ojfmwppwqffwpAfqmbqgbppfqwpwfmg#wlebmwbpzgltm#jmkbqalvqEqffglniftfoqz,balvw--pfbq`kofdfmgpjp#nbgfnlgfqm#lmoz#lmlmoz#wljnbdf!#ojmfbq#sbjmwfqbmg#mlwqbqfoz#b`qlmzngfojufqpklqwfq33%bns8bp#nbmztjgwk>!,)#?"X@wjwof#>le#wkf#oltfpw#sj`hfg#fp`bsfgvpfp#lesflsofp#Svaoj`Nbwwkftwb`wj`pgbnbdfgtbz#elqobtp#lefbpz#wl#tjmgltpwqlmd##pjnsof~`bw`k+pfufmwkjmelal{tfmw#wlsbjmwfg`jwjyfmJ#glm$wqfwqfbw-#Plnf#tt-!*8\talnajmdnbjowl9nbgf#jm-#Nbmz#`bqqjfp\x7f\x7fx~8tjtlqh#lepzmlmzngfefbwpebulqfglswj`bosbdfWqbvmofpp#pfmgjmdofew!=?`lnP`lqBoo#wkfiRvfqz-wlvqjpw@obppj`ebopf!#Tjokfonpvavqapdfmvjmfajpklsp-psojw+dolabo#elooltpalgz#lemlnjmbo@lmwb`wpf`vobqofew#wl`kjfeoz.kjggfm.abmmfq?,oj=\t\t-#Tkfm#jm#alwkgjpnjppF{solqfbotbzp#ujb#wkfpsb/]lotfoebqfqvojmd#bqqbmdf`bswbjmkjp#plmqvof#lekf#wllhjwpfoe/>3%bns8+`boofgpbnsofpwl#nbhf`ln,sbdNbqwjm#Hfmmfgzb``fswpevoo#lekbmgofgAfpjgfp,,..=?,baof#wlwbqdfwpfppfm`fkjn#wl#jwp#az#`lnnlm-njmfqbowl#wbhftbzp#wlp-lqd,obgujpfgsfmbowzpjnsof9je#wkfzOfwwfqpb#pklqwKfqafqwpwqjhfp#dqlvsp-ofmdwkeojdkwplufqobspoltoz#ofppfq#pl`jbo#?,s=\t\n\njw#jmwlqbmhfg#qbwf#levo=\x0e\t##bwwfnswsbjq#lenbhf#jwHlmwbhwBmwlmjlkbujmd#qbwjmdp#b`wjufpwqfbnpwqbssfg!*-`pp+klpwjofofbg#wlojwwof#dqlvsp/Sj`wvqf..=\x0e\t\x0e\t#qltp>!#laif`wjmufqpf?ellwfq@vpwlnU=?_,p`qploujmd@kbnafqpobufqztlvmgfgtkfqfbp">#$vmgelq#boosbqwoz#.qjdkw9Bqbajbmab`hfg#`fmwvqzvmjw#lenlajof.Fvqlsf/jp#klnfqjph#legfpjqfg@ojmwlm`lpw#lebdf#le#af`lnf#mlmf#les%rvlw8Njggof#fbg$*X3@qjwj`ppwvgjlp=%`lsz8dqlvs!=bppfnaonbhjmd#sqfppfgtjgdfw-sp9!#<#qfavjowaz#plnfElqnfq#fgjwlqpgfobzfg@bmlmj`kbg#wkfsvpkjmd`obpp>!avw#bqfsbqwjboAbazolmalwwln#`bqqjfq@lnnbmgjwp#vpfBp#tjwk`lvqpfpb#wkjqggfmlwfpbopl#jmKlvpwlm13s{8!=b``vpfgglvaof#dlbo#leEbnlvp#*-ajmg+sqjfpwp#Lmojmfjm#Ivozpw#(#!d`lmpvowgf`jnbokfosevoqfujufgjp#ufqzq$($jswolpjmd#efnbofpjp#boplpwqjmdpgbzp#lebqqjuboevwvqf#?laif`welq`jmdPwqjmd+!#,=\t\n\nkfqf#jpfm`lgfg-##Wkf#aboollmglmf#az,`lnnlmad`lolqobt#le#Jmgjbmbbuljgfgavw#wkf1s{#0s{irvfqz-bewfq#bsloj`z-nfm#bmgellwfq.>#wqvf8elq#vpfp`qffm-Jmgjbm#jnbdf#>ebnjoz/kwws9,,#%maps8gqjufqpfwfqmbopbnf#bpmlwj`fgujftfqp~*+*8\t#jp#nlqfpfbplmpelqnfq#wkf#mftjp#ivpw`lmpfmw#Pfbq`ktbp#wkftkz#wkfpkjssfgaq=?aq=tjgwk9#kfjdkw>nbgf#le`vjpjmfjp#wkbwb#ufqz#Bgnjqbo#ej{fg8mlqnbo#NjppjlmSqfpp/#lmwbqjl`kbqpfwwqz#wl#jmubgfg>!wqvf!psb`jmdjp#nlpwb#nlqf#wlwboozeboo#le~*8\x0e\t##jnnfmpfwjnf#jmpfw#lvwpbwjpezwl#ejmggltm#wlolw#le#Sobzfqpjm#Ivmfrvbmwvnmlw#wkfwjnf#wlgjpwbmwEjmmjpkpq`#>#+pjmdof#kfos#leDfqnbm#obt#bmgobafofgelqfpwp`llhjmdpsb`f!=kfbgfq.tfoo#bpPwbmofzaqjgdfp,dolabo@qlbwjb#Balvw#X3^8\t##jw/#bmgdqlvsfgafjmd#b*xwkqltkf#nbgfojdkwfqfwkj`boEEEEEE!alwwln!ojhf#b#fnsolzpojuf#jmbp#pffmsqjmwfqnlpw#leva.ojmhqfif`wpbmg#vpfjnbdf!=pv``ffgeffgjmdMv`ofbqjmelqnbwl#kfosTlnfm$pMfjwkfqNf{j`bmsqlwfjm?wbaof#az#nbmzkfbowkzobtpvjwgfujpfg-svpk+xpfoofqppjnsoz#Wkqlvdk-`llhjf#Jnbdf+logfq!=vp-ip!=#Pjm`f#vmjufqpobqdfq#lsfm#wl"..#fmgojfp#jm$^*8\x0e\t##nbqhfwtkl#jp#+!GLN@lnbmbdfglmf#elqwzsfle#Hjmdglnsqlejwpsqlslpfwl#pklt`fmwfq8nbgf#jwgqfppfgtfqf#jmnj{wvqfsqf`jpfbqjpjmdpq`#>#$nbhf#b#pf`vqfgAbswjpwulwjmd#\t\n\nubq#Nbq`k#1dqft#vs@ojnbwf-qfnlufphjoofgtbz#wkf?,kfbg=eb`f#leb`wjmd#qjdkw!=wl#tlqhqfgv`fpkbp#kbgfqf`wfgpklt+*8b`wjlm>allh#lebm#bqfb>>#!kww?kfbgfq\t?kwno=`lmelqneb`jmd#`llhjf-qfoz#lmklpwfg#-`vpwlnkf#tfmwavw#elqpsqfbg#Ebnjoz#b#nfbmplvw#wkfelqvnp-ellwbdf!=Nlajo@ofnfmwp!#jg>!bp#kjdkjmwfmpf..=?"..efnbof#jp#pffmjnsojfgpfw#wkfb#pwbwfbmg#kjpebpwfpwafpjgfpavwwlm\\alvmgfg!=?jnd#Jmelal{fufmwp/b#zlvmdbmg#bqfMbwjuf#`kfbsfqWjnflvwbmg#kbpfmdjmfptlm#wkf+nlpwozqjdkw9#ejmg#b#.alwwlnSqjm`f#bqfb#lenlqf#lepfbq`k\\mbwvqf/ofdboozsfqjlg/obmg#lelq#tjwkjmgv`fgsqlujmdnjppjofol`boozBdbjmpwwkf#tbzh%rvlw8s{8!=\x0e\tsvpkfg#babmglmmvnfqbo@fqwbjmJm#wkjpnlqf#jmlq#plnfmbnf#jpbmg/#jm`qltmfgJPAM#3.`qfbwfpL`wlafqnbz#mlw`fmwfq#obwf#jmGfefm`ffmb`wfgtjpk#wlaqlbgoz`llojmdlmolbg>jw-#Wkfqf`lufqNfnafqpkfjdkw#bppvnfp?kwno=\tsflsof-jm#lmf#>tjmgltellwfq\\b#dllg#qfhobnblwkfqp/wl#wkjp\\`llhjfsbmfo!=Olmglm/gfejmfp`qvpkfgabswjpn`lbpwbopwbwvp#wjwof!#nluf#wlolpw#jmafwwfq#jnsojfpqjuboqzpfqufqp#PzpwfnSfqkbspfp#bmg#`lmwfmgeoltjmdobpwfg#qjpf#jmDfmfpjpujft#leqjpjmd#pffn#wlavw#jm#ab`hjmdkf#tjoodjufm#bdjujmd#`jwjfp-eolt#le#Obwfq#boo#avwKjdktbzlmoz#azpjdm#lekf#glfpgjeefqpabwwfqz%bns8obpjmdofpwkqfbwpjmwfdfqwbhf#lmqfevpfg`boofg#>VP%bnsPff#wkfmbwjufpaz#wkjppzpwfn-kfbg#le9klufq/ofpajbmpvqmbnfbmg#boo`lnnlm,kfbgfq\\\\sbqbnpKbqubqg,sj{fo-qfnlubopl#olmdqlof#leiljmwozphzp`qbVmj`lgfaq#,=\x0e\tBwobmwbmv`ofvp@lvmwz/svqfoz#`lvmw!=fbpjoz#avjog#blm`oj`hb#djufmsljmwfqk%rvlw8fufmwp#fopf#x\tgjwjlmpmlt#wkf/#tjwk#nbm#tkllqd,Tfalmf#bmg`buboqzKf#gjfgpfbwwof33/333#xtjmgltkbuf#wlje+tjmgbmg#jwpplofoz#n%rvlw8qfmftfgGfwqljwbnlmdpwfjwkfq#wkfn#jmPfmbwlqVp?,b=?Hjmd#leEqbm`jp.sqlgv`kf#vpfgbqw#bmgkjn#bmgvpfg#azp`lqjmdbw#klnfwl#kbufqfobwfpjajojwzeb`wjlmAveebolojmh!=?tkbw#kfeqff#wl@jwz#le`lnf#jmpf`wlqp`lvmwfglmf#gbzmfqulvpprvbqf#~8je+dljm#tkbwjnd!#bojp#lmozpfbq`k,wvfpgbzollpfozPlolnlmpf{vbo#.#?b#kqnfgjvn!GL#MLW#Eqbm`f/tjwk#b#tbq#bmgpf`lmg#wbhf#b#=\x0e\t\x0e\t\x0e\tnbqhfw-kjdktbzglmf#jm`wjujwz!obpw!=laojdfgqjpf#wl!vmgfejnbgf#wl#Fbqoz#sqbjpfgjm#jwp#elq#kjpbwkofwfIvsjwfqZbkll"#wfqnfg#pl#nbmzqfbooz#p-#Wkf#b#tlnbm<ubovf>gjqf`w#qjdkw!#aj`z`ofb`jmd>!gbz#bmgpwbwjmdQbwkfq/kjdkfq#Leej`f#bqf#mltwjnfp/#tkfm#b#sbz#elqlm#wkjp.ojmh!=8alqgfqbqlvmg#bmmvbo#wkf#Mftsvw#wkf-`ln!#wbhjm#wlb#aqjfe+jm#wkfdqlvsp-8#tjgwkfmyznfppjnsof#jm#obwfxqfwvqmwkfqbszb#sljmwabmmjmdjmhp!=\t+*8!#qfb#sob`f_v330@bbalvw#bwq=\x0e\t\n\n``lvmw#djufp#b?P@QJSWQbjotbzwkfnfp,wlloal{AzJg+!{kvnbmp/tbw`kfpjm#plnf#je#+tj`lnjmd#elqnbwp#Vmgfq#avw#kbpkbmgfg#nbgf#azwkbm#jmefbq#legfmlwfg,jeqbnfofew#jmulowbdfjm#fb`kb%rvlw8abpf#leJm#nbmzvmgfqdlqfdjnfpb`wjlm#?,s=\x0e\t?vpwlnUb8%dw8?,jnslqwplq#wkbwnlpwoz#%bns8qf#pjyf>!?,b=?,kb#`obppsbppjufKlpw#>#TkfwkfqefqwjofUbqjlvp>X^8+ev`bnfqbp,=?,wg=b`wp#bpJm#plnf=\x0e\t\x0e\t?"lqdbmjp#?aq#,=Afjijmd`bwbo/Lgfvwp`kfvqlsfvfvphbqbdbfjodfpufmphbfpsb/]bnfmpbifvpvbqjlwqbabiln/E{j`ls/Mdjmbpjfnsqfpjpwfnbl`wvaqfgvqbmwfb/]bgjqfnsqfpbnlnfmwlmvfpwqlsqjnfqbwqbu/Epdqb`jbpmvfpwqbsql`fplfpwbglp`bojgbgsfqplmbm/Vnfqlb`vfqgln/Vpj`bnjfnaqllefqwbpbodvmlpsb/Apfpfifnsolgfqf`klbgfn/Mpsqjubglbdqfdbqfmob`fpslpjaofklwfofppfujoobsqjnfql/Vowjnlfufmwlpbq`kjul`vowvqbnvifqfpfmwqbgbbmvm`jlfnabqdlnfq`bgldqbmgfpfpwvgjlnfilqfpefaqfqlgjpf/]lwvqjpnl`/_gjdlslqwbgbfpsb`jlebnjojbbmwlmjlsfqnjwfdvbqgbqbodvmbpsqf`jlpbodvjfmpfmwjglujpjwbpw/Awvol`lml`fqpfdvmgl`lmpfileqbm`jbnjmvwlppfdvmgbwfmfnlpfef`wlpn/Mobdbpfpj/_mqfujpwbdqbmbgb`lnsqbqjmdqfpldbq`/Abb``j/_mf`vbglqrvjfmfpjm`ovplgfafq/Mnbwfqjbklnaqfpnvfpwqbslgq/Abnb/]bmb/Vowjnbfpwbnlplej`jbowbnajfmmjmd/Vmpbovglpslgfnlpnfilqbqslpjwjlmavpjmfppklnfsbdfpf`vqjwzobmdvbdfpwbmgbqg`bnsbjdmefbwvqfp`bwfdlqzf{wfqmbo`kjogqfmqfpfqufgqfpfbq`kf{`kbmdfebulqjwfwfnsobwfnjojwbqzjmgvpwqzpfquj`fpnbwfqjbosqlgv`wpy.jmgf{9`lnnfmwpplewtbqf`lnsofwf`bofmgbqsobwelqnbqwj`ofpqfrvjqfgnlufnfmwrvfpwjlmavjogjmdslojwj`pslppjaofqfojdjlmskzpj`boeffgab`hqfdjpwfqsj`wvqfpgjpbaofgsqlwl`lobvgjfm`fpfwwjmdpb`wjujwzfofnfmwpofbqmjmdbmzwkjmdbapwqb`wsqldqfpplufqujftnbdbyjmff`lmlnj`wqbjmjmdsqfppvqfubqjlvp#?pwqlmd=sqlsfqwzpklssjmdwldfwkfqbgubm`fgafkbujlqgltmolbgefbwvqfgellwaboopfof`wfgObmdvbdfgjpwbm`fqfnfnafqwqb`hjmdsbpptlqgnlgjejfgpwvgfmwpgjqf`wozejdkwjmdmlqwkfqmgbwbabpfefpwjuboaqfbhjmdol`bwjlmjmwfqmfwgqlsgltmsqb`wj`ffujgfm`fevm`wjlmnbqqjbdfqfpslmpfsqlaofnpmfdbwjufsqldqbnpbmbozpjpqfofbpfgabmmfq!=svq`kbpfsloj`jfpqfdjlmbo`qfbwjufbqdvnfmwallhnbqhqfefqqfq`kfnj`bogjujpjlm`booab`hpfsbqbwfsqlif`wp`lmeoj`wkbqgtbqfjmwfqfpwgfojufqznlvmwbjmlawbjmfg>#ebopf8elq+ubq#b``fswfg`bsb`jwz`lnsvwfqjgfmwjwzbjq`qbewfnsolzfgsqlslpfgglnfpwj`jm`ovgfpsqlujgfgklpsjwboufqwj`bo`loobspfbssqlb`ksbqwmfqpoldl!=?bgbvdkwfqbvwklq!#`vowvqboebnjojfp,jnbdfp,bppfnaozsltfqevowfb`kjmdejmjpkfggjpwqj`w`qjwj`bo`dj.ajm,svqslpfpqfrvjqfpfof`wjlmaf`lnjmdsqlujgfpb`bgfnj`f{fq`jpfb`wvbooznfgj`jmf`lmpwbmwb``jgfmwNbdbyjmfgl`vnfmwpwbqwjmdalwwln!=lapfqufg9#%rvlw8f{wfmgfgsqfujlvpPlewtbqf`vpwlnfqgf`jpjlmpwqfmdwkgfwbjofgpojdkwozsobmmjmdwf{wbqfb`vqqfm`zfufqzlmfpwqbjdkwwqbmpefqslpjwjufsqlgv`fgkfqjwbdfpkjssjmdbaplovwfqf`fjufgqfofubmwavwwlm!#ujlofm`fbmztkfqfafmfejwpobvm`kfgqf`fmwozboojbm`felooltfgnvowjsofavoofwjmjm`ovgfgl``vqqfgjmwfqmbo\'+wkjp*-qfsvaoj`=?wq=?wg`lmdqfppqf`lqgfgvowjnbwfplovwjlm?vo#jg>!gjp`lufqKlnf?,b=tfapjwfpmfwtlqhpbowklvdkfmwjqfoznfnlqjbonfppbdfp`lmwjmvfb`wjuf!=plnftkbwuj`wlqjbTfpwfqm##wjwof>!Ol`bwjlm`lmwqb`wujpjwlqpGltmolbgtjwklvw#qjdkw!=\tnfbpvqfptjgwk#>#ubqjbaofjmuloufgujqdjmjbmlqnboozkbssfmfgb``lvmwppwbmgjmdmbwjlmboQfdjpwfqsqfsbqfg`lmwqlopb``vqbwfajqwkgbzpwqbwfdzleej`jbodqbskj`p`qjnjmboslppjaoz`lmpvnfqSfqplmbopsfbhjmdubojgbwfb`kjfufg-isd!#,=nb`kjmfp?,k1=\t##hfztlqgpeqjfmgozaqlwkfqp`lnajmfglqjdjmbo`lnslpfgf{sf`wfgbgfrvbwfsbhjpwbmeloolt!#ubovbaof?,obafo=qfobwjufaqjmdjmdjm`qfbpfdlufqmlqsovdjmp,Ojpw#le#Kfbgfq!=!#mbnf>!#+%rvlw8dqbgvbwf?,kfbg=\t`lnnfq`fnbobzpjbgjqf`wlqnbjmwbjm8kfjdkw9p`kfgvof`kbmdjmdab`h#wl#`bwkloj`sbwwfqmp`lolq9# dqfbwfpwpvssojfpqfojbaof?,vo=\t\n\n?pfof`w#`jwjyfmp`olwkjmdtbw`kjmd?oj#jg>!psf`jej``bqqzjmdpfmwfm`f?`fmwfq=`lmwqbpwwkjmhjmd`bw`k+f*plvwkfqmNj`kbfo#nfq`kbmw`bqlvpfosbggjmd9jmwfqjlq-psojw+!ojybwjlmL`wlafq#*xqfwvqmjnsqlufg..%dw8\t\t`lufqbdf`kbjqnbm-smd!#,=pvaif`wpQj`kbqg#tkbwfufqsqlabaozqf`lufqzabpfabooivgdnfmw`lmmf`w--`pp!#,=#tfapjwfqfslqwfggfebvow!,=?,b=\x0e\tfof`wqj`p`lwobmg`qfbwjlmrvbmwjwz-#JPAM#3gjg#mlw#jmpwbm`f.pfbq`k.!#obmd>!psfbhfqp@lnsvwfq`lmwbjmpbq`kjufpnjmjpwfqqfb`wjlmgjp`lvmwJwbojbml`qjwfqjbpwqlmdoz9#$kwws9$p`qjsw$`lufqjmdleefqjmdbssfbqfgAqjwjpk#jgfmwjezEb`fallhmvnfqlvpufkj`ofp`lm`fqmpBnfqj`bmkbmgojmdgju#jg>!Tjoojbn#sqlujgfq\\`lmwfmwb``vqb`zpf`wjlm#bmgfqplmeof{jaof@bwfdlqzobtqfm`f?p`qjsw=obzlvw>!bssqlufg#nb{jnvnkfbgfq!=?,wbaof=Pfquj`fpkbnjowlm`vqqfmw#`bmbgjbm`kbmmfop,wkfnfp,,bqwj`oflswjlmboslqwvdboubovf>!!jmwfqubotjqfofppfmwjwofgbdfm`jfpPfbq`k!#nfbpvqfgwklvpbmgpsfmgjmd%kfoojs8mft#Gbwf!#pjyf>!sbdfMbnfnjggof!#!#,=?,b=kjggfm!=pfrvfm`fsfqplmbolufqeoltlsjmjlmpjoojmljpojmhp!=\t\n?wjwof=ufqpjlmppbwvqgbzwfqnjmbojwfnsqlsfmdjmffqpf`wjlmpgfpjdmfqsqlslpbo>!ebopf!Fpsb/]loqfofbpfppvanjw!#fq%rvlw8bggjwjlmpznswlnplqjfmwfgqfplvq`fqjdkw!=?sofbpvqfpwbwjlmpkjpwlqz-ofbujmd##alqgfq>`lmwfmwp`fmwfq!=-\t\tPlnf#gjqf`wfgpvjwbaofavodbqjb-pklt+*8gfpjdmfgDfmfqbo#`lm`fswpF{bnsofptjoojbnpLqjdjmbo!=?psbm=pfbq`k!=lsfqbwlqqfrvfpwpb#%rvlw8booltjmdGl`vnfmwqfujpjlm-#\t\tWkf#zlvqpfoe@lmwb`w#nj`kjdbmFmdojpk#`lovnajbsqjlqjwzsqjmwjmdgqjmhjmdeb`jojwzqfwvqmfg@lmwfmw#leej`fqpQvppjbm#dfmfqbwf.;;6:.2!jmgj`bwfebnjojbq#rvbojwznbqdjm93#`lmwfmwujftslqw`lmwb`wp.wjwof!=slqwbaof-ofmdwk#fojdjaofjmuloufpbwobmwj`lmolbg>!gfebvow-pvssojfgsbznfmwpdolppbqz\t\tBewfq#dvjgbm`f?,wg=?wgfm`lgjmdnjggof!=`bnf#wl#gjpsobzpp`lwwjpkilmbwkbmnbilqjwztjgdfwp-`ojmj`bowkbjobmgwfb`kfqp?kfbg=\t\nbeef`wfgpvsslqwpsljmwfq8wlPwqjmd?,pnboo=lhobklnbtjoo#af#jmufpwlq3!#bow>!klojgbzpQfplvq`foj`fmpfg#+tkj`k#-#Bewfq#`lmpjgfqujpjwjmdf{solqfqsqjnbqz#pfbq`k!#bmgqljg!rvj`hoz#nffwjmdpfpwjnbwf8qfwvqm#8`lolq9 #kfjdkw>bssqlubo/#%rvlw8#`kf`hfg-njm-ip!nbdmfwj`=?,b=?,kelqf`bpw-#Tkjof#wkvqpgbzgufqwjpf%fb`vwf8kbp@obppfubovbwflqgfqjmdf{jpwjmdsbwjfmwp#Lmojmf#`lolqbglLswjlmp!`bnsafoo?"..#fmg?,psbm=??aq#,=\x0e\t\\slsvsp\x7fp`jfm`fp/%rvlw8#rvbojwz#Tjmgltp#bppjdmfgkfjdkw9#?a#`obppof%rvlw8#ubovf>!#@lnsbmzf{bnsofp?jeqbnf#afojfufpsqfpfmwpnbqpkboosbqw#le#sqlsfqoz*-\t\tWkf#wb{lmlnznv`k#le#?,psbm=\t!#gbwb.pqwvdv/Fpp`qlooWl#sqlif`w?kfbg=\x0e\tbwwlqmfzfnskbpjppslmplqpebm`zal{tlqog$p#tjogojef`kf`hfg>pfppjlmpsqldqbnns{8elmw.#Sqlif`wilvqmbopafojfufgub`bwjlmwklnsplmojdkwjmdbmg#wkf#psf`jbo#alqgfq>3`kf`hjmd?,walgz=?avwwlm#@lnsofwf`ofbqej{\t?kfbg=\tbqwj`of#?pf`wjlmejmgjmdpqlof#jm#slsvobq##L`wlafqtfapjwf#f{slpvqfvpfg#wl##`kbmdfplsfqbwfg`oj`hjmdfmwfqjmd`lnnbmgpjmelqnfg#mvnafqp##?,gju=`qfbwjmdlmPvanjwnbqzobmg`loofdfpbmbozwj`ojpwjmdp`lmwb`w-olddfgJmbgujplqzpjaojmdp`lmwfmw!p%rvlw8*p-#Wkjp#sb`hbdfp`kf`hal{pvddfpwpsqfdmbmwwlnlqqltpsb`jmd>j`lm-smdibsbmfpf`lgfabpfavwwlm!=dbnaojmdpv`k#bp#/#tkjof#?,psbm=#njpplvqjpslqwjmdwls92s{#-?,psbm=wfmpjlmptjgwk>!1obyzolbgmlufnafqvpfg#jm#kfjdkw>!`qjsw!=\t%maps8?,?wq=?wg#kfjdkw91,sqlgv`w`lvmwqz#jm`ovgf#ellwfq!#%ow8"..#wjwof!=?,irvfqz-?,elqn=\t+\vBl\bQ\x7f*+\vUm\x05Gx*kqubwphjjwbojbmlqln/Nm(ow/Pqh/Kf4K4]4C5dwbnaj/Emmlwj`jbpnfmpbifpsfqplmbpgfqf`klpmb`jlmbopfquj`jl`lmwb`wlvpvbqjlpsqldqbnbdlajfqmlfnsqfpbpbmvm`jlpubofm`jb`lolnajbgfpsv/Epgfslqwfpsqlzf`wlsqlgv`wls/Vaoj`lmlplwqlpkjpwlqjbsqfpfmwfnjoolmfpnfgjbmwfsqfdvmwbbmwfqjlqqf`vqplpsqlaofnbpbmwjbdlmvfpwqlplsjmj/_mjnsqjnjqnjfmwqbpbn/Eqj`bufmgfglqpl`jfgbgqfpsf`wlqfbojybqqfdjpwqlsbobaqbpjmwfq/Epfmwlm`fpfpsf`jbonjfnaqlpqfbojgbg`/_qglabybqbdlybs/Mdjmbppl`jbofpaolrvfbqdfpwj/_mborvjofqpjpwfnbp`jfm`jbp`lnsofwlufqpj/_m`lnsofwbfpwvgjlps/Vaoj`blaifwjulboj`bmwfavp`bglq`bmwjgbgfmwqbgbpb``jlmfpbq`kjulppvsfqjlqnbzlq/Abbofnbmjbevm`j/_m/Vowjnlpkb`jfmglbrvfoolpfgj`j/_mefqmbmglbnajfmwfeb`fallhmvfpwqbp`ojfmwfpsql`fplpabpwbmwfsqfpfmwbqfslqwbq`lmdqfplsvaoj`bq`lnfq`jl`lmwqbwli/_ufmfpgjpwqjwlw/E`mj`b`lmivmwlfmfqd/Abwqbabibqbpwvqjbpqf`jfmwfvwjojybqalofw/Ampboubglq`lqqf`wbwqbabilpsqjnfqlpmfdl`jlpojafqwbggfwboofpsbmwboobsq/_{jnlbonfq/Abbmjnbofprvj/Emfp`lqby/_mpf``j/_mavp`bmglls`jlmfpf{wfqjlq`lm`fswlwlgbu/Abdbofq/Abfp`qjajqnfgj`jmboj`fm`jb`lmpvowbbpsf`wlp`q/Awj`bg/_obqfpivpwj`jbgfafq/Mmsfq/Alglmf`fpjwbnbmwfmfqsfrvf/]lqf`jajgbwqjavmbowfmfqjef`bm`j/_m`bmbqjbpgfp`bqdbgjufqplpnboolq`bqfrvjfqfw/E`mj`lgfafq/Abujujfmgbejmbmybpbgfobmwfevm`jlmb`lmpfilpgje/A`jo`jvgbgfpbmwjdvbpbubmybgbw/Eqnjmlvmjgbgfpp/Mm`kfy`bnsb/]bplewlmj`qfujpwbp`lmwjfmfpf`wlqfpnlnfmwlpeb`vowbg`q/Egjwlgjufqpbppvsvfpwleb`wlqfppfdvmglpsfrvf/]b<_<R<X<\\<Y=m<W<T<Y=m=n=`<]=g<W<R<]=g=n=`=a=n<R<P<y=m<W<T=n<R<_<R<P<Y<Q=c<^=m<Y=i=a=n<R<U<X<\\<Z<Y<]=g<W<T<_<R<X=o<X<Y<Q=`=a=n<R=n<]=g<W<\\=m<Y<]=c<R<X<T<Q=m<Y<]<Y<Q<\\<X<R=m<\\<U=n=h<R=n<R<Q<Y<_<R=m<^<R<T=m<^<R<U<T<_=l=g=n<R<Z<Y<^=m<Y<P=m<^<R=b<W<T=d=`=a=n<T=i<S<R<V<\\<X<Q<Y<U<X<R<P<\\<P<T=l<\\<W<T<]<R=n<Y<P=o=i<R=n=c<X<^=o=i=m<Y=n<T<W=b<X<T<X<Y<W<R<P<T=l<Y=n<Y<]=c=m<^<R<Y<^<T<X<Y=k<Y<_<R=a=n<T<P=m=k<Y=n=n<Y<P=g=j<Y<Q=g=m=n<\\<W<^<Y<X=`=n<Y<P<Y<^<R<X=g=n<Y<]<Y<^=g=d<Y<Q<\\<P<T=n<T<S<\\=n<R<P=o<S=l<\\<^<W<T=j<\\<R<X<Q<\\<_<R<X=g<[<Q<\\=b<P<R<_=o<X=l=o<_<^=m<Y<U<T<X<Y=n<V<T<Q<R<R<X<Q<R<X<Y<W<\\<X<Y<W<Y=m=l<R<V<T=b<Q=c<^<Y=m=`<y=m=n=`=l<\\<[<\\<Q<\\=d<T4K5h5h5k4K5h4F5f4@5i5f4U4B4K4Y4E4K5h4\\5f4U5h5f5k4@4C5f4C4K5h4N5j4K5h4]4C4F4A5o5i4Y5m4A4E5o4K5j4F4K5h5h5f5f5o5d5j4X4D5o4E5m5f5k4K4D5j4K4F4A5d4K4M4O5o4G4]4B5h4K5h4K5h4A4D4C5h5f5h4C4]5d4_4K4Z4V4[4F5o5d5j5k5j4K5o4_4K4A4E5j4K4C5f4K5h4[4D4U5h5f5o4X5o4]4K5f5i5o5j5i5j5k4K4X4]5o4E4]4J5f4_5j4X5f4[5i4K4\\4K4K5h5m5j4X4D4K4D4F4U4D4]4]4A5i4E5o4K5m4E5f5n5d5h5i4]5o4^5o5h5i4E4O4A5i4C5n5h4D5f5f4U5j5f4Y5d4]4E4[4]5f5n4X4K4]5o4@5d4K5h4O4B4]5e5i4U5j4K4K4D4A4G4U4]5d4Z4D4X5o5h5i4_4@5h4D5j4K5j4B4K5h4C5o4F4K4D5o5h5f4E4D4C5d5j4O5f4Z4K5f5d4@4C5m4]5f5n5o4F4D4F4O5m4Z5h5i4[4D4B4K5o4G4]4D4K4]5o4K5m4Z5h4K4A5h5e5j5m4_5k4O5f4K5i4]4C5d4C4O5j5k4K4C5f5j4K4K5h4K5j5i4U4]4Z4F4U5h5i4C4K4B5h5i5i5o5j\x03\x03\x03\x03\x03\x03\x03\x03\x02\x03\x02\x03\x02\x03\x02\x03\x01\x03\x01\x03\x01\x03\x01\x03\x07\x03\x07\x03\x07\x03\x07\x03\x03\x02\x01\0\x07\x06\x05\x04\x04\x05\x06\x07\0\x01\x02\x03\v\n\t\b\x0f\x0e\r\f\f\r\x0e\x0f\b\t\n\v\x13\x12\x11\x10\x17\x16\x15\x14\x14\x15\x16\x17\x10\x11\x12\x13\x1b\x1a\x19\x18\x1f\x1e\x1d\x1c\x1c\x1d\x1e\x1f\x18\x19\x1a\x1b\x13\x13\x13\x13\x03\x03\x03\x03\x03\x03\x03\x03\x13\x13\x13\x13\x02\x03\x03\x03\x01\x03\x03\x03\x01\x03\x03\x03\x02\x03\x03\x03\x02\x03\x03\x03\0\x03\x03\x03\x13\x13\x03\x02\x03\x03\x03\x02\x03\x03\x13\x13\x03\x02\x03\x03\x03\v\x03\v\x03\v\x03\v\x03\x03\x03\x02\x03\x01\x03\0\x03\x07\x03\x06\x03\x05\x03\x04qfplvq`fp`lvmwqjfprvfpwjlmpfrvjsnfmw`lnnvmjwzbubjobaofkjdkojdkwGWG,{kwnonbqhfwjmdhmltofgdfplnfwkjmd`lmwbjmfqgjqf`wjlmpvap`qjafbgufqwjpf`kbqb`wfq!#ubovf>!?,pfof`w=Bvpwqbojb!#`obpp>!pjwvbwjlmbvwklqjwzelooltjmdsqjnbqjozlsfqbwjlm`kboofmdfgfufolsfgbmlmznlvpevm`wjlm#evm`wjlmp`lnsbmjfppwqv`wvqfbdqffnfmw!#wjwof>!slwfmwjbofgv`bwjlmbqdvnfmwppf`lmgbqz`lszqjdkwobmdvbdfpf{`ovpjuf`lmgjwjlm?,elqn=\x0e\tpwbwfnfmwbwwfmwjlmAjldqbskz~#fopf#x\tplovwjlmptkfm#wkf#Bmbozwj`pwfnsobwfpgbmdfqlvppbwfoojwfgl`vnfmwpsvaojpkfqjnslqwbmwsqlwlwzsfjmeovfm`f%qbrvl8?,feef`wjufdfmfqboozwqbmpelqnafbvwjevowqbmpslqwlqdbmjyfgsvaojpkfgsqlnjmfmwvmwjo#wkfwkvnambjoMbwjlmbo#-el`vp+*8lufq#wkf#njdqbwjlmbmmlvm`fgellwfq!=\tf{`fswjlmofpp#wkbmf{sfmpjufelqnbwjlmeqbnftlqhwfqqjwlqzmgj`bwjlm`vqqfmwoz`obppMbnf`qjwj`jpnwqbgjwjlmfopftkfqfBof{bmgfqbssljmwfgnbwfqjbopaqlbg`bpwnfmwjlmfgbeejojbwf?,lswjlm=wqfbwnfmwgjeefqfmw,gfebvow-Sqfpjgfmwlm`oj`h>!ajldqbskzlwkfqtjpfsfqnbmfmwEqbm/KbjpKlooztllgf{sbmpjlmpwbmgbqgp?,pwzof=\tqfgv`wjlmGf`fnafq#sqfefqqfg@bnaqjgdflsslmfmwpAvpjmfpp#`lmevpjlm=\t?wjwof=sqfpfmwfgf{sobjmfgglfp#mlw#tlqogtjgfjmwfqeb`fslpjwjlmpmftpsbsfq?,wbaof=\tnlvmwbjmpojhf#wkf#fppfmwjboejmbm`jbopfof`wjlmb`wjlm>!,babmglmfgFgv`bwjlmsbqpfJmw+pwbajojwzvmbaof#wl?,wjwof=\tqfobwjlmpMlwf#wkbwfeej`jfmwsfqelqnfgwtl#zfbqpPjm`f#wkfwkfqfelqftqbssfq!=bowfqmbwfjm`qfbpfgAbwwof#lesfq`fjufgwqzjmd#wlmf`fppbqzslqwqbzfgfof`wjlmpFojybafwk?,jeqbnf=gjp`lufqzjmpvqbm`fp-ofmdwk8ofdfmgbqzDfldqbskz`bmgjgbwf`lqslqbwfplnfwjnfppfquj`fp-jmkfqjwfg?,pwqlmd=@lnnvmjwzqfojdjlvpol`bwjlmp@lnnjwwffavjogjmdpwkf#tlqogml#olmdfqafdjmmjmdqfefqfm`f`bmmlw#afeqfrvfm`zwzsj`boozjmwl#wkf#qfobwjuf8qf`lqgjmdsqfpjgfmwjmjwjboozwf`kmjrvfwkf#lwkfqjw#`bm#aff{jpwfm`fvmgfqojmfwkjp#wjnfwfofsklmfjwfnp`lsfsqb`wj`fpbgubmwbdf*8qfwvqm#Elq#lwkfqsqlujgjmdgfnl`qb`zalwk#wkf#f{wfmpjufpveefqjmdpvsslqwfg`lnsvwfqp#evm`wjlmsqb`wj`bopbjg#wkbwjw#nbz#afFmdojpk?,eqln#wkf#p`kfgvofggltmolbgp?,obafo=\tpvpsf`wfgnbqdjm9#3psjqjwvbo?,kfbg=\t\tnj`qlplewdqbgvboozgjp`vppfgkf#af`bnff{f`vwjufirvfqz-ipklvpfklog`lmejqnfgsvq`kbpfgojwfqboozgfpwqlzfgvs#wl#wkfubqjbwjlmqfnbjmjmdjw#jp#mlw`fmwvqjfpIbsbmfpf#bnlmd#wkf`lnsofwfgbodlqjwknjmwfqfpwpqfafoojlmvmgfejmfgfm`lvqbdfqfpjybaofjmuloujmdpfmpjwjufvmjufqpbosqlujpjlm+bowklvdkefbwvqjmd`lmgv`wfg*/#tkj`k#`lmwjmvfg.kfbgfq!=Efaqvbqz#mvnfqlvp#lufqeolt9`lnslmfmweqbdnfmwpf{`foofmw`lopsbm>!wf`kmj`bomfbq#wkf#Bgubm`fg#plvq`f#lef{sqfppfgKlmd#Hlmd#Eb`fallhnvowjsof#nf`kbmjpnfofubwjlmleefmpjuf?,elqn=\t\npslmplqfggl`vnfmw-lq#%rvlw8wkfqf#bqfwklpf#tklnlufnfmwpsql`fppfpgjeej`vowpvanjwwfgqf`lnnfmg`lmujm`fgsqlnlwjmd!#tjgwk>!-qfsob`f+`obppj`bo`lbojwjlmkjp#ejqpwgf`jpjlmpbppjpwbmwjmgj`bwfgfulovwjlm.tqbssfq!fmlvdk#wlbolmd#wkfgfojufqfg..=\x0e\t?"..Bnfqj`bm#sqlwf`wfgMlufnafq#?,pwzof=?evqmjwvqfJmwfqmfw##lmaovq>!pvpsfmgfgqf`jsjfmwabpfg#lm#Nlqflufq/balojpkfg`loof`wfgtfqf#nbgffnlwjlmbofnfqdfm`zmbqqbwjufbgul`bwfps{8alqgfq`lnnjwwfggjq>!owq!fnsolzffpqfpfbq`k-#pfof`wfgpv``fpplq`vpwlnfqpgjpsobzfgPfswfnafqbgg@obpp+Eb`fallh#pvddfpwfgbmg#obwfqlsfqbwjmdfobalqbwfPlnfwjnfpJmpwjwvwf`fqwbjmozjmpwboofgelooltfqpIfqvpbofnwkfz#kbuf`lnsvwjmddfmfqbwfgsqlujm`fpdvbqbmwffbqajwqbqzqf`ldmjyftbmwfg#wls{8tjgwk9wkflqz#leafkbujlvqTkjof#wkffpwjnbwfgafdbm#wl#jw#af`bnfnbdmjwvgfnvpw#kbufnlqf#wkbmGjqf`wlqzf{wfmpjlmpf`qfwbqzmbwvqboozl``vqqjmdubqjbaofpdjufm#wkfsobwelqn-?,obafo=?ebjofg#wl`lnslvmgphjmgp#le#pl`jfwjfpbolmdpjgf#..%dw8\t\tplvwktfpwwkf#qjdkwqbgjbwjlmnbz#kbuf#vmfp`bsf+pslhfm#jm!#kqfe>!,sqldqbnnflmoz#wkf#`lnf#eqlngjqf`wlqzavqjfg#jmb#pjnjobqwkfz#tfqf?,elmw=?,Mlqtfdjbmpsf`jejfgsqlgv`jmdsbppfmdfq+mft#Gbwfwfnslqbqzej`wjlmboBewfq#wkffrvbwjlmpgltmolbg-qfdvobqozgfufolsfqbaluf#wkfojmhfg#wlskfmlnfmbsfqjlg#lewllowjs!=pvapwbm`fbvwlnbwj`bpsf`w#leBnlmd#wkf`lmmf`wfgfpwjnbwfpBjq#Elq`fpzpwfn#lelaif`wjufjnnfgjbwfnbhjmd#jwsbjmwjmdp`lmrvfqfgbqf#pwjoosql`fgvqfdqltwk#lekfbgfg#azFvqlsfbm#gjujpjlmpnlof`vofpeqbm`kjpfjmwfmwjlmbwwqb`wfg`kjogkllgbopl#vpfggfgj`bwfgpjmdbslqfgfdqff#leebwkfq#le`lmeoj`wp?,b=?,s=\t`bnf#eqlntfqf#vpfgmlwf#wkbwqf`fjujmdF{f`vwjuffufm#nlqfb``fpp#wl`lnnbmgfqSlojwj`bonvpj`jbmpgfoj`jlvpsqjplmfqpbgufmw#leVWE.;!#,=?"X@GBWBX!=@lmwb`wPlvwkfqm#ad`lolq>!pfqjfp#le-#Jw#tbp#jm#Fvqlsfsfqnjwwfgubojgbwf-bssfbqjmdleej`jboppfqjlvpoz.obmdvbdfjmjwjbwfgf{wfmgjmdolmd.wfqnjmeobwjlmpv`k#wkbwdfw@llhjfnbqhfg#az?,avwwlm=jnsofnfmwavw#jw#jpjm`qfbpfpgltm#wkf#qfrvjqjmdgfsfmgfmw..=\t?"..#jmwfqujftTjwk#wkf#`lsjfp#le`lmpfmpvptbp#avjowUfmfyvfob+elqnfqozwkf#pwbwfsfqplmmfopwqbwfdj`ebulvq#lejmufmwjlmTjhjsfgjb`lmwjmfmwujqwvbooztkj`k#tbpsqjm`jsof@lnsofwf#jgfmwj`bopklt#wkbwsqjnjwjufbtbz#eqlnnlof`vobqsqf`jpfozgjpploufgVmgfq#wkfufqpjlm>!=%maps8?,Jw#jp#wkf#Wkjp#jp#tjoo#kbuflqdbmjpnpplnf#wjnfEqjfgqj`ktbp#ejqpwwkf#lmoz#eb`w#wkbwelqn#jg>!sqf`fgjmdWf`kmj`boskzpj`jpwl``vqp#jmmbujdbwlqpf`wjlm!=psbm#jg>!plvdkw#wlafolt#wkfpvqujujmd~?,pwzof=kjp#gfbwkbp#jm#wkf`bvpfg#azsbqwjboozf{jpwjmd#vpjmd#wkftbp#djufmb#ojpw#leofufop#lemlwjlm#leLeej`jbo#gjpnjppfgp`jfmwjpwqfpfnaofpgvsoj`bwff{solpjufqf`lufqfgboo#lwkfqdboofqjfpxsbggjmd9sflsof#leqfdjlm#lebggqfppfpbppl`jbwfjnd#bow>!jm#nlgfqmpklvog#afnfwklg#leqfslqwjmdwjnfpwbnsmffgfg#wlwkf#Dqfbwqfdbqgjmdpffnfg#wlujftfg#bpjnsb`w#lmjgfb#wkbwwkf#Tlqogkfjdkw#lef{sbmgjmdWkfpf#bqf`vqqfmw!=`bqfevooznbjmwbjmp`kbqdf#le@obppj`bobggqfppfgsqfgj`wfgltmfqpkjs?gju#jg>!qjdkw!=\x0e\tqfpjgfm`fofbuf#wkf`lmwfmw!=bqf#lewfm##~*+*8\x0e\tsqlabaoz#Sqlefpplq.avwwlm!#qfpslmgfgpbzp#wkbwkbg#wl#afsob`fg#jmKvmdbqjbmpwbwvp#lepfqufp#bpVmjufqpbof{f`vwjlmbddqfdbwfelq#tkj`kjmef`wjlmbdqffg#wlkltfufq/#slsvobq!=sob`fg#lm`lmpwqv`wfof`wlqbopznalo#lejm`ovgjmdqfwvqm#wlbq`kjwf`w@kqjpwjbmsqfujlvp#ojujmd#jmfbpjfq#wlsqlefpplq\t%ow8"..#feef`w#lebmbozwj`ptbp#wbhfmtkfqf#wkfwllh#lufqafojfe#jmBeqjhbbmpbp#ebq#bpsqfufmwfgtlqh#tjwkb#psf`jbo?ejfogpfw@kqjpwnbpQfwqjfufg\t\tJm#wkf#ab`h#jmwlmlqwkfbpwnbdbyjmfp=?pwqlmd=`lnnjwwffdlufqmjmddqlvsp#lepwlqfg#jmfpwbaojpkb#dfmfqbojwp#ejqpwwkfjq#ltmslsvobwfgbm#laif`w@bqjaafbmboolt#wkfgjpwqj`wptjp`lmpjmol`bwjlm-8#tjgwk9#jmkbajwfgPl`jbojpwIbmvbqz#2?,ellwfq=pjnjobqoz`klj`f#lewkf#pbnf#psf`jej`#avpjmfpp#Wkf#ejqpw-ofmdwk8#gfpjqf#wlgfbo#tjwkpjm`f#wkfvpfqBdfmw`lm`fjufgjmgf{-sksbp#%rvlw8fmdbdf#jmqf`fmwoz/eft#zfbqptfqf#bopl\t?kfbg=\t?fgjwfg#azbqf#hmltm`jwjfp#jmb``fpphfz`lmgfnmfgbopl#kbufpfquj`fp/ebnjoz#leP`kllo#le`lmufqwfgmbwvqf#le#obmdvbdfnjmjpwfqp?,laif`w=wkfqf#jp#b#slsvobqpfrvfm`fpbgul`bwfgWkfz#tfqfbmz#lwkfqol`bwjlm>fmwfq#wkfnv`k#nlqfqfeof`wfgtbp#mbnfglqjdjmbo#b#wzsj`botkfm#wkfzfmdjmffqp`lvog#mlwqfpjgfmwptfgmfpgbzwkf#wkjqg#sqlgv`wpIbmvbqz#1tkbw#wkfzb#`fqwbjmqfb`wjlmpsql`fpplqbewfq#kjpwkf#obpw#`lmwbjmfg!=?,gju=\t?,b=?,wg=gfsfmg#lmpfbq`k!=\tsjf`fp#le`lnsfwjmdQfefqfm`fwfmmfppfftkj`k#kbp#ufqpjlm>?,psbm=#??,kfbgfq=djufp#wkfkjpwlqjbmubovf>!!=sbggjmd93ujft#wkbwwldfwkfq/wkf#nlpw#tbp#elvmgpvapfw#lebwwb`h#lm`kjogqfm/sljmwp#lesfqplmbo#slpjwjlm9boofdfgoz@ofufobmgtbp#obwfqbmg#bewfqbqf#djufmtbp#pwjoop`qloojmdgfpjdm#lenbhfp#wkfnv`k#ofppBnfqj`bmp-\t\tBewfq#/#avw#wkfNvpfvn#leolvjpjbmb+eqln#wkfnjmmfplwbsbqwj`ofpb#sql`fppGlnjmj`bmulovnf#leqfwvqmjmdgfefmpjuf33s{\x7fqjdknbgf#eqlnnlvpflufq!#pwzof>!pwbwfp#le+tkj`k#jp`lmwjmvfpEqbm`jp`lavjogjmd#tjwklvw#btjwk#plnftkl#tlvogb#elqn#leb#sbqw#leafelqf#jwhmltm#bp##Pfquj`fpol`bwjlm#bmg#lewfmnfbpvqjmdbmg#jw#jpsbsfqab`hubovfp#le\x0e\t?wjwof=>#tjmglt-gfwfqnjmffq%rvlw8#sobzfg#azbmg#fbqoz?,`fmwfq=eqln#wkjpwkf#wkqffsltfq#bmgle#%rvlw8jmmfqKWNO?b#kqfe>!z9jmojmf8@kvq`k#lewkf#fufmwufqz#kjdkleej`jbo#.kfjdkw9#`lmwfmw>!,`dj.ajm,wl#`qfbwfbeqjhbbmpfpsfqbmwleqbm/Kbjpobwujf)Mvojfwvuj)_(`f)Mwjmb(af)Mwjmb\fUh\fT{\fTN\n{I\np@\x04Fr\vBl\bQ\x7f\tA{\vUm\x05Gx\tA{\x01yp\x06YA\0zX\bTV\bWl\bUd\x04BM\vB{\npV\v@x\x04B\\\np@\x04Db\x04Gz\tal\npa\tfM\tuD\bV~\x04mx\vQ}\ndS\tp\\\bVK\bS]\bU|\x05oD\tkV\ved\vHR\nb~\x04M`\nJp\x05oD\x04|Q\nLP\x04Sw\bTl\nAI\nxC\bWt\tBq\x05F`\x04Cm\vLm\tKx\t}t\bPv\ny\\\naB\tV\x7f\nZd\x04XU\x04li\tfr\ti@\tBH\x04BD\x04BV\t`V\n[]\tp_\tTn\n~A\nxR\tuD\t`{\bV@\tTn\tHK\tAJ\vxs\x04Zf\nqI\x04Zf\vBM\v|j\t}t\bSM\nmC\vQ}pfquj`jlpbqw/A`volbqdfmwjmbabq`folmb`vborvjfqsvaoj`bglsqlgv`wlpslo/Awj`bqfpsvfpwbtjhjsfgjbpjdvjfmwfa/Vprvfgb`lnvmjgbgpfdvqjgbgsqjm`jsbosqfdvmwbp`lmwfmjglqfpslmgfqufmfyvfobsqlaofnbpgj`jfnaqfqfob`j/_mmlujfnaqfpjnjobqfpsqlzf`wlpsqldqbnbpjmpwjwvwlb`wjujgbgfm`vfmwqbf`lmln/Abjn/Mdfmfp`lmwb`wbqgfp`bqdbqmf`fpbqjlbwfm`j/_mwfo/Eelml`lnjpj/_m`bm`jlmfp`bsb`jgbgfm`lmwqbqbm/Mojpjpebulqjwlpw/Eqnjmlpsqlujm`jbfwjrvfwbpfofnfmwlpevm`jlmfpqfpvowbgl`bq/M`wfqsqlsjfgbgsqjm`jsjlmf`fpjgbgnvmj`jsbo`qfb`j/_mgfp`bqdbpsqfpfm`jb`lnfq`jbolsjmjlmfpfifq`j`jlfgjwlqjbopbobnbm`bdlmy/Mofygl`vnfmwlsfo/A`vobqf`jfmwfpdfmfqbofpwbqqbdlmbsq/M`wj`bmlufgbgfpsqlsvfpwbsb`jfmwfpw/E`mj`bplaifwjulp`lmwb`wlp\fHB\fIk\fHn\fH^\fHS\fHc\fHU\fId\fHn\fH{\fHC\fHR\fHT\fHR\fHI\fHc\fHY\fHn\fH\\\fHU\fIk\fHy\fIg\fHd\fHy\fIm\fHw\fH\\\fHU\fHR\fH@\fHR\fHJ\fHy\fHU\fHR\fHT\fHA\fIl\fHU\fIm\fHc\fH\\\fHU\fIl\fHB\fId\fHn\fHJ\fHS\fHD\fH@\fHR\fHHgjsolgl`p\fHT\fHB\fHC\fH\\\fIn\fHF\fHD\fHR\fHB\fHF\fHH\fHR\fHG\fHS\fH\\\fHx\fHT\fHH\fHH\fH\\\fHU\fH^\fIg\fH{\fHU\fIm\fHj\fH@\fHR\fH\\\fHJ\fIk\fHZ\fHU\fIm\fHd\fHz\fIk\fH^\fHC\fHJ\fHS\fHy\fHR\fHB\fHY\fIk\fH@\fHH\fIl\fHD\fH@\fIl\fHv\fHB\fI`\fHH\fHT\fHR\fH^\fH^\fIk\fHz\fHp\fIe\fH@\fHB\fHJ\fHJ\fHH\fHI\fHR\fHD\fHU\fIl\fHZ\fHU\fH\\\fHi\fH^\fH{\fHy\fHA\fIl\fHD\fH{\fH\\\fHF\fHR\fHT\fH\\\fHR\fHH\fHy\fHS\fHc\fHe\fHT\fIk\fH{\fHC\fIl\fHU\fIn\fHm\fHj\fH{\fIk\fHs\fIl\fHB\fHz\fIg\fHp\fHy\fHR\fH\\\fHi\fHA\fIl\fH{\fHC\fIk\fHH\fIm\fHB\fHY\fIg\fHs\fHJ\fIk\fHn\fHi\fH{\fH\\\fH|\fHT\fIk\fHB\fIk\fH^\fH^\fH{\fHR\fHU\fHR\fH^\fHf\fHF\fH\\\fHv\fHR\fH\\\fH|\fHT\fHR\fHJ\fIk\fH\\\fHp\fHS\fHT\fHJ\fHS\fH^\fH@\fHn\fHJ\fH@\fHD\fHR\fHU\fIn\fHn\fH^\fHR\fHz\fHp\fIl\fHH\fH@\fHs\fHD\fHB\fHS\fH^\fHk\fHT\fIk\fHj\fHD\fIk\fHD\fHC\fHR\fHy\fIm\fH^\fH^\fIe\fH{\fHA\fHR\fH{\fH\\\fIk\fH^\fHp\fH{\fHU\fH\\\fHR\fHB\fH^\fH{\fIk\fHF\fIk\fHp\fHU\fHR\fHI\fHk\fHT\fIl\fHT\fHU\fIl\fHy\fH^\fHR\fHL\fIl\fHy\fHU\fHR\fHm\fHJ\fIn\fH\\\fHH\fHU\fHH\fHT\fHR\fHH\fHC\fHR\fHJ\fHj\fHC\fHR\fHF\fHR\fHy\fHy\fI`\fHD\fHZ\fHR\fHB\fHJ\fIk\fHz\fHC\fHU\fIl\fH\\\fHR\fHC\fHz\fIm\fHJ\fH^\fH{\fIl`bwfdlqjfpf{sfqjfm`f?,wjwof=\x0e\t@lszqjdkw#ibubp`qjsw`lmgjwjlmpfufqzwkjmd?s#`obpp>!wf`kmloldzab`hdqlvmg?b#`obpp>!nbmbdfnfmw%`lsz8#132ibubP`qjsw`kbqb`wfqpaqfbg`qvnawkfnpfoufpklqjylmwbodlufqmnfmw@bojelqmjbb`wjujwjfpgjp`lufqfgMbujdbwjlmwqbmpjwjlm`lmmf`wjlmmbujdbwjlmbssfbqbm`f?,wjwof=?n`kf`hal{!#wf`kmjrvfpsqlwf`wjlmbssbqfmwozbp#tfoo#bpvmw$/#$VB.qfplovwjlmlsfqbwjlmpwfofujpjlmwqbmpobwfgTbpkjmdwlmmbujdbwlq-#>#tjmglt-jnsqfppjlm%ow8aq%dw8ojwfqbwvqfslsvobwjlmad`lolq>! fpsf`jbooz#`lmwfmw>!sqlgv`wjlmmftpofwwfqsqlsfqwjfpgfejmjwjlmofbgfqpkjsWf`kmloldzSbqojbnfmw`lnsbqjplmvo#`obpp>!-jmgf{Le+!`lm`ovpjlmgjp`vppjlm`lnslmfmwpajloldj`boQfulovwjlm\\`lmwbjmfqvmgfqpwllgmlp`qjsw=?sfqnjppjlmfb`k#lwkfqbwnlpskfqf#lmel`vp>!?elqn#jg>!sql`fppjmdwkjp-ubovfdfmfqbwjlm@lmefqfm`fpvapfrvfmwtfoo.hmltmubqjbwjlmpqfsvwbwjlmskfmlnfmlmgjp`jsojmfoldl-smd!#+gl`vnfmw/alvmgbqjfpf{sqfppjlmpfwwofnfmwAb`hdqlvmglvw#le#wkffmwfqsqjpf+!kwwsp9!#vmfp`bsf+!sbpptlqg!#gfnl`qbwj`?b#kqfe>!,tqbssfq!=\tnfnafqpkjsojmdvjpwj`s{8sbggjmdskjolplskzbppjpwbm`fvmjufqpjwzeb`jojwjfpqf`ldmjyfgsqfefqfm`fje#+wzsflenbjmwbjmfgul`bavobqzkzslwkfpjp-pvanjw+*8%bns8maps8bmmlwbwjlmafkjmg#wkfElvmgbwjlmsvaojpkfq!bppvnswjlmjmwqlgv`fg`lqqvswjlmp`jfmwjpwpf{soj`jwozjmpwfbg#legjnfmpjlmp#lm@oj`h>!`lmpjgfqfggfsbqwnfmwl``vsbwjlmpllm#bewfqjmufpwnfmwsqlmlvm`fgjgfmwjejfgf{sfqjnfmwNbmbdfnfmwdfldqbskj`!#kfjdkw>!ojmh#qfo>!-qfsob`f+,gfsqfppjlm`lmefqfm`fsvmjpknfmwfojnjmbwfgqfpjpwbm`fbgbswbwjlmlsslpjwjlmtfoo#hmltmpvssofnfmwgfwfqnjmfgk2#`obpp>!3s{8nbqdjmnf`kbmj`bopwbwjpwj`p`fofaqbwfgDlufqmnfmw\t\tGvqjmd#wgfufolsfqpbqwjej`jbofrvjubofmwlqjdjmbwfg@lnnjppjlmbwwb`knfmw?psbm#jg>!wkfqf#tfqfMfgfqobmgpafzlmg#wkfqfdjpwfqfgilvqmbojpweqfrvfmwozboo#le#wkfobmd>!fm!#?,pwzof=\x0e\tbaplovwf8#pvsslqwjmdf{wqfnfoz#nbjmpwqfbn?,pwqlmd=#slsvobqjwzfnsolznfmw?,wbaof=\x0e\t#`lopsbm>!?,elqn=\t##`lmufqpjlmbalvw#wkf#?,s=?,gju=jmwfdqbwfg!#obmd>!fmSlqwvdvfpfpvapwjwvwfjmgjujgvbojnslppjaofnvowjnfgjbbonlpw#boos{#plojg# bsbqw#eqlnpvaif`w#wljm#Fmdojpk`qjwj`jyfgf{`fsw#elqdvjgfojmfplqjdjmboozqfnbqhbaofwkf#pf`lmgk1#`obpp>!?b#wjwof>!+jm`ovgjmdsbqbnfwfqpsqlkjajwfg>#!kwws9,,gj`wjlmbqzsfq`fswjlmqfulovwjlmelvmgbwjlms{8kfjdkw9pv``fppevopvsslqwfqpnjoofmmjvnkjp#ebwkfqwkf#%rvlw8ml.qfsfbw8`lnnfq`jbojmgvpwqjbofm`lvqbdfgbnlvmw#le#vmleej`jbofeej`jfm`zQfefqfm`fp`llqgjmbwfgjp`objnfqf{sfgjwjlmgfufolsjmd`bo`vobwfgpjnsojejfgofdjwjnbwfpvapwqjmd+3!#`obpp>!`lnsofwfozjoovpwqbwfejuf#zfbqpjmpwqvnfmwSvaojpkjmd2!#`obpp>!spz`kloldz`lmejgfm`fmvnafq#le#bapfm`f#leel`vpfg#lmiljmfg#wkfpwqv`wvqfpsqfujlvpoz=?,jeqbnf=lm`f#bdbjmavw#qbwkfqjnnjdqbmwple#`lvqpf/b#dqlvs#leOjwfqbwvqfVmojhf#wkf?,b=%maps8\tevm`wjlm#jw#tbp#wkf@lmufmwjlmbvwlnlajofSqlwfpwbmwbddqfppjufbewfq#wkf#Pjnjobqoz/!#,=?,gju=`loof`wjlm\x0e\tevm`wjlmujpjajojwzwkf#vpf#leulovmwffqpbwwqb`wjlmvmgfq#wkf#wkqfbwfmfg)?"X@GBWBXjnslqwbm`fjm#dfmfqbowkf#obwwfq?,elqn=\t?,-jmgf{Le+$j#>#38#j#?gjeefqfm`fgfulwfg#wlwqbgjwjlmppfbq`k#elqvowjnbwfozwlvqmbnfmwbwwqjavwfppl.`boofg#~\t?,pwzof=fubovbwjlmfnskbpjyfgb``fppjaof?,pf`wjlm=pv``fppjlmbolmd#tjwkNfbmtkjof/jmgvpwqjfp?,b=?aq#,=kbp#af`lnfbpsf`wp#leWfofujpjlmpveej`jfmwabphfwabooalwk#pjgfp`lmwjmvjmdbm#bqwj`of?jnd#bow>!bgufmwvqfpkjp#nlwkfqnbm`kfpwfqsqjm`jsofpsbqwj`vobq`lnnfmwbqzfeef`wp#legf`jgfg#wl!=?pwqlmd=svaojpkfqpIlvqmbo#legjeej`vowzeb`jojwbwfb``fswbaofpwzof-`pp!\nevm`wjlm#jmmlubwjlm=@lszqjdkwpjwvbwjlmptlvog#kbufavpjmfppfpGj`wjlmbqzpwbwfnfmwplewfm#vpfgsfqpjpwfmwjm#Ibmvbqz`lnsqjpjmd?,wjwof=\t\ngjsolnbwj``lmwbjmjmdsfqelqnjmdf{wfmpjlmpnbz#mlw#af`lm`fsw#le#lm`oj`h>!Jw#jp#boplejmbm`jbo#nbhjmd#wkfOv{fnalvqdbggjwjlmbobqf#`boofgfmdbdfg#jm!p`qjsw!*8avw#jw#tbpfof`wqlmj`lmpvanjw>!\t?"..#Fmg#fof`wqj`boleej`jboozpvddfpwjlmwls#le#wkfvmojhf#wkfBvpwqbojbmLqjdjmboozqfefqfm`fp\t?,kfbg=\x0e\tqf`ldmjpfgjmjwjbojyfojnjwfg#wlBof{bmgqjbqfwjqfnfmwBgufmwvqfpelvq#zfbqp\t\t%ow8"..#jm`qfbpjmdgf`lqbwjlmk0#`obpp>!lqjdjmp#lelaojdbwjlmqfdvobwjlm`obppjejfg+evm`wjlm+bgubmwbdfpafjmd#wkf#kjpwlqjbmp?abpf#kqfeqfsfbwfgoztjoojmd#wl`lnsbqbaofgfpjdmbwfgmlnjmbwjlmevm`wjlmbojmpjgf#wkfqfufobwjlmfmg#le#wkfp#elq#wkf#bvwklqjyfgqfevpfg#wlwbhf#sob`fbvwlmlnlvp`lnsqlnjpfslojwj`bo#qfpwbvqbmwwtl#le#wkfEfaqvbqz#1rvbojwz#leptelaif`w-vmgfqpwbmgmfbqoz#bootqjwwfm#azjmwfqujftp!#tjgwk>!2tjwkgqbtboeolbw9ofewjp#vpvbooz`bmgjgbwfpmftpsbsfqpnzpwfqjlvpGfsbqwnfmwafpw#hmltmsbqojbnfmwpvssqfppfg`lmufmjfmwqfnfnafqfggjeefqfmw#pzpwfnbwj`kbp#ofg#wlsqlsbdbmgb`lmwqloofgjmeovfm`fp`fqfnlmjbosql`objnfgSqlwf`wjlmoj#`obpp>!P`jfmwjej``obpp>!ml.wqbgfnbqhpnlqf#wkbm#tjgfpsqfbgOjafqbwjlmwllh#sob`fgbz#le#wkfbp#olmd#bpjnsqjplmfgBggjwjlmbo\t?kfbg=\t?nObalqbwlqzMlufnafq#1f{`fswjlmpJmgvpwqjboubqjfwz#leeolbw9#ofeGvqjmd#wkfbppfppnfmwkbuf#affm#gfbop#tjwkPwbwjpwj`pl``vqqfm`f,vo=?,gju=`ofbqej{!=wkf#svaoj`nbmz#zfbqptkj`k#tfqflufq#wjnf/pzmlmznlvp`lmwfmw!=\tsqfpvnbaozkjp#ebnjozvpfqBdfmw-vmf{sf`wfgjm`ovgjmd#`kboofmdfgb#njmlqjwzvmgfejmfg!afolmdp#wlwbhfm#eqlnjm#L`wlafqslpjwjlm9#pbjg#wl#afqfojdjlvp#Efgfqbwjlm#qltpsbm>!lmoz#b#eftnfbmw#wkbwofg#wl#wkf..=\x0e\t?gju#?ejfogpfw=Bq`kajpkls#`obpp>!mlafjmd#vpfgbssqlb`kfpsqjujofdfpmlp`qjsw=\tqfpvowp#jmnbz#af#wkfFbpwfq#fddnf`kbmjpnpqfbplmbaofSlsvobwjlm@loof`wjlmpfof`wfg!=mlp`qjsw=\x0e,jmgf{-sksbqqjubo#le.ippgh$**8nbmbdfg#wljm`lnsofwf`bpvbowjfp`lnsofwjlm@kqjpwjbmpPfswfnafq#bqjwknfwj`sql`fgvqfpnjdkw#kbufSqlgv`wjlmjw#bssfbqpSkjolplskzeqjfmgpkjsofbgjmd#wldjujmd#wkfwltbqg#wkfdvbqbmwffggl`vnfmwfg`lolq9 333ujgfl#dbnf`lnnjppjlmqfeof`wjmd`kbmdf#wkfbppl`jbwfgpbmp.pfqjelmhfzsqfpp8#sbggjmd9Kf#tbp#wkfvmgfqozjmdwzsj`booz#/#bmg#wkf#pq`Fofnfmwpv``fppjufpjm`f#wkf#pklvog#af#mfwtlqhjmdb``lvmwjmdvpf#le#wkfoltfq#wkbmpkltp#wkbw?,psbm=\t\n\n`lnsobjmwp`lmwjmvlvprvbmwjwjfpbpwqlmlnfqkf#gjg#mlwgvf#wl#jwpbssojfg#wlbm#bufqbdffeelqwp#wlwkf#evwvqfbwwfnsw#wlWkfqfelqf/`bsbajojwzQfsvaoj`bmtbp#elqnfgFof`wqlmj`hjolnfwfqp`kboofmdfpsvaojpkjmdwkf#elqnfqjmgjdfmlvpgjqf`wjlmppvapjgjbqz`lmpsjqb`zgfwbjop#lebmg#jm#wkfbeelqgbaofpvapwbm`fpqfbplm#elq`lmufmwjlmjwfnwzsf>!baplovwfozpvsslpfgozqfnbjmfg#bbwwqb`wjufwqbufoojmdpfsbqbwfozel`vpfp#lmfofnfmwbqzbssoj`baofelvmg#wkbwpwzofpkffwnbmvp`qjswpwbmgp#elq#ml.qfsfbw+plnfwjnfp@lnnfq`jbojm#Bnfqj`bvmgfqwbhfmrvbqwfq#lebm#f{bnsofsfqplmboozjmgf{-sks<?,avwwlm=\tsfq`fmwbdfafpw.hmltm`qfbwjmd#b!#gjq>!owqOjfvwfmbmw\t?gju#jg>!wkfz#tlvogbajojwz#lenbgf#vs#lemlwfg#wkbw`ofbq#wkbwbqdvf#wkbwwl#bmlwkfq`kjogqfm$psvqslpf#leelqnvobwfgabpfg#vslmwkf#qfdjlmpvaif`w#lesbppfmdfqpslppfppjlm-\t\tJm#wkf#Afelqf#wkfbewfqtbqgp`vqqfmwoz#b`qlpp#wkfp`jfmwjej``lnnvmjwz-`bsjwbojpnjm#Dfqnbmzqjdkw.tjmdwkf#pzpwfnPl`jfwz#leslojwj`jbmgjqf`wjlm9tfmw#lm#wlqfnlubo#le#Mft#Zlqh#bsbqwnfmwpjmgj`bwjlmgvqjmd#wkfvmofpp#wkfkjpwlqj`bokbg#affm#bgfejmjwjufjmdqfgjfmwbwwfmgbm`f@fmwfq#elqsqlnjmfm`fqfbgzPwbwfpwqbwfdjfpavw#jm#wkfbp#sbqw#le`lmpwjwvwf`objn#wkbwobalqbwlqz`lnsbwjaofebjovqf#le/#pv`k#bp#afdbm#tjwkvpjmd#wkf#wl#sqlujgfefbwvqf#leeqln#tkj`k,!#`obpp>!dfloldj`bopfufqbo#legfojafqbwfjnslqwbmw#klogp#wkbwjmd%rvlw8#ubojdm>wlswkf#Dfqnbmlvwpjgf#lemfdlwjbwfgkjp#`bqffqpfsbqbwjlmjg>!pfbq`ktbp#`boofgwkf#elvqwkqf`qfbwjlmlwkfq#wkbmsqfufmwjlmtkjof#wkf#fgv`bwjlm/`lmmf`wjmdb``vqbwfoztfqf#avjowtbp#hjoofgbdqffnfmwpnv`k#nlqf#Gvf#wl#wkftjgwk9#233plnf#lwkfqHjmdgln#lewkf#fmwjqfebnlvp#elqwl#`lmmf`wlaif`wjufpwkf#Eqfm`ksflsof#bmgefbwvqfg!=jp#pbjg#wlpwqv`wvqboqfefqfmgvnnlpw#lewfmb#pfsbqbwf.=\t?gju#jg#Leej`jbo#tlqogtjgf-bqjb.obafowkf#sobmfwbmg#jw#tbpg!#ubovf>!ollhjmd#bwafmfej`jbobqf#jm#wkfnlmjwlqjmdqfslqwfgozwkf#nlgfqmtlqhjmd#lmbooltfg#wltkfqf#wkf#jmmlubwjuf?,b=?,gju=plvmgwqb`hpfbq`kElqnwfmg#wl#afjmsvw#jg>!lsfmjmd#leqfpwqj`wfgbglswfg#azbggqfppjmdwkfloldjbmnfwklgp#leubqjbmw#le@kqjpwjbm#ufqz#obqdfbvwlnlwjufaz#ebq#wkfqbmdf#eqlnsvqpvjw#leeloolt#wkfaqlvdkw#wljm#Fmdobmgbdqff#wkbwb``vpfg#le`lnfp#eqlnsqfufmwjmdgju#pwzof>kjp#lq#kfqwqfnfmglvpeqffgln#le`lm`fqmjmd3#2fn#2fn8Abphfwaboo,pwzof-`ppbm#fbqojfqfufm#bewfq,!#wjwof>!-`ln,jmgf{wbhjmd#wkfsjwwpavqdk`lmwfmw!=\x0e?p`qjsw=+ewvqmfg#lvwkbujmd#wkf?,psbm=\x0e\t#l``bpjlmboaf`bvpf#jwpwbqwfg#wlskzpj`booz=?,gju=\t##`qfbwfg#az@vqqfmwoz/#ad`lolq>!wbajmgf{>!gjpbpwqlvpBmbozwj`p#bopl#kbp#b=?gju#jg>!?,pwzof=\t?`boofg#elqpjmdfq#bmg-pq`#>#!,,ujlobwjlmpwkjp#sljmw`lmpwbmwozjp#ol`bwfgqf`lqgjmdpg#eqln#wkfmfgfqobmgpslqwvdv/Fp;N;};D;u;F5m4K4]4_7`gfpbqqlool`lnfmwbqjlfgv`b`j/_mpfswjfnaqfqfdjpwqbglgjqf``j/_mvaj`b`j/_msvaoj`jgbgqfpsvfpwbpqfpvowbglpjnslqwbmwfqfpfqubglpbqw/A`volpgjefqfmwfppjdvjfmwfpqfs/Vaoj`bpjwvb`j/_mnjmjpwfqjlsqjub`jgbggjqf`wlqjlelqnb`j/_mslaob`j/_msqfpjgfmwf`lmw','fmjglpb``fplqjlpwf`kmlqbwjsfqplmbofp`bwfdlq/Abfpsf`jbofpgjpslmjaofb`wvbojgbgqfefqfm`jbuboobglojgajaojlwf`bqfob`jlmfp`bofmgbqjlslo/Awj`bpbmwfqjlqfpgl`vnfmwlpmbwvqbofybnbwfqjbofpgjefqfm`jbf`lm/_nj`bwqbmpslqwfqlgq/Advfysbqwj`jsbqfm`vfmwqbmgjp`vpj/_mfpwqv`wvqbevmgb`j/_meqf`vfmwfpsfqnbmfmwfwlwbonfmwf<P<R<Z<Q<R<]=o<X<Y=n<P<R<Z<Y=n<^=l<Y<P=c=n<\\<V<Z<Y=k=n<R<]=g<]<R<W<Y<Y<R=k<Y<Q=`=a=n<R<_<R<V<R<_<X<\\<S<R=m<W<Y<^=m<Y<_<R=m<\\<U=n<Y=k<Y=l<Y<[<P<R<_=o=n=m<\\<U=n<\\<Z<T<[<Q<T<P<Y<Z<X=o<]=o<X=o=n<s<R<T=m<V<[<X<Y=m=`<^<T<X<Y<R=m<^=c<[<T<Q=o<Z<Q<R=m<^<R<Y<U<W=b<X<Y<U<S<R=l<Q<R<P<Q<R<_<R<X<Y=n<Y<U=m<^<R<T=i<S=l<\\<^<\\=n<\\<V<R<U<P<Y=m=n<R<T<P<Y<Y=n<Z<T<[<Q=`<R<X<Q<R<U<W=o=k=d<Y<S<Y=l<Y<X=k<\\=m=n<T=k<\\=m=n=`=l<\\<]<R=n<Q<R<^=g=i<S=l<\\<^<R=m<R<]<R<U<S<R=n<R<P<P<Y<Q<Y<Y=k<T=m<W<Y<Q<R<^=g<Y=o=m<W=o<_<R<V<R<W<R<Q<\\<[<\\<X=n<\\<V<R<Y=n<R<_<X<\\<S<R=k=n<T<s<R=m<W<Y=n<\\<V<T<Y<Q<R<^=g<U=m=n<R<T=n=n<\\<V<T=i=m=l<\\<[=o<M<\\<Q<V=n=h<R=l=o<P<v<R<_<X<\\<V<Q<T<_<T=m<W<R<^<\\<Q<\\=d<Y<U<Q<\\<U=n<T=m<^<R<T<P=m<^=c<[=`<W=b<]<R<U=k<\\=m=n<R=m=l<Y<X<T<v=l<R<P<Y<H<R=l=o<P=l=g<Q<V<Y=m=n<\\<W<T<S<R<T=m<V=n=g=m=c=k<P<Y=m=c=j=j<Y<Q=n=l=n=l=o<X<\\=m<\\<P=g=i=l=g<Q<V<\\<q<R<^=g<U=k<\\=m<R<^<P<Y=m=n<\\=h<T<W=`<P<P<\\=l=n<\\=m=n=l<\\<Q<P<Y=m=n<Y=n<Y<V=m=n<Q<\\=d<T=i<P<T<Q=o=n<T<P<Y<Q<T<T<P<Y=b=n<Q<R<P<Y=l<_<R=l<R<X=m<\\<P<R<P=a=n<R<P=o<V<R<Q=j<Y=m<^<R<Y<P<V<\\<V<R<U<|=l=i<T<^5i5j4F4C5e4I4]4_4K5h4]4_4K5h4E4K5h4U4K5i5o4F4D5k4K4D4]4K5i4@4K5h5f5d5i4K5h4Y5d4]4@4C5f4C4E4K5h4U4Z5d4I4Z4K5m4E4K5h5n4_5i4K5h4U4K4D4F4A5i5f5h5i5h5m4K4F5i5h4F5n5e4F4U4C5f5h4K5h4X4U4]4O4B4D4K4]4F4[5d5f4]4U5h5f5o5i4I4]5m4K5n4[5h4D4K4F4K5h5h4V4E4F4]4F5f4D4K5h5j4K4_4K5h4X5f4B5i5j4F4C5f4K5h4U4]4D4K5h5n4Y4Y4K5m5h4K5i4U5h5f5k4K4F4A4C5f4G4K5h5h5k5i4K5h4U5i5h5i5o4F4D4E5f5i5o5j5o4K5h4[5m5h5m5f4C5f5d4I4C4K4]4E4F4K4]5f4B4K5h4Y4A4E4F4_4@5f5h4K5h5d5n4F4U5j4C5i4K5i4C5f5j4E4F4Y5i5f5i4O4]4X5f5m4K5h4\\5f5j4U4]4D5f4E4D5d4K4D4E4O5h4U4K4D4K5h4_5m4]5i4X4K5o5h4F4U4K5h5e4K5h4O5d5h4K5h4_5j4E4@4K5i4U4E4K5h4Y4A5m4K5h4C5f5j5o5h5i4K4F4K5h4B4K4Y4K5h5i5h5m4O4U4Z4K4M5o4F4K4D4E4K5h4B5f4]4]4_4K4J5h4K5h5n5h4D4K5h4O4C4D5i5n4K4[4U5i4]4K4_5h5i5j4[5n4E4K5h5o4F4D4K5h4]4@5h4K4X4F4]5o4K5h5n4C5i5f4U4[5f5opAzWbdMbnf+-isd!#bow>!2s{#plojg# -dje!#bow>!wqbmpsbqfmwjmelqnbwjlmbssoj`bwjlm!#lm`oj`h>!fpwbaojpkfgbgufqwjpjmd-smd!#bow>!fmujqlmnfmwsfqelqnbm`fbssqlsqjbwf%bns8ngbpk8jnnfgjbwfoz?,pwqlmd=?,qbwkfq#wkbmwfnsfqbwvqfgfufolsnfmw`lnsfwjwjlmsob`fklogfqujpjajojwz9`lszqjdkw!=3!#kfjdkw>!fufm#wklvdkqfsob`fnfmwgfpwjmbwjlm@lqslqbwjlm?vo#`obpp>!Bppl`jbwjlmjmgjujgvbopsfqpsf`wjufpfwWjnflvw+vqo+kwws9,,nbwkfnbwj`pnbqdjm.wls9fufmwvbooz#gfp`qjswjlm*#ml.qfsfbw`loof`wjlmp-ISD\x7fwkvna\x7fsbqwj`jsbwf,kfbg=?algzeolbw9ofew8?oj#`obpp>!kvmgqfgp#le\t\tKltfufq/#`lnslpjwjlm`ofbq9alwk8`llsfqbwjlmtjwkjm#wkf#obafo#elq>!alqgfq.wls9Mft#Yfbobmgqf`lnnfmgfgsklwldqbskzjmwfqfpwjmd%ow8pvs%dw8`lmwqlufqpzMfwkfqobmgpbowfqmbwjufnb{ofmdwk>!ptjwyfqobmgGfufolsnfmwfppfmwjbooz\t\tBowklvdk#?,wf{wbqfb=wkvmgfqajqgqfsqfpfmwfg%bns8mgbpk8psf`vobwjlm`lnnvmjwjfpofdjpobwjlmfof`wqlmj`p\t\n?gju#jg>!joovpwqbwfgfmdjmffqjmdwfqqjwlqjfpbvwklqjwjfpgjpwqjavwfg5!#kfjdkw>!pbmp.pfqje8`bsbaof#le#gjpbssfbqfgjmwfqb`wjufollhjmd#elqjw#tlvog#afBedkbmjpwbmtbp#`qfbwfgNbwk-eollq+pvqqlvmgjmd`bm#bopl#aflapfqubwjlmnbjmwfmbm`ffm`lvmwfqfg?k1#`obpp>!nlqf#qf`fmwjw#kbp#affmjmubpjlm#le*-dfwWjnf+*evmgbnfmwboGfpsjwf#wkf!=?gju#jg>!jmpsjqbwjlmf{bnjmbwjlmsqfsbqbwjlmf{sobmbwjlm?jmsvw#jg>!?,b=?,psbm=ufqpjlmp#lejmpwqvnfmwpafelqf#wkf##>#$kwws9,,Gfp`qjswjlmqfobwjufoz#-pvapwqjmd+fb`k#le#wkff{sfqjnfmwpjmeovfmwjbojmwfdqbwjlmnbmz#sflsofgvf#wl#wkf#`lnajmbwjlmgl#mlw#kbufNjggof#Fbpw?mlp`qjsw=?`lszqjdkw!#sfqkbsp#wkfjmpwjwvwjlmjm#Gf`fnafqbqqbmdfnfmwnlpw#ebnlvpsfqplmbojwz`qfbwjlm#leojnjwbwjlmpf{`ovpjufozplufqfjdmwz.`lmwfmw!=\t?wg#`obpp>!vmgfqdqlvmgsbqboofo#wlgl`wqjmf#lel``vsjfg#azwfqnjmloldzQfmbjppbm`fb#mvnafq#lepvsslqw#elqf{solqbwjlmqf`ldmjwjlmsqfgf`fpplq?jnd#pq`>!,?k2#`obpp>!svaoj`bwjlmnbz#bopl#afpsf`jbojyfg?,ejfogpfw=sqldqfppjufnjoojlmp#lepwbwfp#wkbwfmelq`fnfmwbqlvmg#wkf#lmf#bmlwkfq-sbqfmwMlgfbdqj`vowvqfBowfqmbwjufqfpfbq`kfqpwltbqgp#wkfNlpw#le#wkfnbmz#lwkfq#+fpsf`jbooz?wg#tjgwk>!8tjgwk9233&jmgfsfmgfmw?k0#`obpp>!#lm`kbmdf>!*-bgg@obpp+jmwfqb`wjlmLmf#le#wkf#gbvdkwfq#leb``fpplqjfpaqbm`kfp#le\x0e\t?gju#jg>!wkf#obqdfpwgf`obqbwjlmqfdvobwjlmpJmelqnbwjlmwqbmpobwjlmgl`vnfmwbqzjm#lqgfq#wl!=\t?kfbg=\t?!#kfjdkw>!2b`qlpp#wkf#lqjfmwbwjlm*8?,p`qjsw=jnsofnfmwfg`bm#af#pffmwkfqf#tbp#bgfnlmpwqbwf`lmwbjmfq!=`lmmf`wjlmpwkf#Aqjwjpktbp#tqjwwfm"jnslqwbmw8s{8#nbqdjm.elooltfg#azbajojwz#wl#`lnsoj`bwfggvqjmd#wkf#jnnjdqbwjlmbopl#`boofg?k7#`obpp>!gjpwjm`wjlmqfsob`fg#azdlufqmnfmwpol`bwjlm#lejm#Mlufnafqtkfwkfq#wkf?,s=\t?,gju=b`rvjpjwjlm`boofg#wkf#sfqpf`vwjlmgfpjdmbwjlmxelmw.pjyf9bssfbqfg#jmjmufpwjdbwff{sfqjfm`fgnlpw#ojhfoztjgfoz#vpfggjp`vppjlmpsqfpfm`f#le#+gl`vnfmw-f{wfmpjufozJw#kbp#affmjw#glfp#mlw`lmwqbqz#wljmkbajwbmwpjnsqlufnfmwp`klobqpkjs`lmpvnswjlmjmpwqv`wjlmelq#f{bnsoflmf#lq#nlqfs{8#sbggjmdwkf#`vqqfmwb#pfqjfp#lebqf#vpvboozqlof#jm#wkfsqfujlvpoz#gfqjubwjufpfujgfm`f#lef{sfqjfm`fp`lolqp`kfnfpwbwfg#wkbw`fqwjej`bwf?,b=?,gju=\t#pfof`wfg>!kjdk#p`klloqfpslmpf#wl`lnelqwbaofbglswjlm#lewkqff#zfbqpwkf#`lvmwqzjm#Efaqvbqzpl#wkbw#wkfsflsof#tkl#sqlujgfg#az?sbqbn#mbnfbeef`wfg#azjm#wfqnp#lebssljmwnfmwJPL.;;6:.2!tbp#alqm#jmkjpwlqj`bo#qfdbqgfg#bpnfbpvqfnfmwjp#abpfg#lm#bmg#lwkfq#9#evm`wjlm+pjdmjej`bmw`fofaqbwjlmwqbmpnjwwfg,ip,irvfqz-jp#hmltm#bpwkflqfwj`bo#wbajmgf{>!jw#`lvog#af?mlp`qjsw=\tkbujmd#affm\x0e\t?kfbg=\x0e\t?#%rvlw8Wkf#`lnsjobwjlmkf#kbg#affmsqlgv`fg#azskjolplskfq`lmpwqv`wfgjmwfmgfg#wlbnlmd#lwkfq`lnsbqfg#wlwl#pbz#wkbwFmdjmffqjmdb#gjeefqfmwqfefqqfg#wlgjeefqfm`fpafojfe#wkbwsklwldqbskpjgfmwjezjmdKjpwlqz#le#Qfsvaoj`#lemf`fppbqjozsqlabajojwzwf`kmj`boozofbujmd#wkfpsf`wb`vobqeqb`wjlm#lefof`wqj`jwzkfbg#le#wkfqfpwbvqbmwpsbqwmfqpkjsfnskbpjp#lmnlpw#qf`fmwpkbqf#tjwk#pbzjmd#wkbwejoofg#tjwkgfpjdmfg#wljw#jp#lewfm!=?,jeqbnf=bp#elooltp9nfqdfg#tjwkwkqlvdk#wkf`lnnfq`jbo#sljmwfg#lvwlsslqwvmjwzujft#le#wkfqfrvjqfnfmwgjujpjlm#lesqldqbnnjmdkf#qf`fjufgpfwJmwfqubo!=?,psbm=?,jm#Mft#Zlqhbggjwjlmbo#`lnsqfppjlm\t\t?gju#jg>!jm`lqslqbwf8?,p`qjsw=?bwwb`kFufmwaf`bnf#wkf#!#wbqdfw>!\\`bqqjfg#lvwPlnf#le#wkfp`jfm`f#bmgwkf#wjnf#le@lmwbjmfq!=nbjmwbjmjmd@kqjpwlskfqNv`k#le#wkftqjwjmdp#le!#kfjdkw>!1pjyf#le#wkfufqpjlm#le#nj{wvqf#le#afwtffm#wkfF{bnsofp#lefgv`bwjlmbo`lnsfwjwjuf#lmpvanjw>!gjqf`wlq#legjpwjm`wjuf,GWG#[KWNO#qfobwjmd#wlwfmgfm`z#wlsqlujm`f#letkj`k#tlvoggfpsjwf#wkfp`jfmwjej`#ofdjpobwvqf-jmmfqKWNO#boofdbwjlmpBdqj`vowvqftbp#vpfg#jmbssqlb`k#wljmwfoojdfmwzfbqp#obwfq/pbmp.pfqjegfwfqnjmjmdSfqelqnbm`fbssfbqbm`fp/#tkj`k#jp#elvmgbwjlmpbaaqfujbwfgkjdkfq#wkbmp#eqln#wkf#jmgjujgvbo#`lnslpfg#lepvsslpfg#wl`objnp#wkbwbwwqjavwjlmelmw.pjyf92fofnfmwp#leKjpwlqj`bo#kjp#aqlwkfqbw#wkf#wjnfbmmjufqpbqzdlufqmfg#azqfobwfg#wl#vowjnbwfoz#jmmlubwjlmpjw#jp#pwjoo`bm#lmoz#afgfejmjwjlmpwlDNWPwqjmdB#mvnafq#lejnd#`obpp>!Fufmwvbooz/tbp#`kbmdfgl``vqqfg#jmmfjdkalqjmdgjpwjmdvjpktkfm#kf#tbpjmwqlgv`jmdwfqqfpwqjboNbmz#le#wkfbqdvfp#wkbwbm#Bnfqj`bm`lmrvfpw#letjgfpsqfbg#tfqf#hjoofgp`qffm#bmg#Jm#lqgfq#wlf{sf`wfg#wlgfp`fmgbmwpbqf#ol`bwfgofdjpobwjufdfmfqbwjlmp#ab`hdqlvmgnlpw#sflsofzfbqp#bewfqwkfqf#jp#mlwkf#kjdkfpweqfrvfmwoz#wkfz#gl#mlwbqdvfg#wkbwpkltfg#wkbwsqfglnjmbmwwkfloldj`boaz#wkf#wjnf`lmpjgfqjmdpklqw.ojufg?,psbm=?,b=`bm#af#vpfgufqz#ojwwoflmf#le#wkf#kbg#boqfbgzjmwfqsqfwfg`lnnvmj`bwfefbwvqfp#ledlufqmnfmw/?,mlp`qjsw=fmwfqfg#wkf!#kfjdkw>!0Jmgfsfmgfmwslsvobwjlmpobqdf.p`bof-#Bowklvdk#vpfg#jm#wkfgfpwqv`wjlmslppjajojwzpwbqwjmd#jmwtl#lq#nlqff{sqfppjlmppvalqgjmbwfobqdfq#wkbmkjpwlqz#bmg?,lswjlm=\x0e\t@lmwjmfmwbofojnjmbwjmdtjoo#mlw#afsqb`wj`f#lejm#eqlmw#lepjwf#le#wkffmpvqf#wkbwwl#`qfbwf#bnjppjppjssjslwfmwjboozlvwpwbmgjmdafwwfq#wkbmtkbw#jp#mltpjwvbwfg#jmnfwb#mbnf>!WqbgjwjlmbopvddfpwjlmpWqbmpobwjlmwkf#elqn#lebwnlpskfqj`jgfloldj`bofmwfqsqjpfp`bo`vobwjmdfbpw#le#wkfqfnmbmwp#lesovdjmpsbdf,jmgf{-sks<qfnbjmfg#jmwqbmpelqnfgKf#tbp#bopltbp#boqfbgzpwbwjpwj`bojm#ebulq#leNjmjpwqz#lenlufnfmw#leelqnvobwjlmjp#qfrvjqfg?ojmh#qfo>!Wkjp#jp#wkf#?b#kqfe>!,slsvobqjyfgjmuloufg#jmbqf#vpfg#wlbmg#pfufqbonbgf#az#wkfpffnp#wl#afojhfoz#wkbwSbofpwjmjbmmbnfg#bewfqjw#kbg#affmnlpw#`lnnlmwl#qfefq#wlavw#wkjp#jp`lmpf`vwjufwfnslqbqjozJm#dfmfqbo/`lmufmwjlmpwbhfp#sob`fpvagjujpjlmwfqqjwlqjbolsfqbwjlmbosfqnbmfmwoztbp#obqdfozlvwaqfbh#lejm#wkf#sbpwelooltjmd#b#{nomp9ld>!=?b#`obpp>!`obpp>!wf{w@lmufqpjlm#nbz#af#vpfgnbmveb`wvqfbewfq#afjmd`ofbqej{!=\trvfpwjlm#letbp#fof`wfgwl#af`lnf#baf`bvpf#le#plnf#sflsofjmpsjqfg#azpv``fppevo#b#wjnf#tkfmnlqf#`lnnlmbnlmdpw#wkfbm#leej`jbotjgwk9233&8wf`kmloldz/tbp#bglswfgwl#hffs#wkfpfwwofnfmwpojuf#ajqwkpjmgf{-kwno!@lmmf`wj`vwbppjdmfg#wl%bns8wjnfp8b``lvmw#elqbojdm>qjdkwwkf#`lnsbmzbotbzp#affmqfwvqmfg#wljmuloufnfmwAf`bvpf#wkfwkjp#sfqjlg!#mbnf>!r!#`lmejmfg#wlb#qfpvow#leubovf>!!#,=jp#b`wvboozFmujqlmnfmw\x0e\t?,kfbg=\x0e\t@lmufqpfoz/=\t?gju#jg>!3!#tjgwk>!2jp#sqlabaozkbuf#af`lnf`lmwqloojmdwkf#sqlaofn`jwjyfmp#leslojwj`jbmpqfb`kfg#wkfbp#fbqoz#bp9mlmf8#lufq?wbaof#`fooubojgjwz#legjqf`woz#wllmnlvpfgltmtkfqf#jw#jptkfm#jw#tbpnfnafqp#le#qfobwjlm#wlb``lnnlgbwfbolmd#tjwk#Jm#wkf#obwfwkf#Fmdojpkgfoj`jlvp!=wkjp#jp#mlwwkf#sqfpfmwje#wkfz#bqfbmg#ejmboozb#nbwwfq#le\x0e\t\n?,gju=\x0e\t\x0e\t?,p`qjsw=ebpwfq#wkbmnbilqjwz#lebewfq#tkj`k`lnsbqbwjufwl#nbjmwbjmjnsqluf#wkfbtbqgfg#wkffq!#`obpp>!eqbnfalqgfqqfpwlqbwjlmjm#wkf#pbnfbmbozpjp#lewkfjq#ejqpwGvqjmd#wkf#`lmwjmfmwbopfrvfm`f#leevm`wjlm+*xelmw.pjyf9#tlqh#lm#wkf?,p`qjsw=\t?afdjmp#tjwkibubp`qjsw9`lmpwjwvfmwtbp#elvmgfgfrvjojaqjvnbppvnf#wkbwjp#djufm#azmffgp#wl#af`llqgjmbwfpwkf#ubqjlvpbqf#sbqw#lelmoz#jm#wkfpf`wjlmp#lejp#b#`lnnlmwkflqjfp#legjp`lufqjfpbppl`jbwjlmfgdf#le#wkfpwqfmdwk#leslpjwjlm#jmsqfpfmw.gbzvmjufqpboozwl#elqn#wkfavw#jmpwfbg`lqslqbwjlmbwwb`kfg#wljp#`lnnlmozqfbplmp#elq#%rvlw8wkf#`bm#af#nbgftbp#baof#wltkj`k#nfbmpavw#gjg#mlwlmNlvpfLufqbp#slppjaoflsfqbwfg#az`lnjmd#eqlnwkf#sqjnbqzbggjwjlm#leelq#pfufqbowqbmpefqqfgb#sfqjlg#lebqf#baof#wlkltfufq/#jwpklvog#kbufnv`k#obqdfq\t\n?,p`qjsw=bglswfg#wkfsqlsfqwz#legjqf`wfg#azfeef`wjufoztbp#aqlvdkw`kjogqfm#leSqldqbnnjmdolmdfq#wkbmnbmvp`qjswptbq#bdbjmpwaz#nfbmp#lebmg#nlpw#lepjnjobq#wl#sqlsqjfwbqzlqjdjmbwjmdsqfpwjdjlvpdqbnnbwj`bof{sfqjfm`f-wl#nbhf#wkfJw#tbp#bopljp#elvmg#jm`lnsfwjwlqpjm#wkf#V-P-qfsob`f#wkfaqlvdkw#wkf`bo`vobwjlmeboo#le#wkfwkf#dfmfqbosqb`wj`boozjm#klmlq#leqfofbpfg#jmqfpjgfmwjbobmg#plnf#lehjmd#le#wkfqfb`wjlm#wl2pw#Fbqo#le`vowvqf#bmgsqjm`jsbooz?,wjwof=\t##wkfz#`bm#afab`h#wl#wkfplnf#le#kjpf{slpvqf#wlbqf#pjnjobqelqn#le#wkfbggEbulqjwf`jwjyfmpkjssbqw#jm#wkfsflsof#tjwkjm#sqb`wj`fwl#`lmwjmvf%bns8njmvp8bssqlufg#az#wkf#ejqpw#booltfg#wkfbmg#elq#wkfevm`wjlmjmdsobzjmd#wkfplovwjlm#wlkfjdkw>!3!#jm#kjp#allhnlqf#wkbm#belooltp#wkf`qfbwfg#wkfsqfpfm`f#jm%maps8?,wg=mbwjlmbojpwwkf#jgfb#leb#`kbqb`wfqtfqf#elq`fg#`obpp>!awmgbzp#le#wkfefbwvqfg#jmpkltjmd#wkfjmwfqfpw#jmjm#sob`f#lewvqm#le#wkfwkf#kfbg#leOlqg#le#wkfslojwj`boozkbp#jwp#ltmFgv`bwjlmbobssqlubo#leplnf#le#wkffb`k#lwkfq/afkbujlq#lebmg#af`bvpfbmg#bmlwkfqbssfbqfg#lmqf`lqgfg#jmaob`h%rvlw8nbz#jm`ovgfwkf#tlqog$p`bm#ofbg#wlqfefqp#wl#balqgfq>!3!#dlufqmnfmw#tjmmjmd#wkfqfpvowfg#jm#tkjof#wkf#Tbpkjmdwlm/wkf#pvaif`w`jwz#jm#wkf=?,gju=\x0e\t\n\nqfeof`w#wkfwl#`lnsofwfaf`bnf#nlqfqbgjlb`wjufqfif`wfg#aztjwklvw#bmzkjp#ebwkfq/tkj`k#`lvog`lsz#le#wkfwl#jmgj`bwfb#slojwj`bob``lvmwp#le`lmpwjwvwfptlqhfg#tjwkfq?,b=?,oj=le#kjp#ojefb``lnsbmjfg`ojfmwTjgwksqfufmw#wkfOfdjpobwjufgjeefqfmwozwldfwkfq#jmkbp#pfufqboelq#bmlwkfqwf{w#le#wkfelvmgfg#wkff#tjwk#wkf#jp#vpfg#elq`kbmdfg#wkfvpvbooz#wkfsob`f#tkfqftkfqfbp#wkf=#?b#kqfe>!!=?b#kqfe>!wkfnpfoufp/bowklvdk#kfwkbw#`bm#afwqbgjwjlmboqlof#le#wkfbp#b#qfpvowqfnluf@kjoggfpjdmfg#aztfpw#le#wkfPlnf#sflsofsqlgv`wjlm/pjgf#le#wkfmftpofwwfqpvpfg#az#wkfgltm#wl#wkfb``fswfg#azojuf#jm#wkfbwwfnswp#wllvwpjgf#wkfeqfrvfm`jfpKltfufq/#jmsqldqbnnfqpbw#ofbpw#jmbssql{jnbwfbowklvdk#jwtbp#sbqw#lebmg#ubqjlvpDlufqmlq#lewkf#bqwj`ofwvqmfg#jmwl=?b#kqfe>!,wkf#f`lmlnzjp#wkf#nlpwnlpw#tjgfoztlvog#obwfqbmg#sfqkbspqjpf#wl#wkfl``vqp#tkfmvmgfq#tkj`k`lmgjwjlmp-wkf#tfpwfqmwkflqz#wkbwjp#sqlgv`fgwkf#`jwz#lejm#tkj`k#kfpffm#jm#wkfwkf#`fmwqboavjogjmd#lenbmz#le#kjpbqfb#le#wkfjp#wkf#lmoznlpw#le#wkfnbmz#le#wkfwkf#TfpwfqmWkfqf#jp#mlf{wfmgfg#wlPwbwjpwj`bo`lopsbm>1#\x7fpklqw#pwlqzslppjaof#wlwlsloldj`bo`qjwj`bo#leqfslqwfg#wlb#@kqjpwjbmgf`jpjlm#wljp#frvbo#wlsqlaofnp#leWkjp#`bm#afnfq`kbmgjpfelq#nlpw#leml#fujgfm`ffgjwjlmp#lefofnfmwp#jm%rvlw8-#Wkf`ln,jnbdfp,tkj`k#nbhfpwkf#sql`fppqfnbjmp#wkfojwfqbwvqf/jp#b#nfnafqwkf#slsvobqwkf#bm`jfmwsqlaofnp#jmwjnf#le#wkfgfefbwfg#azalgz#le#wkfb#eft#zfbqpnv`k#le#wkfwkf#tlqh#le@bojelqmjb/pfqufg#bp#bdlufqmnfmw-`lm`fswp#lenlufnfmw#jm\n\n?gju#jg>!jw!#ubovf>!obmdvbdf#lebp#wkfz#bqfsqlgv`fg#jmjp#wkbw#wkff{sobjm#wkfgju=?,gju=\tKltfufq#wkfofbg#wl#wkf\n?b#kqfe>!,tbp#dqbmwfgsflsof#kbuf`lmwjmvbooztbp#pffm#bpbmg#qfobwfgwkf#qlof#lesqlslpfg#azle#wkf#afpwfb`k#lwkfq-@lmpwbmwjmfsflsof#eqlngjbof`wp#lewl#qfujpjlmtbp#qfmbnfgb#plvq`f#lewkf#jmjwjboobvm`kfg#jmsqlujgf#wkfwl#wkf#tfpwtkfqf#wkfqfbmg#pjnjobqafwtffm#wtljp#bopl#wkfFmdojpk#bmg`lmgjwjlmp/wkbw#jw#tbpfmwjwofg#wlwkfnpfoufp-rvbmwjwz#leqbmpsbqfm`zwkf#pbnf#bpwl#iljm#wkf`lvmwqz#bmgwkjp#jp#wkfWkjp#ofg#wlb#pwbwfnfmw`lmwqbpw#wlobpwJmgf{Lewkqlvdk#kjpjp#gfpjdmfgwkf#wfqn#jpjp#sqlujgfgsqlwf`w#wkfmd?,b=?,oj=Wkf#`vqqfmwwkf#pjwf#lepvapwbmwjbof{sfqjfm`f/jm#wkf#Tfpwwkfz#pklvogpolufm(ajmb`lnfmwbqjlpvmjufqpjgbg`lmgj`jlmfpb`wjujgbgfpf{sfqjfm`jbwf`mlold/Absqlgv``j/_msvmwvb`j/_mbsoj`b`j/_m`lmwqbpf/]b`bwfdlq/Abpqfdjpwqbqpfsqlefpjlmbowqbwbnjfmwlqfd/Apwqbwfpf`qfwbq/Absqjm`jsbofpsqlwf``j/_mjnslqwbmwfpjnslqwbm`jbslpjajojgbgjmwfqfpbmwf`qf`jnjfmwlmf`fpjgbgfppvp`qjajqpfbpl`jb`j/_mgjpslmjaofpfubovb`j/_mfpwvgjbmwfpqfpslmpbaofqfplov`j/_mdvbgbobibqbqfdjpwqbglplslqwvmjgbg`lnfq`jbofpelwldqbe/Abbvwlqjgbgfpjmdfmjfq/Abwfofujpj/_m`lnsfwfm`jblsfqb`jlmfpfpwbaof`jglpjnsofnfmwfb`wvbonfmwfmbufdb`j/_m`lmelqnjgbgojmf.kfjdkw9elmw.ebnjoz9!#9#!kwws9,,bssoj`bwjlmpojmh!#kqfe>!psf`jej`booz,,?"X@GBWBX\tLqdbmjybwjlmgjpwqjavwjlm3s{8#kfjdkw9qfobwjlmpkjsgfuj`f.tjgwk?gju#`obpp>!?obafo#elq>!qfdjpwqbwjlm?,mlp`qjsw=\t,jmgf{-kwno!tjmglt-lsfm+#"jnslqwbmw8bssoj`bwjlm,jmgfsfmgfm`f,,ttt-dlldoflqdbmjybwjlmbvwl`lnsofwfqfrvjqfnfmwp`lmpfqubwjuf?elqn#mbnf>!jmwfoof`wvbonbqdjm.ofew92;wk#`fmwvqzbm#jnslqwbmwjmpwjwvwjlmpbaaqfujbwjlm?jnd#`obpp>!lqdbmjpbwjlm`jujojybwjlm2:wk#`fmwvqzbq`kjwf`wvqfjm`lqslqbwfg13wk#`fmwvqz.`lmwbjmfq!=nlpw#mlwbaoz,=?,b=?,gju=mlwjej`bwjlm$vmgfejmfg$*Evqwkfqnlqf/afojfuf#wkbwjmmfqKWNO#>#sqjlq#wl#wkfgqbnbwj`boozqfefqqjmd#wlmfdlwjbwjlmpkfbgrvbqwfqpPlvwk#Beqj`bvmpv``fppevoSfmmpzoubmjbBp#b#qfpvow/?kwno#obmd>!%ow8,pvs%dw8gfbojmd#tjwkskjobgfoskjbkjpwlqj`booz*8?,p`qjsw=\tsbggjmd.wls9f{sfqjnfmwbodfwBwwqjavwfjmpwqv`wjlmpwf`kmloldjfpsbqw#le#wkf#>evm`wjlm+*xpvap`qjswjlmo-gwg!=\x0e\t?kwdfldqbskj`bo@lmpwjwvwjlm$/#evm`wjlm+pvsslqwfg#azbdqj`vowvqbo`lmpwqv`wjlmsvaoj`bwjlmpelmw.pjyf9#2b#ubqjfwz#le?gju#pwzof>!Fm`z`olsfgjbjeqbnf#pq`>!gfnlmpwqbwfgb``lnsojpkfgvmjufqpjwjfpGfnldqbskj`p*8?,p`qjsw=?gfgj`bwfg#wlhmltofgdf#lepbwjpeb`wjlmsbqwj`vobqoz?,gju=?,gju=Fmdojpk#+VP*bssfmg@kjog+wqbmpnjppjlmp-#Kltfufq/#jmwfoojdfm`f!#wbajmgf{>!eolbw9qjdkw8@lnnlmtfbowkqbmdjmd#eqlnjm#tkj`k#wkfbw#ofbpw#lmfqfsqlgv`wjlmfm`z`olsfgjb8elmw.pjyf92ivqjpgj`wjlmbw#wkbw#wjnf!=?b#`obpp>!Jm#bggjwjlm/gfp`qjswjlm(`lmufqpbwjlm`lmwb`w#tjwkjp#dfmfqboozq!#`lmwfmw>!qfsqfpfmwjmd%ow8nbwk%dw8sqfpfmwbwjlml``bpjlmbooz?jnd#tjgwk>!mbujdbwjlm!=`lnsfmpbwjlm`kbnsjlmpkjsnfgjb>!boo!#ujlobwjlm#leqfefqfm`f#wlqfwvqm#wqvf8Pwqj`w,,FM!#wqbmpb`wjlmpjmwfqufmwjlmufqjej`bwjlmJmelqnbwjlm#gjeej`vowjfp@kbnsjlmpkjs`bsbajojwjfp?"Xfmgje^..=~\t?,p`qjsw=\t@kqjpwjbmjwzelq#f{bnsof/Sqlefppjlmboqfpwqj`wjlmppvddfpw#wkbwtbp#qfofbpfg+pv`k#bp#wkfqfnluf@obpp+vmfnsolznfmwwkf#Bnfqj`bmpwqv`wvqf#le,jmgf{-kwno#svaojpkfg#jmpsbm#`obpp>!!=?b#kqfe>!,jmwqlgv`wjlmafolmdjmd#wl`objnfg#wkbw`lmpfrvfm`fp?nfwb#mbnf>!Dvjgf#wl#wkflufqtkfonjmdbdbjmpw#wkf#`lm`fmwqbwfg/\t-mlmwlv`k#lapfqubwjlmp?,b=\t?,gju=\te#+gl`vnfmw-alqgfq9#2s{#xelmw.pjyf92wqfbwnfmw#le3!#kfjdkw>!2nlgjej`bwjlmJmgfsfmgfm`fgjujgfg#jmwldqfbwfq#wkbmb`kjfufnfmwpfpwbaojpkjmdIbubP`qjsw!#mfufqwkfofpppjdmjej`bm`fAqlbg`bpwjmd=%maps8?,wg=`lmwbjmfq!=\tpv`k#bp#wkf#jmeovfm`f#leb#sbqwj`vobqpq`>$kwws9,,mbujdbwjlm!#kboe#le#wkf#pvapwbmwjbo#%maps8?,gju=bgubmwbdf#legjp`lufqz#leevmgbnfmwbo#nfwqlslojwbmwkf#lsslpjwf!#{no9obmd>!gfojafqbwfozbojdm>`fmwfqfulovwjlm#lesqfpfqubwjlmjnsqlufnfmwpafdjmmjmd#jmIfpvp#@kqjpwSvaoj`bwjlmpgjpbdqffnfmwwf{w.bojdm9q/#evm`wjlm+*pjnjobqjwjfpalgz=?,kwno=jp#`vqqfmwozboskbafwj`bojp#plnfwjnfpwzsf>!jnbdf,nbmz#le#wkf#eolt9kjggfm8bubjobaof#jmgfp`qjaf#wkff{jpwfm`f#leboo#lufq#wkfwkf#Jmwfqmfw\n?vo#`obpp>!jmpwboobwjlmmfjdkalqkllgbqnfg#elq`fpqfgv`jmd#wkf`lmwjmvfp#wlMlmfwkfofpp/wfnsfqbwvqfp\t\n\n?b#kqfe>!`olpf#wl#wkff{bnsofp#le#jp#balvw#wkf+pff#afolt*-!#jg>!pfbq`ksqlefppjlmbojp#bubjobaofwkf#leej`jbo\n\n?,p`qjsw=\t\t\n\n?gju#jg>!b``fofqbwjlmwkqlvdk#wkf#Kboo#le#Ebnfgfp`qjswjlmpwqbmpobwjlmpjmwfqefqfm`f#wzsf>$wf{w,qf`fmw#zfbqpjm#wkf#tlqogufqz#slsvobqxab`hdqlvmg9wqbgjwjlmbo#plnf#le#wkf#`lmmf`wfg#wlf{soljwbwjlmfnfqdfm`f#le`lmpwjwvwjlmB#Kjpwlqz#lepjdmjej`bmw#nbmveb`wvqfgf{sf`wbwjlmp=?mlp`qjsw=?`bm#af#elvmgaf`bvpf#wkf#kbp#mlw#affmmfjdkalvqjmdtjwklvw#wkf#bggfg#wl#wkf\n?oj#`obpp>!jmpwqvnfmwboPlujfw#Vmjlmb`hmltofgdfgtkj`k#`bm#afmbnf#elq#wkfbwwfmwjlm#wlbwwfnswp#wl#gfufolsnfmwpJm#eb`w/#wkf?oj#`obpp>!bjnsoj`bwjlmppvjwbaof#elqnv`k#le#wkf#`lolmjybwjlmsqfpjgfmwjbo`bm`foAvaaof#Jmelqnbwjlmnlpw#le#wkf#jp#gfp`qjafgqfpw#le#wkf#nlqf#lq#ofppjm#PfswfnafqJmwfoojdfm`fpq`>!kwws9,,s{8#kfjdkw9#bubjobaof#wlnbmveb`wvqfqkvnbm#qjdkwpojmh#kqfe>!,bubjobajojwzsqlslqwjlmbolvwpjgf#wkf#bpwqlmlnj`bokvnbm#afjmdpmbnf#le#wkf#bqf#elvmg#jmbqf#abpfg#lmpnboofq#wkbmb#sfqplm#tklf{sbmpjlm#lebqdvjmd#wkbwmlt#hmltm#bpJm#wkf#fbqozjmwfqnfgjbwfgfqjufg#eqlnP`bmgjmbujbm?,b=?,gju=\x0e\t`lmpjgfq#wkfbm#fpwjnbwfgwkf#Mbwjlmbo?gju#jg>!sbdqfpvowjmd#jm`lnnjppjlmfgbmboldlvp#wlbqf#qfrvjqfg,vo=\t?,gju=\ttbp#abpfg#lmbmg#af`bnf#b%maps8%maps8w!#ubovf>!!#tbp#`bswvqfgml#nlqf#wkbmqfpsf`wjufoz`lmwjmvf#wl#=\x0e\t?kfbg=\x0e\t?tfqf#`qfbwfgnlqf#dfmfqbojmelqnbwjlm#vpfg#elq#wkfjmgfsfmgfmw#wkf#Jnsfqjbo`lnslmfmw#lewl#wkf#mlqwkjm`ovgf#wkf#@lmpwqv`wjlmpjgf#le#wkf#tlvog#mlw#afelq#jmpwbm`fjmufmwjlm#lenlqf#`lnsof{`loof`wjufozab`hdqlvmg9#wf{w.bojdm9#jwp#lqjdjmbojmwl#b``lvmwwkjp#sql`fppbm#f{wfmpjufkltfufq/#wkfwkfz#bqf#mlwqfif`wfg#wkf`qjwj`jpn#legvqjmd#tkj`ksqlabaoz#wkfwkjp#bqwj`of+evm`wjlm+*xJw#pklvog#afbm#bdqffnfmwb``jgfmwboozgjeefqp#eqlnBq`kjwf`wvqfafwwfq#hmltmbqqbmdfnfmwpjmeovfm`f#lmbwwfmgfg#wkfjgfmwj`bo#wlplvwk#le#wkfsbpp#wkqlvdk{no!#wjwof>!tfjdkw9alog8`qfbwjmd#wkfgjpsobz9mlmfqfsob`fg#wkf?jnd#pq`>!,jkwwsp9,,ttt-Tlqog#Tbq#JJwfpwjnlmjbopelvmg#jm#wkfqfrvjqfg#wl#bmg#wkbw#wkfafwtffm#wkf#tbp#gfpjdmfg`lmpjpwp#le#`lmpjgfqbaozsvaojpkfg#azwkf#obmdvbdf@lmpfqubwjlm`lmpjpwfg#leqfefq#wl#wkfab`h#wl#wkf#`pp!#nfgjb>!Sflsof#eqln#bubjobaof#lmsqlufg#wl#afpvddfpwjlmp!tbp#hmltm#bpubqjfwjfp#leojhfoz#wl#af`lnsqjpfg#lepvsslqw#wkf#kbmgp#le#wkf`lvsofg#tjwk`lmmf`w#bmg#alqgfq9mlmf8sfqelqnbm`fpafelqf#afjmdobwfq#af`bnf`bo`vobwjlmplewfm#`boofgqfpjgfmwp#lenfbmjmd#wkbw=?oj#`obpp>!fujgfm`f#elqf{sobmbwjlmpfmujqlmnfmwp!=?,b=?,gju=tkj`k#booltpJmwqlgv`wjlmgfufolsfg#azb#tjgf#qbmdflm#afkboe#leubojdm>!wls!sqjm`jsof#lebw#wkf#wjnf/?,mlp`qjsw=\x0epbjg#wl#kbufjm#wkf#ejqpwtkjof#lwkfqpkzslwkfwj`boskjolplskfqpsltfq#le#wkf`lmwbjmfg#jmsfqelqnfg#azjmbajojwz#wltfqf#tqjwwfmpsbm#pwzof>!jmsvw#mbnf>!wkf#rvfpwjlmjmwfmgfg#elqqfif`wjlm#lejnsojfp#wkbwjmufmwfg#wkfwkf#pwbmgbqgtbp#sqlabaozojmh#afwtffmsqlefpplq#lejmwfqb`wjlmp`kbmdjmd#wkfJmgjbm#L`fbm#`obpp>!obpwtlqhjmd#tjwk$kwws9,,ttt-zfbqp#afelqfWkjp#tbp#wkfqf`qfbwjlmbofmwfqjmd#wkfnfbpvqfnfmwpbm#f{wqfnfozubovf#le#wkfpwbqw#le#wkf\t?,p`qjsw=\t\tbm#feelqw#wljm`qfbpf#wkfwl#wkf#plvwkpsb`jmd>!3!=pveej`jfmwozwkf#Fvqlsfbm`lmufqwfg#wl`ofbqWjnflvwgjg#mlw#kbuf`lmpfrvfmwozelq#wkf#mf{wf{wfmpjlm#lef`lmlnj`#bmgbowklvdk#wkfbqf#sqlgv`fgbmg#tjwk#wkfjmpveej`jfmwdjufm#az#wkfpwbwjmd#wkbwf{sfmgjwvqfp?,psbm=?,b=\twklvdkw#wkbwlm#wkf#abpjp`foosbggjmd>jnbdf#le#wkfqfwvqmjmd#wljmelqnbwjlm/pfsbqbwfg#azbppbppjmbwfgp!#`lmwfmw>!bvwklqjwz#lemlqwktfpwfqm?,gju=\t?gju#!=?,gju=\x0e\t##`lmpvowbwjlm`lnnvmjwz#lewkf#mbwjlmbojw#pklvog#afsbqwj`jsbmwp#bojdm>!ofewwkf#dqfbwfpwpfof`wjlm#lepvsfqmbwvqbogfsfmgfmw#lmjp#nfmwjlmfgbooltjmd#wkftbp#jmufmwfgb``lnsbmzjmdkjp#sfqplmbobubjobaof#bwpwvgz#le#wkflm#wkf#lwkfqf{f`vwjlm#leKvnbm#Qjdkwpwfqnp#le#wkfbppl`jbwjlmpqfpfbq`k#bmgpv``ffgfg#azgfefbwfg#wkfbmg#eqln#wkfavw#wkfz#bqf`lnnbmgfq#lepwbwf#le#wkfzfbqp#le#bdfwkf#pwvgz#le?vo#`obpp>!psob`f#jm#wkftkfqf#kf#tbp?oj#`obpp>!ewkfqf#bqf#mltkj`k#af`bnfkf#svaojpkfgf{sqfppfg#jmwl#tkj`k#wkf`lnnjppjlmfqelmw.tfjdkw9wfqqjwlqz#lef{wfmpjlmp!=Qlnbm#Fnsjqffrvbo#wl#wkfJm#`lmwqbpw/kltfufq/#bmgjp#wzsj`boozbmg#kjp#tjef+bopl#`boofg=?vo#`obpp>!feef`wjufoz#fuloufg#jmwlpffn#wl#kbuftkj`k#jp#wkfwkfqf#tbp#mlbm#f{`foofmwboo#le#wkfpfgfp`qjafg#azJm#sqb`wj`f/aqlbg`bpwjmd`kbqdfg#tjwkqfeof`wfg#jmpvaif`wfg#wlnjojwbqz#bmgwl#wkf#sljmwf`lmlnj`boozpfwWbqdfwjmdbqf#b`wvboozuj`wlqz#lufq+*8?,p`qjsw=`lmwjmvlvpozqfrvjqfg#elqfulovwjlmbqzbm#feef`wjufmlqwk#le#wkf/#tkj`k#tbp#eqlmw#le#wkflq#lwkfqtjpfplnf#elqn#lekbg#mlw#affmdfmfqbwfg#azjmelqnbwjlm-sfqnjwwfg#wljm`ovgfp#wkfgfufolsnfmw/fmwfqfg#jmwlwkf#sqfujlvp`lmpjpwfmwozbqf#hmltm#bpwkf#ejfog#lewkjp#wzsf#ledjufm#wl#wkfwkf#wjwof#le`lmwbjmp#wkfjmpwbm`fp#lejm#wkf#mlqwkgvf#wl#wkfjqbqf#gfpjdmfg`lqslqbwjlmptbp#wkbw#wkflmf#le#wkfpfnlqf#slsvobqpv``ffgfg#jmpvsslqw#eqlnjm#gjeefqfmwglnjmbwfg#azgfpjdmfg#elqltmfqpkjs#lebmg#slppjaozpwbmgbqgjyfgqfpslmpfWf{wtbp#jmwfmgfgqf`fjufg#wkfbppvnfg#wkbwbqfbp#le#wkfsqjnbqjoz#jmwkf#abpjp#lejm#wkf#pfmpfb``lvmwp#elqgfpwqlzfg#azbw#ofbpw#wtltbp#gf`obqfg`lvog#mlw#afPf`qfwbqz#lebssfbq#wl#afnbqdjm.wls92,]_p(\x7f_p(\',df*xwkqlt#f~8wkf#pwbqw#lewtl#pfsbqbwfobmdvbdf#bmgtkl#kbg#affmlsfqbwjlm#legfbwk#le#wkfqfbo#mvnafqp\n?ojmh#qfo>!sqlujgfg#wkfwkf#pwlqz#le`lnsfwjwjlmpfmdojpk#+VH*fmdojpk#+VP*<p<R<Q<_<R<W<M=l<S=m<V<T=m=l<S=m<V<T=m=l<S=m<V<R5h4U4]4D5f4E\nAO\x05Gx\bTA\nzk\vBl\bQ\x7f\bTA\nzk\vUm\bQ\x7f\bTA\nzk\npe\x05u|\ti@\tcT\bVV\n\\}\nxS\tVp\x05tS\x05k`\t[X\t[X\vHR\bPv\bTW\bUe\n\x7fa\bQp\v_W\vWs\nxS\vAz\n_y\x04Khjmelqnb`j/_mkfqqbnjfmwbpfof`wq/_mj`lgfp`qjs`j/_m`obpjej`bglp`lml`jnjfmwlsvaoj`b`j/_mqfob`jlmbgbpjmelqn/Mwj`bqfob`jlmbglpgfsbqwbnfmwlwqbabibglqfpgjqf`wbnfmwfbzvmwbnjfmwlnfq`bglOjaqf`lmw/M`wfmlpkbajwb`jlmfp`vnsojnjfmwlqfpwbvqbmwfpgjpslpj`j/_m`lmpf`vfm`jbfof`wq/_mj`bbsoj`b`jlmfpgfp`lmf`wbgljmpwbob`j/_mqfbojyb`j/_mvwjojyb`j/_mfm`j`olsfgjbfmefqnfgbgfpjmpwqvnfmwlpf{sfqjfm`jbpjmpwjwv`j/_msbqwj`vobqfppva`bwfdlqjb=n<R<W=`<V<R<L<R=m=m<T<T=l<\\<]<R=n=g<]<R<W=`=d<Y<S=l<R=m=n<R<P<R<Z<Y=n<Y<X=l=o<_<T=i=m<W=o=k<\\<Y=m<Y<U=k<\\=m<^=m<Y<_<X<\\<L<R=m=m<T=c<p<R=m<V<^<Y<X=l=o<_<T<Y<_<R=l<R<X<\\<^<R<S=l<R=m<X<\\<Q<Q=g=i<X<R<W<Z<Q=g<T<P<Y<Q<Q<R<p<R=m<V<^=g=l=o<]<W<Y<U<p<R=m<V<^<\\=m=n=l<\\<Q=g<Q<T=k<Y<_<R=l<\\<]<R=n<Y<X<R<W<Z<Y<Q=o=m<W=o<_<T=n<Y<S<Y=l=`<r<X<Q<\\<V<R<S<R=n<R<P=o=l<\\<]<R=n=o<\\<S=l<Y<W=c<^<R<R<]=e<Y<R<X<Q<R<_<R=m<^<R<Y<_<R=m=n<\\=n=`<T<X=l=o<_<R<U=h<R=l=o<P<Y=i<R=l<R=d<R<S=l<R=n<T<^=m=m=g<W<V<\\<V<\\<Z<X=g<U<^<W<\\=m=n<T<_=l=o<S<S=g<^<P<Y=m=n<Y=l<\\<]<R=n<\\=m<V<\\<[<\\<W<S<Y=l<^=g<U<X<Y<W<\\=n=`<X<Y<Q=`<_<T<S<Y=l<T<R<X<]<T<[<Q<Y=m<R=m<Q<R<^<Y<P<R<P<Y<Q=n<V=o<S<T=n=`<X<R<W<Z<Q<\\=l<\\<P<V<\\=i<Q<\\=k<\\<W<R<L<\\<]<R=n<\\<N<R<W=`<V<R=m<R<^=m<Y<P<^=n<R=l<R<U<Q<\\=k<\\<W<\\=m<S<T=m<R<V=m<W=o<Z<]=g=m<T=m=n<Y<P<S<Y=k<\\=n<T<Q<R<^<R<_<R<S<R<P<R=e<T=m<\\<U=n<R<^<S<R=k<Y<P=o<S<R<P<R=e=`<X<R<W<Z<Q<R=m=m=g<W<V<T<]=g=m=n=l<R<X<\\<Q<Q=g<Y<P<Q<R<_<T<Y<S=l<R<Y<V=n<M<Y<U=k<\\=m<P<R<X<Y<W<T=n<\\<V<R<_<R<R<Q<W<\\<U<Q<_<R=l<R<X<Y<^<Y=l=m<T=c=m=n=l<\\<Q<Y=h<T<W=`<P=g=o=l<R<^<Q=c=l<\\<[<Q=g=i<T=m<V<\\=n=`<Q<Y<X<Y<W=b=c<Q<^<\\=l=c<P<Y<Q=`=d<Y<P<Q<R<_<T=i<X<\\<Q<Q<R<U<[<Q<\\=k<T=n<Q<Y<W=`<[=c=h<R=l=o<P<\\<N<Y<S<Y=l=`<P<Y=m=c=j<\\<[<\\=e<T=n=g<w=o=k=d<T<Y\fHD\fHU\fIl\fHn\fHy\fH\\\fHD\fIk\fHi\fHF\fHD\fIk\fHy\fHS\fHC\fHR\fHy\fH\\\fIk\fHn\fHi\fHD\fIa\fHC\fHy\fIa\fHC\fHR\fH{\fHR\fHk\fHM\fH@\fHR\fH\\\fIk\fHy\fHS\fHT\fIl\fHJ\fHS\fHC\fHR\fHF\fHU\fH^\fIk\fHT\fHS\fHn\fHU\fHA\fHR\fH\\\fHH\fHi\fHF\fHD\fIl\fHY\fHR\fH^\fIk\fHT\fIk\fHY\fHR\fHy\fH\\\fHH\fIk\fHB\fIk\fH\\\fIk\fHU\fIg\fHD\fIk\fHT\fHy\fHH\fIk\fH@\fHU\fIm\fHH\fHT\fHR\fHk\fHs\fHU\fIg\fH{\fHR\fHp\fHR\fHD\fIk\fHB\fHS\fHD\fHs\fHy\fH\\\fHH\fHR\fHy\fH\\\fHD\fHR\fHe\fHD\fHy\fIk\fHC\fHU\fHR\fHm\fHT\fH@\fHT\fIk\fHA\fHR\fH[\fHR\fHj\fHF\fHy\fIk\fH^\fHS\fHC\fIk\fHZ\fIm\fH\\\fIn\fHk\fHT\fHy\fIk\fHt\fHn\fHs\fIk\fHB\fIk\fH\\\fIl\fHT\fHy\fHH\fHR\fHB\fIk\fH\\\fHR\fH^\fIk\fHy\fH\\\fHi\fHK\fHS\fHy\fHi\fHF\fHD\fHR\fHT\fHB\fHR\fHp\fHB\fIm\fHq\fIk\fHy\fHR\fH\\\fHO\fHU\fIg\fHH\fHR\fHy\fHM\fHP\fIl\fHC\fHU\fHR\fHn\fHU\fIg\fHs\fH^\fHZ\fH@\fIa\fHJ\fH^\fHS\fHC\fHR\fHp\fIl\fHY\fHD\fHp\fHR\fHH\fHR\fHy\fId\fHT\fIk\fHj\fHF\fHy\fHR\fHY\fHR\fH^\fIl\fHJ\fIk\fHD\fIk\fHF\fIn\fH\\\fIl\fHF\fHR\fHD\fIl\fHe\fHT\fHy\fIk\fHU\fIg\fH{\fIl\fH@\fId\fHL\fHy\fHj\fHF\fHy\fIl\fHY\fH\\\fIa\fH[\fH{\fHR\fHn\fHY\fHj\fHF\fHy\fIg\fHp\fHS\fH^\fHR\fHp\fHR\fHD\fHR\fHT\fHU\fHB\fHH\fHU\fHB\fIk\fHn\fHe\fHD\fHy\fIl\fHC\fHR\fHU\fIn\fHJ\fH\\\fIa\fHp\fHT\fIn\fHv\fIl\fHF\fHT\fHn\fHJ\fHT\fHY\fHR\fH^\fHU\fIg\fHD\fHR\fHU\fIg\fHH\fIl\fHp\fId\fHT\fIk\fHY\fHR\fHF\fHT\fHp\fHD\fHH\fHR\fHD\fIk\fHH\fHR\fHp\fHR\fH\\\fIl\fHt\fHR\fHC\fH^\fHp\fHS\fH^\fIk\fHD\fIl\fHv\fIk\fHp\fHR\fHn\fHv\fHF\fHH\fIa\fH\\\fH{\fIn\fH{\fH^\fHp\fHR\fHH\fIk\fH@\fHR\fHU\fH\\\fHj\fHF\fHD\fIk\fHY\fHR\fHU\fHD\fHk\fHT\fHy\fHR\fHT\fIm\fH@\fHU\fH\\\fHU\fHD\fIk\fHk\fHT\fHT\fIk\fHT\fHU\fHS\fHH\fH@\fHM\fHP\fIk\fHt\fHs\fHD\fHR\fHH\fH^\fHR\fHZ\fHF\fHR\fHn\fHv\fHZ\fIa\fH\\\fIl\fH@\fHM\fHP\fIl\fHU\fIg\fHH\fIk\fHT\fHR\fHd\fHs\fHZ\fHR\fHC\fHJ\fHT\fHy\fHH\fIl\fHp\fHR\fHH\fIl\fHY\fHR\fH^\fHR\fHU\fHp\fHR\fH\\\fHF\fHs\fHD\fHR\fH\\\fHz\fHD\fIk\fHT\fHM\fHP\fHy\fHB\fHS\fH^\fHR\fHe\fHT\fHy\fIl\fHy\fIk\fHY\fH^\fH^\fH{\fHH\fHR\fHz\fHR\fHD\fHR\fHi\fH\\\fIa\fHI\fHp\fHU\fHR\fHn\fHJ\fIk\fHz\fHR\fHF\fHU\fH^\fIl\fHD\fHS\fHC\fHB\fH@\fHS\fHD\fHR\fH@\fId\fHn\fHy\fHy\fHU\fIl\fHn\fHy\fHU\fHD\fHR\fHJ\fIk\fHH\fHR\fHU\fHB\fH^\fIk\fHy\fHR\fHG\fIl\fHp\fH@\fHy\fHS\fHH\fIm\fH\\\fHH\fHB\fHR\fHn\fH{\fHY\fHU\fIl\fHn\fH\\\fIg\fHp\fHP\fHB\fHS\fH^\fIl\fHj\fH\\\fIg\fHF\fHT\fIk\fHD\fHR\fHC\fHR\fHJ\fHY\fH^\fIk\fHD\fIk\fHz\fHR\fHH\fHR\fHy\fH\\\fIl\fH@\fHe\fHD\fHy\fHR\fHp\fHY\fHR\fH@\fHF\fIn\fH\\\fHR\fH@\fHM\fHP\fHR\fHT\fI`\fHJ\fHR\fHZ\fIk\fHC\fH\\\fHy\fHS\fHC\fIk\fHy\fHU\fHR\fHn\fHi\fHy\fHT\fH\\\fH@\fHD\fHR\fHc\fHY\fHU\fHR\fHn\fHT\fIa\fHI\fH^\fHB\fHS\fH^\fIk\fH^\fIk\fHz\fHy\fHY\fHS\fH[\fHC\fHy\fIa\fH\\\fHn\fHT\fHB\fIn\fHU\fHI\fHR\fHD\fHR4F4_4F4[5f4U5i4X4K4]5o4E4D5d4K4_4[4E4K5h4Y5m4A4E5i5d4K4Z5f4U4K5h4B4K4Y4E4K5h5i4^5f4C4K5h4U4K5i4E4K5h5o4K4F4D4K5h4]4C5d4C4D4]5j4K5i4@4K5h4C5d5h4E4K5h4U4K5h5i4K5h5i5d5n4U4K5h4U4]4D5f4K5h4_4]5f4U4K5h4@5d4K5h4K5h4\\5k4K4D4K5h4A5f4K4E4K5h4A5n5d5n4K5h5o4]5f5i4K5h4U4]4K5n5i4A5m5d4T4E4K5h4G4K5j5f5i4X4K5k4C4E4K5h5i4]4O4E4K5h5n4]4N5j4K5h4X4D4K4D4K5h4A5d4K4]4K5h4@4C5f4C4K5h4O4_4]4E4K5h4U5h5d5i5i4@5i5d4U4E4K5h4]4A5i5j4K5h5j5n4K4[5m5h4_4[5f5j4K5h5o5d5f4F4K5h4C5j5f4K4D4]5o4K4F5k4K5h4]5f4K4Z4F4A5f4K4F5f4D4F5d5n5f4F4K5h4O5d5h5e4K5h4D4]5f4C4K5h5o5h4K5i4K5h4]4K4D4[4K5h4X4B4Y5f4_5f4K4]4K4F4K5h4G4K5h4G4K5h4Y5h4K4E4K5h4A4C5f4G4K5h4^5d4K4]4K5h4B5h5f4@4K5h4@5i5f4U4K5h4U4K5i5k4K5h4@5i4K5h4K5h4_4K4U4E5i4X4K5k4C5k4K5h4]4J5f4_4K5h4C4B5d5h4K5h5m5j5f4E4K5h5o4F4K4D4K5h4C5d4]5f4K5h4C4]5d4_4K4_4F4V4]5n4F4Y4K5i5f5i4K5h4D5j4K4F4K5h4U4T5f5ifmwfqwbjmnfmwvmgfqpwbmgjmd#>#evm`wjlm+*-isd!#tjgwk>!`lmejdvqbwjlm-smd!#tjgwk>!?algz#`obpp>!Nbwk-qbmgln+*`lmwfnslqbqz#Vmjwfg#Pwbwfp`jq`vnpwbm`fp-bssfmg@kjog+lqdbmjybwjlmp?psbm#`obpp>!!=?jnd#pq`>!,gjpwjmdvjpkfgwklvpbmgp#le#`lnnvmj`bwjlm`ofbq!=?,gju=jmufpwjdbwjlmebuj`lm-j`l!#nbqdjm.qjdkw9abpfg#lm#wkf#Nbppb`kvpfwwpwbaof#alqgfq>jmwfqmbwjlmbobopl#hmltm#bpsqlmvm`jbwjlmab`hdqlvmg9 esbggjmd.ofew9Elq#f{bnsof/#njp`foobmflvp%ow8,nbwk%dw8spz`kloldj`bojm#sbqwj`vobqfbq`k!#wzsf>!elqn#nfwklg>!bp#lsslpfg#wlPvsqfnf#@lvqwl``bpjlmbooz#Bggjwjlmbooz/Mlqwk#Bnfqj`bs{8ab`hdqlvmglsslqwvmjwjfpFmwfqwbjmnfmw-wlOltfq@bpf+nbmveb`wvqjmdsqlefppjlmbo#`lnajmfg#tjwkElq#jmpwbm`f/`lmpjpwjmd#le!#nb{ofmdwk>!qfwvqm#ebopf8`lmp`jlvpmfppNfgjwfqqbmfbmf{wqblqgjmbqzbppbppjmbwjlmpvapfrvfmwoz#avwwlm#wzsf>!wkf#mvnafq#lewkf#lqjdjmbo#`lnsqfkfmpjufqfefqp#wl#wkf?,vo=\t?,gju=\tskjolplskj`bool`bwjlm-kqfetbp#svaojpkfgPbm#Eqbm`jp`l+evm`wjlm+*x\t?gju#jg>!nbjmplskjpwj`bwfgnbwkfnbwj`bo#,kfbg=\x0e\t?algzpvddfpwp#wkbwgl`vnfmwbwjlm`lm`fmwqbwjlmqfobwjlmpkjspnbz#kbuf#affm+elq#f{bnsof/Wkjp#bqwj`of#jm#plnf#`bpfpsbqwp#le#wkf#gfejmjwjlm#leDqfbw#Aqjwbjm#`foosbggjmd>frvjubofmw#wlsob`fklogfq>!8#elmw.pjyf9#ivpwjej`bwjlmafojfufg#wkbwpveefqfg#eqlnbwwfnswfg#wl#ofbgfq#le#wkf`qjsw!#pq`>!,+evm`wjlm+*#xbqf#bubjobaof\t\n?ojmh#qfo>!#pq`>$kwws9,,jmwfqfpwfg#jm`lmufmwjlmbo#!#bow>!!#,=?,bqf#dfmfqboozkbp#bopl#affmnlpw#slsvobq#`lqqfpslmgjmd`qfgjwfg#tjwkwzof>!alqgfq9?,b=?,psbm=?,-dje!#tjgwk>!?jeqbnf#pq`>!wbaof#`obpp>!jmojmf.aol`h8b``lqgjmd#wl#wldfwkfq#tjwkbssql{jnbwfozsbqojbnfmwbqznlqf#bmg#nlqfgjpsobz9mlmf8wqbgjwjlmboozsqfglnjmbmwoz%maps8\x7f%maps8%maps8?,psbm=#`foopsb`jmd>?jmsvw#mbnf>!lq!#`lmwfmw>!`lmwqlufqpjbosqlsfqwz>!ld9,{.pkl`htbuf.gfnlmpwqbwjlmpvqqlvmgfg#azMfufqwkfofpp/tbp#wkf#ejqpw`lmpjgfqbaof#Bowklvdk#wkf#`loobalqbwjlmpklvog#mlw#afsqlslqwjlm#le?psbm#pwzof>!hmltm#bp#wkf#pklqwoz#bewfqelq#jmpwbm`f/gfp`qjafg#bp#,kfbg=\t?algz#pwbqwjmd#tjwkjm`qfbpjmdoz#wkf#eb`w#wkbwgjp`vppjlm#lenjggof#le#wkfbm#jmgjujgvbogjeej`vow#wl#sljmw#le#ujftklnlpf{vbojwzb``fswbm`f#le?,psbm=?,gju=nbmveb`wvqfqplqjdjm#le#wkf`lnnlmoz#vpfgjnslqwbm`f#legfmlnjmbwjlmpab`hdqlvmg9# ofmdwk#le#wkfgfwfqnjmbwjlmb#pjdmjej`bmw!#alqgfq>!3!=qfulovwjlmbqzsqjm`jsofp#lejp#`lmpjgfqfgtbp#gfufolsfgJmgl.Fvqlsfbmuvomfqbaof#wlsqlslmfmwp#lebqf#plnfwjnfp`olpfq#wl#wkfMft#Zlqh#@jwz#mbnf>!pfbq`kbwwqjavwfg#wl`lvqpf#le#wkfnbwkfnbwj`jbmaz#wkf#fmg#lebw#wkf#fmg#le!#alqgfq>!3!#wf`kmloldj`bo-qfnluf@obpp+aqbm`k#le#wkffujgfm`f#wkbw"Xfmgje^..=\x0e\tJmpwjwvwf#le#jmwl#b#pjmdofqfpsf`wjufoz-bmg#wkfqfelqfsqlsfqwjfp#lejp#ol`bwfg#jmplnf#le#tkj`kWkfqf#jp#bopl`lmwjmvfg#wl#bssfbqbm`f#le#%bns8mgbpk8#gfp`qjafp#wkf`lmpjgfqbwjlmbvwklq#le#wkfjmgfsfmgfmwozfrvjssfg#tjwkglfp#mlw#kbuf?,b=?b#kqfe>!`lmevpfg#tjwk?ojmh#kqfe>!,bw#wkf#bdf#lebssfbq#jm#wkfWkfpf#jm`ovgfqfdbqgofpp#le`lvog#af#vpfg#pwzof>%rvlw8pfufqbo#wjnfpqfsqfpfmw#wkfalgz=\t?,kwno=wklvdkw#wl#afslsvobwjlm#leslppjajojwjfpsfq`fmwbdf#leb``fpp#wl#wkfbm#bwwfnsw#wlsqlgv`wjlm#leirvfqz,irvfqzwtl#gjeefqfmwafolmd#wl#wkffpwbaojpknfmwqfsob`jmd#wkfgfp`qjswjlm!#gfwfqnjmf#wkfbubjobaof#elqB``lqgjmd#wl#tjgf#qbmdf#le\n?gju#`obpp>!nlqf#`lnnlmozlqdbmjpbwjlmpevm`wjlmbojwztbp#`lnsofwfg#%bns8ngbpk8#sbqwj`jsbwjlmwkf#`kbqb`wfqbm#bggjwjlmbobssfbqp#wl#afeb`w#wkbw#wkfbm#f{bnsof#lepjdmjej`bmwozlmnlvpflufq>!af`bvpf#wkfz#bpzm`#>#wqvf8sqlaofnp#tjwkpffnp#wl#kbufwkf#qfpvow#le#pq`>!kwws9,,ebnjojbq#tjwkslppfppjlm#leevm`wjlm#+*#xwllh#sob`f#jmbmg#plnfwjnfppvapwbmwjbooz?psbm=?,psbm=jp#lewfm#vpfgjm#bm#bwwfnswdqfbw#gfbo#leFmujqlmnfmwbopv``fppevooz#ujqwvbooz#boo13wk#`fmwvqz/sqlefppjlmbopmf`fppbqz#wl#gfwfqnjmfg#az`lnsbwjajojwzaf`bvpf#jw#jpGj`wjlmbqz#lenlgjej`bwjlmpWkf#elooltjmdnbz#qfefq#wl9@lmpfrvfmwoz/Jmwfqmbwjlmbobowklvdk#plnfwkbw#tlvog#aftlqog$p#ejqpw`obppjejfg#bpalwwln#le#wkf+sbqwj`vobqozbojdm>!ofew!#nlpw#`lnnlmozabpjp#elq#wkfelvmgbwjlm#le`lmwqjavwjlmpslsvobqjwz#le`fmwfq#le#wkfwl#qfgv`f#wkfivqjpgj`wjlmpbssql{jnbwjlm#lmnlvpflvw>!Mft#Wfpwbnfmw`loof`wjlm#le?,psbm=?,b=?,jm#wkf#Vmjwfgejon#gjqf`wlq.pwqj`w-gwg!=kbp#affm#vpfgqfwvqm#wl#wkfbowklvdk#wkjp`kbmdf#jm#wkfpfufqbo#lwkfqavw#wkfqf#bqfvmsqf`fgfmwfgjp#pjnjobq#wlfpsf`jbooz#jmtfjdkw9#alog8jp#`boofg#wkf`lnsvwbwjlmbojmgj`bwf#wkbwqfpwqj`wfg#wl\n?nfwb#mbnf>!bqf#wzsj`booz`lmeoj`w#tjwkKltfufq/#wkf#Bm#f{bnsof#le`lnsbqfg#tjwkrvbmwjwjfp#leqbwkfq#wkbm#b`lmpwfoobwjlmmf`fppbqz#elqqfslqwfg#wkbwpsf`jej`bwjlmslojwj`bo#bmg%maps8%maps8?qfefqfm`fp#wlwkf#pbnf#zfbqDlufqmnfmw#ledfmfqbwjlm#lekbuf#mlw#affmpfufqbo#zfbqp`lnnjwnfmw#wl\n\n?vo#`obpp>!ujpvbojybwjlm2:wk#`fmwvqz/sqb`wjwjlmfqpwkbw#kf#tlvogbmg#`lmwjmvfgl``vsbwjlm#lejp#gfejmfg#bp`fmwqf#le#wkfwkf#bnlvmw#le=?gju#pwzof>!frvjubofmw#legjeefqfmwjbwfaqlvdkw#balvwnbqdjm.ofew9#bvwlnbwj`boozwklvdkw#le#bpPlnf#le#wkfpf\t?gju#`obpp>!jmsvw#`obpp>!qfsob`fg#tjwkjp#lmf#le#wkffgv`bwjlm#bmgjmeovfm`fg#azqfsvwbwjlm#bp\t?nfwb#mbnf>!b``lnnlgbwjlm?,gju=\t?,gju=obqdf#sbqw#leJmpwjwvwf#elqwkf#pl.`boofg#bdbjmpw#wkf#Jm#wkjp#`bpf/tbp#bssljmwfg`objnfg#wl#afKltfufq/#wkjpGfsbqwnfmw#lewkf#qfnbjmjmdfeef`w#lm#wkfsbqwj`vobqoz#gfbo#tjwk#wkf\t?gju#pwzof>!bonlpw#botbzpbqf#`vqqfmwozf{sqfppjlm#leskjolplskz#leelq#nlqf#wkbm`jujojybwjlmplm#wkf#jpobmgpfof`wfgJmgf{`bm#qfpvow#jm!#ubovf>!!#,=wkf#pwqv`wvqf#,=?,b=?,gju=Nbmz#le#wkfpf`bvpfg#az#wkfle#wkf#Vmjwfgpsbm#`obpp>!n`bm#af#wqb`fgjp#qfobwfg#wlaf`bnf#lmf#lejp#eqfrvfmwozojujmd#jm#wkfwkflqfwj`boozElooltjmd#wkfQfulovwjlmbqzdlufqmnfmw#jmjp#gfwfqnjmfgwkf#slojwj`bojmwqlgv`fg#jmpveej`jfmw#wlgfp`qjswjlm!=pklqw#pwlqjfppfsbqbwjlm#lebp#wl#tkfwkfqhmltm#elq#jwptbp#jmjwjboozgjpsobz9aol`hjp#bm#f{bnsofwkf#sqjm`jsbo`lmpjpwp#le#bqf`ldmjyfg#bp,algz=?,kwno=b#pvapwbmwjboqf`lmpwqv`wfgkfbg#le#pwbwfqfpjpwbm`f#wlvmgfqdqbgvbwfWkfqf#bqf#wtldqbujwbwjlmbobqf#gfp`qjafgjmwfmwjlmboozpfqufg#bp#wkf`obpp>!kfbgfqlsslpjwjlm#wlevmgbnfmwboozglnjmbwfg#wkfbmg#wkf#lwkfqboojbm`f#tjwktbp#elq`fg#wlqfpsf`wjufoz/bmg#slojwj`bojm#pvsslqw#lesflsof#jm#wkf13wk#`fmwvqz-bmg#svaojpkfgolbg@kbqwafbwwl#vmgfqpwbmgnfnafq#pwbwfpfmujqlmnfmwboejqpw#kboe#le`lvmwqjfp#bmgbq`kjwf`wvqboaf#`lmpjgfqfg`kbqb`wfqjyfg`ofbqJmwfqubobvwklqjwbwjufEfgfqbwjlm#letbp#pv``ffgfgbmg#wkfqf#bqfb#`lmpfrvfm`fwkf#Sqfpjgfmwbopl#jm`ovgfgeqff#plewtbqfpv``fppjlm#legfufolsfg#wkftbp#gfpwqlzfgbtbz#eqln#wkf8\t?,p`qjsw=\t?bowklvdk#wkfzelooltfg#az#bnlqf#sltfqevoqfpvowfg#jm#bVmjufqpjwz#leKltfufq/#nbmzwkf#sqfpjgfmwKltfufq/#plnfjp#wklvdkw#wlvmwjo#wkf#fmgtbp#bmmlvm`fgbqf#jnslqwbmwbopl#jm`ovgfp=?jmsvw#wzsf>wkf#`fmwfq#le#GL#MLW#BOWFQvpfg#wl#qfefqwkfnfp,<plqw>wkbw#kbg#affmwkf#abpjp#elqkbp#gfufolsfgjm#wkf#pvnnfq`lnsbqbwjufozgfp`qjafg#wkfpv`k#bp#wklpfwkf#qfpvowjmdjp#jnslppjaofubqjlvp#lwkfqPlvwk#Beqj`bmkbuf#wkf#pbnffeef`wjufmfppjm#tkj`k#`bpf8#wf{w.bojdm9pwqv`wvqf#bmg8#ab`hdqlvmg9qfdbqgjmd#wkfpvsslqwfg#wkfjp#bopl#hmltmpwzof>!nbqdjmjm`ovgjmd#wkfabkbpb#Nfobzvmlqph#alhn/Iomlqph#mzmlqphpolufm)M(ajmbjmwfqmb`jlmbo`bojej`b`j/_m`lnvmj`b`j/_m`lmpwqv``j/_m!=?gju#`obpp>!gjpbnajdvbwjlmGlnbjmMbnf$/#$bgnjmjpwqbwjlmpjnvowbmflvpozwqbmpslqwbwjlmJmwfqmbwjlmbo#nbqdjm.alwwln9qfpslmpjajojwz?"Xfmgje^..=\t?,=?nfwb#mbnf>!jnsofnfmwbwjlmjmeqbpwqv`wvqfqfsqfpfmwbwjlmalqgfq.alwwln9?,kfbg=\t?algz=>kwws&0B&1E&1E?elqn#nfwklg>!nfwklg>!slpw!#,ebuj`lm-j`l!#~*8\t?,p`qjsw=\t-pfwBwwqjavwf+Bgnjmjpwqbwjlm>#mft#Bqqbz+*8?"Xfmgje^..=\x0e\tgjpsobz9aol`h8Vmelqwvmbwfoz/!=%maps8?,gju=,ebuj`lm-j`l!=>$pwzofpkffw$#jgfmwjej`bwjlm/#elq#f{bnsof/?oj=?b#kqfe>!,bm#bowfqmbwjufbp#b#qfpvow#lesw!=?,p`qjsw=\twzsf>!pvanjw!#\t+evm`wjlm+*#xqf`lnnfmgbwjlmelqn#b`wjlm>!,wqbmpelqnbwjlmqf`lmpwqv`wjlm-pwzof-gjpsobz#B``lqgjmd#wl#kjggfm!#mbnf>!bolmd#tjwk#wkfgl`vnfmw-algz-bssql{jnbwfoz#@lnnvmj`bwjlmpslpw!#b`wjlm>!nfbmjmd#%rvlw8..?"Xfmgje^..=Sqjnf#Njmjpwfq`kbqb`wfqjpwj`?,b=#?b#`obpp>wkf#kjpwlqz#le#lmnlvpflufq>!wkf#dlufqmnfmwkqfe>!kwwsp9,,tbp#lqjdjmbooztbp#jmwqlgv`fg`obppjej`bwjlmqfsqfpfmwbwjufbqf#`lmpjgfqfg?"Xfmgje^..=\t\tgfsfmgp#lm#wkfVmjufqpjwz#le#jm#`lmwqbpw#wl#sob`fklogfq>!jm#wkf#`bpf#lejmwfqmbwjlmbo#`lmpwjwvwjlmbopwzof>!alqgfq.9#evm`wjlm+*#xAf`bvpf#le#wkf.pwqj`w-gwg!=\t?wbaof#`obpp>!b``lnsbmjfg#azb``lvmw#le#wkf?p`qjsw#pq`>!,mbwvqf#le#wkf#wkf#sflsof#jm#jm#bggjwjlm#wlp*8#ip-jg#>#jg!#tjgwk>!233&!qfdbqgjmd#wkf#Qlnbm#@bwkloj`bm#jmgfsfmgfmwelooltjmd#wkf#-dje!#tjgwk>!2wkf#elooltjmd#gjp`qjnjmbwjlmbq`kbfloldj`bosqjnf#njmjpwfq-ip!=?,p`qjsw=`lnajmbwjlm#le#nbqdjmtjgwk>!`qfbwfFofnfmw+t-bwwb`kFufmw+?,b=?,wg=?,wq=pq`>!kwwsp9,,bJm#sbqwj`vobq/#bojdm>!ofew!#@yf`k#Qfsvaoj`Vmjwfg#Hjmdgln`lqqfpslmgfm`f`lm`ovgfg#wkbw-kwno!#wjwof>!+evm`wjlm#+*#x`lnfp#eqln#wkfbssoj`bwjlm#le?psbm#`obpp>!pafojfufg#wl#affnfmw+$p`qjsw$?,b=\t?,oj=\t?ojufqz#gjeefqfmw=?psbm#`obpp>!lswjlm#ubovf>!+bopl#hmltm#bp\n?oj=?b#kqfe>!=?jmsvw#mbnf>!pfsbqbwfg#eqlnqfefqqfg#wl#bp#ubojdm>!wls!=elvmgfq#le#wkfbwwfnswjmd#wl#`bqalm#gjl{jgf\t\t?gju#`obpp>!`obpp>!pfbq`k.,algz=\t?,kwno=lsslqwvmjwz#wl`lnnvmj`bwjlmp?,kfbg=\x0e\t?algz#pwzof>!tjgwk9Wj\rVSmd#Uj\rWkw`kbmdfp#jm#wkfalqgfq.`lolq9 3!#alqgfq>!3!#?,psbm=?,gju=?tbp#gjp`lufqfg!#wzsf>!wf{w!#*8\t?,p`qjsw=\t\tGfsbqwnfmw#le#f``ofpjbpwj`bowkfqf#kbp#affmqfpvowjmd#eqln?,algz=?,kwno=kbp#mfufq#affmwkf#ejqpw#wjnfjm#qfpslmpf#wlbvwlnbwj`booz#?,gju=\t\t?gju#jtbp#`lmpjgfqfgsfq`fmw#le#wkf!#,=?,b=?,gju=`loof`wjlm#le#gfp`fmgfg#eqlnpf`wjlm#le#wkfb``fsw.`kbqpfwwl#af#`lmevpfgnfnafq#le#wkf#sbggjmd.qjdkw9wqbmpobwjlm#lejmwfqsqfwbwjlm#kqfe>$kwws9,,tkfwkfq#lq#mlwWkfqf#bqf#boplwkfqf#bqf#nbmzb#pnboo#mvnafqlwkfq#sbqwp#lejnslppjaof#wl##`obpp>!avwwlmol`bwfg#jm#wkf-#Kltfufq/#wkfbmg#fufmwvboozBw#wkf#fmg#le#af`bvpf#le#jwpqfsqfpfmwp#wkf?elqn#b`wjlm>!#nfwklg>!slpw!jw#jp#slppjaofnlqf#ojhfoz#wlbm#jm`qfbpf#jmkbuf#bopl#affm`lqqfpslmgp#wlbmmlvm`fg#wkbwbojdm>!qjdkw!=nbmz#`lvmwqjfpelq#nbmz#zfbqpfbqojfpw#hmltmaf`bvpf#jw#tbpsw!=?,p`qjsw=\x0e#ubojdm>!wls!#jmkbajwbmwp#leelooltjmd#zfbq\x0e\t?gju#`obpp>!njoojlm#sflsof`lmwqlufqpjbo#`lm`fqmjmd#wkfbqdvf#wkbw#wkfdlufqmnfmw#bmgb#qfefqfm`f#wlwqbmpefqqfg#wlgfp`qjajmd#wkf#pwzof>!`lolq9bowklvdk#wkfqfafpw#hmltm#elqpvanjw!#mbnf>!nvowjsoj`bwjlmnlqf#wkbm#lmf#qf`ldmjwjlm#le@lvm`jo#le#wkffgjwjlm#le#wkf##?nfwb#mbnf>!Fmwfqwbjmnfmw#btbz#eqln#wkf#8nbqdjm.qjdkw9bw#wkf#wjnf#lejmufpwjdbwjlmp`lmmf`wfg#tjwkbmg#nbmz#lwkfqbowklvdk#jw#jpafdjmmjmd#tjwk#?psbm#`obpp>!gfp`fmgbmwp#le?psbm#`obpp>!j#bojdm>!qjdkw!?,kfbg=\t?algz#bpsf`wp#le#wkfkbp#pjm`f#affmFvqlsfbm#Vmjlmqfnjmjp`fmw#lenlqf#gjeej`vowUj`f#Sqfpjgfmw`lnslpjwjlm#lesbppfg#wkqlvdknlqf#jnslqwbmwelmw.pjyf922s{f{sobmbwjlm#lewkf#`lm`fsw#letqjwwfm#jm#wkf\n?psbm#`obpp>!jp#lmf#le#wkf#qfpfnaobm`f#wllm#wkf#dqlvmgptkj`k#`lmwbjmpjm`ovgjmd#wkf#gfejmfg#az#wkfsvaoj`bwjlm#lenfbmp#wkbw#wkflvwpjgf#le#wkfpvsslqw#le#wkf?jmsvw#`obpp>!?psbm#`obpp>!w+Nbwk-qbmgln+*nlpw#sqlnjmfmwgfp`qjswjlm#le@lmpwbmwjmlsoftfqf#svaojpkfg?gju#`obpp>!pfbssfbqp#jm#wkf2!#kfjdkw>!2!#nlpw#jnslqwbmwtkj`k#jm`ovgfptkj`k#kbg#affmgfpwqv`wjlm#lewkf#slsvobwjlm\t\n?gju#`obpp>!slppjajojwz#leplnfwjnfp#vpfgbssfbq#wl#kbufpv``fpp#le#wkfjmwfmgfg#wl#afsqfpfmw#jm#wkfpwzof>!`ofbq9a\x0e\t?,p`qjsw=\x0e\t?tbp#elvmgfg#jmjmwfqujft#tjwk\\jg!#`lmwfmw>!`bsjwbo#le#wkf\x0e\t?ojmh#qfo>!pqfofbpf#le#wkfsljmw#lvw#wkbw{NOKwwsQfrvfpwbmg#pvapfrvfmwpf`lmg#obqdfpwufqz#jnslqwbmwpsf`jej`bwjlmppvqeb`f#le#wkfbssojfg#wl#wkfelqfjdm#sloj`z\\pfwGlnbjmMbnffpwbaojpkfg#jmjp#afojfufg#wlJm#bggjwjlm#wlnfbmjmd#le#wkfjp#mbnfg#bewfqwl#sqlwf`w#wkfjp#qfsqfpfmwfgGf`obqbwjlm#lenlqf#feej`jfmw@obppjej`bwjlmlwkfq#elqnp#lekf#qfwvqmfg#wl?psbm#`obpp>!`sfqelqnbm`f#le+evm`wjlm+*#x\x0eje#bmg#lmoz#jeqfdjlmp#le#wkfofbgjmd#wl#wkfqfobwjlmp#tjwkVmjwfg#Mbwjlmppwzof>!kfjdkw9lwkfq#wkbm#wkfzsf!#`lmwfmw>!Bppl`jbwjlm#le\t?,kfbg=\t?algzol`bwfg#lm#wkfjp#qfefqqfg#wl+jm`ovgjmd#wkf`lm`fmwqbwjlmpwkf#jmgjujgvbobnlmd#wkf#nlpwwkbm#bmz#lwkfq,=\t?ojmh#qfo>!#qfwvqm#ebopf8wkf#svqslpf#lewkf#bajojwz#wl8`lolq9 eee~\t-\t?psbm#`obpp>!wkf#pvaif`w#legfejmjwjlmp#le=\x0e\t?ojmh#qfo>!`objn#wkbw#wkfkbuf#gfufolsfg?wbaof#tjgwk>!`fofaqbwjlm#leElooltjmd#wkf#wl#gjpwjmdvjpk?psbm#`obpp>!awbhfp#sob`f#jmvmgfq#wkf#mbnfmlwfg#wkbw#wkf=?"Xfmgje^..=\tpwzof>!nbqdjm.jmpwfbg#le#wkfjmwqlgv`fg#wkfwkf#sql`fpp#lejm`qfbpjmd#wkfgjeefqfm`fp#jmfpwjnbwfg#wkbwfpsf`jbooz#wkf,gju=?gju#jg>!tbp#fufmwvboozwkqlvdklvw#kjpwkf#gjeefqfm`fplnfwkjmd#wkbwpsbm=?,psbm=?,pjdmjej`bmwoz#=?,p`qjsw=\x0e\t\x0e\tfmujqlmnfmwbo#wl#sqfufmw#wkfkbuf#affm#vpfgfpsf`jbooz#elqvmgfqpwbmg#wkfjp#fppfmwjbooztfqf#wkf#ejqpwjp#wkf#obqdfpwkbuf#affm#nbgf!#pq`>!kwws9,,jmwfqsqfwfg#bppf`lmg#kboe#le`qloojmd>!ml!#jp#`lnslpfg#leJJ/#Kloz#Qlnbmjp#f{sf`wfg#wlkbuf#wkfjq#ltmgfejmfg#bp#wkfwqbgjwjlmbooz#kbuf#gjeefqfmwbqf#lewfm#vpfgwl#fmpvqf#wkbwbdqffnfmw#tjwk`lmwbjmjmd#wkfbqf#eqfrvfmwozjmelqnbwjlm#lmf{bnsof#jp#wkfqfpvowjmd#jm#b?,b=?,oj=?,vo=#`obpp>!ellwfqbmg#fpsf`jboozwzsf>!avwwlm!#?,psbm=?,psbm=tkj`k#jm`ovgfg=\t?nfwb#mbnf>!`lmpjgfqfg#wkf`bqqjfg#lvw#azKltfufq/#jw#jpaf`bnf#sbqw#lejm#qfobwjlm#wlslsvobq#jm#wkfwkf#`bsjwbo#letbp#leej`jbooztkj`k#kbp#affmwkf#Kjpwlqz#lebowfqmbwjuf#wlgjeefqfmw#eqlnwl#pvsslqw#wkfpvddfpwfg#wkbwjm#wkf#sql`fpp##?gju#`obpp>!wkf#elvmgbwjlmaf`bvpf#le#kjp`lm`fqmfg#tjwkwkf#vmjufqpjwzlsslpfg#wl#wkfwkf#`lmwf{w#le?psbm#`obpp>!swf{w!#mbnf>!r!\n\n?gju#`obpp>!wkf#p`jfmwjej`qfsqfpfmwfg#aznbwkfnbwj`jbmpfof`wfg#az#wkfwkbw#kbuf#affm=?gju#`obpp>!`gju#jg>!kfbgfqjm#sbqwj`vobq/`lmufqwfg#jmwl*8\t?,p`qjsw=\t?skjolplskj`bo#pqsphlkqubwphjwj\rVSmd#Uj\rWkw<L=o=m=m<V<T<U=l=o=m=m<V<T<Ujmufpwjdb`j/_msbqwj`jsb`j/_m<V<R=n<R=l=g<Y<R<]<W<\\=m=n<T<V<R=n<R=l=g<U=k<Y<W<R<^<Y<V=m<T=m=n<Y<P=g<q<R<^<R=m=n<T<V<R=n<R=l=g=i<R<]<W<\\=m=n=`<^=l<Y<P<Y<Q<T<V<R=n<R=l<\\=c=m<Y<_<R<X<Q=c=m<V<\\=k<\\=n=`<Q<R<^<R=m=n<T<O<V=l<\\<T<Q=g<^<R<S=l<R=m=g<V<R=n<R=l<R<U=m<X<Y<W<\\=n=`<S<R<P<R=e=`=b=m=l<Y<X=m=n<^<R<]=l<\\<[<R<P=m=n<R=l<R<Q=g=o=k<\\=m=n<T<Y=n<Y=k<Y<Q<T<Y<\x7f<W<\\<^<Q<\\=c<T=m=n<R=l<T<T=m<T=m=n<Y<P<\\=l<Y=d<Y<Q<T=c<M<V<\\=k<\\=n=`<S<R=a=n<R<P=o=m<W<Y<X=o<Y=n=m<V<\\<[<\\=n=`=n<R<^<\\=l<R<^<V<R<Q<Y=k<Q<R=l<Y=d<Y<Q<T<Y<V<R=n<R=l<R<Y<R=l<_<\\<Q<R<^<V<R=n<R=l<R<P<L<Y<V<W<\\<P<\\4K5h5i5j4F4C5e5i5j4F4C5f4K4F4K5h5i5d4Z5d4U4K5h4D4]4K5i4@4K5h5i5d4K5n4U4K5h4]4_4K4J5h5i4X4K4]5o4K4F4K5h4O4U4Z4K4M4K5h4]5f4K4Z4E4K5h4F4Y5i5f5i4K5h4K4U4Z4K4M4K5h5j4F4K4J4@4K5h4O5h4U4K4D4K5h4F4_4@5f5h4K5h4O5n4_4K5i4K5h4Z4V4[4K4F4K5h5m5f4C5f5d4K5h4F4]4A5f4D4K5h4@4C5f4C4E4K5h4F4U5h5f5i4K5h4O4B4D4K4]4K5h4K5m5h4K5i4K5h4O5m5h4K5i4K5h4F4K4]5f4B4K5h4F5n5j5f4E4K5h4K5h4U4K4D4K5h4B5d4K4[4]4K5h5i4@4F5i4U4K5h4C5f5o5d4]4K5h4_5f4K4A4E4U4D4C4K5h5h5k4K5h4F4]4D5f4E4K5h4]5d4K4D4[4K5h4O4C4D5f4E4K5h4K4B4D4K4]4K5h5i4F4A4C4E4K5h4K4V4K5j5f`vqplq9sljmwfq8?,wjwof=\t?nfwb#!#kqfe>!kwws9,,!=?psbm#`obpp>!nfnafqp#le#wkf#tjmglt-ol`bwjlmufqwj`bo.bojdm9,b=#\x7f#?b#kqfe>!?"gl`wzsf#kwno=nfgjb>!p`qffm!#?lswjlm#ubovf>!ebuj`lm-j`l!#,=\t\n\n?gju#`obpp>!`kbqb`wfqjpwj`p!#nfwklg>!dfw!#,algz=\t?,kwno=\tpklqw`vw#j`lm!#gl`vnfmw-tqjwf+sbggjmd.alwwln9qfsqfpfmwbwjufppvanjw!#ubovf>!bojdm>!`fmwfq!#wkqlvdklvw#wkf#p`jfm`f#ej`wjlm\t##?gju#`obpp>!pvanjw!#`obpp>!lmf#le#wkf#nlpw#ubojdm>!wls!=?tbp#fpwbaojpkfg*8\x0e\t?,p`qjsw=\x0e\tqfwvqm#ebopf8!=*-pwzof-gjpsobzaf`bvpf#le#wkf#gl`vnfmw-`llhjf?elqn#b`wjlm>!,~algzxnbqdjm938Fm`z`olsfgjb#leufqpjlm#le#wkf#-`qfbwfFofnfmw+mbnf!#`lmwfmw>!?,gju=\t?,gju=\t\tbgnjmjpwqbwjuf#?,algz=\t?,kwno=kjpwlqz#le#wkf#!=?jmsvw#wzsf>!slqwjlm#le#wkf#bp#sbqw#le#wkf#%maps8?b#kqfe>!lwkfq#`lvmwqjfp!=\t?gju#`obpp>!?,psbm=?,psbm=?Jm#lwkfq#tlqgp/gjpsobz9#aol`h8`lmwqlo#le#wkf#jmwqlgv`wjlm#le,=\t?nfwb#mbnf>!bp#tfoo#bp#wkf#jm#qf`fmw#zfbqp\x0e\t\n?gju#`obpp>!?,gju=\t\n?,gju=\tjmpsjqfg#az#wkfwkf#fmg#le#wkf#`lnsbwjaof#tjwkaf`bnf#hmltm#bp#pwzof>!nbqdjm9-ip!=?,p`qjsw=?#Jmwfqmbwjlmbo#wkfqf#kbuf#affmDfqnbm#obmdvbdf#pwzof>!`lolq9 @lnnvmjpw#Sbqwz`lmpjpwfmw#tjwkalqgfq>!3!#`foo#nbqdjmkfjdkw>!wkf#nbilqjwz#le!#bojdm>!`fmwfqqfobwfg#wl#wkf#nbmz#gjeefqfmw#Lqwklgl{#@kvq`kpjnjobq#wl#wkf#,=\t?ojmh#qfo>!ptbp#lmf#le#wkf#vmwjo#kjp#gfbwk~*+*8\t?,p`qjsw=lwkfq#obmdvbdfp`lnsbqfg#wl#wkfslqwjlmp#le#wkfwkf#Mfwkfqobmgpwkf#nlpw#`lnnlmab`hdqlvmg9vqo+bqdvfg#wkbw#wkfp`qloojmd>!ml!#jm`ovgfg#jm#wkfMlqwk#Bnfqj`bm#wkf#mbnf#le#wkfjmwfqsqfwbwjlmpwkf#wqbgjwjlmbogfufolsnfmw#le#eqfrvfmwoz#vpfgb#`loof`wjlm#leufqz#pjnjobq#wlpvqqlvmgjmd#wkff{bnsof#le#wkjpbojdm>!`fmwfq!=tlvog#kbuf#affmjnbdf\\`bswjlm#>bwwb`kfg#wl#wkfpvddfpwjmd#wkbwjm#wkf#elqn#le#jmuloufg#jm#wkfjp#gfqjufg#eqlnmbnfg#bewfq#wkfJmwqlgv`wjlm#wlqfpwqj`wjlmp#lm#pwzof>!tjgwk9#`bm#af#vpfg#wl#wkf#`qfbwjlm#lenlpw#jnslqwbmw#jmelqnbwjlm#bmgqfpvowfg#jm#wkf`loobspf#le#wkfWkjp#nfbmp#wkbwfofnfmwp#le#wkftbp#qfsob`fg#azbmbozpjp#le#wkfjmpsjqbwjlm#elqqfdbqgfg#bp#wkfnlpw#pv``fppevohmltm#bp#%rvlw8b#`lnsqfkfmpjufKjpwlqz#le#wkf#tfqf#`lmpjgfqfgqfwvqmfg#wl#wkfbqf#qfefqqfg#wlVmplvq`fg#jnbdf=\t\n?gju#`obpp>!`lmpjpwp#le#wkfpwlsSqlsbdbwjlmjmwfqfpw#jm#wkfbubjobajojwz#lebssfbqp#wl#kbuffof`wqlnbdmfwj`fmbaofPfquj`fp+evm`wjlm#le#wkfJw#jp#jnslqwbmw?,p`qjsw=?,gju=evm`wjlm+*xubq#qfobwjuf#wl#wkfbp#b#qfpvow#le#wkf#slpjwjlm#leElq#f{bnsof/#jm#nfwklg>!slpw!#tbp#elooltfg#az%bns8ngbpk8#wkfwkf#bssoj`bwjlmip!=?,p`qjsw=\x0e\tvo=?,gju=?,gju=bewfq#wkf#gfbwktjwk#qfpsf`w#wlpwzof>!sbggjmd9jp#sbqwj`vobqozgjpsobz9jmojmf8#wzsf>!pvanjw!#jp#gjujgfg#jmwl\bTA\nzk#+\vBl\bQ\x7f*qfpslmpbajojgbgbgnjmjpwqb`j/_mjmwfqmb`jlmbofp`lqqfpslmgjfmwf\fHe\fHF\fHC\fIg\fH{\fHF\fIn\fH\\\fIa\fHY\fHU\fHB\fHR\fH\\\fIk\fH^\fIg\fH{\fIg\fHn\fHv\fIm\fHD\fHR\fHY\fH^\fIk\fHy\fHS\fHD\fHT\fH\\\fHy\fHR\fH\\\fHF\fIm\fH^\fHS\fHT\fHz\fIg\fHp\fIk\fHn\fHv\fHR\fHU\fHS\fHc\fHA\fIk\fHp\fIk\fHn\fHZ\fHR\fHB\fHS\fH^\fHU\fHB\fHR\fH\\\fIl\fHp\fHR\fH{\fH\\\fHO\fH@\fHD\fHR\fHD\fIk\fHy\fIm\fHB\fHR\fH\\\fH@\fIa\fH^\fIe\fH{\fHB\fHR\fH^\fHS\fHy\fHB\fHU\fHS\fH^\fHR\fHF\fIo\fH[\fIa\fHL\fH@\fHN\fHP\fHH\fIk\fHA\fHR\fHp\fHF\fHR\fHy\fIa\fH^\fHS\fHy\fHs\fIa\fH\\\fIk\fHD\fHz\fHS\fH^\fHR\fHG\fHJ\fI`\fH\\\fHR\fHD\fHB\fHR\fHB\fH^\fIk\fHB\fHH\fHJ\fHR\fHD\fH@\fHR\fHp\fHR\fH\\\fHY\fHS\fHy\fHR\fHT\fHy\fIa\fHC\fIg\fHn\fHv\fHR\fHU\fHH\fIk\fHF\fHU\fIm\fHm\fHv\fH@\fHH\fHR\fHC\fHR\fHT\fHn\fHY\fHR\fHJ\fHJ\fIk\fHz\fHD\fIk\fHF\fHS\fHw\fH^\fIk\fHY\fHS\fHZ\fIk\fH[\fH\\\fHR\fHp\fIa\fHC\fHe\fHH\fIa\fHH\fH\\\fHB\fIm\fHn\fH@\fHd\fHJ\fIg\fHD\fIg\fHn\fHe\fHF\fHy\fH\\\fHO\fHF\fHN\fHP\fIk\fHn\fHT\fIa\fHI\fHS\fHH\fHG\fHS\fH^\fIa\fHB\fHB\fIm\fHz\fIa\fHC\fHi\fHv\fIa\fHw\fHR\fHw\fIn\fHs\fHH\fIl\fHT\fHn\fH{\fIl\fHH\fHp\fHR\fHc\fH{\fHR\fHY\fHS\fHA\fHR\fH{\fHt\fHO\fIa\fHs\fIk\fHJ\fIn\fHT\fH\\\fIk\fHJ\fHS\fHD\fIg\fHn\fHU\fHH\fIa\fHC\fHR\fHT\fIk\fHy\fIa\fHT\fH{\fHR\fHn\fHK\fIl\fHY\fHS\fHZ\fIa\fHY\fH\\\fHR\fHH\fIk\fHn\fHJ\fId\fHs\fIa\fHT\fHD\fHy\fIa\fHZ\fHR\fHT\fHR\fHB\fHD\fIk\fHi\fHJ\fHR\fH^\fHH\fH@\fHS\fHp\fH^\fIl\fHF\fIm\fH\\\fIn\fH[\fHU\fHS\fHn\fHJ\fIl\fHB\fHS\fHH\fIa\fH\\\fHy\fHY\fHS\fHH\fHR\fH\\\fIm\fHF\fHC\fIk\fHT\fIa\fHI\fHR\fHD\fHy\fH\\\fIg\fHM\fHP\fHB\fIm\fHy\fIa\fHH\fHC\fIg\fHp\fHD\fHR\fHy\fIo\fHF\fHC\fHR\fHF\fIg\fHT\fIa\fHs\fHt\fH\\\fIk\fH^\fIn\fHy\fHR\fH\\\fIa\fHC\fHY\fHS\fHv\fHR\fH\\\fHT\fIn\fHv\fHD\fHR\fHB\fIn\fH^\fIa\fHC\fHJ\fIk\fHz\fIk\fHn\fHU\fHB\fIk\fHZ\fHR\fHT\fIa\fHy\fIn\fH^\fHB\fId\fHn\fHD\fIk\fHH\fId\fHC\fHR\fH\\\fHp\fHS\fHT\fHy\fIkqpp({no!#wjwof>!.wzsf!#`lmwfmw>!wjwof!#`lmwfmw>!bw#wkf#pbnf#wjnf-ip!=?,p`qjsw=\t?!#nfwklg>!slpw!#?,psbm=?,b=?,oj=ufqwj`bo.bojdm9w,irvfqz-njm-ip!=-`oj`h+evm`wjlm+#pwzof>!sbggjmd.~*+*8\t?,p`qjsw=\t?,psbm=?b#kqfe>!?b#kqfe>!kwws9,,*8#qfwvqm#ebopf8wf{w.gf`lqbwjlm9#p`qloojmd>!ml!#alqgfq.`loobspf9bppl`jbwfg#tjwk#Abkbpb#JmglmfpjbFmdojpk#obmdvbdf?wf{w#{no9psb`f>-dje!#alqgfq>!3!?,algz=\t?,kwno=\tlufqeolt9kjggfm8jnd#pq`>!kwws9,,bggFufmwOjpwfmfqqfpslmpjaof#elq#p-ip!=?,p`qjsw=\t,ebuj`lm-j`l!#,=lsfqbwjmd#pzpwfn!#pwzof>!tjgwk92wbqdfw>!\\aobmh!=Pwbwf#Vmjufqpjwzwf{w.bojdm9ofew8\tgl`vnfmw-tqjwf+/#jm`ovgjmd#wkf#bqlvmg#wkf#tlqog*8\x0e\t?,p`qjsw=\x0e\t?!#pwzof>!kfjdkw98lufqeolt9kjggfmnlqf#jmelqnbwjlmbm#jmwfqmbwjlmbob#nfnafq#le#wkf#lmf#le#wkf#ejqpw`bm#af#elvmg#jm#?,gju=\t\n\n?,gju=\tgjpsobz9#mlmf8!=!#,=\t?ojmh#qfo>!\t##+evm`wjlm+*#xwkf#26wk#`fmwvqz-sqfufmwGfebvow+obqdf#mvnafq#le#Azybmwjmf#Fnsjqf-isd\x7fwkvna\x7fofew\x7fubpw#nbilqjwz#lenbilqjwz#le#wkf##bojdm>!`fmwfq!=Vmjufqpjwz#Sqfppglnjmbwfg#az#wkfPf`lmg#Tlqog#Tbqgjpwqjavwjlm#le#pwzof>!slpjwjlm9wkf#qfpw#le#wkf#`kbqb`wfqjyfg#az#qfo>!mleloolt!=gfqjufp#eqln#wkfqbwkfq#wkbm#wkf#b#`lnajmbwjlm#lepwzof>!tjgwk9233Fmdojpk.psfbhjmd`lnsvwfq#p`jfm`falqgfq>!3!#bow>!wkf#f{jpwfm`f#leGfnl`qbwj`#Sbqwz!#pwzof>!nbqdjm.Elq#wkjp#qfbplm/-ip!=?,p`qjsw=\t\npAzWbdMbnf+p*X3^ip!=?,p`qjsw=\x0e\t?-ip!=?,p`qjsw=\x0e\tojmh#qfo>!j`lm!#$#bow>$$#`obpp>$elqnbwjlm#le#wkfufqpjlmp#le#wkf#?,b=?,gju=?,gju=,sbdf=\t##?sbdf=\t?gju#`obpp>!`lmwaf`bnf#wkf#ejqpwabkbpb#Jmglmfpjbfmdojpk#+pjnsof*"y"W"W"["Q"U"V"@=i=l<^<\\=n=m<V<T<V<R<P<S<\\<Q<T<T=c<^<W=c<Y=n=m=c<x<R<]<\\<^<T=n=`=k<Y<W<R<^<Y<V<\\=l<\\<[<^<T=n<T=c<t<Q=n<Y=l<Q<Y=n<r=n<^<Y=n<T=n=`<Q<\\<S=l<T<P<Y=l<T<Q=n<Y=l<Q<Y=n<V<R=n<R=l<R<_<R=m=n=l<\\<Q<T=j=g<V<\\=k<Y=m=n<^<Y=o=m<W<R<^<T=c=i<S=l<R<]<W<Y<P=g<S<R<W=o=k<T=n=`=c<^<W=c=b=n=m=c<Q<\\<T<]<R<W<Y<Y<V<R<P<S<\\<Q<T=c<^<Q<T<P<\\<Q<T<Y=m=l<Y<X=m=n<^<\\4K5h5i5d4K4Z5f4U4K5h4]4J5f4_5f4E4K5h4K5j4F5n4K5h5i4X4K4]5o4K4F5o4K5h4_5f4K4]4K4F4K5h5i5o4F5d4D4E4K5h4_4U5d4C5f4E4K4A4Y4K4J5f4K4F4K5h4U4K5h5i5f4E4K5h4Y5d4F5f4K4F4K5h4K5j4F4]5j4F4K5h4F4Y4K5i5f5i4K5h4I4_5h4K5i5f4K5h5i4X4K4]5o4E4K5h5i4]4J5f4K4Fqlalwp!#`lmwfmw>!?gju#jg>!ellwfq!=wkf#Vmjwfg#Pwbwfp?jnd#pq`>!kwws9,,-isd\x7fqjdkw\x7fwkvna\x7f-ip!=?,p`qjsw=\x0e\t?ol`bwjlm-sqlwl`loeqbnfalqgfq>!3!#p!#,=\t?nfwb#mbnf>!?,b=?,gju=?,gju=?elmw.tfjdkw9alog8%rvlw8#bmg#%rvlw8gfsfmgjmd#lm#wkf#nbqdjm938sbggjmd9!#qfo>!mleloolt!#Sqfpjgfmw#le#wkf#wtfmwjfwk#`fmwvqzfujpjlm=\t##?,sbdfJmwfqmfw#F{solqfqb-bpzm`#>#wqvf8\x0e\tjmelqnbwjlm#balvw?gju#jg>!kfbgfq!=!#b`wjlm>!kwws9,,?b#kqfe>!kwwsp9,,?gju#jg>!`lmwfmw!?,gju=\x0e\t?,gju=\x0e\t?gfqjufg#eqln#wkf#?jnd#pq`>$kwws9,,b``lqgjmd#wl#wkf#\t?,algz=\t?,kwno=\tpwzof>!elmw.pjyf9p`qjsw#obmdvbdf>!Bqjbo/#Kfoufwj`b/?,b=?psbm#`obpp>!?,p`qjsw=?p`qjsw#slojwj`bo#sbqwjfpwg=?,wq=?,wbaof=?kqfe>!kwws9,,ttt-jmwfqsqfwbwjlm#leqfo>!pwzofpkffw!#gl`vnfmw-tqjwf+$?`kbqpfw>!vwe.;!=\tafdjmmjmd#le#wkf#qfufbofg#wkbw#wkfwfofujpjlm#pfqjfp!#qfo>!mleloolt!=#wbqdfw>!\\aobmh!=`objnjmd#wkbw#wkfkwws&0B&1E&1Ettt-nbmjefpwbwjlmp#leSqjnf#Njmjpwfq#lejmeovfm`fg#az#wkf`obpp>!`ofbqej{!=,gju=\x0e\t?,gju=\x0e\t\x0e\twkqff.gjnfmpjlmbo@kvq`k#le#Fmdobmgle#Mlqwk#@bqlojmbprvbqf#hjolnfwqfp-bggFufmwOjpwfmfqgjpwjm`w#eqln#wkf`lnnlmoz#hmltm#bpSklmfwj`#Boskbafwgf`obqfg#wkbw#wkf`lmwqloofg#az#wkfAfmibnjm#Eqbmhojmqlof.sobzjmd#dbnfwkf#Vmjufqpjwz#lejm#Tfpwfqm#Fvqlsfsfqplmbo#`lnsvwfqSqlif`w#Dvwfmafqdqfdbqgofpp#le#wkfkbp#affm#sqlslpfgwldfwkfq#tjwk#wkf=?,oj=?oj#`obpp>!jm#plnf#`lvmwqjfpnjm-ip!=?,p`qjsw=le#wkf#slsvobwjlmleej`jbo#obmdvbdf?jnd#pq`>!jnbdfp,jgfmwjejfg#az#wkfmbwvqbo#qfplvq`fp`obppjej`bwjlm#le`bm#af#`lmpjgfqfgrvbmwvn#nf`kbmj`pMfufqwkfofpp/#wkfnjoojlm#zfbqp#bdl?,algz=\x0e\t?,kwno=\x0e"y"W"W"["Q"U"V"@\twbhf#bgubmwbdf#lebmg/#b``lqgjmd#wlbwwqjavwfg#wl#wkfNj`qlplew#Tjmgltpwkf#ejqpw#`fmwvqzvmgfq#wkf#`lmwqlogju#`obpp>!kfbgfqpklqwoz#bewfq#wkfmlwbaof#f{`fswjlmwfmp#le#wklvpbmgppfufqbo#gjeefqfmwbqlvmg#wkf#tlqog-qfb`kjmd#njojwbqzjplobwfg#eqln#wkflsslpjwjlm#wl#wkfwkf#Log#WfpwbnfmwBeqj`bm#Bnfqj`bmpjmpfqwfg#jmwl#wkfpfsbqbwf#eqln#wkfnfwqlslojwbm#bqfbnbhfp#jw#slppjaofb`hmltofgdfg#wkbwbqdvbaoz#wkf#nlpwwzsf>!wf{w,`pp!=\twkf#JmwfqmbwjlmboB``lqgjmd#wl#wkf#sf>!wf{w,`pp!#,=\t`ljm`jgf#tjwk#wkfwtl.wkjqgp#le#wkfGvqjmd#wkjp#wjnf/gvqjmd#wkf#sfqjlgbmmlvm`fg#wkbw#kfwkf#jmwfqmbwjlmbobmg#nlqf#qf`fmwozafojfufg#wkbw#wkf`lmp`jlvpmfpp#bmgelqnfqoz#hmltm#bppvqqlvmgfg#az#wkfejqpw#bssfbqfg#jml``bpjlmbooz#vpfgslpjwjlm9baplovwf8!#wbqdfw>!\\aobmh!#slpjwjlm9qfobwjuf8wf{w.bojdm9`fmwfq8ib{,ojap,irvfqz,2-ab`hdqlvmg.`lolq9 wzsf>!bssoj`bwjlm,bmdvbdf!#`lmwfmw>!?nfwb#kwws.frvju>!Sqjub`z#Sloj`z?,b=f+!&0@p`qjsw#pq`>$!#wbqdfw>!\\aobmh!=Lm#wkf#lwkfq#kbmg/-isd\x7fwkvna\x7fqjdkw\x7f1?,gju=?gju#`obpp>!?gju#pwzof>!eolbw9mjmfwffmwk#`fmwvqz?,algz=\x0e\t?,kwno=\x0e\t?jnd#pq`>!kwws9,,p8wf{w.bojdm9`fmwfqelmw.tfjdkw9#alog8#B``lqgjmd#wl#wkf#gjeefqfm`f#afwtffm!#eqbnfalqgfq>!3!#!#pwzof>!slpjwjlm9ojmh#kqfe>!kwws9,,kwno7,ollpf-gwg!=\tgvqjmd#wkjp#sfqjlg?,wg=?,wq=?,wbaof=`olpfoz#qfobwfg#wlelq#wkf#ejqpw#wjnf8elmw.tfjdkw9alog8jmsvw#wzsf>!wf{w!#?psbm#pwzof>!elmw.lmqfbgzpwbwf`kbmdf\n?gju#`obpp>!`ofbqgl`vnfmw-ol`bwjlm-#Elq#f{bnsof/#wkf#b#tjgf#ubqjfwz#le#?"GL@WZSF#kwno=\x0e\t?%maps8%maps8%maps8!=?b#kqfe>!kwws9,,pwzof>!eolbw9ofew8`lm`fqmfg#tjwk#wkf>kwws&0B&1E&1Ettt-jm#slsvobq#`vowvqfwzsf>!wf{w,`pp!#,=jw#jp#slppjaof#wl#Kbqubqg#Vmjufqpjwzwzofpkffw!#kqfe>!,wkf#nbjm#`kbqb`wfqL{elqg#Vmjufqpjwz##mbnf>!hfztlqgp!#`pwzof>!wf{w.bojdm9wkf#Vmjwfg#Hjmdglnefgfqbo#dlufqmnfmw?gju#pwzof>!nbqdjm#gfsfmgjmd#lm#wkf#gfp`qjswjlm#le#wkf?gju#`obpp>!kfbgfq-njm-ip!=?,p`qjsw=gfpwqv`wjlm#le#wkfpojdkwoz#gjeefqfmwjm#b``lqgbm`f#tjwkwfof`lnnvmj`bwjlmpjmgj`bwfp#wkbw#wkfpklqwoz#wkfqfbewfqfpsf`jbooz#jm#wkf#Fvqlsfbm#`lvmwqjfpKltfufq/#wkfqf#bqfpq`>!kwws9,,pwbwj`pvddfpwfg#wkbw#wkf!#pq`>!kwws9,,ttt-b#obqdf#mvnafq#le#Wfof`lnnvmj`bwjlmp!#qfo>!mleloolt!#wKloz#Qlnbm#Fnsfqlqbonlpw#f{`ovpjufoz!#alqgfq>!3!#bow>!Pf`qfwbqz#le#Pwbwf`vonjmbwjmd#jm#wkf@JB#Tlqog#Eb`wallhwkf#nlpw#jnslqwbmwbmmjufqpbqz#le#wkfpwzof>!ab`hdqlvmg.?oj=?fn=?b#kqfe>!,wkf#Bwobmwj`#L`fbmpwqj`woz#psfbhjmd/pklqwoz#afelqf#wkfgjeefqfmw#wzsfp#lewkf#Lwwlnbm#Fnsjqf=?jnd#pq`>!kwws9,,Bm#Jmwqlgv`wjlm#wl`lmpfrvfm`f#le#wkfgfsbqwvqf#eqln#wkf@lmefgfqbwf#Pwbwfpjmgjdfmlvp#sflsofpSql`ffgjmdp#le#wkfjmelqnbwjlm#lm#wkfwkflqjfp#kbuf#affmjmuloufnfmw#jm#wkfgjujgfg#jmwl#wkqffbgib`fmw#`lvmwqjfpjp#qfpslmpjaof#elqgjpplovwjlm#le#wkf`loobalqbwjlm#tjwktjgfoz#qfdbqgfg#bpkjp#`lmwfnslqbqjfpelvmgjmd#nfnafq#leGlnjmj`bm#Qfsvaoj`dfmfqbooz#b``fswfgwkf#slppjajojwz#lebqf#bopl#bubjobaofvmgfq#`lmpwqv`wjlmqfpwlqbwjlm#le#wkfwkf#dfmfqbo#svaoj`jp#bonlpw#fmwjqfozsbppfp#wkqlvdk#wkfkbp#affm#pvddfpwfg`lnsvwfq#bmg#ujgflDfqnbmj`#obmdvbdfp#b``lqgjmd#wl#wkf#gjeefqfmw#eqln#wkfpklqwoz#bewfqtbqgpkqfe>!kwwsp9,,ttt-qf`fmw#gfufolsnfmwAlbqg#le#Gjqf`wlqp?gju#`obpp>!pfbq`k\x7f#?b#kqfe>!kwws9,,Jm#sbqwj`vobq/#wkfNvowjsof#ellwmlwfplq#lwkfq#pvapwbm`fwklvpbmgp#le#zfbqpwqbmpobwjlm#le#wkf?,gju=\x0e\t?,gju=\x0e\t\x0e\t?b#kqfe>!jmgf{-skstbp#fpwbaojpkfg#jmnjm-ip!=?,p`qjsw=\tsbqwj`jsbwf#jm#wkfb#pwqlmd#jmeovfm`fpwzof>!nbqdjm.wls9qfsqfpfmwfg#az#wkfdqbgvbwfg#eqln#wkfWqbgjwjlmbooz/#wkfFofnfmw+!p`qjsw!*8Kltfufq/#pjm`f#wkf,gju=\t?,gju=\t?gju#ofew8#nbqdjm.ofew9sqlwf`wjlm#bdbjmpw38#ufqwj`bo.bojdm9Vmelqwvmbwfoz/#wkfwzsf>!jnbdf,{.j`lm,gju=\t?gju#`obpp>!#`obpp>!`ofbqej{!=?gju#`obpp>!ellwfq\n\n?,gju=\t\n\n?,gju=\twkf#nlwjlm#sj`wvqf<}=f<W<_<\\=l=m<V<T<]=f<W<_<\\=l=m<V<T<H<Y<X<Y=l<\\=j<T<T<Q<Y=m<V<R<W=`<V<R=m<R<R<]=e<Y<Q<T<Y=m<R<R<]=e<Y<Q<T=c<S=l<R<_=l<\\<P<P=g<r=n<S=l<\\<^<T=n=`<]<Y=m<S<W<\\=n<Q<R<P<\\=n<Y=l<T<\\<W=g<S<R<[<^<R<W=c<Y=n<S<R=m<W<Y<X<Q<T<Y=l<\\<[<W<T=k<Q=g=i<S=l<R<X=o<V=j<T<T<S=l<R<_=l<\\<P<P<\\<S<R<W<Q<R=m=n=`=b<Q<\\=i<R<X<T=n=m=c<T<[<]=l<\\<Q<Q<R<Y<Q<\\=m<Y<W<Y<Q<T=c<T<[<P<Y<Q<Y<Q<T=c<V<\\=n<Y<_<R=l<T<T<|<W<Y<V=m<\\<Q<X=l\fHJ\fIa\fHY\fHR\fH\\\fHR\fHB\fId\fHD\fIm\fHi\fH^\fHF\fIa\fH\\\fHJ\fHR\fHD\fHA\fHR\fH\\\fHH\fIl\fHC\fHi\fHD\fIm\fHJ\fIk\fHZ\fHU\fHS\fHD\fIa\fHJ\fIl\fHk\fHn\fHM\fHS\fHC\fHR\fHJ\fHS\fH^\fIa\fH^\fIl\fHi\fHK\fHS\fHy\fHR\fH\\\fHY\fIl\fHM\fHS\fHC\fIg\fHv\fHS\fHs\fIa\fHL\fIk\fHT\fHB\fHR\fHv\fHR\fH\\\fHp\fHn\fHy\fIa\fHZ\fHD\fHJ\fIm\fHD\fHS\fHC\fHR\fHF\fIa\fH\\\fHC\fIg\fH{\fHi\fHD\fIm\fHT\fHR\fH\\\fH}\fHD\fH^\fHR\fHk\fHD\fHF\fHR\fH\\\fIa\fHs\fIl\fHZ\fH\\\fIa\fHH\fIg\fHn\fH^\fIg\fHy\fHT\fHA\fHR\fHG\fHP\fIa\fH^\fId\fHZ\fHZ\fH\\\fIa\fHH\fIk\fHn\fHF\fIa\fH\\\fHJ\fIk\fHZ\fHF\fIa\fH^\fIk\fHC\fH\\\fHy\fIk\fHn\fHJ\fIa\fH\\\fHT\fIa\fHI\fHS\fHH\fHS\fHe\fHH\fIa\fHF\fHR\fHJ\fHe\fHD\fIa\fHU\fIk\fHn\fHv\fHS\fHs\fIa\fHL\fHR\fHC\fHR\fHH\fIa\fH\\\fHR\fHp\fIa\fHC\fHR\fHJ\fHR\fHF\fIm\fH\\\fHR\fHD\fIk\fHp\fIg\fHM\fHP\fIk\fHn\fHi\fHD\fIm\fHY\fHR\fHJ\fHZ\fIa\fH\\\fIk\fHO\fIl\fHZ\fHS\fHy\fIa\fH[\fHR\fHT\fH\\\fHy\fHR\fH\\\fIl\fHT\fHn\fH{\fIa\fH\\\fHU\fHF\fH\\\fHS\fHO\fHR\fHB\fH@\fIa\fH\\\fHR\fHn\fHM\fH@\fHv\fIa\fHv\fIg\fHn\fHe\fHF\fH^\fH@\fIa\fHK\fHB\fHn\fHH\fIa\fH\\\fIl\fHT\fHn\fHF\fH\\\fIa\fHy\fHe\fHB\fIa\fHB\fIl\fHJ\fHB\fHR\fHK\fIa\fHC\fHB\fHT\fHU\fHR\fHC\fHH\fHR\fHZ\fH@\fIa\fHJ\fIg\fHn\fHB\fIl\fHM\fHS\fHC\fHR\fHj\fHd\fHF\fIl\fHc\fH^\fHB\fIg\fH@\fHR\fHk\fH^\fHT\fHn\fHz\fIa\fHC\fHR\fHj\fHF\fH\\\fIk\fHZ\fHD\fHi\fHD\fIm\fH@\fHn\fHK\fH@\fHR\fHp\fHP\fHR\fH\\\fHD\fHY\fIl\fHD\fHH\fHB\fHF\fIa\fH\\\fHB\fIm\fHz\fHF\fIa\fH\\\fHZ\fIa\fHD\fHF\fH\\\fHS\fHY\fHR\fH\\\fHD\fIm\fHy\fHT\fHR\fHD\fHT\fHB\fH\\\fIa\fHI\fHD\fHj\fHC\fIg\fHp\fHS\fHH\fHT\fIg\fHB\fHY\fHR\fH\\4K5h5i4X4K4]5o4K4F4K5h5i5j4F4C5f4K4F4K5h5o5i4D5f5d4F4]4K5h5i4X4K5k4C4K4F4U4C4C4K5h4^5d4K4]4U4C4C4K5h4]4C5d4C4K5h4I4_5h4K5i5f4E4K5h5m5d4F5d4X5d4D4K5h5i4_4K4D5n4K4F4K5h5i4U5h5d5i4K4F4K5h5i4_5h4_5h4K4F4K5h4@4]4K5m5f5o4_4K5h4K4_5h4K5i5f4E4K5h4K4F4Y4K5h4K4Fhfztlqgp!#`lmwfmw>!t0-lqd,2:::,{kwno!=?b#wbqdfw>!\\aobmh!#wf{w,kwno8#`kbqpfw>!#wbqdfw>!\\aobmh!=?wbaof#`foosbggjmd>!bvwl`lnsofwf>!lee!#wf{w.bojdm9#`fmwfq8wl#obpw#ufqpjlm#az#ab`hdqlvmg.`lolq9# !#kqfe>!kwws9,,ttt-,gju=?,gju=?gju#jg>?b#kqfe>! !#`obpp>!!=?jnd#pq`>!kwws9,,`qjsw!#pq`>!kwws9,,\t?p`qjsw#obmdvbdf>!,,FM!#!kwws9,,ttt-tfm`lgfVQJ@lnslmfmw+!#kqfe>!ibubp`qjsw9?gju#`obpp>!`lmwfmwgl`vnfmw-tqjwf+$?p`slpjwjlm9#baplovwf8p`qjsw#pq`>!kwws9,,#pwzof>!nbqdjm.wls9-njm-ip!=?,p`qjsw=\t?,gju=\t?gju#`obpp>!t0-lqd,2:::,{kwno!#\t\x0e\t?,algz=\x0e\t?,kwno=gjpwjm`wjlm#afwtffm,!#wbqdfw>!\\aobmh!=?ojmh#kqfe>!kwws9,,fm`lgjmd>!vwe.;!<=\tt-bggFufmwOjpwfmfq<b`wjlm>!kwws9,,ttt-j`lm!#kqfe>!kwws9,,#pwzof>!ab`hdqlvmg9wzsf>!wf{w,`pp!#,=\tnfwb#sqlsfqwz>!ld9w?jmsvw#wzsf>!wf{w!##pwzof>!wf{w.bojdm9wkf#gfufolsnfmw#le#wzofpkffw!#wzsf>!wfkwno8#`kbqpfw>vwe.;jp#`lmpjgfqfg#wl#afwbaof#tjgwk>!233&!#Jm#bggjwjlm#wl#wkf#`lmwqjavwfg#wl#wkf#gjeefqfm`fp#afwtffmgfufolsnfmw#le#wkf#Jw#jp#jnslqwbmw#wl#?,p`qjsw=\t\t?p`qjsw##pwzof>!elmw.pjyf92=?,psbm=?psbm#jg>daOjaqbqz#le#@lmdqfpp?jnd#pq`>!kwws9,,jnFmdojpk#wqbmpobwjlmB`bgfnz#le#P`jfm`fpgju#pwzof>!gjpsobz9`lmpwqv`wjlm#le#wkf-dfwFofnfmwAzJg+jg*jm#`lmivm`wjlm#tjwkFofnfmw+$p`qjsw$*8#?nfwb#sqlsfqwz>!ld9<}=f<W<_<\\=l=m<V<T\t#wzsf>!wf{w!#mbnf>!=Sqjub`z#Sloj`z?,b=bgnjmjpwfqfg#az#wkffmbaofPjmdofQfrvfpwpwzof>%rvlw8nbqdjm9?,gju=?,gju=?,gju=?=?jnd#pq`>!kwws9,,j#pwzof>%rvlw8eolbw9qfefqqfg#wl#bp#wkf#wlwbo#slsvobwjlm#lejm#Tbpkjmdwlm/#G-@-#pwzof>!ab`hdqlvmg.bnlmd#lwkfq#wkjmdp/lqdbmjybwjlm#le#wkfsbqwj`jsbwfg#jm#wkfwkf#jmwqlgv`wjlm#lejgfmwjejfg#tjwk#wkfej`wjlmbo#`kbqb`wfq#L{elqg#Vmjufqpjwz#njpvmgfqpwbmgjmd#leWkfqf#bqf/#kltfufq/pwzofpkffw!#kqfe>!,@lovnajb#Vmjufqpjwzf{sbmgfg#wl#jm`ovgfvpvbooz#qfefqqfg#wljmgj`bwjmd#wkbw#wkfkbuf#pvddfpwfg#wkbwbeejojbwfg#tjwk#wkf`lqqfobwjlm#afwtffmmvnafq#le#gjeefqfmw=?,wg=?,wq=?,wbaof=Qfsvaoj`#le#Jqfobmg\t?,p`qjsw=\t?p`qjsw#vmgfq#wkf#jmeovfm`f`lmwqjavwjlm#wl#wkfLeej`jbo#tfapjwf#lekfbgrvbqwfqp#le#wkf`fmwfqfg#bqlvmg#wkfjnsoj`bwjlmp#le#wkfkbuf#affm#gfufolsfgEfgfqbo#Qfsvaoj`#leaf`bnf#jm`qfbpjmdoz`lmwjmvbwjlm#le#wkfMlwf/#kltfufq/#wkbwpjnjobq#wl#wkbw#le#`bsbajojwjfp#le#wkfb``lqgbm`f#tjwk#wkfsbqwj`jsbmwp#jm#wkfevqwkfq#gfufolsnfmwvmgfq#wkf#gjqf`wjlmjp#lewfm#`lmpjgfqfgkjp#zlvmdfq#aqlwkfq?,wg=?,wq=?,wbaof=?b#kwws.frvju>![.VB.skzpj`bo#sqlsfqwjfple#Aqjwjpk#@lovnajbkbp#affm#`qjwj`jyfg+tjwk#wkf#f{`fswjlmrvfpwjlmp#balvw#wkfsbppjmd#wkqlvdk#wkf3!#`foosbggjmd>!3!#wklvpbmgp#le#sflsofqfgjqf`wp#kfqf-#Elqkbuf#`kjogqfm#vmgfq&0F&0@,p`qjsw&0F!**8?b#kqfe>!kwws9,,ttt-?oj=?b#kqfe>!kwws9,,pjwf\\mbnf!#`lmwfmw>!wf{w.gf`lqbwjlm9mlmfpwzof>!gjpsobz9#mlmf?nfwb#kwws.frvju>![.mft#Gbwf+*-dfwWjnf+*#wzsf>!jnbdf,{.j`lm!?,psbm=?psbm#`obpp>!obmdvbdf>!ibubp`qjswtjmglt-ol`bwjlm-kqfe?b#kqfe>!ibubp`qjsw9..=\x0e\t?p`qjsw#wzsf>!w?b#kqfe>$kwws9,,ttt-klqw`vw#j`lm!#kqfe>!?,gju=\x0e\t?gju#`obpp>!?p`qjsw#pq`>!kwws9,,!#qfo>!pwzofpkffw!#w?,gju=\t?p`qjsw#wzsf>,b=#?b#kqfe>!kwws9,,#booltWqbmpsbqfm`z>![.VB.@lnsbwjaof!#`lmqfobwjlmpkjs#afwtffm\t?,p`qjsw=\x0e\t?p`qjsw#?,b=?,oj=?,vo=?,gju=bppl`jbwfg#tjwk#wkf#sqldqbnnjmd#obmdvbdf?,b=?b#kqfe>!kwws9,,?,b=?,oj=?oj#`obpp>!elqn#b`wjlm>!kwws9,,?gju#pwzof>!gjpsobz9wzsf>!wf{w!#mbnf>!r!?wbaof#tjgwk>!233&!#ab`hdqlvmg.slpjwjlm9!#alqgfq>!3!#tjgwk>!qfo>!pklqw`vw#j`lm!#k5=?vo=?oj=?b#kqfe>!##?nfwb#kwws.frvju>!`pp!#nfgjb>!p`qffm!#qfpslmpjaof#elq#wkf#!#wzsf>!bssoj`bwjlm,!#pwzof>!ab`hdqlvmg.kwno8#`kbqpfw>vwe.;!#booltwqbmpsbqfm`z>!pwzofpkffw!#wzsf>!wf\x0e\t?nfwb#kwws.frvju>!=?,psbm=?psbm#`obpp>!3!#`foopsb`jmd>!3!=8\t?,p`qjsw=\t?p`qjsw#plnfwjnfp#`boofg#wkfglfp#mlw#mf`fppbqjozElq#nlqf#jmelqnbwjlmbw#wkf#afdjmmjmd#le#?"GL@WZSF#kwno=?kwnosbqwj`vobqoz#jm#wkf#wzsf>!kjggfm!#mbnf>!ibubp`qjsw9uljg+3*8!feef`wjufmfpp#le#wkf#bvwl`lnsofwf>!lee!#dfmfqbooz#`lmpjgfqfg=?jmsvw#wzsf>!wf{w!#!=?,p`qjsw=\x0e\t?p`qjswwkqlvdklvw#wkf#tlqog`lnnlm#njp`lm`fswjlmbppl`jbwjlm#tjwk#wkf?,gju=\t?,gju=\t?gju#`gvqjmd#kjp#ojefwjnf/`lqqfpslmgjmd#wl#wkfwzsf>!jnbdf,{.j`lm!#bm#jm`qfbpjmd#mvnafqgjsolnbwj`#qfobwjlmpbqf#lewfm#`lmpjgfqfgnfwb#`kbqpfw>!vwe.;!#?jmsvw#wzsf>!wf{w!#f{bnsofp#jm`ovgf#wkf!=?jnd#pq`>!kwws9,,jsbqwj`jsbwjlm#jm#wkfwkf#fpwbaojpknfmw#le\t?,gju=\t?gju#`obpp>!%bns8maps8%bns8maps8wl#gfwfqnjmf#tkfwkfqrvjwf#gjeefqfmw#eqlnnbqhfg#wkf#afdjmmjmdgjpwbm`f#afwtffm#wkf`lmwqjavwjlmp#wl#wkf`lmeoj`w#afwtffm#wkftjgfoz#`lmpjgfqfg#wltbp#lmf#le#wkf#ejqpwtjwk#ubqzjmd#gfdqffpkbuf#psf`vobwfg#wkbw+gl`vnfmw-dfwFofnfmwsbqwj`jsbwjmd#jm#wkflqjdjmbooz#gfufolsfgfwb#`kbqpfw>!vwe.;!=#wzsf>!wf{w,`pp!#,=\tjmwfq`kbmdfbaoz#tjwknlqf#`olpfoz#qfobwfgpl`jbo#bmg#slojwj`bowkbw#tlvog#lwkfqtjpfsfqsfmgj`vobq#wl#wkfpwzof#wzsf>!wf{w,`ppwzsf>!pvanjw!#mbnf>!ebnjojfp#qfpjgjmd#jmgfufolsjmd#`lvmwqjfp`lnsvwfq#sqldqbnnjmdf`lmlnj`#gfufolsnfmwgfwfqnjmbwjlm#le#wkfelq#nlqf#jmelqnbwjlmlm#pfufqbo#l``bpjlmpslqwvdv/Fp#+Fvqlsfv*<O<V=l<\\={<Q=m=`<V<\\=o<V=l<\\={<Q=m=`<V<\\<L<R=m=m<T<U=m<V<R<U<P<\\=n<Y=l<T<\\<W<R<^<T<Q=h<R=l<P<\\=j<T<T=o<S=l<\\<^<W<Y<Q<T=c<Q<Y<R<]=i<R<X<T<P<R<T<Q=h<R=l<P<\\=j<T=c<t<Q=h<R=l<P<\\=j<T=c<L<Y=m<S=o<]<W<T<V<T<V<R<W<T=k<Y=m=n<^<R<T<Q=h<R=l<P<\\=j<T=b=n<Y=l=l<T=n<R=l<T<T<X<R=m=n<\\=n<R=k<Q<R4K5h5i4F5d4K4@4C5d5j4K5h4K4X4F4]4K5o4K4F4K5h4K5n4F4]4K4A4K4Fkwno8#`kbqpfw>VWE.;!#pfwWjnflvw+evm`wjlm+*gjpsobz9jmojmf.aol`h8?jmsvw#wzsf>!pvanjw!#wzsf#>#$wf{w,ibubp`qj?jnd#pq`>!kwws9,,ttt-!#!kwws9,,ttt-t0-lqd,pklqw`vw#j`lm!#kqfe>!!#bvwl`lnsofwf>!lee!#?,b=?,gju=?gju#`obpp>?,b=?,oj=\t?oj#`obpp>!`pp!#wzsf>!wf{w,`pp!#?elqn#b`wjlm>!kwws9,,{w,`pp!#kqfe>!kwws9,,ojmh#qfo>!bowfqmbwf!#\x0e\t?p`qjsw#wzsf>!wf{w,#lm`oj`h>!ibubp`qjsw9+mft#Gbwf*-dfwWjnf+*~kfjdkw>!2!#tjgwk>!2!#Sflsof$p#Qfsvaoj`#le##?b#kqfe>!kwws9,,ttt-wf{w.gf`lqbwjlm9vmgfqwkf#afdjmmjmd#le#wkf#?,gju=\t?,gju=\t?,gju=\tfpwbaojpknfmw#le#wkf#?,gju=?,gju=?,gju=?,g ujftslqwxnjm.kfjdkw9\t?p`qjsw#pq`>!kwws9,,lswjlm=?lswjlm#ubovf>lewfm#qfefqqfg#wl#bp#,lswjlm=\t?lswjlm#ubov?"GL@WZSF#kwno=\t?"..XJmwfqmbwjlmbo#Bjqslqw=\t?b#kqfe>!kwws9,,ttt?,b=?b#kqfe>!kwws9,,t\fTL\fT^\fTE\fT^\fUh\fT{\fTN\roI\ro|\roL\ro{\roO\rov\rot\nAO\x05Gx\bTA\nzk#+\vUm\x05Gx*\fHD\fHS\fH\\\fIa\fHJ\fIk\fHZ\fHM\fHR\fHe\fHD\fH^\fIg\fHM\fHy\fIa\fH[\fIk\fHH\fIa\fH\\\fHp\fHR\fHD\fHy\fHR\fH\\\fIl\fHT\fHn\fH@\fHn\fHK\fHS\fHH\fHT\fIa\fHI\fHR\fHF\fHD\fHR\fHT\fIa\fHY\fIl\fHy\fHR\fH\\\fHT\fHn\fHT\fIa\fHy\fH\\\fHO\fHT\fHR\fHB\fH{\fIa\fH\\\fIl\fHv\fHS\fHs\fIa\fHL\fIg\fHn\fHY\fHS\fHp\fIa\fHr\fHR\fHD\fHi\fHB\fIk\fH\\\fHS\fHy\fHR\fHY\fHS\fHA\fHS\fHD\fIa\fHD\fH{\fHR\fHM\fHS\fHC\fHR\fHm\fHy\fIa\fHC\fIg\fHn\fHy\fHS\fHT\fIm\fH\\\fHy\fIa\fH[\fHR\fHF\fHU\fIm\fHm\fHv\fHH\fIl\fHF\fIa\fH\\\fH@\fHn\fHK\fHD\fHs\fHS\fHF\fIa\fHF\fHO\fIl\fHy\fIa\fH\\\fHS\fHy\fIk\fHs\fHF\fIa\fH\\\fHR\fH\\\fHn\fHA\fHF\fIa\fH\\\fHR\fHF\fIa\fHH\fHB\fHR\fH^\fHS\fHy\fIg\fHn\fH\\\fHG\fHP\fIa\fHH\fHR\fH\\\fHD\fHS\fH\\\fIa\fHB\fHR\fHO\fH^\fHS\fHB\fHS\fHs\fIk\fHMgfp`qjswjlm!#`lmwfmw>!gl`vnfmw-ol`bwjlm-sqlw-dfwFofnfmwpAzWbdMbnf+?"GL@WZSF#kwno=\t?kwno#?nfwb#`kbqpfw>!vwe.;!=9vqo!#`lmwfmw>!kwws9,,-`pp!#qfo>!pwzofpkffw!pwzof#wzsf>!wf{w,`pp!=wzsf>!wf{w,`pp!#kqfe>!t0-lqd,2:::,{kwno!#{nowzsf>!wf{w,ibubp`qjsw!#nfwklg>!dfw!#b`wjlm>!ojmh#qfo>!pwzofpkffw!##>#gl`vnfmw-dfwFofnfmwwzsf>!jnbdf,{.j`lm!#,=`foosbggjmd>!3!#`foops-`pp!#wzsf>!wf{w,`pp!#?,b=?,oj=?oj=?b#kqfe>!!#tjgwk>!2!#kfjdkw>!2!!=?b#kqfe>!kwws9,,ttt-pwzof>!gjpsobz9mlmf8!=bowfqmbwf!#wzsf>!bssoj.,,T0@,,GWG#[KWNO#2-3#foopsb`jmd>!3!#`foosbg#wzsf>!kjggfm!#ubovf>!,b=%maps8?psbm#qlof>!p\t?jmsvw#wzsf>!kjggfm!#obmdvbdf>!IbubP`qjsw!##gl`vnfmw-dfwFofnfmwpAd>!3!#`foopsb`jmd>!3!#zsf>!wf{w,`pp!#nfgjb>!wzsf>$wf{w,ibubp`qjsw$tjwk#wkf#f{`fswjlm#le#zsf>!wf{w,`pp!#qfo>!pw#kfjdkw>!2!#tjgwk>!2!#>$(fm`lgfVQJ@lnslmfmw+?ojmh#qfo>!bowfqmbwf!#\talgz/#wq/#jmsvw/#wf{wnfwb#mbnf>!qlalwp!#`lmnfwklg>!slpw!#b`wjlm>!=\t?b#kqfe>!kwws9,,ttt-`pp!#qfo>!pwzofpkffw!#?,gju=?,gju=?gju#`obppobmdvbdf>!ibubp`qjsw!=bqjb.kjggfm>!wqvf!=.[?qjsw!#wzsf>!wf{w,ibubpo>38~*+*8\t+evm`wjlm+*xab`hdqlvmg.jnbdf9#vqo+,b=?,oj=?oj=?b#kqfe>!k\n\n?oj=?b#kqfe>!kwws9,,bwlq!#bqjb.kjggfm>!wqv=#?b#kqfe>!kwws9,,ttt-obmdvbdf>!ibubp`qjsw!#,lswjlm=\t?lswjlm#ubovf,gju=?,gju=?gju#`obpp>qbwlq!#bqjb.kjggfm>!wqf>+mft#Gbwf*-dfwWjnf+*slqwvdv/Fp#+gl#Aqbpjo*<R=l<_<\\<Q<T<[<\\=j<T<T<^<R<[<P<R<Z<Q<R=m=n=`<R<]=l<\\<[<R<^<\\<Q<T=c=l<Y<_<T=m=n=l<\\=j<T<T<^<R<[<P<R<Z<Q<R=m=n<T<R<]=c<[<\\=n<Y<W=`<Q<\\?"GL@WZSF#kwno#SVAOJ@#!mw.Wzsf!#`lmwfmw>!wf{w,?nfwb#kwws.frvju>!@lmwfqbmpjwjlmbo,,FM!#!kwws9?kwno#{nomp>!kwws9,,ttt.,,T0@,,GWG#[KWNO#2-3#WGWG,{kwno2.wqbmpjwjlmbo,,ttt-t0-lqd,WQ,{kwno2,sf#>#$wf{w,ibubp`qjsw$8?nfwb#mbnf>!gfp`qjswjlmsbqfmwMlgf-jmpfqwAfelqf?jmsvw#wzsf>!kjggfm!#mbip!#wzsf>!wf{w,ibubp`qj+gl`vnfmw*-qfbgz+evm`wjp`qjsw#wzsf>!wf{w,ibubpjnbdf!#`lmwfmw>!kwws9,,VB.@lnsbwjaof!#`lmwfmw>wno8#`kbqpfw>vwe.;!#,=\tojmh#qfo>!pklqw`vw#j`lm?ojmh#qfo>!pwzofpkffw!#?,p`qjsw=\t?p`qjsw#wzsf>>#gl`vnfmw-`qfbwfFofnfm?b#wbqdfw>!\\aobmh!#kqfe>#gl`vnfmw-dfwFofnfmwpAjmsvw#wzsf>!wf{w!#mbnf>b-wzsf#>#$wf{w,ibubp`qjmsvw#wzsf>!kjggfm!#mbnfkwno8#`kbqpfw>vwe.;!#,=gwg!=\t?kwno#{nomp>!kwws.,,T0@,,GWG#KWNO#7-32#WfmwpAzWbdMbnf+$p`qjsw$*jmsvw#wzsf>!kjggfm!#mbn?p`qjsw#wzsf>!wf{w,ibubp!#pwzof>!gjpsobz9mlmf8!=gl`vnfmw-dfwFofnfmwAzJg+>gl`vnfmw-`qfbwfFofnfmw+$#wzsf>$wf{w,ibubp`qjsw$jmsvw#wzsf>!wf{w!#mbnf>!g-dfwFofnfmwpAzWbdMbnf+pmj`bo!#kqfe>!kwws9,,ttt-@,,GWG#KWNO#7-32#Wqbmpjw?pwzof#wzsf>!wf{w,`pp!=\t\t?pwzof#wzsf>!wf{w,`pp!=jlmbo-gwg!=\t?kwno#{nomp>kwws.frvju>!@lmwfmw.Wzsfgjmd>!3!#`foopsb`jmd>!3!kwno8#`kbqpfw>vwe.;!#,=\t#pwzof>!gjpsobz9mlmf8!=??oj=?b#kqfe>!kwws9,,ttt-#wzsf>$wf{w,ibubp`qjsw$=<X<Y=c=n<Y<W=`<Q<R=m=n<T=m<R<R=n<^<Y=n=m=n<^<T<T<S=l<R<T<[<^<R<X=m=n<^<\\<]<Y<[<R<S<\\=m<Q<R=m=n<T\fHF\fIm\fHT\fIa\fHH\fHS\fHy\fHR\fHy\fHR\fHn\fH{\fIa\fH\\\fIk\fHT\fHe\fHD\fIa\fHU\fIg\fHn\fHD\fIk\fHY\fHS\fHK\fHR\fHD\fHT\fHA\fHR\fHG\fHS\fHy\fIa\fHT\fHS\fHn\fH{\fHT\fIm\fH\\\fHy\fIa\fH[\fHS\fHH\fHy\fIe\fHF\fIl\fH\\\fHR\fHk\fHs\fHY\fHS\fHp\fIa\fHr\fHR\fHF\fHD\fHy\fHR\fH\\\fIa\fH\\\fHY\fHR\fHd\fHT\fHy\fIa\fH\\\fHS\fHC\fHH\fHR',"\u06f7%\u018c'T%\x85'W%\xd7%O%g%\xa6&\u0193%\u01e5&>&*&'&^&\x88\u0178\u0c3e&\u01ad&\u0192&)&^&%&'&\x82&P&1&\xb1&3&]&m&u&E&t&C&\xcf&V&V&/&>&6&\u0f76\u177co&p&@&E&M&P&x&@&F&e&\xcc&7&:&(&D&0&C&)&.&F&-&1&(&L&F&1\u025e*\u03ea\u21f3&\u1372&K&;&)&E&H&P&0&?&9&V&\x81&-&v&a&,&E&)&?&=&'&'&B&\u0d2e&\u0503&\u0316*&*8&%&%&&&%,)&\x9a&>&\x86&7&]&F&2&>&J&6&n&2&%&?&\x8e&2&6&J&g&-&0&,&*&J&*&O&)&6&(&<&B&N&.&P&@&2&.&W&M&%\u053c\x84(,(<&,&\u03da&\u18c7&-&,(%&(&%&(\u013b0&X&D&\x81&j&'&J&(&.&B&3&Z&R&h&3&E&E&<\xc6-\u0360\u1ef3&%8?&@&,&Z&@&0&J&,&^&x&_&6&C&6&C\u072c\u2a25&f&-&-&-&-&,&J&2&8&z&8&C&Y&8&-&d&\u1e78\xcc-&7&1&F&7&t&W&7&I&.&.&^&=\u0f9c\u19d3&8(>&/&/&\u077b')'\u1065')'%@/&0&%\u043e\u09c0*&*@&C\u053d\u05d4\u0274\u05eb4\u0dd7\u071a\u04d16\u0d84&/\u0178\u0303Z&*%\u0246\u03ff&\u0134&1\xa8\u04b4\u0174",w,"AAAAKKLLKKKKKJJIHHIHHGGFF"),function(f,w){if(w.length>31)throw"sizeBits length must be at most 31";for(let f=0;f<4;++f)if(0!=w[f])throw"first 4 must be 0";let b=N,j=$;j.set(w.subarray(0,0+w.length),0);let l=0,m=f.length;for(let f=0;f<w.length;++f){b[f]=l;let w=j[f];if(0!=w){if(w>=31)throw"newSizeBits values must be less than 31";if(l+=f<<w,l<=0||l>m)throw"newSizeBits is inconsistent: overflow"}}for(let f=w.length;f<32;++f)b[f]=l;if(l!=m)throw"newSizeBits is inconsistent: underflow";L=f}(f,w)}function ff(f,w){return f<=w?f:w}function wf(f,w,b,j){if(null==f)return-1;let l=ff(f.offset+j,f.data.length),m=l-f.offset;return w.set(f.data.subarray(f.offset,l),b),f.offset+=m,m}return function(w,b){let j=new Z;if(t(j,new f(w)),b){let f=b.customDictionary;f&&function(f,w){if(1!=f.j)throw"State MUST be freshly initialized";if(0==f.Vf&&(f.Tf=new Array(16),f.df=new Int32Array(16),f.tf=-1),15==f.Vf)throw"Too many dictionary chunks";f.Tf[f.Vf]=w,f.Vf++,f.vf+=w.length,f.df[f.Vf]=f.vf}(j,f)}let l=0,m=[];for(;;){let f=new Int8Array(16384);if(m.push(f),j.nf=f,j.gf=0,j.lf=16384,j.mf=0,D(j),l+=j.mf,j.mf<16384)break}!function(f){if(0==f.j)throw"State MUST be initialized";11!=f.j&&(f.j=11,null!=f.input&&(f.input,f.input=null))}(j);let p=new Int8Array(l),q=0;for(let f=0;f<m.length;++f){let w=m[f],b=ff(l,q+16384)-q;b<16384?p.set(w.subarray(0,b),q):p.set(w,q),q+=b}return p}})();
-
- - - -
- -
- - - - -
- - -
- - -
-
- - - - -
- - - -
-
- -
-
- -
- - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/favicon.ico b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/favicon.ico deleted file mode 100644 index 63e859b4..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/favicon.ico and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/i18n/en-US.json b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/i18n/en-US.json deleted file mode 100644 index 55f08fc8..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/i18n/en-US.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$Text": "English", - "Dashboard": "Dashboard", - "eCommerce": "eCommerce", - "Analytics": "Analytics", - "Apps": "Apps", - "Shop": "Shop", - "Details": "Details", - "Order": "Order", - "Todo": "Todo", - "Invoice": "Invoice", - "List": "List", - "Preview": "Preview", - "Edit": "Edit", - "Add": "Add", - "User": "User", - "View": "View", - "Pages": "Pages", - "Auth": "Auth", - "Login v1": "Login v1", - "Login v2": "Login v2", - "Not Authorized": "Not Authorized", - "Register v1": "Register v1", - "Register v2": "Register v2", - "Forgot Password v1": "Forgot Password v1", - "Forgot Password v2": "Forgot Password v2", - "Reset Password v1": "Reset Password v1", - "Reset Password v2": "Reset Password v2", - "Others": "Others", - "Account Settings": "Account Settings", - "Favorite": "Favorite" -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/i18n/languageConfig.json b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/i18n/languageConfig.json deleted file mode 100644 index bbb1d45d..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/i18n/languageConfig.json +++ /dev/null @@ -1,6 +0,0 @@ -[ - "zh-CN", - "en-US" -] - - diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/i18n/zh-CN.json b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/i18n/zh-CN.json deleted file mode 100644 index 893ec8dd..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/i18n/zh-CN.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "$DefaultLanguage": "true", - "$Text": "中文简体", - "Dashboard": "仪表盘", - "eCommerce": "电å­å•†åŠ¡", - "Analytics": "分æž", - "Apps": "应用", - "Shop": "购物", - "Details": "商å“详情", - "Order": "订å•", - "Todo": "工作事项", - "Invoice": "å‘票 ", - "List": "列表", - "Preview": "预览 ", - "Edit": "编辑", - "Add": "新建", - "User": "用户", - "View": "展示", - "Pages": "页é¢", - "Auth": "è®¤è¯ ", - "Login v1": "登录版本1", - "Login v2": "登录版本2", - "Not Authorized": "没有授æƒ", - "Register v1": "注册版本1", - "Register v2": "注册版本2", - "Forgot Password v1": "忘记密ç ç‰ˆæœ¬1", - "Forgot Password v2": "忘记密ç ç‰ˆæœ¬2", - "Reset Password v1": "é‡ç½®å¯†ç ç‰ˆæœ¬1", - "Reset Password v2": "é‡ç½®å¯†ç ç‰ˆæœ¬2", - "Others": "å…¶ä»–", - "Account Settings": "账户设置", - "Favorite": "æ”¶è—" -} diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/analytics/json.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/analytics/json.png deleted file mode 100644 index fee45284..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/analytics/json.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/analytics/left.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/analytics/left.png deleted file mode 100644 index ee5e3b2b..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/analytics/left.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/analytics/right.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/analytics/right.png deleted file mode 100644 index 30bb2ccb..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/analytics/right.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/1.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/1.png deleted file mode 100644 index da3754e3..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/1.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/10.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/10.png deleted file mode 100644 index cbe272a3..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/10.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/11.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/11.png deleted file mode 100644 index 21ef2c50..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/11.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/12.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/12.png deleted file mode 100644 index ff6d5a31..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/12.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/13.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/13.png deleted file mode 100644 index ae9bf58e..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/13.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/14.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/14.png deleted file mode 100644 index 85bad7d6..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/14.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/15.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/15.png deleted file mode 100644 index d8534205..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/15.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/16.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/16.png deleted file mode 100644 index 786058d9..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/16.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/17.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/17.png deleted file mode 100644 index e7549e8f..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/17.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/18.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/18.png deleted file mode 100644 index e52030bc..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/18.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/19.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/19.png deleted file mode 100644 index aa787303..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/19.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/2.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/2.png deleted file mode 100644 index 288cbf98..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/2.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/20.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/20.png deleted file mode 100644 index e96eae40..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/20.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/21.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/21.png deleted file mode 100644 index b51bc803..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/21.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/22.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/22.png deleted file mode 100644 index e898ca53..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/22.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/23.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/23.png deleted file mode 100644 index 869f6c7b..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/23.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/24.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/24.png deleted file mode 100644 index 25c11b17..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/24.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/25.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/25.png deleted file mode 100644 index d9c77137..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/25.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/26.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/26.png deleted file mode 100644 index 185e5955..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/26.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/27.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/27.png deleted file mode 100644 index a17d5dd0..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/27.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/3.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/3.png deleted file mode 100644 index 49a1031a..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/3.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/4.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/4.png deleted file mode 100644 index 2662d30a..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/4.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/5.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/5.png deleted file mode 100644 index f9236e20..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/5.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/6.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/6.png deleted file mode 100644 index 421093a2..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/6.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/7.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/7.png deleted file mode 100644 index 60f2e651..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/7.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/8.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/8.png deleted file mode 100644 index fd90e291..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/8.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/9.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/9.png deleted file mode 100644 index 12f81f81..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/apps-eCommerce/9.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/auth/forgot-password-v2.9faba3c1.svg b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/auth/forgot-password-v2.9faba3c1.svg deleted file mode 100644 index 030d94c0..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/auth/forgot-password-v2.9faba3c1.svg +++ /dev/null @@ -1,207 +0,0 @@ - - - Illustration - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/auth/register-v2.0a9e487c.svg b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/auth/register-v2.0a9e487c.svg deleted file mode 100644 index d1ac05b0..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/auth/register-v2.0a9e487c.svg +++ /dev/null @@ -1,351 +0,0 @@ - - - Group - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/1.svg b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/1.svg deleted file mode 100644 index a47f78f5..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/1.svg +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/10.svg b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/10.svg deleted file mode 100644 index 082ab6ea..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/10.svg +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/11.svg b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/11.svg deleted file mode 100644 index ed6e9b2a..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/11.svg +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/12.svg b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/12.svg deleted file mode 100644 index 0533369c..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/12.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/13.svg b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/13.svg deleted file mode 100644 index 93b28c41..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/13.svg +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/14.svg b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/14.svg deleted file mode 100644 index fd688f93..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/14.svg +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/2.svg b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/2.svg deleted file mode 100644 index f4a8944d..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/2.svg +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/3.svg b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/3.svg deleted file mode 100644 index b2e10605..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/3.svg +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/4.svg b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/4.svg deleted file mode 100644 index 58e0cfe7..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/4.svg +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/7.svg b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/7.svg deleted file mode 100644 index 6cefecfb..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/7.svg +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/8.svg b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/8.svg deleted file mode 100644 index 61c13aa8..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/8.svg +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/9.svg b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/9.svg deleted file mode 100644 index cb45b1e5..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/avatar/9.svg +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/eCommerce/rectangle.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/eCommerce/rectangle.png deleted file mode 100644 index 1ab629b5..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/eCommerce/rectangle.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/eCommerce/trophy.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/eCommerce/trophy.png deleted file mode 100644 index 98f0b8d0..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/eCommerce/trophy.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/login/2873.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/login/2873.png deleted file mode 100644 index 4b7e7881..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/login/2873.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/login/Gxwd.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/login/Gxwd.png deleted file mode 100644 index 503ecde3..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/login/Gxwd.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/login/left.svg b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/login/left.svg deleted file mode 100644 index 103158e7..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/login/left.svg +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/mainLayout/logo-en.svg b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/mainLayout/logo-en.svg deleted file mode 100644 index d4198657..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/mainLayout/logo-en.svg +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/mainLayout/logo.svg b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/mainLayout/logo.svg deleted file mode 100644 index 0fd854c5..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/mainLayout/logo.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/status/401.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/status/401.png deleted file mode 100644 index 1f94504e..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/status/401.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/status/404.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/status/404.png deleted file mode 100644 index 39f2c595..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/status/404.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/status/500.png b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/status/500.png deleted file mode 100644 index fa65a8f6..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/img/status/500.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/index.html b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/index.html deleted file mode 100644 index 5253e0a1..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/index.html +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - Masa.Mc.Web.Admin - - - - - - - - - - - - - -
- - -
- -
- An unhandled error has occurred. - Reload - 🗙 -
- - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/nav/nav.json b/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/nav/nav.json deleted file mode 100644 index 1829e716..00000000 --- a/src/Web/Masa.Mc.Web.Admin.WebAssembly/wwwroot/nav/nav.json +++ /dev/null @@ -1,203 +0,0 @@ -[ - { - "Id": 1, - "Title": "Dashboard", - "Icon": "mdi-trending-up", - "Children": [ - { - "Id": 2, - "Title": "eCommerce", - "Icon": "mdi-circle", - "Href": "dashboard/ecommerce" - }, - { - "Id": 3, - "Hide": true, - "Title": "Analytics", - "Icon": "mdi-circle", - "Href": "dashboard/analytics" - } - ] - }, - { - "Id": 4, - "Title": "eCommerce", - "Icon": "mdi-cart-outline", - "Children": [ - { - "Id": 5, - "Title": "Shop", - "Icon": "mdi-circle", - "Href": "app/ecommerce/shop" - }, - { - "Id": 6, - "Title": "Details", - "Icon": "mdi-circle", - "Href": "app/ecommerce/details" - }, - { - "Id": 7, - "Title": "Order", - "Icon": "mdi-circle", - "Href": "app/ecommerce/order" - } - ] - }, - { - "Id": 8, - "Title": "Todo", - "Icon": "mdi-calendar-check-outline", - "Href": "app/todo" - }, - { - "Id": 9, - "Title": "Invoice", - "Icon": "mdi-content-paste", - "Hide": true, - "Children": [ - { - "Id": 10, - "Title": "List", - "Icon": "mdi-circle", - "Href": "app/invoice/list" - }, - { - "Id": 11, - "Title": "Preview", - "Icon": "mdi-circle", - "Href": "app/invoice/preview" - }, - { - "Id": 12, - "Title": "Edit", - "Icon": "mdi-circle", - "Href": "app/invoice/edit" - }, - { - "Id": 13, - "Title": "Add", - "Icon": "mdi-circle", - "Href": "app/invoice/add" - } - ] - }, - { - "Id": 14, - "Title": "User", - "Icon": "mdi-account-outline", - "Children": [ - { - "Id": 15, - "Title": "List", - "Icon": "mdi-circle", - "Href": "app/user/list" - }, - { - "Id": 16, - "Title": "View", - "Icon": "mdi-circle", - "Href": "app/user/view" - }, - { - "Id": 17, - "Title": "Edit", - "Icon": "mdi-circle", - "Href": "app/user/edit" - } - ] - }, - { - "Id": 18, - "Title": "Auth", - "Icon": "mdi-file-outline", - "Children": [ - { - "Id": 19, - "Title": "Login v1", - "Icon": "mdi-circle", - "Href": "pages/authentication/login-v1" - }, - { - "Id": 20, - "Title": "Login v2", - "Icon": "mdi-circle", - "Href": "pages/authentication/login-v2" - }, - { - "Id": 21, - "Hide": true, - "Title": "Register v1", - "Icon": "mdi-circle", - "Href": "pages/authentication/register-v1" - }, - { - "Id": 22, - "Hide": true, - "Title": "Register v2", - "Icon": "mdi-circle", - "Href": "pages/authentication/register-v2" - }, - { - "Id": 23, - "Hide": true, - "Title": "Forgot Password v1", - "Icon": "mdi-circle", - "Href": "pages/authentication/forgot-password-v1" - }, - { - "Id": 24, - "Hide": true, - "Title": "Forgot Password v2", - "Icon": "mdi-circle", - "Href": "pages/authentication/forgot-password-v2" - }, - { - "Id": 25, - "Hide": true, - "Title": "Reset Password v1", - "Icon": "mdi-circle", - "Href": "pages/authentication/reset-password-v1" - }, - { - "Id": 26, - "Hide": true, - "Title": "Reset Password v2", - "Icon": "mdi-circle", - "Href": "pages/authentication/reset-password-v2" - } - ] - }, - { - "Id": 27, - "Title": "Others", - "Icon": "mdi-dots-horizontal", - "Children": [ - { - "Id": 28, - "Hide": true, - "Title": "Account Settings", - "Icon": "mdi-circle", - "Href": "pages/others/account-settings" - }, - { - "Id": 29, - "Title": "500", - "Icon": "mdi-circle", - "Href": "pages/others/500" - }, - { - "Id": 30, - "Title": "401", - "Icon": "mdi-circle", - "Href": "pages/others/401" - }, - { - "Id": 31, - "Title": "404", - "Icon": "mdi-circle", - "Href": "pages/others/404" - } - ] - } -] diff --git a/src/Web/Masa.Mc.Web.Admin/App.razor b/src/Web/Masa.Mc.Web.Admin/App.razor deleted file mode 100644 index 14b4a160..00000000 --- a/src/Web/Masa.Mc.Web.Admin/App.razor +++ /dev/null @@ -1,28 +0,0 @@ -@inject TokenProvider TokenProvider - - - - - - - - - - - - - - -@code { - [Parameter] - public TokenProvider InitialState { get; set; } = null!; - - protected override Task OnInitializedAsync() - { - TokenProvider.AccessToken = InitialState.AccessToken; - TokenProvider.RefreshToken = InitialState.RefreshToken; - TokenProvider.IdToken = InitialState.IdToken; - return base.OnInitializedAsync(); - } -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Components/AutoHeight.razor b/src/Web/Masa.Mc.Web.Admin/Components/AutoHeight.razor deleted file mode 100644 index 2d4a628d..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/AutoHeight.razor +++ /dev/null @@ -1,28 +0,0 @@ -
- @HeaderContent -
- @AutoHeightContent -
- @FooterContent -
- - -@code { - [Parameter] - public RenderFragment? HeaderContent { get; set; } - - [Parameter] - public RenderFragment? AutoHeightContent { get; set; } - - [Parameter] - public RenderFragment? FooterContent { get; set; } - - [Parameter] - public string AutoClass { get; set; } = ""; - - [Parameter] - public string Class { get; set; } = ""; - - [Parameter] - public bool Overflow { get; set; } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Components/ButtonGroup/BooleanButtonGroup.razor b/src/Web/Masa.Mc.Web.Admin/Components/ButtonGroup/BooleanButtonGroup.razor deleted file mode 100644 index 958d4ddd..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/ButtonGroup/BooleanButtonGroup.razor +++ /dev/null @@ -1,25 +0,0 @@ -@inherits AdminCompontentBase - -@if (StyleType == StyleTypes.Toggle) -{ - - @foreach (var (key, value) in KeyValues) - { - - fa fa-regular fa-mars - @T(key) - - } - -} -else -{ - - @foreach (var (key, value) in KeyValues) - { - - @T(key) - - } - -} diff --git a/src/Web/Masa.Mc.Web.Admin/Components/ButtonGroup/BooleanButtonGroup.razor.cs b/src/Web/Masa.Mc.Web.Admin/Components/ButtonGroup/BooleanButtonGroup.razor.cs deleted file mode 100644 index fa11ae06..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/ButtonGroup/BooleanButtonGroup.razor.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Components.ButtonGroup; - -public partial class BooleanButtonGroup -{ - [Parameter] - public bool? Value { get; set; } - - [Parameter] - public EventCallback ValueChanged { get; set; } - - [Parameter] - public List> Items { get; set; } = new(); - - [Parameter] - public StyleTypes StyleType { get; set; } - - [Parameter] - public bool Disabled { get; set; } - - public List> KeyValues { get; set; } = new(); - - protected override void OnParametersSet() - { - KeyValues = Items.Any() ? Items : GetBooleanMap(); - } -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Chip/ColorTag.razor b/src/Web/Masa.Mc.Web.Admin/Components/Chip/ColorTag.razor deleted file mode 100644 index 81c96a21..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Chip/ColorTag.razor +++ /dev/null @@ -1,22 +0,0 @@ -
@ChildContent
- -@code { - [Parameter] - public RenderFragment? ChildContent { get; set; } - - [Parameter] - public string Color { get; set; } = default!; - - [Parameter] - public string Class { get; set; } = default!; - - protected override void OnParametersSet() - { - base.OnParametersSet(); - - if (string.IsNullOrEmpty(Color)) - { - Color = "emphasis2"; - } - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Clamp.razor b/src/Web/Masa.Mc.Web.Admin/Components/Clamp.razor deleted file mode 100644 index 4b30a92f..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Clamp.razor +++ /dev/null @@ -1,23 +0,0 @@ -@inherits AdminCompontentBase -
@_childContent
- -@code { - [Parameter] - public RenderFragment? ChildContent { get; set; } - - private RenderFragment? _childContent { get; set; } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - await base.OnAfterRenderAsync(firstRender); - - if (firstRender) - { - await Js.InvokeVoidAsync("$clamp", Ref, new { clamp = "auto" }); - - _childContent = ChildContent; - - StateHasChanged(); - } - } -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Default/DefaultIcon.cs b/src/Web/Masa.Mc.Web.Admin/Components/Default/DefaultIcon.cs deleted file mode 100644 index 67930795..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Default/DefaultIcon.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Components.Default; - -public class DefaultIcon : SIcon -{ - public override async Task SetParametersAsync(ParameterView parameters) - { - Size = 20; - - await base.SetParametersAsync(parameters); - } -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Default/DefaultSheetDialog.cs b/src/Web/Masa.Mc.Web.Admin/Components/Default/DefaultSheetDialog.cs deleted file mode 100644 index b355100c..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Default/DefaultSheetDialog.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Components.Default; - -public class DefaultSheetDialog : SSheetDialog -{ - protected override void OnParametersSet() - { - base.OnParametersSet(); - EnableDomReload = true; - ContentClass ??= ""; - if (ContentClass.Contains("sheetDialogPadding") is false) - ContentClass += " sheetDialogPadding"; - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Default/DefaultSubTitle.razor b/src/Web/Masa.Mc.Web.Admin/Components/Default/DefaultSubTitle.razor deleted file mode 100644 index 2959ed11..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Default/DefaultSubTitle.razor +++ /dev/null @@ -1,11 +0,0 @@ -
- @ChildContent -
- -@code { - [Parameter] - public RenderFragment? ChildContent { get; set; } - - [Parameter] - public string Class { get; set; } = "mt-9 mb-6"; -} diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Default/DefaultTitle.razor b/src/Web/Masa.Mc.Web.Admin/Components/Default/DefaultTitle.razor deleted file mode 100644 index 33c387d2..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Default/DefaultTitle.razor +++ /dev/null @@ -1,9 +0,0 @@ -@ChildContent - -@code { - [Parameter] - public RenderFragment? ChildContent { get; set; } - - [Parameter] - public string Class { get; set; } = ""; -} diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Default/DefaultUserAvatar.razor b/src/Web/Masa.Mc.Web.Admin/Components/Default/DefaultUserAvatar.razor deleted file mode 100644 index 10da1da3..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Default/DefaultUserAvatar.razor +++ /dev/null @@ -1,13 +0,0 @@ - - - - -@code { - [Parameter] - public string Avatar { get; set; } - - [Parameter] - public StringNumber Size { get; set; } - - private string _defaultAvatar = "https://cdn.masastack.com/stack/images/avatar/mr.chen.svg"; -} diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Editor/DefaultEditor.razor b/src/Web/Masa.Mc.Web.Admin/Components/Editor/DefaultEditor.razor deleted file mode 100644 index fdf8ed58..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Editor/DefaultEditor.razor +++ /dev/null @@ -1,3 +0,0 @@ -@inherits AdminCompontentBase - - \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Editor/DefaultEditor.razor.cs b/src/Web/Masa.Mc.Web.Admin/Components/Editor/DefaultEditor.razor.cs deleted file mode 100644 index a38e4328..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Editor/DefaultEditor.razor.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Components.Editor; - -public partial class DefaultEditor : AdminCompontentBase -{ - [Parameter] - public string Value { get; set; } = string.Empty; - - [Parameter] - public EventCallback ValueChanged { get; set; } - - [Parameter] - public string ContentClass { get; set; } = default!; - - [Parameter] - public string ContentStyle { get; set; } = default!; - - [Parameter] - public string? Placeholder { get; set; } - - [Parameter] - public bool ReadOnly { get; set; } - - private OssService OssService => McCaller.OssService; - - private MEditor Ref { get; set; } = default!; - - private IJSObjectReference VditorHelper = default!; - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - await base.OnAfterRenderAsync(firstRender); - if (IsDisposed || !firstRender) - { - return; - } - VditorHelper = await Js.InvokeAsync("import", "./_content/Masa.Mc.Web.Admin/js/vditor/quill-helper.js"); - } - - private async Task HandleUploadAsync(List flist) - { - var paramter = await OssService.GetSecurityTokenAsync(); - await VditorHelper.InvokeVoidAsync("upload", Ref.Ref, paramter); - return true; - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Components/ExtraProperties.razor b/src/Web/Masa.Mc.Web.Admin/Components/ExtraProperties.razor deleted file mode 100644 index dbed1ba3..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/ExtraProperties.razor +++ /dev/null @@ -1,83 +0,0 @@ -@inherits AdminCompontentBase - -
- @T("AdditionalFields") - @if (!Readonly) - { - - mdi-plus - - } -
- - @foreach (var item in _items) - { - - - : - - - - - - @if (!Readonly) - { - - mdi-delete - - } - - - - } - - -@code { - [Parameter] - public ExtraPropertyDictionary Value { get; set; } = new(); - - [Parameter] - public EventCallback ValueChanged { get; set; } - - [Parameter] - public bool Readonly { get; set; } - - private List _items = new(); - - protected override void OnParametersSet() - { - if (!_items.Any() || (_items.Count == 1 && string.IsNullOrWhiteSpace(_items[0].Name))) - { - _items = Value.Select(x => new ItemDto(x.Key, x.Value?.ToString() ?? string.Empty)).ToList(); - } - - if (!_items.Any()) - { - _items.Add(new ItemDto()); - } - - } - - public async Task HandleChangeAsync() - { - foreach (var item in _items) - { - if (string.IsNullOrWhiteSpace(item.Name)) - continue; - - Value.AddOrUpdate(item.Name, item.Value, (a,b) => item.Value); - } - - await ValueChanged.InvokeAsync(Value); - } - - public void HandleAdd() - { - _items.Add(new ItemDto()); - } - - public void HandleDel(ItemDto item) - { - _items.Remove(item); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Components/GenericColumnRender/DefaultGenericColumnRender.razor b/src/Web/Masa.Mc.Web.Admin/Components/GenericColumnRender/DefaultGenericColumnRender.razor deleted file mode 100644 index fa62b8ab..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/GenericColumnRender/DefaultGenericColumnRender.razor +++ /dev/null @@ -1,34 +0,0 @@ -@if (Value is DateTime dateTime) -{ - -} -else if (Value is DateTimeOffset dateTimeOffset) -{ - -} -else -{ - if(Width != null) - { -
- - @Value - -
- } - else - { -
@Value
- } -} - -@code { - [Parameter] - public object? Value { get; set; } - - [Parameter] - public StringNumber? Width { get; set; } - - [Inject] - public JsInitVariables JsInitVariables { get; set; } = default!; -} diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Group/ColorsGroup.razor b/src/Web/Masa.Mc.Web.Admin/Components/Group/ColorsGroup.razor deleted file mode 100644 index 456b67ae..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Group/ColorsGroup.razor +++ /dev/null @@ -1,36 +0,0 @@ -
- @foreach (var item in Colors) - { - @if (Value == item) - { -
- } - else - { -
-
-
- } - } -
- -@code { - [EditorRequired] - [Parameter] - public List Colors { get; set; } = new(); - - [Parameter] - public string Value { get; set; } = string.Empty; - - [Parameter] - public int Size { get; set; } = 20; - - [Parameter] - public EventCallback ValueChanged { get; set; } - - private async Task OnClickHandler(string color) - { - Value = color; - await ValueChanged.InvokeAsync(color); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Lists/DateTimeListItem.razor b/src/Web/Masa.Mc.Web.Admin/Components/Lists/DateTimeListItem.razor deleted file mode 100644 index 1f2e7cc3..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Lists/DateTimeListItem.razor +++ /dev/null @@ -1,12 +0,0 @@ -@inherits AdminCompontentBase - - - @Value?.ToString(T("$DateFormat")) - @Value?.ToString(T("$TimeFormat")) - - - -@code { - [Parameter] - public DateTimeOffset? Value { get; set; } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Markdown/DefaultMarkdown.razor b/src/Web/Masa.Mc.Web.Admin/Components/Markdown/DefaultMarkdown.razor deleted file mode 100644 index e958713a..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Markdown/DefaultMarkdown.razor +++ /dev/null @@ -1,3 +0,0 @@ -@inherits AdminCompontentBase - - \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Markdown/DefaultMarkdown.razor.cs b/src/Web/Masa.Mc.Web.Admin/Components/Markdown/DefaultMarkdown.razor.cs deleted file mode 100644 index 02c7f30b..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Markdown/DefaultMarkdown.razor.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Components.Markdown; - -public partial class DefaultMarkdown: AdminCompontentBase -{ - [Parameter] - public string Value { get; set; } = string.Empty; - - [Parameter] - public string Html { get; set; } = string.Empty; - - [Parameter] - public bool Reaonly { get; set; } - - [Parameter] - public EventCallback ValueChanged { get; set; } - - [Parameter] - public EventCallback HtmlChanged { get; set; } - - private OssService OssService => McCaller.OssService; - - private MMarkdown Ref { get; set; } = default!; - - private IJSObjectReference VditorHelper = default!; - - protected override void OnInitialized() - { - base.OnInitialized(); - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - await base.OnAfterRenderAsync(firstRender); - if (IsDisposed || !firstRender) - { - return; - } - VditorHelper = await Js.InvokeAsync("import", "./_content/Masa.Mc.Web.Admin/js/vditor/vditor-helper.js"); - } - - private async Task HandleUploadAsync() - { - var paramter = await OssService.GetSecurityTokenAsync(); - await VditorHelper.InvokeVoidAsync("upload", Ref.Ref, paramter); - } - - public async ValueTask DisposeAsync() - { - try - { - if (VditorHelper != null) - { - await VditorHelper.DisposeAsync(); - } - } - catch (Exception) - { - } - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Components/MenuTooltip.razor b/src/Web/Masa.Mc.Web.Admin/Components/MenuTooltip.razor deleted file mode 100644 index c0b2d01c..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/MenuTooltip.razor +++ /dev/null @@ -1,23 +0,0 @@ - - - - mdi-help-circle-outline - - - - @((MarkupString)Tooltip) - - - -@code { - [Parameter] - public string Tooltip { get; set; } - - [Parameter] - public string Class { get; set; } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageRecords/MessageRecordStatusTag.razor b/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageRecords/MessageRecordStatusTag.razor deleted file mode 100644 index 4c974254..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageRecords/MessageRecordStatusTag.razor +++ /dev/null @@ -1,14 +0,0 @@ -@inherits AdminCompontentBase -@if (Value == true) -{ - @T("Success") -} -else if (Value == false) -{ - @T("Failure") -} - -@code { - [Parameter] - public bool? Value { get; set; } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageRecords/MessageRecordStatusTag.razor.css b/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageRecords/MessageRecordStatusTag.razor.css deleted file mode 100644 index 798249e3..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageRecords/MessageRecordStatusTag.razor.css +++ /dev/null @@ -1,10 +0,0 @@ -.tag { - border-radius: 18px; - display: inline-flex; - justify-content: center; - align-items: center; - padding: 8px; - min-width: 56px; - border-radius: 18px; - height: 27px; -} diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTasks/MessageTaskHistorySelect.razor b/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTasks/MessageTaskHistorySelect.razor deleted file mode 100644 index 2bc9141e..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTasks/MessageTaskHistorySelect.razor +++ /dev/null @@ -1,22 +0,0 @@ -@inherits AdminCompontentBase - - \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTasks/MessageTaskHistorySelect.razor.cs b/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTasks/MessageTaskHistorySelect.razor.cs deleted file mode 100644 index 83eb556b..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTasks/MessageTaskHistorySelect.razor.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Components.Modules.MessageTasks; - -public partial class MessageTaskHistorySelect : AdminCompontentBase -{ - [Parameter] - public Guid? Value { get; set; } - - [Parameter] - public EventCallback ValueChanged { get; set; } - - [Parameter] - public string Placeholder { get; set; } = ""; - - [Parameter] - public string? Label { get; set; } - - [Parameter] - public EventCallback OnClearClick { get; set; } - - [Parameter] - public EventCallback OnSelectedItemUpdate { get; set; } - - private bool _isLoading; - - protected List Items = new(); - - private GetMessageTaskHistoryInputDto _queryParam = new(); - - MessageTaskHistoryService MessageTaskHistoryService => McCaller.MessageTaskHistoryService; - - public async Task UpdateSearchInputAsync(string val) - { - if (Items.Count > 0) return; - if (_isLoading) return; - _isLoading = true; - _queryParam.Filter = val; - Items = (await MessageTaskHistoryService.GetListAsync(_queryParam)).Result; - _isLoading = false; - } -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTasks/MessageTaskHistoryStatusIcon.razor b/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTasks/MessageTaskHistoryStatusIcon.razor deleted file mode 100644 index 62394769..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTasks/MessageTaskHistoryStatusIcon.razor +++ /dev/null @@ -1,53 +0,0 @@ -@switch (Value) -{ - case MessageTaskHistoryStatuses.WaitSend: - - mdi-clock-outline - - break; - case MessageTaskHistoryStatuses.Sending: - - mdi-dots-horizontal-circle-outline - - break; - case MessageTaskHistoryStatuses.Withdrawn: - - mdi-keyboard-return - - break; - case MessageTaskHistoryStatuses.Success: - - mdi-check-circle-outline - - break; - case MessageTaskHistoryStatuses.Fail: - - mdi-close-circle-outline - - break; - case MessageTaskHistoryStatuses.PartialFailure: - - mdi-minus-circle-outline - - break; -} - -@code { - [Parameter] - public MessageTaskHistoryStatuses Value { get; set; } - - [Parameter] - public StringNumber? Size { get; set; } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTasks/MessageTaskReceiverAutoComplete.razor b/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTasks/MessageTaskReceiverAutoComplete.razor deleted file mode 100644 index e500536c..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTasks/MessageTaskReceiverAutoComplete.razor +++ /dev/null @@ -1,28 +0,0 @@ -@inherits AdminCompontentBase - - - - mdi-magnify - - - @RenderFragments.UserSelectItem(data.Item.Avatar, data.Item.DisplayName, T($"DisplayName.MessageTaskReceiverTypes.{data.Item.Type}"), data.Item.PhoneNumber, data.Item.Email) - - \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTasks/MessageTaskReceiverAutoComplete.razor.cs b/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTasks/MessageTaskReceiverAutoComplete.razor.cs deleted file mode 100644 index 6480e649..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTasks/MessageTaskReceiverAutoComplete.razor.cs +++ /dev/null @@ -1,56 +0,0 @@ -namespace Masa.Mc.Web.Admin.Components.Modules.MessageTasks; -public partial class MessageTaskReceiverAutoComplete : AdminCompontentBase -{ - [Parameter] - public List SelectedValues { get; set; } = new(); - - [Parameter] - public EventCallback OnRemove { get; set; } - - [Parameter] - public EventCallback OnAdd { get; set; } - - public List Items { get; set; } = new(); - - public string Search { get; set; } = ""; - - MessageTaskService MessageTaskService => McCaller.MessageTaskService; - - public async Task OnSearchChanged(string search) - { - Search = search; - if (Search == "") - { - Items.Clear(); - } - else if (Search == search) - { - var items = await MessageTaskService.GetMessageTaskReceiverListAsync(search); - Items = items.Where(x => !SelectedValues.Contains(x.SubjectId)).ToList(); - } - } - - public string TextView(MessageTaskReceiverDto subject) - { - if (!string.IsNullOrEmpty(subject.DisplayName)) return subject.DisplayName; - if (!string.IsNullOrEmpty(subject.PhoneNumber)) return subject.PhoneNumber; - if (!string.IsNullOrEmpty(subject.Email)) return subject.Email; - return ""; - } - - public void ResetForm() - { - Items = new(); - } - - public void HandleOnSelectedItemUpdate(MessageTaskReceiverDto item) - { - Items.Remove(item); - - if (OnAdd.HasDelegate) - { - OnAdd.InvokeAsync(item); - } - } -} - diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTasks/MessageTaskStatus.razor b/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTasks/MessageTaskStatus.razor deleted file mode 100644 index fdeac037..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTasks/MessageTaskStatus.razor +++ /dev/null @@ -1,33 +0,0 @@ -@inherits AdminCompontentBase -@switch (Value) -{ - case MessageTaskStatuses.WaitSend: - mdi-clock-outline - @T("DisplayName.MessageTaskStatus.WaitSend") - break; - case MessageTaskStatuses.Sending: - mdi-dots-horizontal-circle-outline - @T("DisplayName.MessageTaskStatus.Sending") - break; - case MessageTaskStatuses.Cancel: - mdi-dots-horizontal-circle-outline - @T("DisplayName.MessageTaskStatus.Cancel") - break; - case MessageTaskStatuses.Success: - mdi-checkbox-marked-circle-outline - @T("DisplayName.MessageTaskStatus.Success") - break; - case MessageTaskStatuses.Fail: - mdi-close-circle-outline - @T("DisplayName.MessageTaskStatus.Fail") - break; - case MessageTaskStatuses.PartialFailure: - mdi-minus-circle-outline - @T("DisplayName.MessageTaskStatus.PartialFailure") - break; -} - -@code { - [Parameter] - public MessageTaskStatuses Value { get; set; } -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTemplates/MessageTemplateAuditStatusTag.razor b/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTemplates/MessageTemplateAuditStatusTag.razor deleted file mode 100644 index 8b2c2a7b..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTemplates/MessageTemplateAuditStatusTag.razor +++ /dev/null @@ -1,18 +0,0 @@ -@inherits AdminCompontentBase -@switch (Value) -{ - case MessageTemplateAuditStatuses.WaitAudit: - @T("WaitAudit") - break; - case MessageTemplateAuditStatuses.Adopt: - @T("Adopt") - break; - case MessageTemplateAuditStatuses.Fail: - @T("Fail") - break; -} - -@code { - [Parameter] - public MessageTemplateAuditStatuses Value { get; set; } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTemplates/MessageTemplateSelect.razor b/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTemplates/MessageTemplateSelect.razor deleted file mode 100644 index 4dd9ef48..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTemplates/MessageTemplateSelect.razor +++ /dev/null @@ -1,21 +0,0 @@ -@inherits AdminCompontentBase - - \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTemplates/MessageTemplateSelect.razor.cs b/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTemplates/MessageTemplateSelect.razor.cs deleted file mode 100644 index 9b117233..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTemplates/MessageTemplateSelect.razor.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Components.Modules.MessageTemplates; - -public partial class MessageTemplateSelect : AdminCompontentBase -{ - [Parameter] - public Guid? Value { get; set; } - - [Parameter] - public EventCallback ValueChanged { get; set; } - - [Parameter] - public string Placeholder { get; set; } = ""; - - [Parameter] - public string? Label { get; set; } - - [Parameter] - public EventCallback OnClearClick { get; set; } - - [Parameter] - public EventCallback OnSelectedItemUpdate { get; set; } - - private bool _isLoading; - - protected List Items = new(); - - private GetMessageTemplateInputDto _queryParam = new(); - - MessageTemplateService MessageTemplateService => McCaller.MessageTemplateService; - - public async Task UpdateSearchInputAsync(string val) - { - if (Items.Count > 0) return; - if (_isLoading) return; - _isLoading = true; - _queryParam.Filter = val; - Items = (await MessageTemplateService.GetListAsync(_queryParam)).Result; - _isLoading = false; - } -} - diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTemplates/MessageTemplateStatusTag.razor b/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTemplates/MessageTemplateStatusTag.razor deleted file mode 100644 index bf851bdf..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Modules/MessageTemplates/MessageTemplateStatusTag.razor +++ /dev/null @@ -1,15 +0,0 @@ -@inherits AdminCompontentBase -@switch (Value) -{ - case MessageTemplateStatuses.Invalid: - @T("DisplayName.MessageTemplateStatus.Invalid") - break; - case MessageTemplateStatuses.Normal: - @T("DisplayName.MessageTemplateStatus.Normal") - break; -} - -@code { - [Parameter] - public MessageTemplateStatuses Value { get; set; } -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/ExternalUserCreateModal.razor b/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/ExternalUserCreateModal.razor deleted file mode 100644 index 72c87675..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/ExternalUserCreateModal.razor +++ /dev/null @@ -1,25 +0,0 @@ -@inherits AdminCompontentBase -
- - - - - - - - - - @(T("Submit")) - - -
diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/ExternalUserCreateModal.razor.cs b/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/ExternalUserCreateModal.razor.cs deleted file mode 100644 index 3857c58c..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/ExternalUserCreateModal.razor.cs +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Components.Modules.Subjects; - -public partial class ExternalUserCreateModal : AdminCompontentBase -{ - [Parameter] - public EventCallback OnOk { get; set; } - - [Inject] - public IAuthClient AuthClient { get; set; } = default!; - - private CreateExternalUserDto _model = new(); - private bool _visible; - - private MForm _form; - - public async Task OpenModalAsync() - { - ResetForm(); - await InvokeAsync(() => - { - _visible = true; - StateHasChanged(); - }); - } - - private void HandleCancel() - { - _visible = false; - _form?.Reset(); - } - - private async Task HandleOk() - { - if (!_form.Validate()) - { - return; - } - - var user = await CreateExternalUserAsync(_model); - - _visible = false; - _form?.Reset(); - - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(user); - } - } - - private void ResetForm() - { - _model = new(); - } - - private async Task CreateExternalUserAsync(CreateExternalUserDto dto) - { - var requestData = new AddUserModel - { - Account = dto.PhoneNumber ?? dto.Email, - Name = dto.DisplayName, - DisplayName = dto.DisplayName, - PhoneNumber = dto.PhoneNumber, - Email = dto.Email - }; - var user = await AuthClient.UserService.AddAsync(requestData); - return user.Adapt(); ; - } -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/SubjectAutoComplete.razor b/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/SubjectAutoComplete.razor deleted file mode 100644 index a564392b..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/SubjectAutoComplete.razor +++ /dev/null @@ -1,29 +0,0 @@ -@inherits AdminCompontentBase - - - - mdi-magnify - - - @RenderFragments.UserSelectItem(data.Item.Avatar, data.Item.DisplayName, T($"DisplayName.SubjectTypes.{data.Item.SubjectType}"), data.Item.PhoneNumber, data.Item.Email) - - - \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/SubjectAutoComplete.razor.cs b/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/SubjectAutoComplete.razor.cs deleted file mode 100644 index e7dd0490..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/SubjectAutoComplete.razor.cs +++ /dev/null @@ -1,59 +0,0 @@ -namespace Masa.Mc.Web.Admin.Components.Modules.Subjects; -public partial class SubjectAutoComplete : AdminCompontentBase -{ - [Parameter] - public List SelectedValues { get; set; } = new(); - - [Parameter] - public EventCallback OnAdd { get; set; } - - [Parameter] - public EventCallback OnBlur { get; set; } - - public List Items { get; set; } = new(); - - public string Search { get; set; } = ""; - - [Inject] - public IAuthClient AuthClient { get; set; } = default!; - - public async Task OnSearchChanged(string search) - { - Search = search; - if (Search == "") - { - Items.Clear(); - } - else if (Search == search) - { - var subjects = await AuthClient.SubjectService.GetListAsync(search); - var dtos = subjects.Adapt>(); - Items = dtos.Where(x => !SelectedValues.Contains(x.SubjectId)).ToList(); - } - } - - public string TextView(SubjectDto subject) - { - if (!string.IsNullOrEmpty(subject.Name)) return subject.Name; - if (!string.IsNullOrEmpty(subject.DisplayName)) return subject.DisplayName; - if (!string.IsNullOrEmpty(subject.PhoneNumber)) return subject.PhoneNumber; - if (!string.IsNullOrEmpty(subject.Email)) return subject.Email; - return ""; - } - - public void ResetForm() - { - Items = new(); - } - - public void HandleOnSelectedItemUpdate(SubjectDto item) - { - Items.Remove(item); - - if (OnAdd.HasDelegate) - { - OnAdd.InvokeAsync(item); - } - } -} - diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/UserAutoComplete.razor b/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/UserAutoComplete.razor deleted file mode 100644 index 0645298b..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/UserAutoComplete.razor +++ /dev/null @@ -1,31 +0,0 @@ -@inherits AdminCompontentBase - - - - mdi-magnify - - - @RenderFragments.UserSelectItem(data.Item.Avatar, data.Item.DisplayName, T($"DisplayName.SubjectTypes.User"), data.Item.PhoneNumber, data.Item.Email) - - \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/UserAutoComplete.razor.cs b/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/UserAutoComplete.razor.cs deleted file mode 100644 index 0ee4db91..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/UserAutoComplete.razor.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Components.Modules.Subjects; - -public partial class UserAutoComplete : AdminCompontentBase -{ - [Parameter] - public List Value { get; set; } = new(); - - [Parameter] - public EventCallback> ValueChanged { get; set; } - - public List Items { get; set; } = new(); - - public List UserSelect { get; set; } = new(); - - public string Search { get; set; } = ""; - - [Inject] - public IAuthClient AuthClient { get; set; } = default!; - - public async Task OnSearchChanged(string search) - { - Search = search; - if (Search == "") - { - Items.Clear(); - } - else if (Search == search) - { - var response = await AuthClient.UserService.SearchAsync(search); - Items = response; - } - } - - public string TextView(UserSelectModel user) - { - if (!string.IsNullOrEmpty(user.DisplayName)) return user.DisplayName; - if (!string.IsNullOrEmpty(user.Account)) return user.Account; - if (!string.IsNullOrEmpty(user.PhoneNumber)) return user.PhoneNumber; - if (!string.IsNullOrEmpty(user.Email)) return user.Email; - return ""; - } - - private async Task HandleValueChanged(List value) - { - value = value ?? new(); - var list = Items.Where(x => value.Contains(x.Id)).ToList(); - UserSelect = list; - if (ValueChanged.HasDelegate) - { - await ValueChanged.InvokeAsync(value); - } - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/UserSelect.razor b/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/UserSelect.razor deleted file mode 100644 index 9d843e58..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/UserSelect.razor +++ /dev/null @@ -1,24 +0,0 @@ -@inherits AdminCompontentBase - - - - @RenderFragments.UserSelectItem(data.Item.Avatar, data.Item.DisplayName, data.Item.Name, data.Item.PhoneNumber, data.Item.Email) - - \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/UserSelect.razor.cs b/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/UserSelect.razor.cs deleted file mode 100644 index 0820bbdc..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Modules/Subjects/UserSelect.razor.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Components.Modules.Subjects; - -public partial class UserSelect : AdminCompontentBase -{ - [Parameter] - public Guid? Value { get; set; } - - [Parameter] - public EventCallback ValueChanged { get; set; } - - [Parameter] - public string Placeholder { get; set; } = ""; - - [Parameter] - public string Label { get; set; } = default!; - - [Parameter] - public EventCallback OnClearClick { get; set; } - - [Parameter] - public EventCallback OnSelectedItemUpdate { get; set; } - - protected List Items = new(); - - public string Search { get; set; } = ""; - - [Inject] - public IAuthClient AuthClient { get; set; } = default!; - - public async Task OnSearchChanged(string search) - { - Search = search; - if (Search == "") - { - Items.Clear(); - } - else if (Search == search) - { - var response = await AuthClient.UserService.SearchAsync(search); - Items = response; - } - } - - public string TextView(UserSelectModel user) - { - if (!string.IsNullOrEmpty(user.DisplayName)) return user.DisplayName; - if (!string.IsNullOrEmpty(user.Name)) return user.Name; - if (!string.IsNullOrEmpty(user.Account)) return user.Account; - if (!string.IsNullOrEmpty(user.PhoneNumber)) return user.PhoneNumber; - if (!string.IsNullOrEmpty(user.Email)) return user.Email; - return ""; - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Components/RichText/DefaultRichText.razor b/src/Web/Masa.Mc.Web.Admin/Components/RichText/DefaultRichText.razor deleted file mode 100644 index a54f4c87..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/RichText/DefaultRichText.razor +++ /dev/null @@ -1,25 +0,0 @@ -
-
-
-
-
- -
- @((MarkupString)Value) -
-
- -
-
-
- -@code { - [Parameter] - public string Value { get; set; } = string.Empty; - - [Parameter] - public string Label { get; set; } = string.Empty; - - [Parameter] - public int Height { get; set; } = 128; -} diff --git a/src/Web/Masa.Mc.Web.Admin/Components/RichText/DefaultRichText.razor.css b/src/Web/Masa.Mc.Web.Admin/Components/RichText/DefaultRichText.razor.css deleted file mode 100644 index cd355ed8..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/RichText/DefaultRichText.razor.css +++ /dev/null @@ -1,15 +0,0 @@ -.content { - position: relative; - color: #333; - font-size: 15px; - line-height: 30px; - width:100%; -} - - .content ::deep p { - margin: 10px 0; - } - - .content ::deep img { - max-width: 100%; - } diff --git a/src/Web/Masa.Mc.Web.Admin/Components/RichText/RichText.razor b/src/Web/Masa.Mc.Web.Admin/Components/RichText/RichText.razor deleted file mode 100644 index b4b30a9a..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/RichText/RichText.razor +++ /dev/null @@ -1,9 +0,0 @@ -
@((MarkupString)Value)
- -@code { - [Parameter] - public string Value { get; set; } = string.Empty; - - [Parameter] - public int Height { get; set; } = 300; -} diff --git a/src/Web/Masa.Mc.Web.Admin/Components/RichText/RichText.razor.css b/src/Web/Masa.Mc.Web.Admin/Components/RichText/RichText.razor.css deleted file mode 100644 index 98bfd3c6..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/RichText/RichText.razor.css +++ /dev/null @@ -1,12 +0,0 @@ -.detail-box { - background: #F0F3FA; - border-radius: 4px; -} - .detail-box .content { - position: relative; - color: #333; - font-size: 15px; - } - .detail-box .content ::deep img { - max-width: 100%; - } diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Selects/BooleanSelect.razor b/src/Web/Masa.Mc.Web.Admin/Components/Selects/BooleanSelect.razor deleted file mode 100644 index 947a6db6..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Selects/BooleanSelect.razor +++ /dev/null @@ -1,15 +0,0 @@ -@inherits AdminCompontentBase - - \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Selects/BooleanSelect.razor.cs b/src/Web/Masa.Mc.Web.Admin/Components/Selects/BooleanSelect.razor.cs deleted file mode 100644 index ed45e683..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Selects/BooleanSelect.razor.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Components.Selects; - -public partial class BooleanSelect -{ - [Parameter] - public string Placeholder { get; set; } = ""; - - [Parameter] - public string? Label { get; set; } - - [Parameter] - public bool? Value { get; set; } - - [Parameter] - public EventCallback ValueChanged { get; set; } - - [Parameter] - public List> Items { get; set; } = new(); - - [Parameter] - public EventCallback OnClearClick { get; set; } - - [Parameter] - public EventCallback> OnSelectedItemUpdate { get; set; } - - public List> KeyValues { get; set; } = new(); - - protected override void OnParametersSet() - { - KeyValues = Items.Any() ? Items : GetBooleanMap(); - } -} - diff --git a/src/Web/Masa.Mc.Web.Admin/Components/StyleTypes.cs b/src/Web/Masa.Mc.Web.Admin/Components/StyleTypes.cs deleted file mode 100644 index 693593e3..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/StyleTypes.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Components; - -public enum StyleTypes -{ - Slider, - Toggle, -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Components/TextField/DefaultSearch.razor b/src/Web/Masa.Mc.Web.Admin/Components/TextField/DefaultSearch.razor deleted file mode 100644 index a25e04c0..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/TextField/DefaultSearch.razor +++ /dev/null @@ -1,59 +0,0 @@ - - - mdi-magnify - - - -@code { - - [Parameter] - public string? Value { get; set; } - - [Parameter] - public EventCallback ValueChanged { get; set; } - - [Parameter] - public string? Class { get; set; } - - [Parameter] - public bool Dense { get; set; } - - [Parameter] - public EventCallback OnEnter { get; set; } - - [Parameter] - public string? Style { get; set; } - - [Parameter] - public string Placeholder { get; set; } = ""; - - [Parameter] - public string BackgroundColor { get; set; } = default!; - - [Parameter] - public bool Clearable { get; set; } - - [Parameter] - public EventCallback OnClearClick { get; set; } - - private async Task HandleOnKeyDown(KeyboardEventArgs args) - { - if (args.Key == "Enter" && OnEnter.HasDelegate) - { - await OnEnter.InvokeAsync(); - } - } - -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Components/Upload/ProgressUpload.razor b/src/Web/Masa.Mc.Web.Admin/Components/Upload/ProgressUpload.razor deleted file mode 100644 index c9a393ac..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Components/Upload/ProgressUpload.razor +++ /dev/null @@ -1,32 +0,0 @@ -@inherits AdminCompontentBase -
- -
- - - - - -
-
-
- -@code { - private int progress = 0; - - private async void HandleFileChange(IBrowserFile file) - { - await using var memoryStream = new MemoryStream(); - await file.OpenReadStream().CopyToAsync(memoryStream); - var fileContent = memoryStream.ToArray(); - progress = 100; - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Consts/IconConsts.cs b/src/Web/Masa.Mc.Web.Admin/Consts/IconConsts.cs deleted file mode 100644 index e6001393..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Consts/IconConsts.cs +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Consts; - -public static class IconConsts -{ - public const string J_PUSH_SVG = "M584.282353 169.200941c-63.668706-10.962824-114.447059 7.529412-143.239529 42.104471-92.762353 111.194353-66.800941 439.958588 103.966117 553.803294 46.742588 31.021176-203.474824 107.339294-338.582588 136.734118-135.168 29.274353-206.426353 42.586353-206.426353-12.227765C0 571.151059 291.237647 120.470588 512.903529 120.470588c35.84 0 73.487059 11.745882 111.254589 32.768 29.274353 17.829647 58.608941 39.936 82.642823 61.620706a460.8 460.8 0 0 1 22.287059 13.673412C886.302118 385.505882 1023.819294 670.418824 1024 888.591059c0 24.395294-25.780706-13.492706-68.065882-57.946353-22.407529-23.431529-48.188235-48.730353-74.089412-71.68-65.054118-54.814118-238.170353-214.618353-445.199059-247.68753-2.469647-0.301176-42.465882-176.971294 6.505412-274.492235 31.924706-63.789176 87.461647-75.474824 141.131294-67.584z"; - public const string GETUI_SVG = "M540.928 96.128a69.024 69.024 0 0 1 64.512 9.504c6.24 4.576 10.976 9.28 14.592 14.208 4.448 6.016 7.168 12.352 8.864 19.296 2.336 9.6 2.72 20.256 2.72 32.576 0-18.048 20.48-47.008 33.6-57.792 25.728-21.088 62.176-14.528 84.64 8.416 19.456 19.904 35.168 79.168-6.848 81.344-12.064 0.672-17.6-7.392-24.32-15.04a54.656 54.656 0 0 0-6.848-6.752c-17.568-13.856-31.392-16.896-42.336-12.96-18.176 6.592-28.192 32.576-33.28 60.256a137.28 137.28 0 0 1 56.704 12.544c21.024 9.632 44.672 31.584 51.744 58.24 8.704 32.704 16.8 151.104-1.664 265.184-3.68 0.48-7.36 1.024-11.104 1.6-7.072 1.024-17.44 1.6-27.424 2.144-9.984 0.48-20.288 1.088-28.192 2.144-26.176 3.552-48.128 26.24-48.96 50.624-0.768 20.256 13.312 35.392 37.536 40.416 6.304 1.312 12.896 1.984 19.712 1.984a136.96 136.96 0 0 0 35.84-5.28c-21.632 64.832-32.288 103.264-13.12 145.952 18.016 40.192 49.6 23.712 73.344-2.912 17.952-20.128 32.256-49.248 8.288-77.632-29.024-34.496-51.2-44.576-48.416-63.264 0.544-3.552 1.568-6.848 3.008-9.984 8.32-18.144 30.912-29.536 54.464-28.32 8.608 0.448 17.344 2.56 25.568 6.624 30.688 15.328 53.952 48.928 42.88 77.696 20.736-18.688 46.144-22.368 67.84-10.08 15.232 8.64 29.312 26.016 24.896 47.488-4.16 20.128-72.832 9.408-98.24 58.944-18.624 36.32-39.616 66.272-74.464 86.208v0.704a9.28 9.28 0 0 1-1.696 5.056 17.28 17.28 0 0 1-2.56 2.944 44.48 44.48 0 0 1-6.752 5.12 122.88 122.88 0 0 1-22.72 10.88c-16.672 6.272-44.128 13.76-80.224 13.76-5.504 0-11.104-0.224-16.608-0.544-18.496 2.56-41.184 4.672-65.824 4.672-6.688 0-13.216-0.128-19.68-0.448a173.536 173.536 0 0 1-18.016 0.8c-22.88 0-69.536-3.392-128.32-25.536-74.112-9.056-131.488-38.176-170.56-86.688-34.144-42.336-43.04-86.656-44.992-99.232a161.6 161.6 0 0 1-1.76-23.168c0-1.536 0.032-3.04 0.128-4.512a277.632 277.632 0 0 1-3.616-26.24c-3.008-30.656-2.144-61.024-4.576-90.816a296.544 296.544 0 0 0-3.456-27.52c-5.568-31.616-13.856-27.232-13.856-57.536 0-21.6 15.488-23.2 15.712-42.784 0.32-28.224-3.84-58.72-3.616-87.904 0.192-26.656 5.344-32.928 22.304-54.08 3.84-4.704 8.32-8.864 13.76-12.288 47.84-30.496 112.192-34.816 167.744-37.376 24.096-1.088 128.096-16.16 158.144-20.128 16.32-2.144 31.328-4.288 45.472-5.792 0.32-8.32 0.32-16.576 0.32-25.28 0-14.368-2.048-29.568-13.184-38.72a33.088 33.088 0 0 0-6.496-4.128c-12.288-5.824-19.968-1.984-26.624 4.128-9.6 8.768-16.896 22.208-32.48 17.44-13.664-4.224-19.488-15.456-20.64-29.792a53.76 53.76 0 0 1 7.84-31.168c4.704-7.968 11.072-15.008 18.272-20.192 4.128-3.008 8.48-5.472 12.96-7.072zM408.288 575.04c-2.688 0-5.632 0.32-8.704 0.864-17.376 3.232-25.984 8.64-31.712 19.904-3.392 6.816-5.696 16.352-7.04 29.568 0.224 1.888 0.416 3.712 0.416 5.504l-0.096 2.144c-0.128 4.064-0.224 8.384-0.224 13.12 0 82.656 31.584 152.416 93.824 207.328a307.424 307.424 0 0 0 114.72 62.592l2.048 0.544a392.064 392.064 0 0 0 31.04 0.224c-29.888-10.784-54.912-29.6-75.68-56.928-32.8-43.104-55.808-108.192-70.336-198.944l-0.576-3.904-0.64-3.936-0.608-7.104-0.224-6.784c0-7.136 0.8-13.792 2.272-19.968a196.256 196.256 0 0 0-5.408-10.72c-16.576-29.472-31.712-33.376-43.104-33.472z m-93.472 23.552c-12.992 0.096-23.424 8.288-29.664 23.2l-1.152 3.104a64.096 64.096 0 0 0-2.016 12 221.12 221.12 0 0 0-1.312 25.728c0 24.608 3.36 72.896 25.856 120.064 24.32 50.816 64.192 87.328 118.496 108.512l4.96 1.824a373.568 373.568 0 0 0 95.36 22.912 324.512 324.512 0 0 1-80.64-51.168c-40.096-35.296-68.448-77.728-84.256-125.344a296.288 296.288 0 0 1-14.656-93.28c0-4.064 0.096-8.48 0.256-13.76l0.032-1.536c0-1.888-0.224-3.68-0.48-5.408a31.808 31.808 0 0 0-30.784-26.848z m188-4.192a29.184 29.184 0 0 0-22.496 10.432 41.024 41.024 0 0 0-7.424 13.312 64.96 64.96 0 0 0-3.232 21.056c0 4.8 0.416 9.824 1.216 15.008l0.576 3.712 0.096 0.704c6.304 39.456 14.24 73.888 23.84 103.52 11.872 36.608 26.336 65.952 43.584 88.608 13.344 17.472 28.32 31.04 45.344 40.96 20.16 11.776 43.264 18.496 70.144 20.512l0.64 0.032c5.856 0.416 11.84 0.544 17.6 0.576 13.664 0 25.952-1.12 36.768-2.88a197.408 197.408 0 0 0 33.056-8.16c-4.448-0.448-9.6-1.152-15.488-2.016-27.072-1.312-69.248-8.16-107.104-34.464-50.72-35.136-77.504-96-77.472-176.16 0-13.696 0.864-28.32 2.368-43.36-1.024-4.736-2.016-9.28-2.944-13.248-6.72-28.192-25.216-38.208-39.072-38.208z m-249.984 42.432h-0.928c-4.608 0-12.288 3.904-18.848 14.816-7.168 11.84-11.104 28.224-11.104 46.176 0 6.752 0.544 13.792 1.6 20.928 1.76 11.616 9.984 52.608 41.792 92.032 26.464 32.736 62.144 56.096 106.304 69.76a222.688 222.688 0 0 1-78.752-91.392c-22.592-47.264-27.328-94.88-27.328-126.528 0-8.032 0.352-15.808 0.928-22.816-2.496-1.568-6.528-2.88-13.664-3.008z m314.848 1.056c-0.896 0-2.464 0.768-4.288 2.816a25.472 25.472 0 0 0-3.232 4.576c0 0.096-0.032 0.128-0.096 0.224-1.6 15.424-2.464 30.144-2.464 43.712 0.032 4.96 0.128 9.76 0.352 14.528 2.944 68.448 26.656 118.624 70.592 149.28 5.824 4.032 11.68 7.584 17.888 10.752-19.52-15.232-34.4-35.744-44.256-61.152a221.536 221.536 0 0 1-11.68-44.544c-3.616-21.952-4.672-43.488-5.504-62.272a454.4 454.4 0 0 0-1.824-28.8c-1.216-10.944-3.04-15.808-4.352-18.016a34.208 34.208 0 0 0-7.584-9.504c-2.112-1.6-3.104-1.6-3.552-1.6z m-390.336 11.104c-96.288-61.12-170.048-172.352-53.952-106.08 21.024 11.968 40.96 18.592 62.048 24.32 2.432 29.376 1.568 59.328 4.48 89.568-4.256-2.56-8.512-5.184-12.576-7.808z m627.712-83.424c32-13.792 37.056-9.216 37.856-7.488 1.76 3.808-4.256 14.656-21.6 30.336a272.064 272.064 0 0 1-60.16 40.512c-26.528 12.96-61.024 26.976-92.544 20.48-17.44-3.616-27.2-13.344-26.688-26.656 0.576-17.376 17.92-34.848 37.056-37.44 7.264-0.992 17.152-1.536 26.688-2.048 10.208-0.544 20.736-1.088 28.352-2.24 5.056-0.768 9.952-1.376 14.688-2.048 19.84-2.688 36.992-5.024 56.352-13.344z m-149.088-173.824a11.936 11.936 0 0 0-14.752 5.408c-1.792 2.816-2.272 5.472-1.472 7.808 1.472 4.128 6.4 5.728 10.784 7.168 1.216 0.416 2.432 0.768 3.456 1.216 6.752 2.88 13.408 8.832 12.416 13.184-6.496 29.472-49.632 26.464-153.888 19.296-8.48-0.576-17.28-1.216-26.528-1.792a726.208 726.208 0 0 0-95.616-0.672c-29.44 1.824-56.032 5.568-81.344 11.296-19.936 4.576-37.952 10.176-54.976 17.152a265.216 265.216 0 0 0-32.128 15.808l-4.704 2.72a108.736 108.736 0 0 1-3.808 2.272l-1.12 0.64-1.344 0.8a16.448 16.448 0 0 1 1.024-4.032c7.264-19.584 3.328-22.944 1.984-24l-1.216-1.088-1.472 0.704c-3.008 1.376-4.48 5.792-6.176 11.84-0.48 1.6-0.896 3.136-1.248 4a124.928 124.928 0 0 1-1.696 3.616c-1.696 3.68-3.456 7.424-4.48 11.616-1.376 6.08 0.128 11.008 4.064 13.216a9.696 9.696 0 0 0 4.96 1.248c5.344 0 11.328-3.232 14.784-6.08 23.712-19.392 88.224-43.04 173.92-49.248 37.632-2.688 75.168 1.792 114.944 6.592 34.688 4.128 70.528 8.416 107.392 7.744 54.112-0.992 59.904-33.6 60.352-43.552 0.768-15.04-11.52-31.392-22.144-34.912z m-125.024 94.816c-145.568-41.696-199.456-4.96-199.456-4.96 82.656-19.936 199.456 4.96 199.456 4.96zM279.136 283.264c-25.216 0-45.792 27.968-45.792 62.272 0 34.368 20.576 62.304 45.792 62.304 25.28 0 45.824-27.968 45.824-62.304 0-34.304-20.576-62.272-45.824-62.272z m-1.28 13.696c18.016 0 32.608 21.824 32.608 48.608s-14.592 48.576-32.608 48.576-32.672-21.76-32.672-48.576S259.84 296.96 277.856 296.96z m304.416-54.56c-26.464 0-48.064 29.312-48.064 65.376 0 36.032 21.6 65.376 48.064 65.376s48.032-29.344 48.032-65.376c0-8.064-1.088-15.712-3.008-22.848-4.736-17.28-14.784-31.136-27.36-37.952a37.056 37.056 0 0 0-17.664-4.576z m0.032 14.496c18.816 0 34.08 22.816 34.08 50.848 0 28-15.264 50.816-34.08 50.816s-34.144-22.816-34.144-50.816c0-28.032 15.328-50.848 34.144-50.848zM270.4 305.152c-9.184 0-16.608 10.56-16.608 23.552s7.424 23.552 16.608 23.552c9.184 0 16.608-10.56 16.608-23.552s-7.424-23.552-16.608-23.552z m304.064-39.872c-9.632 0-17.472 11.072-17.472 24.768 0 13.664 7.84 24.736 17.472 24.736 9.664 0 17.504-11.072 17.504-24.736 0-13.696-7.84-24.768-17.504-24.768z m33.728-145.44c20.8 31.008 13.632 97.088 13.632 97.088s7.136-15.68 7.136-46.688c0-35.744-20.736-50.4-20.736-50.4z m141.792 45.6c-12.096-47.424-66.976-31.712-78.368-27.872l-2.08 0.736c34.368-6.368 55.296 17.248 56.224 35.808 0.896 18.496 32.384 23.168 24.224-8.64z m-154.432-38.528c-13.664-28.32-58.912-34.048-78.144-1.824-20.352 34.144 4.352 50.528 19.04 37.312 6.368-5.696 1.312-21.632 12.672-33.792 8.96-9.536 29.536-17.216 46.4-1.696z"; -} diff --git a/src/Web/Masa.Mc.Web.Admin/Global/Config/GlobalConfig.cs b/src/Web/Masa.Mc.Web.Admin/Global/Config/GlobalConfig.cs deleted file mode 100644 index d5e4320f..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Global/Config/GlobalConfig.cs +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -using Masa.Mc.Web.Admin.Shared; - -namespace Masa.Mc.Web.Admin.Global -{ - public class GlobalConfig - { - #region Field - - private bool _Loading; - - #endregion - - #region Property - - public bool Loading - { - get => _Loading; - set - { - if (_Loading != value) - { - _Loading = value; - OnLoadingChanged?.Invoke(_Loading, LoadingText); - } - } - } - - public string LoadingText = string.Empty; - - public bool ThrottleFlag { get; set; } - - #endregion - - - #region event - - public delegate void GlobalConfigChanged(); - public delegate void LoadingChanged(bool loading, string loadingText); - - public event LoadingChanged? OnLoadingChanged; - - #endregion - } -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Global/Config/PageModes.cs b/src/Web/Masa.Mc.Web.Admin/Global/Config/PageModes.cs deleted file mode 100644 index 15d86d8f..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Global/Config/PageModes.cs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Global.Config -{ - public static class PageModes - { - public const string PageTab = "PageTab"; - public const string Breadcrumb = "Breadcrumb"; - } -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Global/ServiceCollectionExtensions.cs b/src/Web/Masa.Mc.Web.Admin/Global/ServiceCollectionExtensions.cs deleted file mode 100644 index 7bbb93e4..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Global/ServiceCollectionExtensions.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Microsoft.Extensions.DependencyInjection -{ - public static class ServiceCollectionExtensions - { - public static IServiceCollection AddGlobalForServer(this IServiceCollection services) - { - services.AddScoped(); - return services; - } - - public static IServiceCollection AddGlobalForWasmAsync(this IServiceCollection services, string baseUri) - { - services.AddScoped(); - return services; - } - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Masa.Mc.Web.Admin.csproj b/src/Web/Masa.Mc.Web.Admin/Masa.Mc.Web.Admin.csproj deleted file mode 100644 index d915f992..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Masa.Mc.Web.Admin.csproj +++ /dev/null @@ -1,43 +0,0 @@ - - - - net6.0 - enable - enable - - - - - - - - - - - - - - - - - - - - - - - - - - - Always - - - Always - - - Always - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/Model/AppMessageOptions.cs b/src/Web/Masa.Mc.Web.Admin/Model/AppMessageOptions.cs deleted file mode 100644 index 8dda9904..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Model/AppMessageOptions.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Model; - -public class AppMessageOptions -{ - public bool IsWebsiteMessage { get; set; } - - public string IntentUrl { get; set; } = string.Empty; - - public bool IsApnsProduction { get; set; } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Model/AppTemplateModel.cs b/src/Web/Masa.Mc.Web.Admin/Model/AppTemplateModel.cs deleted file mode 100644 index dd8d150d..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Model/AppTemplateModel.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Model; - -public class AppTemplateModel : MessageTemplateDto -{ - public new AppMessageOptions Options { get; set; } = new(); -} diff --git a/src/Web/Masa.Mc.Web.Admin/Model/AppTemplateUpsertModel.cs b/src/Web/Masa.Mc.Web.Admin/Model/AppTemplateUpsertModel.cs deleted file mode 100644 index f0ad81f3..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Model/AppTemplateUpsertModel.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Model; - -public class AppTemplateUpsertModel: MessageTemplateUpsertDto -{ - public new AppMessageOptions Options { get; set; } = new(); -} diff --git a/src/Web/Masa.Mc.Web.Admin/Model/MessageTaskUpsertModel.cs b/src/Web/Masa.Mc.Web.Admin/Model/MessageTaskUpsertModel.cs deleted file mode 100644 index 1d730c28..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Model/MessageTaskUpsertModel.cs +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Model; - -public class MessageTaskUpsertModel -{ - public string DisplayName { get; set; } = string.Empty; - - public Guid? ChannelId { get; set; } - - public ChannelTypes? ChannelType { get; set; } - - public MessageEntityTypes EntityType { get; set; } - - public Guid EntityId { get; set; } - - public bool IsDraft { get; set; } - - public bool IsEnabled { get; set; } - - public ReceiverTypes ReceiverType { get; set; } - - public MessageTaskSelectReceiverTypes SelectReceiverType { get; set; } = MessageTaskSelectReceiverTypes.ManualSelection; - - public string Sign { get; set; } = string.Empty; - - public List Receivers { get; set; } = new(); - - public SendRuleDto SendRules { get; set; } = new(); - - public MessageInfoUpsertDto MessageInfo { get; set; } = new(); - - public ExtraPropertyDictionary Variables { get; set; } = new(); - - public int Step { get; set; } = 1; - - public string SystemId { get; set; } = string.Empty; - - public AppMessageOptions ExtraProperties { get; set; } = new(); - - public bool ComputedJumpUrlShow - { - get - { - return ChannelType == ChannelTypes.WebsiteMessage || (ChannelType == ChannelTypes.App && ExtraProperties.IsWebsiteMessage) || (ChannelType == ChannelTypes.WeixinWork && MessageInfo.Type == (int)WeixinWorkTemplateTypes.TextCard); - } - } - - public bool ComputedTitleShow - { - get - { - return !(ChannelType == ChannelTypes.Sms || (ChannelType == ChannelTypes.WeixinWork && MessageInfo.Type == (int)WeixinWorkTemplateTypes.Text) || ChannelType == ChannelTypes.WeixinWorkWebhook); - } - } - - public bool ComputedJumpUrlRequired - { - get - { - return ChannelType == ChannelTypes.WeixinWork && MessageInfo.Type == (int)WeixinWorkTemplateTypes.TextCard; - } - } - - public bool ComputedMarkdown - { - get - { - return ChannelType != ChannelTypes.App && ChannelType != ChannelTypes.WeixinWork && ChannelType != ChannelTypes.WeixinWorkWebhook; - } - } - - public bool ComputedBroadcast - { - get - { - return ChannelType == ChannelTypes.WebsiteMessage || ChannelType == ChannelTypes.App || ChannelType == ChannelTypes.WeixinWork || ChannelType == ChannelTypes.WeixinWorkWebhook; - } - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Model/Validator/MessageTaskUpsertModelValidator.cs b/src/Web/Masa.Mc.Web.Admin/Model/Validator/MessageTaskUpsertModelValidator.cs deleted file mode 100644 index 97750b61..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Model/Validator/MessageTaskUpsertModelValidator.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Model.Validator; - -public class MessageTaskUpsertModelValidator : AbstractValidator -{ - public MessageTaskUpsertModelValidator() - { - RuleFor(model => model.ChannelType).Required("ChannelTypeRequired").When(m => m.Step == 1 && !m.IsDraft); - RuleFor(model => model.ChannelId).Required("ChannelIdRequired").When(m => m.Step == 1 && !m.IsDraft); - RuleFor(model => model.EntityId).Required("MessageTemplateRequired").When(m => m.EntityType == MessageEntityTypes.Template && m.Step == 1 && !m.IsDraft); - RuleFor(model => model.EntityType).IsInEnum().WithMessage("MessageTypeRequired").When(m => m.Step == 1 && !m.IsDraft); - RuleFor(model => model.MessageInfo).SetValidator(new MessageInfoUpsertDtoValidator()).When(m => m.EntityType == MessageEntityTypes.Ordinary && m.Step == 1 && !m.IsDraft); - - RuleFor(model => model.ReceiverType).IsInEnum().WithMessage("ReceiverTypeRequired").When(m => m.Step == 2 && !m.IsDraft); - RuleFor(model => model.SelectReceiverType).IsInEnum().WithMessage("SelectReceiverTypeRequired").When(m => m.Step == 2 && !m.IsDraft); - RuleFor(model => model.Receivers).Required("ReceiversRequired").When(m => m.ReceiverType == ReceiverTypes.Assign && m.Step == 2 && !m.IsDraft); - - RuleFor(model => model.Sign).Required("SignRequired").ChineseLetterNumber().Length(2, 12).When(m => m.ChannelType == ChannelTypes.Sms && m.Step == 3 && !m.IsDraft); - RuleFor(model => model.SendRules).SetValidator(new SendRuleDtoValidator()).When(m => m.Step == 3 && !m.IsDraft); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/ChannelManagement.razor b/src/Web/Masa.Mc.Web.Admin/Pages/Channels/ChannelManagement.razor deleted file mode 100644 index 5f6f4509..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/ChannelManagement.razor +++ /dev/null @@ -1,33 +0,0 @@ -@inherits AdminCompontentBase -@page "/channels/channelManagement" - -@T("Permission.ChannelManagement") - - - - - @T("Title") - - - - - @if (_entities.Result.Any()) - { -
- @foreach (var _entitie in _entities.Result) - { -
- -
- } -
- } - else - { - - } -
-
- - - \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/ChannelManagement.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/Channels/ChannelManagement.razor.cs deleted file mode 100644 index 43266953..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/ChannelManagement.razor.cs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.Channels; - -public partial class ChannelManagement : AdminCompontentBase -{ - private ChannelEditModal _editModal = default!; - private ChannelCreateModal _createModal = default!; - private GetChannelInputDto _queryParam = new(999); - private PaginatedListDto _entities = new(); - - ChannelService ChannelService => McCaller.ChannelService; - - protected override string? PageName { get; set; } = "ChannelBlock"; - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await LoadData(); - } - await base.OnAfterRenderAsync(firstRender); - } - - private async Task LoadData() - { - Loading = true; - _entities = (await ChannelService.GetListAsync(_queryParam)); - Loading = false; - StateHasChanged(); - } - - private async Task HandleOk() - { - await LoadData(); - } - - private async Task RefreshAsync() - { - _queryParam.Page = 1; - await LoadData(); - } - - private async Task HandleClearAsync() - { - _queryParam=new(15); - await LoadData(); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelAppExtraProperties.razor b/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelAppExtraProperties.razor deleted file mode 100644 index fb83b956..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelAppExtraProperties.razor +++ /dev/null @@ -1,56 +0,0 @@ -@inherits AdminCompontentBase - - @if (!IsAdd) - { - - - - @foreach (var item in GetEnumList()) - { - - - } - - - - } - - @if (_model.Provider == AppChannelProviders.GeTui) - { - - - - - } - - - - - @if (_model.Provider == AppChannelProviders.GeTui) - { - - - - - } - - - - - - \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelAppExtraProperties.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelAppExtraProperties.razor.cs deleted file mode 100644 index ae32e279..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelAppExtraProperties.razor.cs +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.Channels.Modules; - -public partial class ChannelAppExtraProperties : AdminCompontentBase -{ - [Parameter] - public ExtraPropertyDictionary Value { get; set; } = new(); - - [Parameter] - public EventCallback ValueChanged { get; set; } - - [Parameter] - public bool PasswordView { get; set; } - - [Parameter] - public bool IsAdd { get; set; } - - public MForm? Form { get; set; } - - private AppChannelOptions _model = new(); - private bool _passwordShow; - - protected override async Task OnInitializedAsync() - { - await base.OnInitializedAsync(); - - _model = ExtensionPropertyHelper.ConvertToType(Value); - } - - protected override void OnParametersSet() - { - if (_model.Provider == default && Value.HasProperty(nameof(AppChannelOptions.Provider))) - { - var provider = Value.GetProperty(nameof(AppChannelOptions.Provider)); - - _model.Provider = (AppChannelProviders)Enum.Parse(typeof(AppChannelProviders), provider); - } - } - - public async Task HandleChangeAsync() - { - Value = ExtensionPropertyHelper.ConvertToExtraProperty(_model); - await ValueChanged.InvokeAsync(Value); - } -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelCard.razor b/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelCard.razor deleted file mode 100644 index 7564f991..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelCard.razor +++ /dev/null @@ -1,50 +0,0 @@ -@inherits AdminCompontentBase - - - - - @T(Channel.Type.ToString()) - - - - mdi-pencil - - - - - -
@Channel.DisplayName
-
@Channel.Code
-
-
- @if (!string.IsNullOrEmpty(Channel.Description)) - { -
@Channel.Description
- } -
- - - @Channel.ModificationTime.Humanize(culture:I18n.Culture) - - - - @Channel.ModifierName - -
- -@code { - [Parameter] - public EventCallback OnEditClick { get; set; } - - [EditorRequired] - [Parameter] - public ChannelDto Channel { get; set; } = null!; - - private async Task HandleEditClick() - { - if (OnEditClick.HasDelegate) - { - await OnEditClick.InvokeAsync(); - } - } -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelCreateModal.razor b/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelCreateModal.razor deleted file mode 100644 index 6bf22998..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelCreateModal.razor +++ /dev/null @@ -1,122 +0,0 @@ -@inherits AdminCompontentBase -
- - - - - - - -
@T("Description.Channel.Type.Required")
- - - - - - - - - - - - - - - - - - - - -
-
- - -
@T("DisplayName.AppChannelProviders")
- - @foreach (var item in GetEnumList()) - { - - - - @if (context.Hover) - { - @(item == AppChannelProviders.GeTui ? IconConsts.GETUI_SVG : IconConsts.J_PUSH_SVG) -
@T($"DisplayName.AppChannelProviders.{item.ToString()}")
- } - else if (_model.ExtraProperties.GetProperty(nameof(AppChannelOptions.Provider)) == (int)item) - { - @(item == AppChannelProviders.GeTui ? IconConsts.GETUI_SVG : IconConsts.J_PUSH_SVG) -
@T($"DisplayName.AppChannelProviders.{item.ToString()}")
- } - else - { - @(item == AppChannelProviders.GeTui ? IconConsts.GETUI_SVG : IconConsts.J_PUSH_SVG) -
@T($"DisplayName.AppChannelProviders.{item.ToString()}")
- } -
-
-
- } -
-
-
- - - - - - - - - - - - - - - - - - - - - - -
@T("DisplayName.Color.Lable")
-
- - - - - - - -
-
-
-
-
-
- - @if (_step > 1) - { - - mdi-keyboard-backspace - - } - - - @if (_step == 3) - { - @T("Submit") - } - -
-
diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelCreateModal.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelCreateModal.razor.cs deleted file mode 100644 index 4bed22d7..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelCreateModal.razor.cs +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.Channels.Modules; - -public partial class ChannelCreateModal : AdminCompontentBase -{ - [Parameter] - public EventCallback OnOk { get; set; } - - private MForm? _form; - private ChannelUpsertDto _model = new(); - private bool _visible; - private List _colors = new List { "purple", "green", "yellow", "red", "blue" }; - private ChannelExtraProperties _channelExtraPropertiesRef = default!; - - int _step = 1; - - Dictionary _svgAttributes = new Dictionary { ["viewBox"] = "0 0 1024 1024" }; - - ChannelService ChannelService => McCaller.ChannelService; - - protected override string? PageName { get; set; } = "ChannelBlock"; - - private int _nextStep - { - get - { - return _model.Type == ChannelTypes.App ? 2 : 3; - } - } - - private int _previousStep - { - get - { - if (_step == 3) - { - return _model.Type == ChannelTypes.App ? 2 : 1; - } - else - { - return 1; - } - } - } - - public async Task OpenModalAsync() - { - _model.Color = _colors[0]; - await InvokeAsync(() => - { - _visible = true; - StateHasChanged(); - }); - - _form?.ResetValidation(); - } - - private void HandleCancel() - { - _visible = false; - ResetForm(); - } - - private void HandleSelectType(ChannelTypes Type) - { - _model.Type = Type; - - _step = _nextStep; - } - - private async Task HandleOkAsync() - { - Check.NotNull(_form, "form not found"); - - await _channelExtraPropertiesRef.UpdateExtraPropertiesAsync(); - if (!_form.Validate() || !_channelExtraPropertiesRef.Validate()) - { - return; - } - Loading = true; - await ChannelService.CreateAsync(_model); - Loading = false; - await SuccessMessageAsync(T("ChannelCreateMessage")); - _visible = false; - ResetForm(); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - - private void ResetForm() - { - _step = 1; - _model = new(); - } - - private void HandleVisibleChanged(bool val) - { - if (!val) HandleCancel(); - } - - private void HandleAppSelectType(AppChannelProviders Type) - { - _model.ExtraProperties.SetProperty(nameof(AppChannelOptions.Provider), (int)Type); - _step = 3; - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelEditModal.razor b/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelEditModal.razor deleted file mode 100644 index eeffd675..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelEditModal.razor +++ /dev/null @@ -1,56 +0,0 @@ -@inherits AdminCompontentBase -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@T("DisplayName.Color.Lable")
-
- - - - - - - -
-
-
-
-
diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelEditModal.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelEditModal.razor.cs deleted file mode 100644 index 4ed39599..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelEditModal.razor.cs +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.Channels.Modules; - -public partial class ChannelEditModal : AdminCompontentBase -{ - [Parameter] - public EventCallback OnOk { get; set; } - - private MForm _form = default!; - private ChannelUpsertDto _model = new(); - private Guid _entityId; - private bool _visible; - private List channelTypeItems = Enum.GetValues(typeof(ChannelTypes)) - .Cast().ToList(); - private List _colors = new List { "purple", "green", "yellow", "red", "blue" }; - private ChannelExtraProperties _channelExtraPropertiesRef = default!; - - ChannelService ChannelService => McCaller.ChannelService; - - protected override string? PageName { get; set; } = "ChannelBlock"; - - public async Task OpenModalAsync(ChannelDto model) - { - _entityId = model.Id; - _model = model.Adapt(); - _model.Scheme = "Ldap"; - await GetFormDataAsync(); - await InvokeAsync(() => - { - _visible = true; - StateHasChanged(); - }); - } - - private async Task GetFormDataAsync() - { - var dto = await ChannelService.GetAsync(_entityId) ?? new(); - _model = dto.Adapt(); - } - - private void HandleCancel() - { - _visible = false; - ResetForm(); - } - - private async Task HandleOk() - { - await _channelExtraPropertiesRef.UpdateExtraPropertiesAsync(); - if (!_form.Validate() || !_channelExtraPropertiesRef.Validate()) - { - return; - } - Loading = true; - await ChannelService.UpdateAsync(_entityId, _model); - Loading = false; - _visible = false; - ResetForm(); - await SuccessMessageAsync(T("ChannelEditMessage")); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - - private async Task HandleDel() - { - await ConfirmAsync(T("DeletionConfirmationMessage", $"{T("Channel")}\"{_model.DisplayName}\""), DeleteAsync, AlertTypes.Error); - } - private async Task DeleteAsync() - { - Loading = true; - await ChannelService.DeleteAsync(_entityId); - Loading = false; - await SuccessMessageAsync(T("ChannelDeleteMessage")); - _visible = false; - ResetForm(); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - private void ResetForm() - { - _model = new(); - _form.ResetValidation(); - } - - private void HandleVisibleChanged(bool val) - { - if (!val) HandleCancel(); - } -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelEmailExtraProperties.razor b/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelEmailExtraProperties.razor deleted file mode 100644 index a8e2c885..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelEmailExtraProperties.razor +++ /dev/null @@ -1,38 +0,0 @@ -@inherits AdminCompontentBase - - - - - - - - - - - - - - - - - -
- -
-
- - - - -
-
-
-
\ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelEmailExtraProperties.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelEmailExtraProperties.razor.cs deleted file mode 100644 index 47aa6c3a..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelEmailExtraProperties.razor.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.Channels.Modules; - -public partial class ChannelEmailExtraProperties : AdminCompontentBase -{ - [Parameter] - public ExtraPropertyDictionary Value { get; set; } = new(); - - [Parameter] - public EventCallback ValueChanged { get; set; } - - [Parameter] - public bool PasswordView { get; set; } - - public MForm Form { get; set; } = default!; - - private EmailChannelOptions _model = new(); - private bool _passwordShow; - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - _model = ExtensionPropertyHelper.ConvertToType(Value); - } - await base.OnAfterRenderAsync(firstRender); - } - - public async Task HandleChangeAsync() - { - Value = ExtensionPropertyHelper.ConvertToExtraProperty(_model); - await ValueChanged.InvokeAsync(Value); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelExtraProperties.razor b/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelExtraProperties.razor deleted file mode 100644 index 8783cc3e..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelExtraProperties.razor +++ /dev/null @@ -1,22 +0,0 @@ -@inherits AdminCompontentBase - -@if (Type == ChannelTypes.Email) -{ - -} -else if (Type == ChannelTypes.Sms) -{ - -} -else if (Type == ChannelTypes.App) -{ - -} -else if (Type == ChannelTypes.WeixinWork) -{ - -} -else if (Type == ChannelTypes.WeixinWorkWebhook) -{ - -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelExtraProperties.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelExtraProperties.razor.cs deleted file mode 100644 index 81145ebd..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelExtraProperties.razor.cs +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.Channels.Modules; - -public partial class ChannelExtraProperties : AdminCompontentBase -{ - [Parameter] - public ChannelTypes Type { get; set; } - - [Parameter] - public ExtraPropertyDictionary Value - { - get - { - return GetValue(); - } - set - { - SetValue(value); - } - } - - [Parameter] - public EventCallback ValueChanged { get; set; } - - [Parameter] - public bool PasswordView { get; set; } - - [Parameter] - public bool IsAdd { get; set; } - - private ChannelEmailExtraProperties? _emailExtraPropertiesRef; - private ChannelSmsExtraProperties? _smsExtraPropertiesRef; - private ChannelAppExtraProperties? _appExtraPropertiesRef; - private ChannelWeixinWorkExtraProperties? _weixinWorkExtraPropertiesRef; - private ChannelWeixinWorkWebhookExtraProperties? _weixinWorkWebhookExtraPropertiesRef; - - public void HandleChangeAsync(string value, string key) - { - Value[key] = value; - } - - public async Task UpdateExtraPropertiesAsync() - { - if (Type == ChannelTypes.Email && _emailExtraPropertiesRef != null) - { - await _emailExtraPropertiesRef.HandleChangeAsync(); - } - if (Type == ChannelTypes.Sms && _smsExtraPropertiesRef != null) - { - await _smsExtraPropertiesRef.HandleChangeAsync(); - } - if (Type == ChannelTypes.App && _appExtraPropertiesRef != null) - { - await _appExtraPropertiesRef.HandleChangeAsync(); - } - if (Type == ChannelTypes.WeixinWork && _weixinWorkExtraPropertiesRef != null) - { - await _weixinWorkExtraPropertiesRef.HandleChangeAsync(); - } - if (Type == ChannelTypes.WeixinWorkWebhook && _weixinWorkWebhookExtraPropertiesRef != null) - { - await _weixinWorkWebhookExtraPropertiesRef.HandleChangeAsync(); - } - await ValueChanged.InvokeAsync(Value); - } - - public bool Validate() - { - if (Type == ChannelTypes.Email && _emailExtraPropertiesRef != null) - { - return _emailExtraPropertiesRef.Form.Validate(); - } - if (Type == ChannelTypes.Sms && _smsExtraPropertiesRef != null) - { - return _smsExtraPropertiesRef.Form.Validate(); - } - if (Type == ChannelTypes.App && _appExtraPropertiesRef != null && _appExtraPropertiesRef.Form != null) - { - return _appExtraPropertiesRef.Form.Validate(); - } - if (Type == ChannelTypes.WeixinWork && _weixinWorkExtraPropertiesRef != null && _weixinWorkExtraPropertiesRef.Form != null) - { - return _weixinWorkExtraPropertiesRef.Form.Validate(); - } - if (Type == ChannelTypes.WeixinWorkWebhook && _weixinWorkWebhookExtraPropertiesRef != null && _weixinWorkWebhookExtraPropertiesRef.Form != null) - { - return _weixinWorkWebhookExtraPropertiesRef.Form.Validate(); - } - return true; - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelSelectCard.razor b/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelSelectCard.razor deleted file mode 100644 index 6ce1e40a..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelSelectCard.razor +++ /dev/null @@ -1,39 +0,0 @@ -@inherits AdminCompontentBase - - - - @if (context.Hover) - { - @Icon -
@Text
- } - else if (Value == Type) - { - @Icon -
@Text
- } - else - { - @Icon -
@Text
- } -
-
- -@code { - [Parameter] - public ChannelTypes Value { get; set; } - - [Parameter] - public string Text { get; set; } = string.Empty; - - [Parameter] - public ChannelTypes Type { get; set; } - - [Parameter] - public string Icon { get; set; } = string.Empty; - - [Parameter] - public EventCallback ValueChanged { get; set; } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelSmsExtraProperties.razor b/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelSmsExtraProperties.razor deleted file mode 100644 index 1037e761..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelSmsExtraProperties.razor +++ /dev/null @@ -1,19 +0,0 @@ -@inherits AdminCompontentBase - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelSmsExtraProperties.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelSmsExtraProperties.razor.cs deleted file mode 100644 index e314a16d..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelSmsExtraProperties.razor.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.Channels.Modules; - -public partial class ChannelSmsExtraProperties : AdminCompontentBase -{ - [Parameter] - public ExtraPropertyDictionary Value { get; set; } = new(); - - [Parameter] - public EventCallback ValueChanged { get; set; } - - [Parameter] - public bool PasswordView { get; set; } - - public MForm Form { get; set; } = default!; - - private SmsChannelOptions _model = new(); - private bool _passwordShow; - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - _model = ExtensionPropertyHelper.ConvertToType(Value); - } - await base.OnAfterRenderAsync(firstRender); - } - - public async Task HandleChangeAsync() - { - Value = ExtensionPropertyHelper.ConvertToExtraProperty(_model); - await ValueChanged.InvokeAsync(Value); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelWeixinWorkExtraProperties.razor b/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelWeixinWorkExtraProperties.razor deleted file mode 100644 index d5e6c0ba..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelWeixinWorkExtraProperties.razor +++ /dev/null @@ -1,56 +0,0 @@ -@inherits AdminCompontentBase - - - - - - - - - - - - - - - - - -@code { - [Parameter] - public ExtraPropertyDictionary Value { get; set; } = new(); - - [Parameter] - public EventCallback ValueChanged { get; set; } - - [Parameter] - public bool PasswordView { get; set; } - - public MForm Form { get; set; } = default!; - - private WeixinWorkChannelOptions _model = new(); - private bool _passwordShow; - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - _model = ExtensionPropertyHelper.ConvertToType(Value); - } - await base.OnAfterRenderAsync(firstRender); - } - - public async Task HandleChangeAsync() - { - Value = ExtensionPropertyHelper.ConvertToExtraProperty(_model); - await ValueChanged.InvokeAsync(Value); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelWeixinWorkWebhookExtraProperties.razor b/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelWeixinWorkWebhookExtraProperties.razor deleted file mode 100644 index 693eeb2f..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/Channels/Modules/ChannelWeixinWorkWebhookExtraProperties.razor +++ /dev/null @@ -1,42 +0,0 @@ -@inherits AdminCompontentBase - - - - - - - - - -@code { - [Parameter] - public ExtraPropertyDictionary Value { get; set; } = new(); - - [Parameter] - public EventCallback ValueChanged { get; set; } - - [Parameter] - public bool PasswordView { get; set; } - - public MForm Form { get; set; } = default!; - - private WeixinWorkWebhookChannelOptions _model = new(); - private bool _passwordShow; - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - _model = ExtensionPropertyHelper.ConvertToType(Value); - } - await base.OnAfterRenderAsync(firstRender); - } - - public async Task HandleChangeAsync() - { - Value = ExtensionPropertyHelper.ConvertToExtraProperty(_model); - await ValueChanged.InvokeAsync(Value); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageRecords/MessageRecordManagement.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageRecords/MessageRecordManagement.razor deleted file mode 100644 index 8f883c48..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageRecords/MessageRecordManagement.razor +++ /dev/null @@ -1,104 +0,0 @@ -@inherits AdminCompontentBase -@page "/messageRecords/messageRecordManagement" - -@T("Permission.MessageRecord") - - - - - @T("Title") - - - - - - - - - - - - - - - - - - - - - - - - - - - @header.Text - - - @switch (context.Header.Value) - { - case ("Receiver"): - - - - - - - @(!string.IsNullOrEmpty(context.Item.User.DisplayName) ? context.Item.User.DisplayName : !string.IsNullOrEmpty(context.Item.User.PhoneNumber) ? context.Item.User.PhoneNumber : context.Item.User.Account) - - @(!string.IsNullOrEmpty(context.Item.User.DisplayName) && !string.IsNullOrEmpty(context.Item.User.PhoneNumber) ? context.Item.User.PhoneNumber : context.Item.User.Account) - - - break; - case (nameof(MessageTaskReceiverDto.Email)): - - break; - case ("ChannelDisplayName"): - - break; - case nameof(MessageRecordDto.Success): - - break; - case "Action": - mdi-eye - break; - default: - - break; - } - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageRecords/MessageRecordManagement.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageRecords/MessageRecordManagement.razor.cs deleted file mode 100644 index 8e3b0532..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageRecords/MessageRecordManagement.razor.cs +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageRecords; - -public partial class MessageRecordManagement : AdminCompontentBase -{ - private MessageRecordDetailModal _detailModal = default!; - private GetMessageRecordInputDto _queryParam = new(); - private PaginatedListDto _entities = new(); - private List _channelItems = new(); - private List> _successItems = new(); - private ChannelService ChannelService => McCaller.ChannelService; - private MessageRecordService MessageRecordService => McCaller.MessageRecordService; - private DateTimeOffset? _endTime; - private DateTimeOffset? _startTime; - - protected override string? PageName { get; set; } = "MessageRecordBlock"; - - protected async override Task OnInitializedAsync() - { - _channelItems = (await ChannelService.GetListAsync(new GetChannelInputDto(99))).Result; - _successItems = new() - { - new(T("Success"), true), - new(T("Failure"), false) - }; - } - - private void SetDefaultParam() - { - var defaultQueryParam = new GetMessageRecordInputDto() - { - TimeType = MessageRecordTimeTypes.ExpectSendTime, - StartTime = DateTime.Now.Date, - EndTime = DateTime.Now.Date.AddDays(1) - }; - _queryParam = defaultQueryParam; - _endTime = defaultQueryParam.EndTime; - _startTime = defaultQueryParam.StartTime; - } - - public List> GetHeaders() - { - string prefix = "DisplayName.MessageRecord"; - - return new() - { - new() { Text = T("DisplayName.MessageTaskReceiver"), Value = "Receiver", Sortable = false, Width = "8rem" }, - new() { Text = T(nameof(MessageTaskReceiverDto.Email)), Value = nameof(MessageTaskReceiverDto.Email), Sortable = false, Width = "8rem" }, - new() { Text = T("DisplayName.Channel"), Value = "ChannelDisplayName", Sortable = false, Width = "6rem" }, - new() { Text = T($"{prefix}{nameof(MessageRecordDto.DisplayName)}"), Value = nameof(MessageRecordDto.DisplayName), Sortable = false, Width = "8rem" }, - new() { Text = T($"{prefix}{nameof(MessageRecordDto.ExpectSendTime)}"), Value = nameof(MessageRecordDto.ExpectSendTime), Sortable = false, Width = "10rem" }, - new() { Text = T($"{prefix}{nameof(MessageRecordDto.SendTime)}"), Value = nameof(MessageRecordDto.SendTime), Sortable = false, Width = "8rem" }, - new() { Text = T($"{prefix}{nameof(MessageRecordDto.Success)}"), Value = nameof(MessageRecordDto.Success), Sortable = false, Width = "7.5rem" }, - new() { Text = T($"{prefix}{nameof(MessageRecordDto.FailureReason)}"), Value = nameof(MessageRecordDto.FailureReason), Sortable = false, Width = "6.5625rem" }, - new() { Text = T("Action"), Value = "Action", Sortable = false, Width = 105, Align=DataTableHeaderAlign.Center }, - }; - } - - protected async override Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - SetDefaultParam(); - - await LoadData(); - } - await base.OnAfterRenderAsync(firstRender); - } - - private Task DateRangChangedAsync((DateTimeOffset? startDate, DateTimeOffset? endDate) args) - { - (_startTime, _endTime) = args; - _queryParam.StartTime = _startTime?.UtcDateTime; - _queryParam.EndTime = _endTime?.UtcDateTime; - return RefreshAsync(); - } - - private async Task LoadData() - { - Loading = true; - _entities = (await MessageRecordService.GetListAsync(_queryParam)); - Loading = false; - StateHasChanged(); - } - - private async Task HandleOk() - { - await LoadData(); - } - - private async Task RefreshAsync() - { - _queryParam.Page = 1; - await LoadData(); - } - - private async Task HandlePageChanged(int page) - { - _queryParam.Page = page; - await LoadData(); - } - - private async Task HandlePageSizeChanged(int pageSize) - { - _queryParam.PageSize = pageSize; - await LoadData(); - } - - private async Task HandleClearAsync() - { - SetDefaultParam(); - await LoadData(); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageRecords/Modules/MessageRecordDetailModal.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageRecords/Modules/MessageRecordDetailModal.razor deleted file mode 100644 index 10a4a1b7..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageRecords/Modules/MessageRecordDetailModal.razor +++ /dev/null @@ -1,107 +0,0 @@ -@inherits AdminCompontentBase -
- -
-
- -
@(_messageRecord.User.DisplayName)
-
@(_messageRecord.User.Email)
-
@(_messageRecord.User.PhoneNumber)
-
@T("DisplayName.MessageTaskSendTime")
- - - - @T("DisplayName.MessageRecordExpectSendTime") - - - - - -
-
@(_messageRecord.ExpectSendTime?.ToOffset(JsInitVariables.TimezoneOffset).ToString(T("$DateFormat")))
-
@(_messageRecord.ExpectSendTime?.ToOffset(JsInitVariables.TimezoneOffset).ToString(T("$TimeFormat")))
-
-
-
- - - @T("DisplayName.MessageRecordSendTime") - - - - - -
-
@_messageRecord.SendTime?.ToOffset(JsInitVariables.TimezoneOffset).ToString(T("$DateFormat"))
-
@_messageRecord.SendTime?.ToOffset(JsInitVariables.TimezoneOffset).ToString(T("$TimeFormat"))
-
-
-
-
-
@T("DisplayName.MessageRecordResult")
-
-
-
- @if (_messageRecord.Success == true) - { - @T("DisplayName.MessageRecordSuccess.True") - } - @if (_messageRecord.Success == false) - { - @T("DisplayName.MessageRecordSuccess.False") - } -
- @if (_messageRecord.Success == false) - { - @T("Retry") - } -
- @if (_messageRecord.Success == false) - { -
-
- @_messageRecord.FailureReason -
-
@T("DisplayName.MessageRecordFailureReason")
-
- } - @if (_messageTaskHistory is not null) - { -
-
- @_messageTaskHistory.TaskHistoryNo -
-
@T("DisplayName.MessageTaskHistoryNo")
-
- } -
-
- -
-
@T("DisplayName.MessageInfoContent")
- @if (_messageTask is null) - { - @if (_messageRecord.MessageEntityType == MessageEntityTypes.Ordinary) - { - - } - @if (_messageRecord.MessageEntityType == MessageEntityTypes.Template) - { - - } - } - else{ - @if (_messageTask.EntityType == MessageEntityTypes.Ordinary) - { - - } - @if (_messageTask.EntityType == MessageEntityTypes.Template) - { - - } - } -
- -
-
-
\ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageRecords/Modules/MessageRecordDetailModal.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageRecords/Modules/MessageRecordDetailModal.razor.cs deleted file mode 100644 index 24560c38..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageRecords/Modules/MessageRecordDetailModal.razor.cs +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageRecords.Modules; - -public partial class MessageRecordDetailModal : AdminCompontentBase -{ - [Parameter] - public EventCallback OnOk { get; set; } - - private MessageRecordDto _messageRecord = new(); - private MessageTaskDto? _messageTask; - private MessageTaskHistoryDto? _messageTaskHistory; - private Guid _entityId; - private bool _visible; - - MessageRecordService MessageRecordService => McCaller.MessageRecordService; - - MessageTaskService MessageTaskService => McCaller.MessageTaskService; - - MessageTaskHistoryService MessageTaskHistoryService => McCaller.MessageTaskHistoryService; - - public async Task OpenModalAsync(MessageRecordDto model) - { - _entityId = model.Id; - await GetFormDataAsync(); - await InvokeAsync(() => - { - _visible = true; - StateHasChanged(); - }); - } - - private async Task GetFormDataAsync() - { - _messageRecord = await MessageRecordService.GetAsync(_entityId) ?? new(); - - if (_messageRecord.MessageTaskId != Guid.Empty) - { - _messageTask = await MessageTaskService.GetAsync(_messageRecord.MessageTaskId); - } - - if (_messageRecord.MessageTaskHistoryId != Guid.Empty) - { - _messageTaskHistory = await MessageTaskHistoryService.GetAsync(_messageRecord.MessageTaskHistoryId); - } - } - - private void HandleCancel() - { - _visible = false; - ResetForm(); - } - - private void ResetForm() - { - _messageRecord = new(); - _messageTask = null; - _messageTaskHistory = null; - } - - private void HandleVisibleChanged(bool val) - { - if (!val) HandleCancel(); - } - - private async Task HandleRetry() - { - LoadingText = T("SendingMessage"); - Loading = true; - var inputDto = new RetryMessageRecordInputDto { MessageRecordId = _entityId }; - await MessageRecordService.RetryAsync(inputDto); - Loading = false; - await SuccessMessageAsync(T("MessageRecordRetryMessage")); - await GetFormDataAsync(); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageRecords/Modules/MessageRecordDetailModal.razor.css b/src/Web/Masa.Mc.Web.Admin/Pages/MessageRecords/Modules/MessageRecordDetailModal.razor.css deleted file mode 100644 index 734aeb46..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageRecords/Modules/MessageRecordDetailModal.razor.css +++ /dev/null @@ -1,8 +0,0 @@ -.record-detail-left { - width: 428px; -} - -.record-detail-right { - padding: 72px 114px; - width: calc(100% - 428px); -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/MessageTaskList.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/MessageTaskList.razor deleted file mode 100644 index 19f45c22..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/MessageTaskList.razor +++ /dev/null @@ -1,132 +0,0 @@ -@inherits AdminCompontentBase - - -
- mdi-message@T("Permission.SendMessage") -
- - - @T("Title") - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - mdi-file - -
-
- - @(_queryParam.IsDraft == true ? T("All") : T("Draft")) - -
-
-
-
- - @if (_entities.Result.Any()) - { -
- @foreach (var _entitie in _entities.Result) - { -
- -
- } -
- } - else - { - - } - -
- -
- -
-
-
- - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/MessageTaskList.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/MessageTaskList.razor.cs deleted file mode 100644 index ea15e85f..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/MessageTaskList.razor.cs +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTasks; - -public partial class MessageTaskList : AdminCompontentBase -{ - [Parameter] - public EventCallback OnNavigateToSend { get; set; } - - private TemplateMessageEditModal _templateEditModal = default!; - private OrdinaryMessageEditModal _ordinaryEditModal = default!; - private MessageTaskDetailModal _detailModal = default!; - private SendTestMessageModal _sendTestModal = default!; - private GetMessageTaskInputDto _queryParam = new(20) { TimeType = MessageTaskTimeTypes.ModificationTime, Source = MessageTaskSources.Management }; - private PaginatedListDto _entities = new(); - private List _channelItems = new(); - private DateTimeOffset? _endTime; - private DateTimeOffset? _startTime; - - private ChannelService ChannelService => McCaller.ChannelService; - - private MessageTaskService MessageTaskService => McCaller.MessageTaskService; - - protected override string? PageName { get; set; } = "MessageTaskBlock"; - - protected async override Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await LoadData(); - } - await base.OnAfterRenderAsync(firstRender); - } - - private async Task LoadData() - { - Loading = true; - _entities = (await MessageTaskService.GetListAsync(_queryParam)); - _channelItems = (await ChannelService.GetListAsync(new GetChannelInputDto(99))).Result; - Loading = false; - StateHasChanged(); - } - - private Task DateRangChangedAsync((DateTimeOffset? startDate, DateTimeOffset? endDate) args) - { - (_startTime, _endTime) = args; - _queryParam.StartTime = _startTime?.UtcDateTime; - _queryParam.EndTime = _endTime?.UtcDateTime; - return RefreshAsync(); - } - - private async Task HandleOk() - { - await LoadData(); - } - - private async Task RefreshAsync() - { - _queryParam.Page = 1; - await LoadData(); - } - - private async Task HandlePageChanged(int page) - { - _queryParam.Page = page; - await LoadData(); - } - - private async Task HandlePageSizeChanged(int pageSize) - { - _queryParam.PageSize = pageSize; - await LoadData(); - } - - private async Task HandleClearAsync() - { - _queryParam = new(20) { TimeType = MessageTaskTimeTypes.ModificationTime, Source = MessageTaskSources.Management }; - await LoadData(); - } - - private async Task HandleEditAsync(MessageTaskDto model) - { - if (model.EntityType == MessageEntityTypes.Ordinary) - { - await _ordinaryEditModal.OpenModalAsync(model); - } - if (model.EntityType == MessageEntityTypes.Template) - { - await _templateEditModal.OpenModalAsync(model); - } - } - - private async Task NavigateToSend() - { - if (OnNavigateToSend.HasDelegate) - { - await OnNavigateToSend.InvokeAsync(); - } - } - - private async Task HandleDelAsync(Guid _entityId, string displayName) - { - await ConfirmAsync(T("DeletionConfirmationMessage", $"{T("MessageTask")}\"{displayName}\""), async () => { await DeleteAsync(_entityId); }, AlertTypes.Error); - } - - private async Task DeleteAsync(Guid _entityId) - { - Loading = true; - await MessageTaskService.DeleteAsync(_entityId); - Loading = false; - await SuccessMessageAsync(T("MessageTaskDeleteMessage")); - await LoadData(); - } - - private async Task HandleIsDraft() - { - _queryParam.IsDraft = _queryParam.IsDraft == true ? null : true; - await LoadData(); - } - - private async Task HandleIsEnabled(MessageTaskDto item) - { - if (!item.IsEnabled) - { - if (item.IsDraft) - { - await ErrorMessageAsync(T("CouldNotEnableATaskInDraft")); - } - else - { - await ConfirmAsync(T("EnableConfirmationMessageTask"), async () => - { - await MessageTaskService.SetIsEnabledAsync(item.Id, true); - item.IsEnabled = true; - }); - } - } - else - { - await ConfirmAsync(T("DisableConfirmationMessageTask"), async () => - { - await MessageTaskService.SetIsEnabledAsync(item.Id, false); - item.IsEnabled = false; - }); - } - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/ImportReceiversDetailModal.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/ImportReceiversDetailModal.razor deleted file mode 100644 index e9946cce..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/ImportReceiversDetailModal.razor +++ /dev/null @@ -1,119 +0,0 @@ -@inherits AdminCompontentBase -
- - - - - - @if (ChannelType == ChannelTypes.WebsiteMessage) - { - - @T("UserId") - - } - @if (ChannelType == ChannelTypes.Sms) - { - - @T("PhoneNumber") - - } - @if (ChannelType == ChannelTypes.Email) - { - - @T("Email") - - } - @if (ChannelType == ChannelTypes.App) - { - - @T("ClientId") - - } - @if (ChannelType == ChannelTypes.WeixinWork || ChannelType == ChannelTypes.WeixinWorkWebhook) - { - - @T("Account") - - } - @if (Value.Count > 0) - { - foreach (var item in Value[0].Variables) - { - - @item.Key - - } - } - - - - @foreach (var item in _items) - { - - @item.ChannelUserIdentity - @foreach (var v in item.Variables) - { - @v.Value - } - - } - - - - - -
- - -@code { - [Parameter] - public List Value { get; set; } = new(); - - [Parameter] - public ChannelTypes? ChannelType { get; set; } - - private List _items { get; set; } = new(); - - private bool _visible; - private PaginatedOptionsDto _queryParam = new(); - - private void HandleVisibleChanged(bool val) - { - if (!val) HandleCancel(); - } - - public async Task OpenModal() - { - _visible = true; - await LoadData(); - } - - private void HandleCancel() - { - _visible = false; - ResetForm(); - } - - private async Task HandlePageChanged(int page) - { - _queryParam.Page = page; - await LoadData(); - } - - private async Task HandlePageSizeChanged(int pageSize) - { - _queryParam.PageSize = pageSize; - await LoadData(); - } - - private async Task LoadData() - { - _items = Value.Skip((_queryParam.Page - 1) * _queryParam.PageSize).Take(_queryParam.PageSize <= 0 ? int.MaxValue : _queryParam.PageSize).ToList(); - await InvokeAsync(StateHasChanged); - } - - private void ResetForm() - { - _queryParam = new(); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageReceivers.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageReceivers.razor deleted file mode 100644 index 12a30cba..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageReceivers.razor +++ /dev/null @@ -1,19 +0,0 @@ -@inherits AdminCompontentBase - - - - - - - -@if (SelectReceiverType == MessageTaskSelectReceiverTypes.ManualSelection) -{ - -} -@if (SelectReceiverType == MessageTaskSelectReceiverTypes.BatchUpload) -{ - -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageReceivers.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageReceivers.razor.cs deleted file mode 100644 index 760a8776..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageReceivers.razor.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTasks.Modules; - -public partial class MessageReceivers -{ - [Parameter] - public ReceiverTypes ReceiverType { get; set; } = new(); - - [Parameter] - public EventCallback ReceiverTypeChanged { get; set; } - - [Parameter] - public List SelectReceivers { get; set; } = new(); - - [Parameter] - public EventCallback> SelectReceiversChanged { get; set; } - - [Parameter] - public List ImportReceivers { get; set; } = new(); - - [Parameter] - public EventCallback> ImportReceiversChanged { get; set; } - - [Parameter] - public MessageTaskSelectReceiverTypes SelectReceiverType { get; set; } = MessageTaskSelectReceiverTypes.ManualSelection; - - [Parameter] - public EventCallback SelectReceiverTypeChanged { get; set; } - - [Parameter] - public ChannelTypes? ChannelType { get; set; } - - [Parameter] - public EventCallback ChannelTypeChanged { get; set; } - - [Parameter] - public Guid? MessageTemplatesId { get; set; } - - [Parameter] - public EventCallback MessageTemplatesIdChanged { get; set; } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageReceiversImport.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageReceiversImport.razor deleted file mode 100644 index 0692e658..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageReceiversImport.razor +++ /dev/null @@ -1,60 +0,0 @@ -@inherits AdminCompontentBase -
- -
- -
-
-
-
@(_isUpload && Value != null && Value.Any() ? T("UploadComplete") : T("UploadFile"))
-
@_fileName
-
-
- - - -
- @T("Description.MessageReceiversDownload.Name") - @T("Description.MessageReceiversDownload.Tips") -
-
-
- -@if (_importResult != null && _importResult.HasError) -{ - - @T("Description.MessageReceiversImport.ErrorMsg") - -} -@if (Value != null && Value.Any()) -{ - -
- @(string.Format(T("Description.MessageReceiversImport.Tips"), Value.Count)) - @T("View") -
-
-} - \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageReceiversImport.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageReceiversImport.razor.cs deleted file mode 100644 index 29e9768b..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageReceiversImport.razor.cs +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTasks.Modules; - -public partial class MessageReceiversImport -{ - [Parameter] - public List Value { get; set; } = new(); - - [Parameter] - public Guid? MessageTemplatesId { get; set; } - - [Parameter] - public ChannelTypes? ChannelType { get; set; } - - [Parameter] - public EventCallback> ValueChanged { get; set; } - - [Parameter] - public EventCallback> OnAdd { get; set; } - - [Inject] - IBlazorDownloadFileService BlazorDownloadFileService { get; set; } = default!; - - private ImportResultDto _importResult = default!; - private ImportReceiversDetailModal _importReceiversDetailModal = default!; - private int _progress = 0; - private string _fileName = string.Empty; - private bool _isUpload; - private long maxFileSize = 1024 * 1024 * 15; - - MessageTaskService MessageTaskService => McCaller.MessageTaskService; - - protected override void OnParametersSet() - { - if (!_isUpload && Value != null && Value.Any()) - { - _isUpload = true; - _progress = 100; - } - } - - private async Task handleResetAnimation() - { - if (_progress == 0) - { - return; - } - - _progress = 0; - _fileName = string.Empty; - _importResult = default!; - _isUpload = false; - await Task.Delay(400); - } - - private async Task HandleFileChange(InputFileChangeEventArgs e) - { - var file = e.File; - if (file == null) - { - return; - } - - await handleResetAnimation(); - - if (!ChannelType.HasValue) - { - await WarningAsync(T("Description.ChannelType.Required")); - return; - } - if (maxFileSize < file.Size) - { - await WarningAsync(T("UploadFileSizeExceeded")); - return; - } - var fileContent = await ReadFile(file); - _isUpload = true; - if (FileEncoderHelper.GetTextFileEncodingType(fileContent) != Encoding.UTF8) - { - await WarningAsync(T("Description.MessageReceiversUpload.EncodingTips")); - return; - } - _fileName = file.Name; - var dto = new ImportReceiversDto - { - FileName = _fileName, - FileContent = fileContent, - Size = file.Size, - ContentType = "text/csv", - MessageTemplatesId = MessageTemplatesId, - ChannelType = ChannelType.Value - }; - _importResult = await MessageTaskService.ImportReceiversAsync(dto); - Value = _importResult.Data.ToList(); - if (ValueChanged.HasDelegate) - { - await ValueChanged.InvokeAsync(Value); - } - } - - private async Task Download() - { - if (!ChannelType.HasValue) - { - await WarningAsync(T("Description.ChannelType.Required")); - return; - } - var contentBytes = await MessageTaskService.GenerateReceiverImportTemplateAsync(MessageTemplatesId, ChannelType.Value); - await BlazorDownloadFileService.DownloadFile("ReceiverImportTemplate.csv", contentBytes, "text/csv"); - } - - private async Task ReadFile(IBrowserFile file) - { - await using var memoryStream = new MemoryStream(); - using var readStream = file.OpenReadStream(maxFileSize); - var bytesRead = 0; - var totalRead = 0; - var buffer = new byte[2048]; - - while ((bytesRead = await readStream.ReadAsync(buffer)) != 0) - { - totalRead += bytesRead; - - await memoryStream.WriteAsync(buffer, 0, bytesRead); - - _progress = (int)(totalRead * 100.0 / file.Size); - } - return memoryStream.ToArray(); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageReceiversImport.razor.css b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageReceiversImport.razor.css deleted file mode 100644 index 9fbc46be..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageReceiversImport.razor.css +++ /dev/null @@ -1,15 +0,0 @@ -.upload-btn ::deep .m-input { - opacity: 0; - position: absolute; - top: 0; - left: 0; -} -.upload-btn ::deep .m-input__control { - height: 100%; - width: 100%; - position: absolute; -} -.upload-btn ::deep .m-input__slot { - height: 100%; - width: 100%; -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageReceiversSelect.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageReceiversSelect.razor deleted file mode 100644 index 749a3293..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageReceiversSelect.razor +++ /dev/null @@ -1,72 +0,0 @@ -@inherits AdminCompontentBase - - - - - mdi-plus - @T("ExternalMember") - - - -@if (Value != null && Value.Count > 0) -{ - - - @foreach (var item in Value) - { - - - - @if (item.Type != MessageTaskReceiverTypes.User) - { - mdi-animation - } - else - { - @if (string.IsNullOrEmpty(item.Avatar)) - { - - } - else - { - - } - } - - - - @(item.DisplayName) -
- -
- @T($"DisplayName.MessageTaskReceiverTypes.{item.Type}") -
- @if (item.Type == MessageTaskReceiverTypes.User) - { - - @(item.PhoneNumber) -
- -
- @(item.Email) -
- } -
-
- - mdi-close - -
-
-
- } -
-
- - @if (_count > 0) - { - @(string.Format(T("ReceiversCount"), _count)) - } -} - - \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageReceiversSelect.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageReceiversSelect.razor.cs deleted file mode 100644 index 5457a4b0..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageReceiversSelect.razor.cs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTasks.Modules; - -public partial class MessageReceiversSelect : AdminCompontentBase -{ - [Parameter] - public List Value { get; set; } = new(); - - [Parameter] - public EventCallback> ValueChanged { get; set; } - - [Parameter] - public ChannelTypes? Type { get; set; } - - private ExternalUserCreateModal _createModal = default!; - private long _count; - - MessageTaskService MessageTaskService => McCaller.MessageTaskService; - - private async Task HandleOk(UserDto user) - { - var receiver = new MessageTaskReceiverDto - { - SubjectId = user.Id, - DisplayName = user.GetDisplayName(), - Avatar = user.Avatar, - PhoneNumber = user.PhoneNumber ?? string.Empty, - Email = user.Email ?? string.Empty, - Type = MessageTaskReceiverTypes.User - }; - var dtos = new List { receiver }; - await HandleAddAsync(dtos); - } - - private async Task RemoveValue(MessageTaskReceiverDto item) - { - Value.Remove(item); - - await HandleValueChangedAsync(); - } - - private async Task HandleAddAsync(List receivers) - { - foreach (var receiver in receivers) - { - if (!string.IsNullOrEmpty(receiver.PhoneNumber) && Value.Any(x => x.PhoneNumber == receiver.PhoneNumber)) continue; - if (!string.IsNullOrEmpty(receiver.Email) && Value.Any(x => x.Email == receiver.Email)) continue; - if (receiver.SubjectId != default && Value.Any(x => x.SubjectId == receiver.SubjectId)) continue; - Value.Insert(0, receiver); - } - await HandleValueChangedAsync(); - } - - private async Task HandleOnAdd(MessageTaskReceiverDto item) - { - if (!Value.Any(x => x.SubjectId == item.SubjectId)) - { - Value.Add(item); - await HandleValueChangedAsync(); - } - } - - private async Task HandleOnRemove(MessageTaskReceiverDto item) - { - if (Value.Any(x => x.SubjectId == item.SubjectId)) - { - Value.RemoveAll(x => x.SubjectId == item.SubjectId); - await HandleValueChangedAsync(); - } - } - - private async Task HandleValueChangedAsync() - { - if (ValueChanged.HasDelegate) - { - await ValueChanged.InvokeAsync(Value); - } - - _count = await MessageTaskService.ResolveReceiversCountAsync(Value); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageSendingRules.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageSendingRules.razor deleted file mode 100644 index a8862975..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageSendingRules.razor +++ /dev/null @@ -1,45 +0,0 @@ -@inherits AdminCompontentBase - - - - - -@if (Value.IsCustom) -{ - - - - - - - - - - - @T("DisplayName.SendingRule.SendingCount.Tips") - - - - - @if (!string.IsNullOrEmpty(Value.CronExpression)) - { - - - - - - - } -} - - - - - \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageSendingRules.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageSendingRules.razor.cs deleted file mode 100644 index 71641044..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageSendingRules.razor.cs +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTasks.Modules; - -public partial class MessageSendingRules : AdminCompontentBase -{ - [Parameter] - public SendRuleDto Value { get; set; } = new(); - - [Parameter] - public EventCallback ValueChanged { get; set; } - - [Parameter] - public bool ReadOnly { get; set; } - - private bool _cronVisible; - private string _tempCron = string.Empty; - private string _nextRunTimeStr = string.Empty; - - protected override void OnParametersSet() - { - base.OnParametersSet(); - - GetNextRunTime(); - } - - private void OpenCronModal() - { - _cronVisible = true; - - if (CronExpression.IsValidExpression(Value.CronExpression)) - { - _tempCron = Value.CronExpression; - } - } - - private async Task SetCronExpression() - { - if (CronExpression.IsValidExpression(_tempCron)) - { - Value.CronExpression = _tempCron; - GetNextRunTime(); - _cronVisible = false; - } - else - { - await PopupService.EnqueueSnackbarAsync(T("CronExpressionInvalid"), AlertTypes.Error); - } - - } - - private void GetNextRunTime(int showCount = 10) - { - if (!CronExpression.IsValidExpression(Value.CronExpression)) - { - _nextRunTimeStr = T("CronExpressionNotHasNextRunTime"); - return; - } - - var sb = new StringBuilder(); - - var startTime = DateTimeOffset.UtcNow; - - var cronExpression = new CronExpression(Value.CronExpression); - - var timezone = TimeZoneInfo.GetSystemTimeZones().FirstOrDefault(p => p.BaseUtcOffset == JsInitVariables.TimezoneOffset); - - if (timezone != null) - cronExpression.TimeZone = timezone; - - for (int i = 0; i < showCount; i++) - { - var nextExcuteTime = cronExpression.GetNextValidTimeAfter(startTime); - - if (nextExcuteTime.HasValue) - { - startTime = nextExcuteTime.Value; - sb.AppendLine(startTime.ToOffset(JsInitVariables.TimezoneOffset).ToString("yyyy-MM-dd HH:mm:ss")); - } - } - - if (sb.Length == 0) - { - _nextRunTimeStr = T("CronExpressionNotHasNextRunTime"); - } - else - { - _nextRunTimeStr = sb.ToString(); - } - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageSendingRulesInfo.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageSendingRulesInfo.razor deleted file mode 100644 index 9d0200fc..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageSendingRulesInfo.razor +++ /dev/null @@ -1,21 +0,0 @@ -@inherits AdminCompontentBase -@if (Value.IsCustom) -{ -
-
@T("DisplayName.SendingRule.CronExpression")
-
@Value.CronExpression
-
-} -@if (Value.SendingCount>0) -{ -
-
@T("DisplayName.SendingRule.SendingCount")
-
@Value.SendingCount
-
-} - - -@code { - [Parameter] - public SendRuleDto Value { get; set; } = new(); -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageTaskCard.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageTaskCard.razor deleted file mode 100644 index f9e2adda..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageTaskCard.razor +++ /dev/null @@ -1,153 +0,0 @@ -@inherits AdminCompontentBase - - - - - @if (MessageTask.Channel != null) - { - @MessageTask.Channel?.DisplayName - } - - - - - mdi-dots-horizontal - - - - - - - - - - - @if (MessageTask.IsDraft) - { - - - - @T("Edit") - - - - } - else - { - - - - @T("Permission.ViewMessageTask") - - - - } - - - - @T("Test") - - - - - - - @T("Delete") - - - - - - - - - - - - -
@MessageTask.DisplayName
-
@((MessageTask.SendTime?.ToOffset(JsInitVariables.TimezoneOffset) ?? MessageTask.ExpectSendTime?.ToOffset(JsInitVariables.TimezoneOffset))?.ToString(T("$DateTimeFormat")))
- - @MessageTask.Content - -
- - @T($"DisplayName.MessageEntityType.{((MessageEntityTypes)MessageTask.EntityType).ToString()}") - @if (MessageTask.IsDraft == false) - { - - - - - } - - @MessageTask.ModificationTime.Humanize(culture:I18n.Culture) - - - - @MessageTask.ModifierName - -
- -@code { - [EditorRequired] - [Parameter] - public MessageTaskDto MessageTask { get; set; } = null!; - - [Parameter] - public EventCallback OnEdit { get; set; } - - [Parameter] - public EventCallback OnView { get; set; } - - [Parameter] - public EventCallback OnTest { get; set; } - - [Parameter] - public EventCallback OnDelete { get; set; } - - [Parameter] - public EventCallback OnIsEnabled { get; set; } - - protected override string? PageName { get; set; } = "MessageTaskBlock"; - - private async Task HandleOnEdit() - { - if (OnEdit.HasDelegate) - { - await OnEdit.InvokeAsync(); - } - } - - private async Task HandleOnView() - { - if (OnView.HasDelegate) - { - await OnView.InvokeAsync(); - } - } - - private async Task HandleOnTest() - { - if (OnTest.HasDelegate) - { - await OnTest.InvokeAsync(); - } - } - - private async Task HandleOnDelete() - { - if (OnDelete.HasDelegate) - { - await OnDelete.InvokeAsync(); - } - } - - private async Task HandleOnIsEnabled() - { - if (OnIsEnabled.HasDelegate) - { - await OnIsEnabled.InvokeAsync(); - } - } -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageTaskDetailModal.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageTaskDetailModal.razor deleted file mode 100644 index 52f097e0..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageTaskDetailModal.razor +++ /dev/null @@ -1,176 +0,0 @@ -@inherits AdminCompontentBase -
- -
-
- - -
@T("DisplayName.MessageTaskHistory")
- -
- - -
-
- - @if (_histories.Result.Any()) - { -
- - @foreach (var item in _histories.Result) - { - - - @if (_historyInfo.Id == item.Id) - { -
@T($"DisplayName.MessageTaskHistoryStatus.{((MessageTaskHistoryStatuses)item.Status).ToString()}")
- } - else - { -
@T($"DisplayName.MessageTaskHistoryStatus.{((MessageTaskHistoryStatuses)item.Status).ToString()}")
- } -
- - - - -
- @if (_historyInfo.Id == item.Id) - { -
@item.TaskHistoryNo
- } - else - { -
@item.TaskHistoryNo
- } -
@item.SendTime?.ToOffset(JsInitVariables.TimezoneOffset).ToString(T("$DateTimeFormat"))
-
-
-
- } -
-
- } -
- - - -
-
- - - -
- - - @if (_historyInfo.Status == MessageTaskHistoryStatuses.WaitSend && _historyInfo.SendTime.HasValue) - { - - @T(string.Format(T("Description.MessageTaskHistory.SendTimeTips"),_historyInfo.SendTime?.ToOffset(JsInitVariables.TimezoneOffset).ToString(T("$DateTimeFormat")))) - - } - - -
@T("MessageDetails")
- @if (_info.EntityType == MessageEntityTypes.Ordinary) - { - - } - @if (_info.EntityType == MessageEntityTypes.Template) - { - - } - -
@T("DisplayName.MessageTaskReceiver")
-
-
@T("DisplayName.MessageTaskDetail.ReceiverType")
-
@T($"DisplayName.ReceiverType.{_info.ReceiverType.ToString()}")
-
- - @if (_receiverUsers.Any()) - { - - - @foreach (var item in _receiverUsers) - { - - - @if (string.IsNullOrEmpty(item.Avatar)) - { - - } - else - { - - } - - - - @(item.DisplayName) -
- -
- @T("DisplayName.SubjectTypes.User") -
- - @(item.PhoneNumber) -
- -
- @(item.Email) -
-
-
- } -
-
- } - - @if (_info.Channel.Type == ChannelTypes.Sms || _info.SendRules.IsCustom) - { -
@T("DisplayName.MessageTaskSendingRule")
- } - @if (_info.Channel.Type == ChannelTypes.Sms) - { -
-
@T("DisplayName.MessageTemplateSign")
-
@_info.Sign
-
- } - @if (_info.SendRules.IsCustom) - { - - } -
- - @if (_info.Channel.Type == ChannelTypes.WebsiteMessage && _historyInfo.Status != MessageTaskHistoryStatuses.Withdrawn) - { -
- - - @T("Withdraw") - -
- } -
-
-
-
-
-
\ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageTaskDetailModal.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageTaskDetailModal.razor.cs deleted file mode 100644 index 889ef21b..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageTaskDetailModal.razor.cs +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTasks.Modules; - -public partial class MessageTaskDetailModal : AdminCompontentBase -{ - [Parameter] - public EventCallback OnOk { get; set; } - - private MessageTaskDto _info = new(); - private MessageTaskHistoryDto _historyInfo = new(); - private Guid _entityId; - private bool _visible; - private GetMessageTaskHistoryInputDto _queryParam = new(); - - private PaginatedListDto _histories = new(); - private DateOnly? _endTime; - private DateOnly? _startTime; - private List _receiverUsers = new(); - - private MessageTaskService MessageTaskService => McCaller.MessageTaskService; - - private MessageTaskHistoryService MessageTaskHistoryService => McCaller.MessageTaskHistoryService; - - protected override string? PageName { get; set; } = "MessageTaskBlock"; - - - public async Task OpenModalAsync(MessageTaskDto model) - { - _entityId = model.Id; - _queryParam.MessageTaskId = _entityId; - await GetFormDataAsync(); - await InvokeAsync(() => - { - _visible = true; - StateHasChanged(); - }); - } - - private async Task GetFormDataAsync() - { - _info = await MessageTaskService.GetAsync(_entityId) ?? new(); - await LoadData(); - if (_histories.Result.Any()) - { - _historyInfo = _histories.Result[0]; - - await GetReceiversAsync(_historyInfo.Id); - } - } - - private void HandleCancel() - { - _visible = false; - ResetForm(); - } - - private async Task HandleDelAsync() - { - await ConfirmAsync(T("DeletionConfirmationMessage"), DeleteAsync); - } - - private async Task DeleteAsync() - { - Loading = true; - await MessageTaskService.DeleteAsync(_entityId); - Loading = false; - await SuccessMessageAsync(T("MessageTaskDeleteMessage")); - _visible = false; - ResetForm(); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - - private void ResetForm() - { - _info = new(); - _historyInfo = new(); - _queryParam = new() { Page = 1 }; - } - - private void HandleVisibleChanged(bool val) - { - if (!val) HandleCancel(); - } - - private Task OnDateChanged((DateOnly? startDate,DateOnly? endDate) args) - { - (_startTime, _endTime) = args; - _queryParam.StartTime = _startTime?.ToDateTime(TimeOnly.MinValue); - _queryParam.EndTime = _endTime?.ToDateTime(TimeOnly.MaxValue); - return Refresh(); - } - - private async Task Refresh() - { - _queryParam.Page = 1; - await LoadData(); - } - - private async Task LoadData() - { - Loading = true; - _histories = (await MessageTaskHistoryService.GetListAsync(_queryParam)); - Loading = false; - StateHasChanged(); - } - - private async Task HandleItemSelect(MessageTaskHistoryDto item) - { - _historyInfo = item; - await GetReceiversAsync(_historyInfo.Id); - } - - private async Task HandlePageChanged(int page) - { - _queryParam.Page = page; - await LoadData(); - } - - private async Task HandlePageSizeChanged(int pageSize) - { - _queryParam.PageSize = pageSize; - await LoadData(); - } - - private async Task HandleWithdrawnAsync() - { - await ConfirmAsync(T("TaskWithdrawnConfirmationMessage", $"[{_info.DisplayName}]"), WithdrawnAsync); - } - - private async Task WithdrawnAsync() - { - Loading = true; - await MessageTaskService.WithdrawnAsync(_info.Id); - Loading = false; - await SuccessMessageAsync(T("MessageTaskWithdrawnMessage")); - await GetFormDataAsync(); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - - private async Task GetReceiversAsync(Guid id) - { - _receiverUsers = await MessageTaskHistoryService.GetReceiversAsync(id); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageTaskDetailModal.razor.css b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageTaskDetailModal.razor.css deleted file mode 100644 index e31b07d4..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageTaskDetailModal.razor.css +++ /dev/null @@ -1,32 +0,0 @@ -.task-detail-left { - width: 482px; -} - -.task-detail-right { - padding: 48px 114px; - width: calc(100% - 482px); -} - -.task-history-box { - margin-left: -104px; -} - - .task-history-box ::deep .m-timeline-item__dot { - box-shadow: none; - } - - .task-history-box ::deep .m-timeline-item__dot { - background: transparent !important; - } - - .task-history-box ::deep .m-timeline-item__inner-dot { - background-color: transparent !important; - } - - .task-history-box ::deep .m-icon { - background: #ffff !important; - } - - .task-history-box ::deep .theme--light.m-timeline::before { - background: #E2E7F4; - } diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageVariables.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageVariables.razor deleted file mode 100644 index aea328f0..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageVariables.razor +++ /dev/null @@ -1,29 +0,0 @@ -@inherits AdminCompontentBase -
-
@T("DisplayName.VariableValueTransfer")
- - - - @T("DisplayName.Variable") - - - @T("DisplayName.Value") - -
-
- @foreach (var item in _items) - { - - -

@item.Name

-
- - - -
- } -
\ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageVariables.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageVariables.razor.cs deleted file mode 100644 index 32601d0e..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/MessageVariables.razor.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTasks.Modules; - -public partial class MessageVariables : AdminCompontentBase -{ - [Parameter] - public ExtraPropertyDictionary Value { get; set; } = new(); - - [Parameter] - public EventCallback ValueChanged { get; set; } - - [Parameter] - public bool ReadOnly { get; set; } - - private List _items = new(); - - protected async override Task OnInitializedAsync() - { - _items = Value.Select(x => new ItemDto(x.Key, x.Value?.ToString() ?? string.Empty)).ToList(); - - await base.OnInitializedAsync(); - } - - public async Task HandleChangeAsync() - { - var extraProperty = new ExtraPropertyDictionary(); - foreach (var item in _items) - { - extraProperty.TryAdd(item.Name, item.Value); - } - Value = extraProperty; - await ValueChanged.InvokeAsync(Value); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/OrdinaryMessageCreateModal.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/OrdinaryMessageCreateModal.razor deleted file mode 100644 index f07f36db..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/OrdinaryMessageCreateModal.razor +++ /dev/null @@ -1,199 +0,0 @@ -@inherits AdminCompontentBase -
- - - - - - - @T("DisplayName.MessageInfoContent") - - - - @T("DisplayName.MessageTaskReceiver") - - - - @T("DisplayName.MessageTaskSendingRule") - - - - - - - - - - - @if (_model.ChannelType == ChannelTypes.App) - { -
- - -
- } - @if (_model.ChannelType == ChannelTypes.WeixinWork) - { - - - } - @if (_model.ChannelType == ChannelTypes.WeixinWorkWebhook) - { - - - } - @if (_model.ComputedTitleShow) - { - - - } -
- @if (_model.ComputedMarkdown) - { - - - } - else - { - - - } -
- @if (_model.ComputedJumpUrlShow) - { - - - - - - fas fa-link - - - } - @if (_model.ChannelType == ChannelTypes.Sms) - { - - - } - @if (_model.ChannelType == ChannelTypes.App) - { - - - - - @T("OptionalConfiguration") - - - Android - - - - - - Ios - - - - - - - - - - } -
- -
- - @T("Save") - @T("NextStep") -
-
-
-
- - - - @if (_model.ComputedBroadcast && !_selectReceiverType) - { - - } - else - { - - - } - - -
- - mdi-keyboard-backspace - - - @if (_model.ChannelType != ChannelTypes.WebsiteMessage || _selectReceiverType) - { - @T("Save") - @T("NextStep") - } -
-
-
-
- - - - - - - -
- - mdi-keyboard-backspace - - - @T("Save") - @T("SaveSend") -
-
-
-
-
-
-
-
-
-
\ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/OrdinaryMessageCreateModal.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/OrdinaryMessageCreateModal.razor.cs deleted file mode 100644 index deeffc45..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/OrdinaryMessageCreateModal.razor.cs +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTasks.Modules; - -public partial class OrdinaryMessageCreateModal : AdminCompontentBase -{ - [Parameter] - public EventCallback OnOk { get; set; } - - private MForm? _form; - private MessageTaskUpsertModel _model = new() { EntityType = MessageEntityTypes.Ordinary, SystemId = MasaStackProject.MC.Name }; - private bool _visible; - private List _channelItems = new(); - private List _selectReceivers = new(); - private List _importReceivers = new(); - private bool _selectReceiverType; - - MessageTaskService MessageTaskService => McCaller.MessageTaskService; - ChannelService ChannelService => McCaller.ChannelService; - - protected override string? PageName { get; set; } = "MessageTaskBlock"; - - public async Task OpenModalAsync() - { - await InvokeAsync(() => - { - _visible = true; - StateHasChanged(); - }); - - _form?.ResetValidation(); - } - - private void HandleCancel() - { - _visible = false; - ResetForm(); - } - - private async Task HandleSaveAsync() - { - _model.IsDraft = true; - await HandleOkAsync(); - } - - private async Task HandleSendAsync() - { - _model.IsDraft = false; - await HandleOkAsync(); - } - - private async Task HandleOkAsync() - { - Check.NotNull(_form, "form not found"); - - SetReceivers(); - if (!_form.Validate()) - { - return; - } - Loading = true; - var inputDto = _model.Adapt(); - await MessageTaskService.CreateAsync(inputDto); - Loading = false; - if (_model.IsDraft) - { - await SuccessMessageAsync(T("MessageTaskCreateMessage")); - } - else - { - await SuccessMessageAsync(T("MessageTaskSendMessage")); - } - _visible = false; - ResetForm(); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - - private void ResetForm() - { - _model = new() { EntityType = MessageEntityTypes.Ordinary, SystemId = MasaStackProject.MC.Name }; - _selectReceivers = new(); - _importReceivers = new(); - _selectReceiverType = false; - } - - private void HandleVisibleChanged(bool val) - { - if (!val) HandleCancel(); - } - - private async Task HandleChannelTypeChangeAsync() - { - _channelItems = _model.ChannelType.HasValue ? await ChannelService.GetListByTypeAsync(_model.ChannelType.Value) : new(); - if (_model.ChannelType != ChannelTypes.WebsiteMessage) - { - _model.ReceiverType = ReceiverTypes.Assign; - } - else - { - _model.ReceiverType = default; - } - } - - private void HandleReceiverType(ReceiverTypes receiverType) - { - _model.ReceiverType = receiverType; - _selectReceiverType = true; - if (receiverType == ReceiverTypes.Broadcast) - { - _model.Step = 3; - } - } - - private void HandleReceiverBack() - { - if (_model.ChannelType != ChannelTypes.WebsiteMessage || !_selectReceiverType) - { - _model.Step = 1; - } - - if (_selectReceiverType) - { - _selectReceiverType = false; - } - } - - private void HandleSendingRuleBack() - { - _model.Step = 2; - if (_model.ReceiverType == ReceiverTypes.Broadcast) - { - _selectReceiverType = false; - } - } - - private void HandleNextStep() - { - SetReceivers(); - _model.IsDraft = false; - if (!_form.Validate()) - { - return; - } - _model.Step++; - } - - private void SetReceivers() - { - _model.Receivers = _model.SelectReceiverType == MessageTaskSelectReceiverTypes.ManualSelection ? _selectReceivers : _importReceivers; - } - - private void HandleSelectTemplateType(int type) - { - _model.MessageInfo.IsJump = type == (int)WeixinWorkTemplateTypes.Text ? false : true; - } -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/OrdinaryMessageEditModal.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/OrdinaryMessageEditModal.razor deleted file mode 100644 index fd75c44e..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/OrdinaryMessageEditModal.razor +++ /dev/null @@ -1,187 +0,0 @@ -@inherits AdminCompontentBase -
- - - - - - - @T("DisplayName.MessageInfoContent") - - - - @T("DisplayName.MessageTaskReceiver") - - - - @T("DisplayName.MessageTaskSendingRule") - - - - - - - - - - - @if (_model.ChannelType == ChannelTypes.App) - { -
- - -
- } - @if (_model.ChannelType == ChannelTypes.WeixinWork) - { - - - } - @if (_model.ComputedTitleShow) - { - - - } -
- @if (_model.ComputedMarkdown) - { - - - } - else - { - - - } -
- @if (_model.ComputedJumpUrlShow) - { - - - - - - } - @if (_model.ChannelType == ChannelTypes.Sms) - { - - - } - @if (_model.ChannelType == ChannelTypes.App) - { - - - - - @T("OptionalConfiguration") - - - Android - - - - - - Ios - - - - - - - - - - } -
- -
- - @T("Save") - @T("NextStep") -
-
-
-
- - - - @if (_model.ComputedBroadcast && !_selectReceiverType) - { - - } - else - { - - - } - - -
- - mdi-keyboard-backspace - - - @if (_model.ChannelType != ChannelTypes.WebsiteMessage || _selectReceiverType) - { - @T("Save") - @T("NextStep") - } -
-
-
-
- - - - - - - -
- - mdi-keyboard-backspace - - - @T("Save") - @T("SaveSend") -
-
-
-
-
-
-
-
-
-
\ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/OrdinaryMessageEditModal.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/OrdinaryMessageEditModal.razor.cs deleted file mode 100644 index 5f57a626..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/OrdinaryMessageEditModal.razor.cs +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTasks.Modules; - -public partial class OrdinaryMessageEditModal : AdminCompontentBase -{ - [Parameter] - public EventCallback OnOk { get; set; } - - private MForm? _form; - private MessageTaskUpsertModel _model = new() { EntityType = MessageEntityTypes.Ordinary, SystemId = MasaStackProject.MC.Name }; - private Guid _entityId; - private bool _visible; - private List _channelItems = new(); - private List _selectReceivers = new(); - private List _importReceivers = new(); - private bool _selectReceiverType; - - MessageTaskService MessageTaskService => McCaller.MessageTaskService; - ChannelService ChannelService => McCaller.ChannelService; - MessageInfoService MessageInfoService => McCaller.MessageInfoService; - - protected override string? PageName { get; set; } = "MessageTaskBlock"; - - public async Task OpenModalAsync(MessageTaskDto model) - { - _entityId = model.Id; - _model = model.Adapt(); - await GetFormDataAsync(); - await InvokeAsync(() => - { - _visible = true; - StateHasChanged(); - }); - - _form?.ResetValidation(); - } - - private async Task GetFormDataAsync() - { - var dto = await MessageTaskService.GetAsync(_entityId); - if (dto != null) - { - _model = dto.Adapt(); - if (_model.SelectReceiverType == MessageTaskSelectReceiverTypes.ManualSelection) - { - _selectReceivers = _model.Receivers; - } - else - { - _importReceivers = _model.Receivers; - } - _channelItems = _model.ChannelType.HasValue ? await ChannelService.GetListByTypeAsync(_model.ChannelType.Value) : new(); - var messageInfo = await MessageInfoService.GetAsync(_model.EntityId); - if (messageInfo != null) _model.MessageInfo = messageInfo.Adapt(); - } - } - - private void HandleCancel() - { - _visible = false; - ResetForm(); - } - - private async Task HandleSaveAsync() - { - _model.IsDraft = true; - await HandleOkAsync(); - } - - private async Task HandleSendAsync() - { - _model.IsDraft = false; - await HandleOkAsync(); - } - - private async Task HandleOkAsync() - { - Check.NotNull(_form, "form not found"); - - SetReceivers(); - if (!_form.Validate()) - { - return; - } - Loading = true; - var inputDto = _model.Adapt(); - await MessageTaskService.UpdateAsync(_entityId, inputDto); - Loading = false; - if (_model.IsDraft) - { - await SuccessMessageAsync(T("MessageTaskEditMessage")); - } - else - { - await SuccessMessageAsync(T("MessageTaskSendMessage")); - } - _visible = false; - ResetForm(); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - - private void ResetForm() - { - _model = new() { EntityType = MessageEntityTypes.Ordinary, SystemId = MasaStackProject.MC.Name }; - _selectReceivers = new(); - _importReceivers = new(); - _selectReceiverType = false; - } - - private void HandleVisibleChanged(bool val) - { - if (!val) HandleCancel(); - } - - private async Task HandleChannelTypeChangeAsync() - { - _channelItems = _model.ChannelType.HasValue ? await ChannelService.GetListByTypeAsync(_model.ChannelType.Value) : new(); - if (_model.ChannelType != ChannelTypes.WebsiteMessage) - { - _model.ReceiverType = ReceiverTypes.Assign; - } - else - { - _model.ReceiverType = default; - } - if (_channelItems.Count > 0 && !_channelItems.Any(c => c.Id == _model.ChannelId)) - { - _model.ChannelId = null; - } - } - - private void HandleReceiverType(ReceiverTypes receiverType) - { - _model.ReceiverType = receiverType; - _selectReceiverType = true; - if (receiverType == ReceiverTypes.Broadcast) - { - _model.Step = 3; - } - } - - private void HandleReceiverBack() - { - if (_model.ChannelType != ChannelTypes.WebsiteMessage || !_selectReceiverType) - { - _model.Step = 1; - } - - if (_selectReceiverType) - { - _selectReceiverType = false; - } - } - - private void HandleSendingRuleBack() - { - _model.Step = 2; - if (_model.ReceiverType == ReceiverTypes.Broadcast) - { - _selectReceiverType = false; - } - } - - private void HandleNextStep() - { - SetReceivers(); - _model.IsDraft = false; - if (!_form.Validate()) - { - return; - } - _model.Step++; - } - - private void SetReceivers() - { - _model.Receivers = _model.SelectReceiverType == MessageTaskSelectReceiverTypes.ManualSelection ? _selectReceivers : _importReceivers; - } - - private void HandleSelectTemplateType(int type) - { - _model.MessageInfo.IsJump = type != (int)WeixinWorkTemplateTypes.Text; - } -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/OrdinaryMessageInfo.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/OrdinaryMessageInfo.razor deleted file mode 100644 index 76654c58..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/OrdinaryMessageInfo.razor +++ /dev/null @@ -1,73 +0,0 @@ -@inherits AdminCompontentBase -
-
-
@T("DisplayName.ChannelType")
-
@(MessageTask.Channel != null ? T(MessageTask.Channel.Type.ToString()) : string.Empty)
-
-
-
@T("DisplayName.Channel")
-
@MessageTask.Channel?.DisplayName
-
- @if (MessageTask.ChannelType == ChannelTypes.App) - { - - - - - - - } -
-
@T("DisplayName.MessageInfoTitle")
-
@MessageInfo.Title
-
-
-
@T("MessageContent")
-
-
- @if (MessageInfo.IsJump) - { -
-
@T("DisplayName.MessageTemplateJumpUrl")
-
@MessageInfo.JumpUrl
-
- } - @if (MessageTask.ChannelType == ChannelTypes.App) - { - @if (!string.IsNullOrEmpty(MessageTask.ExtraProperties.GetProperty(BusinessConsts.INTENT_URL))) - { -
-
@T("IntentUrl")
-
@(MessageTask.ExtraProperties.GetProperty(BusinessConsts.INTENT_URL))
-
- } - @if (MessageInfo.ExtraProperties.Any()) - { -
@T("AdditionalFields")
- - - - - @T("Key") - - - @T("Value") - - - - - - - - @foreach (var item in MessageInfo.ExtraProperties) - { - - @item.Key - @item.Value - - } - - - } - } -
\ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/OrdinaryMessageInfo.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/OrdinaryMessageInfo.razor.cs deleted file mode 100644 index 377863b6..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/OrdinaryMessageInfo.razor.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTasks.Modules; - -public partial class OrdinaryMessageInfo : AdminCompontentBase -{ - [Parameter] - public Guid MessageInfoId { get; set; } - - [Parameter] - public MessageTaskDto MessageTask { get; set; } = new(); - - public MessageInfoDto MessageInfo { get; set; } = new(); - - MessageInfoService MessageInfoService => McCaller.MessageInfoService; - - protected override string? PageName { get; set; } = "MessageTaskBlock"; - - protected override async Task OnParametersSetAsync() - { - MessageInfo = await MessageInfoService.GetAsync(MessageInfoId) ?? new(); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/OrdinaryMessageInfoByMessageRecord.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/OrdinaryMessageInfoByMessageRecord.razor deleted file mode 100644 index eb9da1c5..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/OrdinaryMessageInfoByMessageRecord.razor +++ /dev/null @@ -1,92 +0,0 @@ -@inherits AdminCompontentBase -
-
-
@T("DisplayName.ChannelType")
-
@(MessageRecord.Channel != null ? T(MessageRecord.Channel.Type.ToString()) : string.Empty)
-
-
-
@T("DisplayName.Channel")
-
@MessageRecord.Channel?.DisplayName
-
- @if (MessageRecord.Channel?.Type == ChannelTypes.App) - { - - - - - - - } -
-
@T("DisplayName.MessageInfoTitle")
-
@MessageInfo.Title
-
-
-
@T("MessageContent")
-
-
- @if (MessageInfo.IsJump) - { -
-
@T("DisplayName.MessageTemplateJumpUrl")
-
@MessageInfo.JumpUrl
-
- } - @if (MessageRecord.Channel?.Type == ChannelTypes.App) - { - @if (!string.IsNullOrEmpty(MessageRecord.ExtraProperties.GetProperty(BusinessConsts.INTENT_URL))) - { -
-
@T("IntentUrl")
-
@(MessageRecord.ExtraProperties.GetProperty(BusinessConsts.INTENT_URL))
-
- } - @if (MessageInfo.ExtraProperties.Any()) - { -
@T("AdditionalFields")
- - - - - @T("Key") - - - @T("Value") - - - - - - - - @foreach (var item in MessageInfo.ExtraProperties) - { - - @item.Key - @item.Value - - } - - - } - } -
- -@code { - [Parameter] - public Guid MessageInfoId { get; set; } - - [Parameter] - public MessageRecordDto MessageRecord { get; set; } = new(); - - public MessageInfoDto MessageInfo { get; set; } = new(); - - MessageInfoService MessageInfoService => McCaller.MessageInfoService; - - protected override string? PageName { get; set; } = "MessageRecordBlock"; - - protected override async Task OnParametersSetAsync() - { - MessageInfo = await MessageInfoService.GetAsync(MessageInfoId) ?? new(); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/ReceiverTypeSelect.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/ReceiverTypeSelect.razor deleted file mode 100644 index 31f8cf0f..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/ReceiverTypeSelect.razor +++ /dev/null @@ -1,81 +0,0 @@ -@inherits AdminCompontentBase - -
- -
-
- - - @if (hoverContext.Hover) - { - mdi-account-supervisor-circle -
@T("DisplayName.ReceiverType.Assign")
- } - else if (Value == ReceiverTypes.Assign) - { - mdi-account-supervisor-circle -
@T("DisplayName.ReceiverType.Assign")
- } - else - { - mdi-account-supervisor-circle -
@T("DisplayName.ReceiverType.Assign")
- } -
-
-
-
- - - @if (hoverContext.Hover) - { - mdi-email -
@T("DisplayName.ReceiverType.Broadcast")
- } - else if (Value == ReceiverTypes.Broadcast) - { - mdi-email -
@T("DisplayName.ReceiverType.Broadcast")
- } - else - { - mdi-email -
@T("DisplayName.ReceiverType.Broadcast")
- } -
-
-
-
-
-
- -@code { - [Parameter] - public ReceiverTypes Value { get; set; } - - [Parameter] - public EventCallback OnClick { get; set; } - - private ReceiverTypes _hoverType; - - private async Task HandleReceiverType(ReceiverTypes receiverType) - { - _hoverType = default; - - if (OnClick.HasDelegate) - { - await OnClick.InvokeAsync(receiverType); - } - else - { - Value = receiverType; - } - } - - private void HandleHoverChanged(bool val, ReceiverTypes hoverType) - { - _hoverType = val ? hoverType : default; - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/SendTestMessageModal.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/SendTestMessageModal.razor deleted file mode 100644 index 5090a81b..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/SendTestMessageModal.razor +++ /dev/null @@ -1,23 +0,0 @@ -@inherits AdminCompontentBase -
- - - - - - - @(T("SendTestMessage")) - - -
diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/SendTestMessageModal.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/SendTestMessageModal.razor.cs deleted file mode 100644 index 7a0bd42d..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/SendTestMessageModal.razor.cs +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTasks.Modules; - -public partial class SendTestMessageModal : AdminCompontentBase -{ - [Parameter] - public EventCallback OnOk { get; set; } - - private SendTestMessageTaskInputDto _input = new(); - private bool _visible; - private List _userIds = new List(); - private Components.Modules.Subjects.UserAutoComplete _userRef = default!; - private ChannelTypes? _type; - - MessageTaskService MessageTaskService => McCaller.MessageTaskService; - - public async Task OpenModalAsync(Guid messageTaskId, ChannelTypes? type) - { - _input.Id = messageTaskId; - _type = type; - - await InvokeAsync(() => - { - _visible = true; - StateHasChanged(); - }); - } - - private void HandleCancel() - { - _visible = false; - ResetForm(); - } - - private async Task HandleOkAsync() - { - Loading = true; - await MessageTaskService.SendTestAsync(_input); - Loading = false; - await SuccessMessageAsync(T("MessageTaskSendMessage")); - _visible = false; - - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - ResetForm(); - } - - private void ResetForm() - { - _input = new(); - } - - private void HandleUserChange(List userId) - { - _userIds = userId; - _input.ReceiverUsers = _userRef.UserSelect.Select(x => new MessageReceiverUserDto - { - UserId = x.Id, - ChannelUserIdentity = GetChannelUserIdentity(x, _type) - }).ToList(); - } - - private string GetChannelUserIdentity(UserSelectModel user, ChannelTypes? type) - { - return type switch - { - ChannelTypes.Sms => user.PhoneNumber ?? string.Empty, - ChannelTypes.Email => user.Email ?? string.Empty, - ChannelTypes.WebsiteMessage => user.Id.ToString(), - _ => string.Empty - }; - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateInfo.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateInfo.razor deleted file mode 100644 index eead50a3..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateInfo.razor +++ /dev/null @@ -1,87 +0,0 @@ -@inherits AdminCompontentBase - -@if (Template.Channel?.Type == ChannelTypes.App) -{ - - - - - - - -} -@if (ComputedTitleShow) -{ - - - - - - -} - - - - - -@if (ComputedJumpUrlShow) -{ - - - - - fa:fas fa-link - - - - -} -@if (Template.Channel?.Type == ChannelTypes.App) -{ - - - - - @T("OptionalConfiguration") - - - Android - - - - - - Ios - - - - - - - -} - -@code { - [Parameter] - public MessageTemplateDto Template { get; set; } = new(); - - private bool ComputedJumpUrlShow - { - get - { - return Template.IsJump && (Template.Channel?.Type == ChannelTypes.WebsiteMessage || (Template.Channel?.Type == ChannelTypes.App && Template.Options.GetProperty("IsWebsiteMessage") || Template.Channel?.Type == ChannelTypes.WeixinWork)); - } - } - - private bool ComputedTitleShow - { - get - { - return !(Template.Channel?.Type == ChannelTypes.Sms || (Template.Channel?.Type == ChannelTypes.WeixinWork && Template.TemplateType == (int)WeixinWorkTemplateTypes.Text) || Template.Channel?.Type == ChannelTypes.WeixinWorkWebhook); - } - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageCreateModal.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageCreateModal.razor deleted file mode 100644 index eec4b67b..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageCreateModal.razor +++ /dev/null @@ -1,155 +0,0 @@ -@inherits AdminCompontentBase -
- - - - - - - @T("DisplayName.MessageInfoContent") - - - - @T("DisplayName.MessageTaskReceiver") - - - - @T("DisplayName.MessageTaskSendingRule") - - - - - - -
-
- - - - - - - - - - - - - - - - - - - @if (_model.EntityId != default) - { - - - @if (_model.Variables.Any()) - { - - } - } - - -
- - @T("Save") - @T("NextStep") -
-
-
-
- - - - @if (_model.ComputedBroadcast && !_selectReceiverType) - { - - } - else - { - - - } - - -
- - mdi-keyboard-backspace - - - @if (!_model.ComputedBroadcast || _selectReceiverType) - { - @T("Save") - @T("NextStep") - } -
-
-
-
- - - - - @if (_messageInfo.Channel != null && _messageInfo.Channel.Type == ChannelTypes.Sms) - { - - - - - - - } - - - -
- - mdi-keyboard-backspace - - - @T("Save") - @T("SaveSend") -
-
-
-
-
-
-
-
-
-
\ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageCreateModal.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageCreateModal.razor.cs deleted file mode 100644 index 32cc0ca9..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageCreateModal.razor.cs +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTasks.Modules; - -public partial class TemplateMessageCreateModal : AdminCompontentBase -{ - [Parameter] - public EventCallback OnOk { get; set; } - - private MForm? _form; - private MessageTaskUpsertModel _model = new() { EntityType = MessageEntityTypes.Template, SystemId = MasaStackProject.MC.Name }; - private bool _visible; - private List _templateItems = new(); - private MessageTemplateDto _messageInfo = new(); - private List _channelItems = new(); - private List _selectReceivers = new(); - private List _importReceivers = new(); - private bool _selectReceiverType; - - MessageTaskService MessageTaskService => McCaller.MessageTaskService; - MessageTemplateService MessageTemplateService => McCaller.MessageTemplateService; - ChannelService ChannelService => McCaller.ChannelService; - - public async Task OpenModalAsync() - { - await InvokeAsync(() => - { - _visible = true; - StateHasChanged(); - }); - - _form?.ResetValidation(); - } - - private void HandleCancel() - { - _visible = false; - ResetForm(); - } - - private async Task HandleSaveAsync() - { - _model.IsDraft = true; - await HandleOkAsync(); - } - - private async Task HandleSendAsync() - { - _model.IsDraft = false; - await HandleOkAsync(); - } - - private async Task HandleOkAsync() - { - Check.NotNull(_form, "form not found"); - - SetReceivers(); - if (!_form.Validate()) - { - return; - } - Loading = true; - var inputDto = _model.Adapt(); - await MessageTaskService.CreateAsync(inputDto); - Loading = false; - if (_model.IsDraft) - { - await SuccessMessageAsync(T("MessageTaskCreateMessage")); - } - else - { - await SuccessMessageAsync(T("MessageTaskSendMessage")); - } - _visible = false; - ResetForm(); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - - private void ResetForm() - { - _model = new() { EntityType = MessageEntityTypes.Template, SystemId = MasaStackProject.MC.Name }; - _selectReceivers = new(); - _importReceivers = new(); - _selectReceiverType = false; - } - - private void HandleVisibleChanged(bool val) - { - if (!val) HandleCancel(); - } - - private async Task HandleTemplateSelectedAsync(MessageTemplateDto item) - { - if (item.Channel != null) _channelItems = await ChannelService.GetListByTypeAsync(item.Channel.Type); - _messageInfo = item; - if (item.Channel != null) _model.ChannelId = item.Channel.Id; - _model.Sign = item.Sign; - _model.Variables = FillVariables(_messageInfo.Items); - HandleChannelTypeChanged(); - } - - private ExtraPropertyDictionary FillVariables(List items) - { - var source = new ExtraPropertyDictionary(); - foreach (var item in items) - { - source.TryAdd(item.Code, string.Empty); - } - return source; - } - - private void HandleChannelTypeChanged() - { - if (_messageInfo.Channel?.Type != ChannelTypes.WebsiteMessage) - { - _model.ReceiverType = ReceiverTypes.Assign; - } - else - { - _model.ReceiverType = default; - } - } - - private void HandleReceiverType(ReceiverTypes receiverType) - { - _model.ReceiverType = receiverType; - _selectReceiverType = true; - if (receiverType == ReceiverTypes.Broadcast) - { - _model.Step = 3; - } - } - - private async Task HandleChannelTypeChangeAsync() - { - _channelItems = _model.ChannelType.HasValue ? await ChannelService.GetListByTypeAsync(_model.ChannelType.Value) : new(); - if (_model.ChannelType != ChannelTypes.WebsiteMessage) - { - _model.ReceiverType = ReceiverTypes.Assign; - } - else - { - _model.ReceiverType = default; - } - } - - private async Task HandleChannelChangeAsync() - { - var inputDto = new GetMessageTemplateInputDto(999) { AuditStatus = MessageTemplateAuditStatuses.Adopt, ChannelId = _model.ChannelId }; - _templateItems = (await MessageTemplateService.GetListAsync(inputDto)).Result; - } - - private void HandleReceiverBack() - { - if (_model.ChannelType != ChannelTypes.WebsiteMessage || !_selectReceiverType) - { - _model.Step = 1; - } - - if (_selectReceiverType) - { - _selectReceiverType = false; - } - } - - private void HandleSendingRuleBack() - { - _model.Step = 2; - if (_model.ReceiverType == ReceiverTypes.Broadcast) - { - _selectReceiverType = false; - } - } - - private void HandleNextStep() - { - SetReceivers(); - _model.IsDraft = false; - if (!_form.Validate()) - { - return; - } - _model.Step++; - } - - private void SetReceivers() - { - _model.Receivers = _model.SelectReceiverType == MessageTaskSelectReceiverTypes.ManualSelection ? _selectReceivers : _importReceivers; - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageEditModal.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageEditModal.razor deleted file mode 100644 index a37b3853..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageEditModal.razor +++ /dev/null @@ -1,151 +0,0 @@ -@inherits AdminCompontentBase -
- - - - - - - @T("DisplayName.MessageInfoContent") - - - - @T("DisplayName.MessageTaskReceiver") - - - - @T("DisplayName.MessageTaskSendingRule") - - - - - - -
-
- - - - - - - - - - - - - - - - - - - @if (_model.EntityId != default) - { - - - - } - - -
- - @T("Save") - @T("NextStep") -
-
-
-
- - - - @if (_model.ComputedBroadcast && !_selectReceiverType) - { - - } - else - { - - - } - - -
- - mdi-keyboard-backspace - - - @if (!_model.ComputedBroadcast || _selectReceiverType) - { - @T("Save") - @T("NextStep") - } -
-
-
-
- - - - - @if (_messageInfo.Channel != null && _messageInfo.Channel.Type == ChannelTypes.Sms) - { - - - - - - - } - - - -
- - mdi-keyboard-backspace - - - @T("Save") - @T("SaveSend") -
-
-
-
-
-
-
-
-
-
\ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageEditModal.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageEditModal.razor.cs deleted file mode 100644 index 74147e44..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageEditModal.razor.cs +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTasks.Modules; - -public partial class TemplateMessageEditModal : AdminCompontentBase -{ - [Parameter] - public EventCallback OnOk { get; set; } - - private MForm? _form; - private MessageTaskUpsertModel _model = new() { EntityType = MessageEntityTypes.Template, SystemId = MasaStackProject.MC.Name }; - private Guid _entityId; - private bool _visible; - private List _templateItems = new(); - private MessageTemplateDto _messageInfo = new(); - private List _channelItems = new(); - private List _selectReceivers = new(); - private List _importReceivers = new(); - private bool _selectReceiverType; - - MessageTaskService MessageTaskService => McCaller.MessageTaskService; - MessageTemplateService MessageTemplateService => McCaller.MessageTemplateService; - ChannelService ChannelService => McCaller.ChannelService; - - public async Task OpenModalAsync(MessageTaskDto model) - { - _entityId = model.Id; - _model = model.Adapt(); - await GetFormDataAsync(); - await InvokeAsync(() => - { - _visible = true; - StateHasChanged(); - }); - - _form?.ResetValidation(); - } - - private async Task GetFormDataAsync() - { - var dto = await MessageTaskService.GetAsync(_entityId) ?? new MessageTaskDto(); - _model = dto.Adapt(); - if (_model.SelectReceiverType == MessageTaskSelectReceiverTypes.ManualSelection) - { - _selectReceivers = _model.Receivers; - } - else - { - _importReceivers = _model.Receivers; - } - _channelItems = _model.ChannelType.HasValue ? await ChannelService.GetListByTypeAsync(_model.ChannelType.Value) : new(); - - if (_model.EntityId != default) - { - _messageInfo = await MessageTemplateService.GetAsync(_model.EntityId) ?? new(); - - FillVariables(_model.Variables,_messageInfo.Items); - } - - await HandleChannelChangeAsync(); - } - - private void HandleCancel() - { - _visible = false; - ResetForm(); - } - - private async Task HandleSaveAsync() - { - _model.IsDraft = true; - await HandleOkAsync(); - } - - private async Task HandleSendAsync() - { - _model.IsDraft = false; - await HandleOkAsync(); - } - - private async Task HandleOkAsync() - { - Check.NotNull(_form, "form not found"); - - SetReceivers(); - if (!_form.Validate()) - { - return; - } - Loading = true; - var inputDto = _model.Adapt(); - await MessageTaskService.UpdateAsync(_entityId, inputDto); - Loading = false; - if (_model.IsDraft) - { - await SuccessMessageAsync(T("MessageTaskEditMessage")); - } - else - { - await SuccessMessageAsync(T("MessageTaskSendMessage")); - } - _visible = false; - ResetForm(); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - - private void ResetForm() - { - _model = new() { EntityType = MessageEntityTypes.Template, SystemId = MasaStackProject.MC.Name }; - _selectReceivers = new(); - _importReceivers = new(); - _selectReceiverType = false; - } - - private void HandleVisibleChanged(bool val) - { - if (!val) HandleCancel(); - } - - private void HandleTemplateSelected(MessageTemplateDto item) - { - _messageInfo = item; - if (item.Channel != null) _model.ChannelId = item.Channel.Id; - _model.Sign = item.Sign; - FillVariables(null, _messageInfo.Items); - HandleChannelTypeChanged(); - } - - private void FillVariables(ExtraPropertyDictionary? variables, List items) - { - if (variables == null) - variables = new ExtraPropertyDictionary(); - - foreach (var item in items) - { - if (!variables.Any(x => x.Key == item.Code)) - { - variables.TryAdd(item.Code, string.Empty); - } - } - } - - private void HandleChannelTypeChanged() - { - if (_messageInfo.Channel?.Type != ChannelTypes.WebsiteMessage) - { - _model.ReceiverType = ReceiverTypes.Assign; - } - else - { - _model.ReceiverType = default; - } - } - - private void HandleReceiverType(ReceiverTypes receiverType) - { - _model.ReceiverType = receiverType; - _selectReceiverType = true; - if (receiverType == ReceiverTypes.Broadcast) - { - _model.Step = 3; - } - } - - private async Task HandleChannelTypeChangeAsync() - { - _channelItems = _model.ChannelType.HasValue ? await ChannelService.GetListByTypeAsync(_model.ChannelType.Value) : new(); - if (_model.ChannelType != ChannelTypes.WebsiteMessage) - { - _model.ReceiverType = ReceiverTypes.Assign; - } - else - { - _model.ReceiverType = default; - } - if (_channelItems.Count > 0 && !_channelItems.Any(c => c.Id == _model.ChannelId)) - { - _model.ChannelId = null; - } - } - - private async Task HandleChannelChangeAsync() - { - var inputDto = new GetMessageTemplateInputDto(999) { AuditStatus = MessageTemplateAuditStatuses.Adopt, ChannelId = _model.ChannelId }; - _templateItems = (await MessageTemplateService.GetListAsync(inputDto)).Result; - } - - private void HandleReceiverBack() - { - if (_model.ChannelType != ChannelTypes.WebsiteMessage || !_selectReceiverType) - { - _model.Step = 1; - } - - if (_selectReceiverType) - { - _selectReceiverType = false; - } - } - - private void HandleSendingRuleBack() - { - _model.Step = 2; - if (_model.ReceiverType == ReceiverTypes.Broadcast) - { - _selectReceiverType = false; - } - } - - private void HandleNextStep() - { - SetReceivers(); - _model.IsDraft = false; - if (!_form.Validate()) - { - return; - } - _model.Step++; - } - - private void SetReceivers() - { - _model.Receivers = _model.SelectReceiverType == MessageTaskSelectReceiverTypes.ManualSelection ? _selectReceivers : _importReceivers; - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageInfo.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageInfo.razor deleted file mode 100644 index f45835cf..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageInfo.razor +++ /dev/null @@ -1,101 +0,0 @@ -@inherits AdminCompontentBase -
-
-
@T("DisplayName.ChannelType")
-
@T(MessageTask.Channel.Type.ToString())
-
-
-
@T("DisplayName.Channel")
-
@MessageTask.Channel.DisplayName
-
- @if (MessageTask.ChannelType == ChannelTypes.App) - { - - - - - - - } -
-
@T("DisplayName.MessageInfoTitle")
-
@(string.IsNullOrEmpty(MessageTemplate.Title)?MessageTemplate.DisplayName:MessageTemplate.Title)
-
-
-
@T("MessageContent")
-
-
- @if (MessageTemplate.IsJump) - { -
-
@T("DisplayName.MessageTemplateJumpUrl")
-
@MessageTemplate.JumpUrl
-
- } - @if (MessageTask.ChannelType == ChannelTypes.App) - { - @if (!string.IsNullOrEmpty(MessageTemplate.Options.GetProperty(BusinessConsts.INTENT_URL))) - { -
-
@T("IntentUrl")
-
@(MessageTemplate.Options.GetProperty(BusinessConsts.INTENT_URL))
-
- } - @if (MessageTemplate.ExtraProperties.Any()) - { -
@T("AdditionalFields")
- - - - - @T("Key") - - - @T("Value") - - - - - - - - @foreach (var item in MessageTemplate.ExtraProperties) - { - - @item.Key - @item.Value - - } - - - } - } - @if (!IsRender && Variables.Any()) - { -
@T("DisplayName.VariableValueTransfer")
- - - - - @T("DisplayName.MessageTemplateItemCode") - - - @T("DisplayName.MessageTemplateItemValue") - - - - - - - - @foreach (var item in Variables) - { - - @item.Key - @item.Value - - } - - - } -
\ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageInfo.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageInfo.razor.cs deleted file mode 100644 index c0163851..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageInfo.razor.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTasks.Modules; - -public partial class TemplateMessageInfo : AdminCompontentBase -{ - [Parameter] - public Guid MessageTemplateId { get; set; } - - [Parameter] - public MessageTaskDto MessageTask { get; set; } = new(); - - [Parameter] - public ExtraPropertyDictionary Variables { get; set; } = new(); - - [Parameter] - public bool IsRender { get; set; } - - public MessageTemplateDto MessageTemplate { get; set; } = new(); - - MessageTemplateService MessageTemplateService => McCaller.MessageTemplateService; - - protected override async Task OnParametersSetAsync() - { - MessageTemplate = await MessageTemplateService.GetAsync(MessageTemplateId) ?? new(); - if (IsRender) - { - await RenderMessageContent(); - } - } - - public async Task RenderMessageContent() - { - var startstr = "{{"; - var endstr = "}}"; - if (MessageTask.Channel.Type == ChannelTypes.Sms) - { - startstr = "${"; - endstr = "}"; - MessageTemplate.Content = $"ã€{MessageTask.Sign}】{MessageTemplate.Content}"; - } - MessageTemplate.Title = await RenderAsync(MessageTemplate.Title, Variables, startstr, endstr); - MessageTemplate.Content = await RenderAsync(MessageTemplate.Content, Variables, startstr, endstr); - MessageTemplate.JumpUrl = await RenderAsync(MessageTemplate.JumpUrl, Variables, startstr, endstr); - } - - public Task RenderAsync(string context, ExtraPropertyDictionary model, string startstr, string endstr) - { - foreach (var item in model) - { - context = context.Replace($"{startstr}{item.Key}{endstr}", item.Value.ToString()); - } - return Task.FromResult(context); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageInfo.razor.css b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageInfo.razor.css deleted file mode 100644 index 2cfea691..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageInfo.razor.css +++ /dev/null @@ -1,6 +0,0 @@ -.template-message-info ::deep .theme--light.m-data-table > .m-data-table__wrapper > table > thead > tr:last-child > th { - border-bottom: none !important; -} -.template-message-info ::deep .theme--light.m-data-table > .m-data-table__wrapper > table > tbody > tr:not(:last-child) > td:not(.m-data-table__mobile-row) { - border-bottom: none; -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageInfoByMessageRecord.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageInfoByMessageRecord.razor deleted file mode 100644 index e4d7c776..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/Modules/TemplateMessageInfoByMessageRecord.razor +++ /dev/null @@ -1,152 +0,0 @@ -@inherits AdminCompontentBase -
-
-
@T("DisplayName.ChannelType")
-
@T(MessageRecord.Channel.Type.ToString())
-
-
-
@T("DisplayName.Channel")
-
@MessageRecord.Channel.DisplayName
-
- @if (MessageRecord.Channel.Type == ChannelTypes.App) - { - - - - - - - } -
-
@T("DisplayName.MessageInfoTitle")
-
@(string.IsNullOrEmpty(MessageTemplate.Title) ? MessageTemplate.DisplayName : MessageTemplate.Title)
-
-
-
@T("MessageContent")
-
-
- @if (MessageTemplate.IsJump) - { -
-
@T("DisplayName.MessageTemplateJumpUrl")
-
@MessageTemplate.JumpUrl
-
- } - @if (MessageRecord.Channel.Type == ChannelTypes.App) - { - @if (!string.IsNullOrEmpty(MessageTemplate.Options.GetProperty(BusinessConsts.INTENT_URL))) - { -
-
@T("IntentUrl")
-
@(MessageTemplate.Options.GetProperty(BusinessConsts.INTENT_URL))
-
- } - @if (MessageTemplate.ExtraProperties.Any()) - { -
@T("AdditionalFields")
- - - - - @T("Key") - - - @T("Value") - - - - - - - - @foreach (var item in MessageTemplate.ExtraProperties) - { - - @item.Key - @item.Value - - } - - - } - } - @if (!IsRender && Variables.Any()) - { -
@T("DisplayName.VariableValueTransfer")
- - - - - @T("DisplayName.MessageTemplateItemCode") - - - @T("DisplayName.MessageTemplateItemValue") - - - - - - - - @foreach (var item in Variables) - { - - @item.Key - @item.Value - - } - - - } -
- -@code { - [Parameter] - public Guid MessageTemplateId { get; set; } - - [Parameter] - public MessageRecordDto MessageRecord { get; set; } = new(); - - [Parameter] - public ExtraPropertyDictionary Variables { get; set; } = new(); - - [Parameter] - public bool IsRender { get; set; } - - public MessageTemplateDto MessageTemplate { get; set; } = new(); - - MessageTemplateService MessageTemplateService => McCaller.MessageTemplateService; - - protected override async Task OnParametersSetAsync() - { - MessageTemplate = await MessageTemplateService.GetAsync(MessageTemplateId) ?? new(); - if (IsRender) - { - await RenderMessageContent(); - } - } - - public async Task RenderMessageContent() - { - var startstr = "{{"; - var endstr = "}}"; - if (MessageRecord.Channel.Type == ChannelTypes.Sms) - { - startstr = "${"; - endstr = "}"; - MessageTemplate.Content = $"ã€{MessageTemplate.Sign}】{MessageTemplate.Content}"; - } - MessageTemplate.Title = await RenderAsync(MessageTemplate.Title, Variables, startstr, endstr); - MessageTemplate.Content = await RenderAsync(MessageTemplate.Content, Variables, startstr, endstr); - MessageTemplate.JumpUrl = await RenderAsync(MessageTemplate.JumpUrl, Variables, startstr, endstr); - } - - public Task RenderAsync(string context, ExtraPropertyDictionary model, string startstr, string endstr) - { - foreach (var item in model) - { - context = context.Replace($"{startstr}{item.Key}{endstr}", item.Value.ToString()); - } - return Task.FromResult(context); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/SendMessage.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/SendMessage.razor deleted file mode 100644 index 50d3f93a..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/SendMessage.razor +++ /dev/null @@ -1,33 +0,0 @@ -@inherits AdminCompontentBase - -
- -
-
- - - mdi-email -
@T("DisplayName.MessageEntityType.Ordinary")
-
-
-
-
- - - mdi-collage -
@T("DisplayName.MessageEntityType.Template")
-
-
-
-
-
- -
- fas fa-tasks@T("DisplayName.MessageTaskList") -
-
- - - \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/SendMessage.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/SendMessage.razor.cs deleted file mode 100644 index 2b5ed9d2..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/SendMessage.razor.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTasks; - -public partial class SendMessage : AdminCompontentBase -{ - [Parameter] - public EventCallback OnNavigateToList { get; set; } - - private OrdinaryMessageCreateModal _ordinaryCreateModal = default!; - private TemplateMessageCreateModal _templateCreateModal = default!; - - private async Task NavigateToList() - { - if (OnNavigateToList.HasDelegate) - { - await OnNavigateToList.InvokeAsync(); - } - //NavigationManager.NavigateTo("/messageTasks/list"); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/SendMessage.razor.css b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/SendMessage.razor.css deleted file mode 100644 index c070c52f..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/SendMessage.razor.css +++ /dev/null @@ -1,19 +0,0 @@ -.grid { - display: grid; - grid-template-columns: repeat(2, 33.3%); - gap: 24px; - width: 100%; - justify-content: center; -} - - .grid .item { - height: 0; - padding-bottom: 100%; - position: relative; - } - - .grid .item ::deep .m-card { - width: 100%; - height: 100%; - position: absolute; - } \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/SendMessageManagement.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/SendMessageManagement.razor deleted file mode 100644 index 41c5a459..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/SendMessageManagement.razor +++ /dev/null @@ -1,11 +0,0 @@ -@inherits AdminCompontentBase -@page "/messageTasks/sendMessage" -@T("Permission.SendMessage") -@if (_isSend) -{ - -} -else -{ - -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/SendMessageManagement.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/SendMessageManagement.razor.cs deleted file mode 100644 index fe23aded..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTasks/SendMessageManagement.razor.cs +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTasks; - -public partial class SendMessageManagement : AdminCompontentBase -{ - private bool _isSend = true; -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/AppTemplateManagement.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/AppTemplateManagement.razor deleted file mode 100644 index 392f5098..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/AppTemplateManagement.razor +++ /dev/null @@ -1,89 +0,0 @@ -@inherits AdminCompontentBase -@page "/messageTemplates/appTemplateManagement" - -@T("App") - - - - - @T("AppTitle") - - - - - - - - - - - - - - - - - @header.Text - - - @switch (context.Header.Value) - { - case ("ChannelDisplayName"): - - break; - case nameof(MessageTemplateDto.AuditStatus): - string color = string.Empty; - switch (context.Item.AuditStatus) - { - case MessageTemplateAuditStatuses.WaitAudit: - color = "orange"; - break; - case MessageTemplateAuditStatuses.Adopt: - color = "sample-green"; - break; - case MessageTemplateAuditStatuses.Fail: - color = "error"; - break; - default: - break; - } - - @T($"DisplayName.MessageTemplateAuditStatus.{context.Item.AuditStatus.ToString()}") - - break; - case nameof(MessageTemplateDto.Status): - - @T($"DisplayName.MessageTemplateStatus.{context.Item.Status.ToString()}") - - break; - case "Action": - mdi-pencil - break; - default: - - break; - } - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/AppTemplateManagement.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/AppTemplateManagement.razor.cs deleted file mode 100644 index fa811e99..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/AppTemplateManagement.razor.cs +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTemplates; - -public partial class AppTemplateManagement : AdminCompontentBase -{ - private AppTemplateUpsertModal _upsertModal = default!; - private GetMessageTemplateInputDto _queryParam = new() { ChannelType = ChannelTypes.App }; - private PaginatedListDto _entities = new(); - private List _channelItems = new(); - private DateTimeOffset? _endTime; - private DateTimeOffset? _startTime; - - private ChannelService ChannelService => McCaller.ChannelService; - - private MessageTemplateService MessageTemplateService => McCaller.MessageTemplateService; - - protected override string? PageName { get; set; } = "MessageTemplateBlock"; - - protected async override Task OnInitializedAsync() - { - _channelItems = await ChannelService.GetListByTypeAsync(ChannelTypes.App); - } - protected async override Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await LoadData(); - } - await base.OnAfterRenderAsync(firstRender); - } - - public List> GetHeaders() - { - var prefix = "DisplayName.MessageTemplate"; - - return new() - { - new() { Text = T($"{prefix}{nameof(MessageTemplateDto.Code)}"), Value = nameof(MessageTemplateDto.Code), Sortable = false, Width = "8rem" }, - new() { Text = T($"{prefix}{nameof(MessageTemplateDto.Title)}"), Value = nameof(MessageTemplateDto.Title), Sortable = false, Width = "13.125rem" }, - new() { Text = T($"{prefix}ChannelDisplayName"), Value = "ChannelDisplayName", Sortable = false, Width = "6.5625rem" }, - new() { Text = T("Modifier"), Value = nameof(MessageTemplateDto.ModifierName), Sortable = false, Width = "6.5625rem" }, - new() { Text = T("ModificationTime"), Value = nameof(MessageTemplateDto.ModificationTime), Sortable = true, Width = "13.125rem" }, - new() { Text = T("Action"), Value = "Action", Sortable = false, Width = 105, Align = DataTableHeaderAlign.Center }, - }; - } - - private Task DateRangChangedAsync((DateTimeOffset? startDate, DateTimeOffset? endDate) args) - { - (_startTime, _endTime) = args; - _queryParam.StartTime = _startTime?.UtcDateTime; - _queryParam.EndTime = _endTime?.UtcDateTime; - return RefreshAsync(); - } - - private async Task LoadData() - { - Loading = true; - _entities = (await MessageTemplateService.GetListAsync(_queryParam)); - Loading = false; - StateHasChanged(); - } - - private async Task HandleOk() - { - await LoadData(); - } - - private async Task RefreshAsync() - { - _queryParam.Page = 1; - await LoadData(); - } - - private async Task HandlePageChanged(int page) - { - _queryParam.Page = page; - await LoadData(); - } - - private async Task HandlePageSizeChanged(int pageSize) - { - _queryParam.PageSize = pageSize; - await LoadData(); - } - - private async Task HandleClearAsync() - { - _queryParam = new() { ChannelType = ChannelTypes.App }; - await LoadData(); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/EmailTemplateManagement.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/EmailTemplateManagement.razor deleted file mode 100644 index 1bf96a1f..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/EmailTemplateManagement.razor +++ /dev/null @@ -1,90 +0,0 @@ -@inherits AdminCompontentBase -@page "/messageTemplates/emailTemplateManagement" - -@T("Email") - - - - - @T("EmailTemplateTitle") - - - - - - - - - - - - - - - - - @header.Text - - - @switch (context.Header.Value) - { - case ("ChannelDisplayName"): - - break; - case nameof(MessageTemplateDto.AuditStatus): - string color = string.Empty; - switch (context.Item.AuditStatus) - { - case MessageTemplateAuditStatuses.WaitAudit: - color = "orange"; - break; - case MessageTemplateAuditStatuses.Adopt: - color = "sample-green"; - break; - case MessageTemplateAuditStatuses.Fail: - color = "error"; - break; - default: - break; - } - - @T($"DisplayName.MessageTemplateAuditStatus.{context.Item.AuditStatus.ToString()}") - - break; - case nameof(MessageTemplateDto.Status): - - @T($"DisplayName.MessageTemplateStatus.{context.Item.Status.ToString()}") - - break; - case "Action": - mdi-pencil - break; - default: - - break; - } - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/EmailTemplateManagement.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/EmailTemplateManagement.razor.cs deleted file mode 100644 index a81c7038..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/EmailTemplateManagement.razor.cs +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTemplates; - -public partial class EmailTemplateManagement : AdminCompontentBase -{ - public List> Headers { get; set; } = new(); - - private EmailTemplateEditModal _editModal = default!; - private EmailTemplateCreateModal _createModal = default!; - private GetMessageTemplateInputDto _queryParam = new() { ChannelType = ChannelTypes.Email }; - private PaginatedListDto _entities = new(); - private List _channelItems = new(); - private DateTimeOffset? _endTime; - private DateTimeOffset? _startTime; - - private ChannelService ChannelService => McCaller.ChannelService; - - private MessageTemplateService MessageTemplateService => McCaller.MessageTemplateService; - - protected override string? PageName { get; set; } = "MessageTemplateBlock"; - - protected async override Task OnInitializedAsync() - { - _channelItems = await ChannelService.GetListByTypeAsync(ChannelTypes.Email); - } - - protected async override Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await LoadData(); - } - await base.OnAfterRenderAsync(firstRender); - } - - public List> GetHeaders() - { - var _prefix = "DisplayName.MessageTemplate"; - - return new() - { - new() { Text = T($"{_prefix}{nameof(MessageTemplateDto.Code)}"), Value = nameof(MessageTemplateDto.Code), Sortable = false, Width = "8rem" }, - new() { Text = T($"{_prefix}{nameof(MessageTemplateDto.Title)}"), Value = nameof(MessageTemplateDto.Title), Sortable = false, Width = "13.125rem" }, - new() { Text = T($"{_prefix}ChannelDisplayName"), Value = "ChannelDisplayName", Sortable = false, Width = "6.5625rem" }, - new() { Text = T("Modifier"), Value = nameof(MessageTemplateDto.ModifierName), Sortable = false, Width = "6.5625rem" }, - new() { Text = T("ModificationTime"), Value = nameof(MessageTemplateDto.ModificationTime), Sortable = true, Width = "13.125rem" }, - new() { Text = T("Action"), Value = "Action", Sortable = false, Width = 105, Align = DataTableHeaderAlign.Center }, - }; - } - - private Task DateRangChangedAsync((DateTimeOffset? startDate, DateTimeOffset? endDate) args) - { - (_startTime, _endTime) = args; - _queryParam.StartTime = _startTime?.UtcDateTime; - _queryParam.EndTime = _endTime?.UtcDateTime; - return RefreshAsync(); - } - - private async Task LoadData() - { - Loading = true; - _entities = (await MessageTemplateService.GetListAsync(_queryParam)); - Loading = false; - StateHasChanged(); - } - - private async Task HandleOk() - { - await LoadData(); - } - - private async Task RefreshAsync() - { - _queryParam.Page = 1; - await LoadData(); - } - - private async Task HandlePageChanged(int page) - { - _queryParam.Page = page; - await LoadData(); - } - - private async Task HandlePageSizeChanged(int pageSize) - { - _queryParam.PageSize = pageSize; - await LoadData(); - } - - private async Task HandleClearAsync() - { - _queryParam = new() { ChannelType = ChannelTypes.Email }; - await LoadData(); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/AppTemplateUpsertModal.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/AppTemplateUpsertModal.razor deleted file mode 100644 index 0b447d39..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/AppTemplateUpsertModal.razor +++ /dev/null @@ -1,111 +0,0 @@ -@inherits AdminCompontentBase - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @T("OptionalConfiguration") - - - Android - - - - - - Ios - - - - - - - - - - - -
- @T("Description.MessageTemplate.PerDayLimit.Tips") -
- - -
- @T("Unit.Bar") -
-
-
-
-
-
diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/AppTemplateUpsertModal.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/AppTemplateUpsertModal.razor.cs deleted file mode 100644 index 54ded2f3..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/AppTemplateUpsertModal.razor.cs +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTemplates.Modules; - -public partial class AppTemplateUpsertModal : AdminCompontentBase -{ - [Parameter] - public EventCallback OnOk { get; set; } - - private MForm? _form; - private AppTemplateUpsertModel _model = new(); - private bool _visible; - private List _channelItems = new(); - private Guid _entityId; - - ChannelService ChannelService => McCaller.ChannelService; - - MessageTemplateService MessageTemplateService => McCaller.MessageTemplateService; - - public async Task OpenModalAsync(MessageTemplateDto? model = null) - { - _entityId = model?.Id ?? default; - _model = model?.Adapt() ?? new(); - - if (_entityId != default) - { - await GetFormDataAsync(); - } - else - { - await InitDataAsync(); - } - - await InvokeAsync(() => - { - _visible = true; - StateHasChanged(); - }); - - _form?.ResetValidation(); - } - - private async Task InitDataAsync() - { - _model.ChannelType = ChannelTypes.App; - - if (string.IsNullOrEmpty(_model.Code)) - { - _model.Code = $"App_{UtilConvert.GetGuidToNumber()}"; - } - - await HandleSelectChannelTypeAsync(_model.ChannelType); - } - - private async Task GetFormDataAsync() - { - var dto = await MessageTemplateService.GetAsync(_entityId) ?? new(); - _model = dto.Adapt(); - _model.ChannelType = dto.Channel.Type; - await HandleSelectChannelTypeAsync(_model.ChannelType); - } - - private void HandleCancel() - { - _visible = false; - ResetForm(); - } - - private async Task HandleOkAsync() - { - Check.NotNull(_form, "form not found"); - - _model.DisplayName = _model.Title; - if (!_form.Validate()) - { - return; - } - Loading = true; - - var inputDto = _model.Adapt(); - - if (_entityId == default) - { - await MessageTemplateService.CreateAsync(inputDto); - } - else - { - await MessageTemplateService.UpdateAsync(_entityId, inputDto); - } - - Loading = false; - await UpsertSuccessfulMessage(_entityId, T("MessageTemplate")); - _visible = false; - ResetForm(); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - - private void ResetForm() - { - _model = new(); - } - - private void HandleVisibleChanged(bool val) - { - if (!val) HandleCancel(); - } - - private async Task HandleSelectChannelTypeAsync(ChannelTypes Type) - { - _channelItems = await ChannelService.GetListByTypeAsync(Type); - } -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/EmailTemplateCreateModal.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/EmailTemplateCreateModal.razor deleted file mode 100644 index cc979ab3..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/EmailTemplateCreateModal.razor +++ /dev/null @@ -1,63 +0,0 @@ -@inherits AdminCompontentBase - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- @T("Description.MessageTemplate.PerDayLimit.Tips") -
- -
- @T("Unit.Bar") -
-
-
-
-
-
diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/EmailTemplateCreateModal.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/EmailTemplateCreateModal.razor.cs deleted file mode 100644 index 8726aca5..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/EmailTemplateCreateModal.razor.cs +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTemplates.Modules; - -public partial class EmailTemplateCreateModal : AdminCompontentBase -{ - [Parameter] - public EventCallback OnOk { get; set; } - - private MForm? _form; - private MessageTemplateUpsertDto _model = new(); - private bool _visible; - private List _channelItems = new(); - - ChannelService ChannelService => McCaller.ChannelService; - - MessageTemplateService MessageTemplateService => McCaller.MessageTemplateService; - - public async Task OpenModalAsync() - { - _model.ChannelType = ChannelTypes.Email; - if (string.IsNullOrEmpty(_model.Code)) - { - _model.Code = $"Email_{UtilConvert.GetGuidToNumber()}"; - } - await HandleSelectChannelTypeAsync(_model.ChannelType); - await InvokeAsync(() => - { - _visible = true; - StateHasChanged(); - }); - - _form?.ResetValidation(); - } - - private void HandleCancel() - { - _visible = false; - ResetForm(); - } - - private async Task HandleOkAsync() - { - Check.NotNull(_form, "form not found"); - - _model.DisplayName = _model.Title; - if (!_form.Validate()) - { - return; - } - Loading = true; - await MessageTemplateService.CreateAsync(_model); - Loading = false; - await SuccessMessageAsync(T("MessageTemplateCreateMessage")); - _visible = false; - ResetForm(); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - - private void ResetForm() - { - _model = new(); - } - - private void HandleVisibleChanged(bool val) - { - if (!val) HandleCancel(); - } - - private async Task HandleSelectChannelTypeAsync(ChannelTypes Type) - { - _channelItems = await ChannelService.GetListByTypeAsync(Type); - if (_channelItems.Count == 1) - { - _model.ChannelId = _channelItems[0].Id; - } - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/EmailTemplateEditModal.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/EmailTemplateEditModal.razor deleted file mode 100644 index d5db5e94..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/EmailTemplateEditModal.razor +++ /dev/null @@ -1,63 +0,0 @@ -@inherits AdminCompontentBase - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- @T("Description.MessageTemplate.PerDayLimit.Tips") -
- -
- @T("Unit.Bar") -
-
-
-
-
-
diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/EmailTemplateEditModal.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/EmailTemplateEditModal.razor.cs deleted file mode 100644 index 3dbe40df..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/EmailTemplateEditModal.razor.cs +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTemplates.Modules; - -public partial class EmailTemplateEditModal : AdminCompontentBase -{ - [Parameter] - public EventCallback OnOk { get; set; } - - private MForm _form = default!; - private MessageTemplateUpsertDto _model = new(); - private Guid _entityId; - private bool _visible; - private List _channelItems = new(); - - ChannelService ChannelService => McCaller.ChannelService; - - MessageTemplateService MessageTemplateService => McCaller.MessageTemplateService; - - public async Task OpenModalAsync(MessageTemplateDto model) - { - _entityId = model.Id; - _model = model.Adapt(); - await GetFormDataAsync(); - await InvokeAsync(() => - { - _visible = true; - StateHasChanged(); - }); - } - - private async Task GetFormDataAsync() - { - var dto = await MessageTemplateService.GetAsync(_entityId) ?? new(); - _model = dto.Adapt(); - _model.ChannelType = dto.Channel.Type; - await HandleSelectChannelType(_model.ChannelType); - } - - private void HandleCancel() - { - _visible = false; - ResetForm(); - } - - private async Task HandleOk() - { - _model.DisplayName = _model.Title; - if (!_form.Validate()) - { - return; - } - Loading = true; - await MessageTemplateService.UpdateAsync(_entityId, _model); - Loading = false; - await SuccessMessageAsync(T("MessageTemplateEditMessage")); - _visible = false; - ResetForm(); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - - private async Task HandleDelAsync() - { - await ConfirmAsync(T("DeletionConfirmationMessage", $"{T("EmailTemplate")}\"{_model.DisplayName}\""), DeleteAsync); - } - - private async Task DeleteAsync() - { - Loading = true; - await MessageTemplateService.DeleteAsync(_entityId); - Loading = false; - await SuccessMessageAsync(T("MessageTemplateDeleteMessage")); - _visible = false; - ResetForm(); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - - private void ResetForm() - { - _model = new(); - _form.ResetValidation(); - } - - private void HandleVisibleChanged(bool val) - { - if (!val) HandleCancel(); - } - - private async Task HandleSelectChannelType(ChannelTypes Type) - { - _channelItems = await ChannelService.GetListByTypeAsync(Type); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/MessageTemplateItemChangedEventArgs.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/MessageTemplateItemChangedEventArgs.cs deleted file mode 100644 index 3b560aa5..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/MessageTemplateItemChangedEventArgs.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTemplates.Modules; - -public class MessageTemplateItemChangedEventArgs -{ - public string OldCode { get; set; } = string.Empty; - - public string NewCode { get; set; } = string.Empty; - - public MessageTemplateItemChangedEventArgs(string oldCode, string newCode) - { - OldCode = oldCode; - NewCode = newCode; - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/MessageTemplateItems.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/MessageTemplateItems.razor deleted file mode 100644 index 47932272..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/MessageTemplateItems.razor +++ /dev/null @@ -1,107 +0,0 @@ -@inherits AdminCompontentBase -
- - - - @T("DisplayName.MessageTemplateItem") - - - - @FormTitle - - - - - - - - - - - - - - - - - - - - - - @T("Cancel") - - - @T("Save") - - - - - - - - @switch (context.Header.Value) - { - case (nameof(MessageTemplateItemDto.Code)): - if (Value.IndexOf(context.Item) == _editedIndex) - { - - } - else - { -
@context.Value
- } - break; - case (nameof(MessageTemplateItemDto.DisplayText)): - if (Value.IndexOf(context.Item)==_editedIndex) - { - - } - else - { -
@context.Value
- } - break; - case "actions": - if (Value.IndexOf(context.Item)==_editedIndex) - { -
- - mdi-close - - - mdi-check - -
- } - else - { - - mdi-pencil - - } - break; - default: -
@context.Value
- break; - } -
-
-
\ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/MessageTemplateItems.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/MessageTemplateItems.razor.cs deleted file mode 100644 index 5f012ba4..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/MessageTemplateItems.razor.cs +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTemplates.Modules; - -public partial class MessageTemplateItems : AdminCompontentBase -{ - [Parameter] - public List Value { get; set; } = new(); - - [Parameter] - public EventCallback> ValueChanged { get; set; } - - [Parameter] - public EventCallback OnEditChanged { get; set; } - - private List> _headers = new(); - private bool _dialog; - private MessageTemplateItemDto _editedItem = new MessageTemplateItemDto(); - private int _editedIndex = -1; - - public string FormTitle - { - get - { - return _editedIndex == -1 ? T("Permission.AddMessageTemplateItem") : T("Permission.EditMessageTemplateItem"); - } - } - - protected override async Task OnInitializedAsync() - { - await base.OnInitializedAsync(); - var _prefix = "DisplayName.MessageTemplateItem"; - _headers = new List> - { - new (){ Text= T($"{_prefix}{nameof(MessageTemplateItemDto.Code)}"),Value= nameof(MessageTemplateItemDto.Code),Sortable=false,Width=175}, - new (){ Text= T($"{_prefix}{nameof(MessageTemplateItemDto.MappingCode)}"), Value= nameof(MessageTemplateItemDto.MappingCode),Sortable=false,Width=175}, - new (){ Text= T($"{_prefix}{nameof(MessageTemplateItemDto.DisplayText)}"), Value= nameof(MessageTemplateItemDto.DisplayText),Sortable=false,Width=166}, - new (){ Text= T("Action"), Value= "actions",Sortable=false,Width=108,Align=DataTableHeaderAlign.Center } - }; - } - - public void Close() - { - _dialog = false; - _editedItem = new MessageTemplateItemDto(); - _editedIndex = -1; - } - - public async Task SaveAsync() - { - if (_editedIndex > -1) - { - var item = Value[_editedIndex]; - if (item.Code != _editedItem.Code && OnEditChanged.HasDelegate) - { - await OnEditChanged.InvokeAsync(new MessageTemplateItemChangedEventArgs(item.Code, _editedItem.Code)); - } - item.Code = _editedItem.Code; - item.MappingCode = _editedItem.MappingCode; - item.DisplayText = _editedItem.DisplayText; - } - else - { - Value.Add(_editedItem); - } - await ValueChanged.InvokeAsync(Value); - Close(); - } - - public void EditItem(MessageTemplateItemDto item) - { - _editedIndex = Value.IndexOf(item); - _editedItem = new MessageTemplateItemDto() - { - Code = item.Code, - MappingCode = item.MappingCode, - DisplayText = item.DisplayText - }; - //_dialog = true; - } - - public async Task DeleteItemConfirmAsync() - { - Value.RemoveAt(_editedIndex); - await ValueChanged.InvokeAsync(Value); - CloseDelete(); - } - - public void CloseDelete() - { - _editedItem = new(); - _editedIndex = -1; - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/MessageTemplateItems.razor.css b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/MessageTemplateItems.razor.css deleted file mode 100644 index 52dad4b2..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/MessageTemplateItems.razor.css +++ /dev/null @@ -1,18 +0,0 @@ -.message-template-items ::deep .theme--light.m-toolbar.m-sheet{ - background-color: #f6f8fd !important; -} -.message-template-items ::deep .theme--light.m-data-table { - background-color: #f6f8fd !important; -} -.message-template-items ::deep .text-start { - padding: 0 !important; -} -.message-template-items ::deep .m-toolbar__content { - padding: 0 !important; -} -.message-template-items ::deep .theme--light.m-data-table > .m-data-table__wrapper > table > tbody > tr:not(:last-child) > td:last-child, .theme--light.m-data-table > .m-data-table__wrapper > table > tbody > tr:not(:last-child) > th:last-child { - border-bottom: none; -} -.message-template-items ::deep .theme--light.m-data-table > .m-data-table__wrapper > table > tbody > tr:not(:last-child) > td:not(.m-data-table__mobile-row), .theme--light.m-data-table > .m-data-table__wrapper > table > tbody > tr:not(:last-child) > th:not(.m-data-table__mobile-row) { - border-bottom: none; -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/SmsTemplateCreateModal.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/SmsTemplateCreateModal.razor deleted file mode 100644 index 2e784d29..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/SmsTemplateCreateModal.razor +++ /dev/null @@ -1,92 +0,0 @@ -@inherits AdminCompontentBase - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @T("SyncTemplate") - - - - - - @if (!string.IsNullOrEmpty(_model.DisplayName)) - { - - - - - - - } - - -
- @T("Description.MessageTemplate.PerDayLimit.Tips") -
- -
- @T("Unit.Bar") -
-
-
-
-
-
diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/SmsTemplateCreateModal.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/SmsTemplateCreateModal.razor.cs deleted file mode 100644 index 0fe08607..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/SmsTemplateCreateModal.razor.cs +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTemplates.Modules; - -public partial class SmsTemplateCreateModal : AdminCompontentBase -{ - [Parameter] - public EventCallback OnOk { get; set; } - - private MForm? _form; - private MessageTemplateUpsertDto _model = new(); - private bool _visible; - private List _channelItems = new(); - private List _templateItems = new(); - - ChannelService ChannelService => McCaller.ChannelService; - - SmsTemplateService SmsTemplateService => McCaller.SmsTemplateService; - - MessageTemplateService MessageTemplateService => McCaller.MessageTemplateService; - - public async Task OpenModalAsync() - { - _model.ChannelType = ChannelTypes.Sms; - if (string.IsNullOrEmpty(_model.Code)) - { - _model.Code = $"SMS_{UtilConvert.GetGuidToNumber()}"; - } - await HandleSelectChannelTypeAsync(_model.ChannelType); - await InvokeAsync(() => - { - _visible = true; - StateHasChanged(); - }); - - _form?.ResetValidation(); - } - - private void HandleCancel() - { - _visible = false; - ResetForm(); - } - - private async Task HandleOkAsync() - { - Check.NotNull(_form, "form not found"); - - if (!_form.Validate()) - { - return; - } - Loading = true; - await MessageTemplateService.CreateAsync(_model); - Loading = false; - await SuccessMessageAsync(T("MessageTemplateCreateMessage")); - _visible = false; - ResetForm(); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - - private void ResetForm() - { - _model = new(); - } - - private void HandleVisibleChanged(bool val) - { - if (!val) HandleCancel(); - } - - private async Task HandleSelectChannelTypeAsync(ChannelTypes Type) - { - _channelItems = await ChannelService.GetListByTypeAsync(Type); - if (_channelItems.Count == 1) - { - _model.ChannelId = _channelItems[0].Id; - await HandleChannelChangeAsync(); - } - } - - private void HandleTemplateSelected(SmsTemplateDto smsTemplate) - { - _model.DisplayName = smsTemplate.TemplateName; - _model.Content = smsTemplate.TemplateContent; - _model.AuditStatus = smsTemplate.AuditStatus; - _model.AuditReason = smsTemplate.AuditReason; - _model.TemplateType = (int)smsTemplate.TemplateType; - _model.Items = ParseTemplateItem(smsTemplate.TemplateContent); - } - - private async Task HandleChannelChangeAsync() - { - _model.DisplayName = string.Empty; - _model.Content = string.Empty; - _model.TemplateId = string.Empty; - _model.Items = new(); - _templateItems = await SmsTemplateService.GetListByChannelIdAsync(_model.ChannelId); - StateHasChanged(); - } - - private List ParseTemplateItem(string content) - { - string startstr = "\\${"; - string endstr = "}"; - var paramList = UtilHelper.MidStrEx(content, startstr, endstr); - return paramList.Distinct().Select(x => new MessageTemplateItemDto { Code = x, MappingCode = x }).ToList(); - } - - private async Task SyncAsync() - { - if (_model.ChannelId == default) - { - return; - } - Loading = true; - await SmsTemplateService.SyncAsync(new SmsTemplateSyncInputDto(_model.ChannelId)); - _templateItems = await SmsTemplateService.GetListByChannelIdAsync(_model.ChannelId); - Loading = false; - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/SmsTemplateEditModal.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/SmsTemplateEditModal.razor deleted file mode 100644 index d2504c9b..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/SmsTemplateEditModal.razor +++ /dev/null @@ -1,89 +0,0 @@ -@inherits AdminCompontentBase - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @T("SyncTemplate") - - - - - - - - - - - - - -
- @T("Description.MessageTemplate.PerDayLimit.Tips") -
- -
- @T("Unit.Bar") -
-
-
-
-
-
diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/SmsTemplateEditModal.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/SmsTemplateEditModal.razor.cs deleted file mode 100644 index d5128e25..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/SmsTemplateEditModal.razor.cs +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTemplates.Modules; - -public partial class SmsTemplateEditModal : AdminCompontentBase -{ - [Parameter] - public EventCallback OnOk { get; set; } - - private MForm _form = default!; - private MessageTemplateUpsertDto _model = new(); - private Guid _entityId; - private bool _visible; - private List _channelItems = new(); - private List _templateItems = new(); - - ChannelService ChannelService => McCaller.ChannelService; - - MessageTemplateService MessageTemplateService => McCaller.MessageTemplateService; - - SmsTemplateService SmsTemplateService => McCaller.SmsTemplateService; - - public async Task OpenModalAsync(MessageTemplateDto model) - { - _model.ChannelType = ChannelTypes.Sms; - _entityId = model.Id; - _model = model.Adapt(); - await GetFormDataAsync(); - await InvokeAsync(() => - { - _visible = true; - StateHasChanged(); - }); - } - - private async Task GetFormDataAsync() - { - var dto = await MessageTemplateService.GetAsync(_entityId) ?? new(); - _model = dto.Adapt(); - _templateItems = await SmsTemplateService.GetListByChannelIdAsync(_model.ChannelId); - _model.ChannelType = dto.Channel.Type; - await HandleSelectChannelTypeAsync(_model.ChannelType); - } - - private void HandleCancel() - { - _visible = false; - ResetForm(); - } - - private async Task HandleOkAsync() - { - if (!_form.Validate()) - { - return; - } - Loading = true; - await MessageTemplateService.UpdateAsync(_entityId, _model); - Loading = false; - await SuccessMessageAsync(T("MessageTemplateEditMessage")); - _visible = false; - ResetForm(); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - - private async Task HandleDelAsync() - { - await ConfirmAsync(T("DeletionConfirmationMessage", $"{T("SmsTemplate")}\"{_model.DisplayName}\""), DeleteAsync, AlertTypes.Error); - } - - private async Task DeleteAsync() - { - Loading = true; - await MessageTemplateService.DeleteAsync(_entityId); - Loading = false; - await SuccessMessageAsync(T("MessageTemplateDeleteMessage")); - _visible = false; - ResetForm(); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - - private void ResetForm() - { - _model = new(); - _form.ResetValidation(); - } - - private void HandleVisibleChanged(bool val) - { - if (!val) HandleCancel(); - } - - private async Task HandleSelectChannelTypeAsync(ChannelTypes Type) - { - _channelItems = await ChannelService.GetListByTypeAsync(Type); - } - - private void HandleTemplateSelected(SmsTemplateDto smsTemplate) - { - _model.DisplayName = smsTemplate.TemplateName; - _model.Content = smsTemplate.TemplateContent; - _model.AuditStatus = smsTemplate.AuditStatus; - _model.AuditReason = smsTemplate.AuditReason; - _model.TemplateType = (int)smsTemplate.TemplateType; - _model.Items = ParseTemplateItem(smsTemplate.TemplateContent); - } - - private async Task HandleChannelChangeAsync() - { - _model.DisplayName = string.Empty; - _model.Content = string.Empty; - _model.TemplateId = string.Empty; - _model.Items = new(); - - _templateItems = await SmsTemplateService.GetListByChannelIdAsync(_model.ChannelId); - } - - private List ParseTemplateItem(string content) - { - string startstr = "\\${"; - string endstr = "}"; - var paramList = UtilHelper.MidStrEx(content, startstr, endstr); - return paramList.Select(x => new MessageTemplateItemDto { Code = x, MappingCode = x }).ToList(); - } - - private async Task SyncAsync() - { - if (_model.ChannelId == default) - { - return; - } - Loading = true; - await SmsTemplateService.SyncAsync(new SmsTemplateSyncInputDto(_model.ChannelId)); - _templateItems = await SmsTemplateService.GetListByChannelIdAsync(_model.ChannelId); - Loading = false; - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/SmsTemplateInfo.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/SmsTemplateInfo.razor deleted file mode 100644 index 7a8a3fd9..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/SmsTemplateInfo.razor +++ /dev/null @@ -1,36 +0,0 @@ -@inherits AdminCompontentBase -
-
-
- @T($"DisplayName.SmsTemplateType.{Enum.GetName(typeof(SmsTemplateTypes), MessageTemplate.TemplateType)}") -
-
@T("DisplayName.MessageTemplateTemplateType")
-
-
-
- @MessageTemplate.DisplayName -
-
@T("DisplayName.MessageTemplateDisplayName")
-
-
-
- @MessageTemplate.Content -
-
@T("DisplayName.MessageTemplateContent")
-
- -
- -@code { - [EditorRequired] - [Parameter] - public MessageTemplateUpsertDto MessageTemplate { get; set; } = null!; - - private void HandleTemplateItemChanged(MessageTemplateItemChangedEventArgs args) - { - string startstr = "${"; - string endstr = "}"; - MessageTemplate.Title = MessageTemplate.Title.Replace($"{startstr}{args.OldCode}{endstr}", $"{startstr}{args.NewCode}{endstr}"); - MessageTemplate.Content = MessageTemplate.Content.Replace($"{startstr}{args.OldCode}{endstr}", $"{startstr}{args.NewCode}{endstr}"); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/SmsTemplateInfo.razor.css b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/SmsTemplateInfo.razor.css deleted file mode 100644 index f4a0c9cf..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/SmsTemplateInfo.razor.css +++ /dev/null @@ -1,16 +0,0 @@ -.item{ - height:48px; - line-height:48px; -} - - .item dt { - padding-right: 24px; - } - - .item dd { - width: 62px; - } - -.template-content { - width: calc(100% - 24px); -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WebsiteMessageTemplateCreateModal.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WebsiteMessageTemplateCreateModal.razor deleted file mode 100644 index 2ef82d59..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WebsiteMessageTemplateCreateModal.razor +++ /dev/null @@ -1,77 +0,0 @@ -@inherits AdminCompontentBase - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- @T("Description.MessageTemplate.PerDayLimit.Tips") -
- -
- @T("Unit.Bar") -
-
-
-
-
-
diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WebsiteMessageTemplateCreateModal.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WebsiteMessageTemplateCreateModal.razor.cs deleted file mode 100644 index 52faeb96..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WebsiteMessageTemplateCreateModal.razor.cs +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTemplates.Modules; - -public partial class WebsiteMessageTemplateCreateModal : AdminCompontentBase -{ - [Parameter] - public EventCallback OnOk { get; set; } - - private MForm? _form; - private MessageTemplateUpsertDto _model = new(); - private bool _visible; - private List _channelItems = new(); - - ChannelService ChannelService => McCaller.ChannelService; - - MessageTemplateService MessageTemplateService => McCaller.MessageTemplateService; - - public async Task OpenModalAsync() - { - _model.ChannelType = ChannelTypes.WebsiteMessage; - if (string.IsNullOrEmpty(_model.Code)) - { - _model.Code = $"WM_{UtilConvert.GetGuidToNumber()}"; - } - await HandleSelectChannelTypeAsync(_model.ChannelType); - await InvokeAsync(() => - { - _visible = true; - StateHasChanged(); - }); - - _form?.ResetValidation(); - } - - private void HandleCancel() - { - _visible = false; - ResetForm(); - } - - private async Task HandleOkAsync() - { - Check.NotNull(_form, "form not found"); - - _model.DisplayName = _model.Title; - if (!_form.Validate()) - { - return; - } - Loading = true; - await MessageTemplateService.CreateAsync(_model); - Loading = false; - await SuccessMessageAsync(T("MessageTemplateCreateMessage")); - _visible = false; - ResetForm(); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - - private void ResetForm() - { - _model = new(); - } - - private void HandleVisibleChanged(bool val) - { - if (!val) HandleCancel(); - } - - private async Task HandleSelectChannelTypeAsync(ChannelTypes Type) - { - _channelItems = await ChannelService.GetListByTypeAsync(Type); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WebsiteMessageTemplateEditModal.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WebsiteMessageTemplateEditModal.razor deleted file mode 100644 index dc8a9800..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WebsiteMessageTemplateEditModal.razor +++ /dev/null @@ -1,69 +0,0 @@ -@inherits AdminCompontentBase - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - -
- @T("Description.MessageTemplate.PerDayLimit.Tips") -
- -
- @T("Unit.Bar") -
-
-
-
-
-
diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WebsiteMessageTemplateEditModal.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WebsiteMessageTemplateEditModal.razor.cs deleted file mode 100644 index c1f337b7..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WebsiteMessageTemplateEditModal.razor.cs +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTemplates.Modules; - -public partial class WebsiteMessageTemplateEditModal : AdminCompontentBase -{ - [Parameter] - public EventCallback OnOk { get; set; } - - private MForm _form = default!; - private MessageTemplateUpsertDto _model = new(); - private Guid _entityId; - private bool _visible; - private List _channelItems = new(); - - ChannelService ChannelService => McCaller.ChannelService; - - MessageTemplateService MessageTemplateService => McCaller.MessageTemplateService; - - public async Task OpenModalAsync(MessageTemplateDto model) - { - _entityId = model.Id; - _model = model.Adapt(); - await GetFormDataAsync(); - await InvokeAsync(() => - { - _visible = true; - StateHasChanged(); - }); - } - - private async Task GetFormDataAsync() - { - var dto = await MessageTemplateService.GetAsync(_entityId) ?? new(); - _model = dto.Adapt(); - _model.ChannelType = dto.Channel.Type; - await HandleSelectChannelType(_model.ChannelType); - } - - private void HandleCancel() - { - _visible = false; - ResetForm(); - } - - private async Task HandleOk() - { - _model.DisplayName = _model.Title; - if (!_form.Validate()) - { - return; - } - Loading = true; - await MessageTemplateService.UpdateAsync(_entityId, _model); - Loading = false; - await SuccessMessageAsync(T("MessageTemplateEditMessage")); - _visible = false; - ResetForm(); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - - private async Task HandleDelAsync() - { - await ConfirmAsync(T("DeletionConfirmationMessage", $"{T("WebsiteMessageTemplate")}\"{_model.DisplayName}\""), DeleteAsync, AlertTypes.Error); - } - - private async Task DeleteAsync() - { - Loading = true; - await MessageTemplateService.DeleteAsync(_entityId); - Loading = false; - await SuccessMessageAsync(T("MessageTemplateDeleteMessage")); - _visible = false; - ResetForm(); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - - private void ResetForm() - { - _model = new(); - _form.ResetValidation(); - } - - private void HandleVisibleChanged(bool val) - { - if (!val) HandleCancel(); - } - - private async Task HandleSelectChannelType(ChannelTypes Type) - { - _channelItems = await ChannelService.GetListByTypeAsync(Type); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WeixinWorkUpsertModal.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WeixinWorkUpsertModal.razor deleted file mode 100644 index 8a2b8f04..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WeixinWorkUpsertModal.razor +++ /dev/null @@ -1,69 +0,0 @@ -@inherits AdminCompontentBase - - - - - - - - - - - - @if (_model.TemplateType == (int)WeixinWorkTemplateTypes.TextCard) - { - - - } - else - { - - - } - - - @if (_model.TemplateType == (int)WeixinWorkTemplateTypes.TextCard) - { - - - } -
- @T("Description.MessageTemplate.PerDayLimit.Tips") -
- - -
- @T("Unit.Bar") -
-
-
-
diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WeixinWorkUpsertModal.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WeixinWorkUpsertModal.razor.cs deleted file mode 100644 index 625f2852..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WeixinWorkUpsertModal.razor.cs +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTemplates.Modules; - -public partial class WeixinWorkUpsertModal : AdminCompontentBase -{ - [Parameter] - public EventCallback OnOk { get; set; } - - private MForm? _form; - private MessageTemplateUpsertDto _model = new(); - private bool _visible; - private List _channelItems = new(); - private Guid _entityId; - - protected override string? PageName { get; set; } = "MessageTemplateBlock"; - - ChannelService ChannelService => McCaller.ChannelService; - - MessageTemplateService MessageTemplateService => McCaller.MessageTemplateService; - - public async Task OpenModalAsync(MessageTemplateDto? model = null) - { - _entityId = model?.Id ?? default; - _model = model?.Adapt() ?? new(); - - if (_entityId != default) - { - await GetFormDataAsync(); - } - else - { - await InitDataAsync(); - } - - await InvokeAsync(() => - { - _visible = true; - StateHasChanged(); - }); - - _form?.ResetValidation(); - } - - private async Task InitDataAsync() - { - _model.ChannelType = ChannelTypes.WeixinWork; - - if (string.IsNullOrEmpty(_model.Code)) - { - _model.Code = $"WXWork_{UtilConvert.GetGuidToNumber()}"; - } - - await HandleSelectChannelTypeAsync(_model.ChannelType); - } - - private async Task GetFormDataAsync() - { - var dto = await MessageTemplateService.GetAsync(_entityId) ?? new(); - _model = dto.Adapt(); - _model.ChannelType = dto.Channel.Type; - await HandleSelectChannelTypeAsync(_model.ChannelType); - } - - private void HandleCancel() - { - _visible = false; - ResetForm(); - } - - private async Task HandleOkAsync() - { - Check.NotNull(_form, "form not found"); - - if (_model.DisplayName.IsNullOrEmpty()) - { - _model.DisplayName = _model.Title; - } - - if (!_form.Validate()) - { - return; - } - Loading = true; - - var inputDto = _model.Adapt(); - - if (_entityId == default) - { - await MessageTemplateService.CreateAsync(inputDto); - } - else - { - await MessageTemplateService.UpdateAsync(_entityId, inputDto); - } - - Loading = false; - await UpsertSuccessfulMessage(_entityId, T("MessageTemplate")); - _visible = false; - ResetForm(); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - - private void ResetForm() - { - _model = new(); - } - - private void HandleVisibleChanged(bool val) - { - if (!val) HandleCancel(); - } - - private async Task HandleSelectChannelTypeAsync(ChannelTypes type) - { - _channelItems = await ChannelService.GetListByTypeAsync(type); - } - - private void HandleSelectTemplateType(int type) - { - _model.MessageInfo.IsJump = type != (int)WeixinWorkTemplateTypes.Text; - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WeixinWorkWebhookUpsertModal.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WeixinWorkWebhookUpsertModal.razor deleted file mode 100644 index e65e1494..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WeixinWorkWebhookUpsertModal.razor +++ /dev/null @@ -1,51 +0,0 @@ -@inherits AdminCompontentBase - - - - - - - - - - - - - - - -
- @T("Description.MessageTemplate.PerDayLimit.Tips") -
- - -
- @T("Unit.Bar") -
-
-
-
\ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WeixinWorkWebhookUpsertModal.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WeixinWorkWebhookUpsertModal.razor.cs deleted file mode 100644 index 94d595cd..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/Modules/WeixinWorkWebhookUpsertModal.razor.cs +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTemplates.Modules; - -public partial class WeixinWorkWebhookUpsertModal : AdminCompontentBase -{ - [Parameter] - public EventCallback OnOk { get; set; } - - private MForm? _form; - private MessageTemplateUpsertDto _model = new(); - private bool _visible; - private List _channelItems = new(); - private Guid _entityId; - - protected override string? PageName { get; set; } = "MessageTemplateBlock"; - - ChannelService ChannelService => McCaller.ChannelService; - - MessageTemplateService MessageTemplateService => McCaller.MessageTemplateService; - - public async Task OpenModalAsync(MessageTemplateDto? model = null) - { - _entityId = model?.Id ?? default; - _model = model?.Adapt() ?? new(); - - if (_entityId != default) - { - await GetFormDataAsync(); - } - else - { - await InitDataAsync(); - } - - await InvokeAsync(() => - { - _visible = true; - StateHasChanged(); - }); - - _form?.ResetValidation(); - } - - private async Task InitDataAsync() - { - _model.ChannelType = ChannelTypes.WeixinWorkWebhook; - - if (string.IsNullOrEmpty(_model.Code)) - { - _model.Code = $"WXWorkWebhook_{UtilConvert.GetGuidToNumber()}"; - } - - await HandleSelectChannelTypeAsync(_model.ChannelType); - } - - private async Task GetFormDataAsync() - { - var dto = await MessageTemplateService.GetAsync(_entityId) ?? new(); - _model = dto.Adapt(); - _model.ChannelType = dto.Channel.Type; - await HandleSelectChannelTypeAsync(_model.ChannelType); - } - - private void HandleCancel() - { - _visible = false; - ResetForm(); - } - - private async Task HandleOkAsync() - { - Check.NotNull(_form, "form not found"); - - if (_model.DisplayName.IsNullOrEmpty()) - { - _model.DisplayName = _model.Title; - } - - if (!_form.Validate()) - { - return; - } - Loading = true; - - var inputDto = _model.Adapt(); - - if (_entityId == default) - { - await MessageTemplateService.CreateAsync(inputDto); - } - else - { - await MessageTemplateService.UpdateAsync(_entityId, inputDto); - } - - Loading = false; - await UpsertSuccessfulMessage(_entityId, T("MessageTemplate")); - _visible = false; - ResetForm(); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - - private void ResetForm() - { - _model = new(); - } - - private void HandleVisibleChanged(bool val) - { - if (!val) HandleCancel(); - } - - private async Task HandleSelectChannelTypeAsync(ChannelTypes type) - { - _channelItems = await ChannelService.GetListByTypeAsync(type); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/SmsTemplateManagement.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/SmsTemplateManagement.razor deleted file mode 100644 index 50c7d65f..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/SmsTemplateManagement.razor +++ /dev/null @@ -1,125 +0,0 @@ -@inherits AdminCompontentBase -@page "/messageTemplates/smsTemplateManagement" - -@T("Sms") - - - - - @T("SmsTemplateTitle") - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @header.Text - - - @switch (context.Header.Value) - { - case ("ChannelDisplayName"): - - break; - case nameof(MessageTemplateDto.TemplateType): - - break; - case nameof(MessageTemplateDto.AuditStatus): - - break; - case nameof(MessageTemplateDto.Status): - - break; - case "Action": - mdi-pencil - break; - default: - - break; - } - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/SmsTemplateManagement.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/SmsTemplateManagement.razor.cs deleted file mode 100644 index d0c6e630..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/SmsTemplateManagement.razor.cs +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTemplates; - -public partial class SmsTemplateManagement : AdminCompontentBase -{ - private SmsTemplateEditModal _editModal = default!; - private SmsTemplateCreateModal _createModal = default!; - private GetMessageTemplateInputDto _queryParam = new() { ChannelType = ChannelTypes.Sms }; - private PaginatedListDto _entities = new(); - private List _channelItems = new(); - private DateTimeOffset? _endTime; - private DateTimeOffset? _startTime; - - private ChannelService ChannelService => McCaller.ChannelService; - - private MessageTemplateService MessageTemplateService => McCaller.MessageTemplateService; - - protected override string? PageName { get; set; } = "MessageTemplateBlock"; - - protected async override Task OnInitializedAsync() - { - _channelItems = await ChannelService.GetListByTypeAsync(ChannelTypes.Sms); - } - - protected async override Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await LoadData(); - } - await base.OnAfterRenderAsync(firstRender); - } - - public List> GetHeaders() - { - var prefix = "DisplayName.MessageTemplate"; - - return new() - { - new() { Text = T($"{prefix}{nameof(MessageTemplateDto.Code)}"), Value = nameof(MessageTemplateDto.Code), Sortable = false, Width = "8rem" }, - new() { Text = T($"{prefix}{nameof(MessageTemplateDto.DisplayName)}"), Value = nameof(MessageTemplateDto.DisplayName), Sortable = false, Width = "6rem"}, - new() { Text = T($"{prefix}{nameof(MessageTemplateDto.TemplateType)}"), Value = nameof(MessageTemplateDto.TemplateType), Sortable = false, Width = "6rem" }, - new() { Text = T($"{prefix}ChannelDisplayName"), Value = "ChannelDisplayName", Sortable = false, Width = "6.5625rem" }, - new() { Text = T($"{prefix}{nameof(MessageTemplateDto.AuditStatus)}"), Value = nameof(MessageTemplateDto.AuditStatus), Sortable = false, Width = "8rem" }, - new() { Text = T("Modifier"), Value = nameof(MessageTemplateDto.ModifierName), Sortable = false, Width = "7rem" }, - new() { Text = T("ModificationTime"), Value = nameof(MessageTemplateDto.ModificationTime), Sortable = true, Width = "7rem" }, - new() { Text = T($"{prefix}{nameof(MessageTemplateDto.Status)}"), Value = nameof(MessageTemplateDto.Status), Sortable = true, Width = "7.5rem" }, - new() { Text = T("Action"), Value = "Action", Sortable = false, Width = 105, Align = DataTableHeaderAlign.Center }, - }; - } - - private Task DateRangChangedAsync((DateTimeOffset? startDate, DateTimeOffset? endDate) args) - { - (_startTime, _endTime) = args; - _queryParam.StartTime = _startTime?.UtcDateTime; - _queryParam.EndTime = _endTime?.UtcDateTime; - return RefreshAsync(); - } - - private async Task LoadData() - { - Loading = true; - _entities = (await MessageTemplateService.GetListAsync(_queryParam)); - Loading = false; - StateHasChanged(); - } - - private async Task HandleOk() - { - await LoadData(); - } - - private async Task RefreshAsync() - { - _queryParam.Page = 1; - await LoadData(); - } - - private async Task HandlePageChanged(int page) - { - _queryParam.Page = page; - await LoadData(); - } - - private async Task HandlePageSizeChanged(int pageSize) - { - _queryParam.PageSize = pageSize; - await LoadData(); - } - - private async Task HandleClearAsync() - { - _queryParam = new() { ChannelType = ChannelTypes.Sms }; - await LoadData(); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/WebsiteMessageTemplateManagement.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/WebsiteMessageTemplateManagement.razor deleted file mode 100644 index 803a8fe4..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/WebsiteMessageTemplateManagement.razor +++ /dev/null @@ -1,90 +0,0 @@ -@inherits AdminCompontentBase -@page "/messageTemplates/websiteMessageTemplateManagement" - -@T("WebsiteMessage") - - - - - @T("WebsiteMessageTitle") - - - - - - - - - - - - - - - - - @header.Text - - - @switch (context.Header.Value) - { - case ("ChannelDisplayName"): - - break; - case nameof(MessageTemplateDto.AuditStatus): - string color = string.Empty; - switch (context.Item.AuditStatus) - { - case MessageTemplateAuditStatuses.WaitAudit: - color = "orange"; - break; - case MessageTemplateAuditStatuses.Adopt: - color = "sample-green"; - break; - case MessageTemplateAuditStatuses.Fail: - color = "error"; - break; - default: - break; - } - - @T($"DisplayName.MessageTemplateAuditStatus.{context.Item.AuditStatus.ToString()}") - - break; - case nameof(MessageTemplateDto.Status): - - @T($"DisplayName.MessageTemplateStatus.{context.Item.Status.ToString()}") - - break; - case "Action": - mdi-pencil - break; - default: - - break; - } - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/WebsiteMessageTemplateManagement.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/WebsiteMessageTemplateManagement.razor.cs deleted file mode 100644 index 82efb5c2..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/WebsiteMessageTemplateManagement.razor.cs +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTemplates; - -public partial class WebsiteMessageTemplateManagement : AdminCompontentBase -{ - private WebsiteMessageTemplateEditModal _editModal = default!; - private WebsiteMessageTemplateCreateModal _createModal = default!; - private GetMessageTemplateInputDto _queryParam = new() { ChannelType = ChannelTypes.WebsiteMessage }; - private PaginatedListDto _entities = new(); - private List _channelItems = new(); - private DateTimeOffset? _endTime; - private DateTimeOffset? _startTime; - - private ChannelService ChannelService => McCaller.ChannelService; - - private MessageTemplateService MessageTemplateService => McCaller.MessageTemplateService; - - protected override string? PageName { get; set; } = "MessageTemplateBlock"; - - protected async override Task OnInitializedAsync() - { - _channelItems = await ChannelService.GetListByTypeAsync(ChannelTypes.WebsiteMessage); - } - protected async override Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await LoadData(); - } - await base.OnAfterRenderAsync(firstRender); - } - - public List> GetHeaders() - { - var prefix = "DisplayName.MessageTemplate"; - - return new() - { - new() { Text = T($"{prefix}{nameof(MessageTemplateDto.Code)}"), Value = nameof(MessageTemplateDto.Code), Sortable = false, Width = "8rem" }, - new() { Text = T($"{prefix}{nameof(MessageTemplateDto.Title)}"), Value = nameof(MessageTemplateDto.Title), Sortable = false, Width = "13.125rem" }, - new() { Text = T($"{prefix}ChannelDisplayName"), Value = "ChannelDisplayName", Sortable = false, Width = "6.5625rem" }, - new() { Text = T("Modifier"), Value = nameof(MessageTemplateDto.ModifierName), Sortable = false, Width = "6.5625rem" }, - new() { Text = T("ModificationTime"), Value = nameof(MessageTemplateDto.ModificationTime), Sortable = true, Width = "13.125rem" }, - new() { Text = T("Action"), Value = "Action", Sortable = false, Width = 105, Align = DataTableHeaderAlign.Center }, - }; - } - - private Task DateRangChangedAsync((DateTimeOffset? startDate, DateTimeOffset? endDate) args) - { - (_startTime, _endTime) = args; - _queryParam.StartTime = _startTime?.UtcDateTime; - _queryParam.EndTime = _endTime?.UtcDateTime; - return RefreshAsync(); - } - - private async Task LoadData() - { - Loading = true; - _entities = (await MessageTemplateService.GetListAsync(_queryParam)); - Loading = false; - StateHasChanged(); - } - - private async Task HandleOk() - { - await LoadData(); - } - - private async Task SearchKeyDown(KeyboardEventArgs eventArgs) - { - if (eventArgs.Key == "Enter") - { - await RefreshAsync(); - } - } - - private async Task RefreshAsync() - { - _queryParam.Page = 1; - await LoadData(); - } - - private async Task HandlePageChanged(int page) - { - _queryParam.Page = page; - await LoadData(); - } - - private async Task HandlePageSizeChanged(int pageSize) - { - _queryParam.PageSize = pageSize; - await LoadData(); - } - - private async Task HandleClearAsync() - { - _queryParam = new() { ChannelType = ChannelTypes.WebsiteMessage }; - await LoadData(); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/WeixinWorkTemplateManagement.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/WeixinWorkTemplateManagement.razor deleted file mode 100644 index 8d9d4cff..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/WeixinWorkTemplateManagement.razor +++ /dev/null @@ -1,67 +0,0 @@ -@inherits AdminCompontentBase -@page "/messageTemplates/weixinWorkTemplateManagement" - -@T("WeixinWork") - - - - - @T("WeixinWork") - - - - - - - - - - - - - - - - - @header.Text - - - @switch (context.Header.Value) - { - case ("ChannelDisplayName"): - - break; - case nameof(MessageTemplateDto.TemplateType): - - break; - case "Action": - mdi-pencil - break; - default: - - break; - } - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/WeixinWorkTemplateManagement.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/WeixinWorkTemplateManagement.razor.cs deleted file mode 100644 index 0110f119..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/WeixinWorkTemplateManagement.razor.cs +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTemplates; - -public partial class WeixinWorkTemplateManagement : AdminCompontentBase -{ - [Inject] - public I18n I18n { get; set; } - - private WeixinWorkUpsertModal _upsertModal = default!; - private GetMessageTemplateInputDto _queryParam = new() { ChannelType = ChannelTypes.WeixinWork }; - private PaginatedListDto _entities = new(); - private List _channelItems = new(); - private DateTimeOffset? _endTime; - private DateTimeOffset? _startTime; - private List> _headers = new(); - - private ChannelService ChannelService => McCaller.ChannelService; - - private MessageTemplateService MessageTemplateService => McCaller.MessageTemplateService; - - protected override string? PageName { get; set; } = "MessageTemplateBlock"; - - protected async override Task OnInitializedAsync() - { - _channelItems = await ChannelService.GetListByTypeAsync(ChannelTypes.WeixinWork); - - LoadHeaders(); - - I18n.CultureChanged += Changed; - } - - protected async override Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await LoadData(); - } - await base.OnAfterRenderAsync(firstRender); - } - - private Task DateRangChangedAsync((DateTimeOffset? startDate, DateTimeOffset? endDate) args) - { - (_startTime, _endTime) = args; - _queryParam.StartTime = _startTime?.UtcDateTime; - _queryParam.EndTime = _endTime?.UtcDateTime; - return RefreshAsync(); - } - - private async Task LoadData() - { - Loading = true; - _entities = (await MessageTemplateService.GetListAsync(_queryParam)); - Loading = false; - StateHasChanged(); - } - - private async Task HandleOk() - { - await LoadData(); - } - - private async Task RefreshAsync() - { - _queryParam.Page = 1; - await LoadData(); - } - - private async Task HandlePageChanged(int page) - { - _queryParam.Page = page; - await LoadData(); - } - - private async Task HandlePageSizeChanged(int pageSize) - { - _queryParam.PageSize = pageSize; - await LoadData(); - } - - private async Task HandleClearAsync() - { - _queryParam = new() { ChannelType = ChannelTypes.App }; - await LoadData(); - } - - private void LoadHeaders() - { - var prefix = "DisplayName.MessageTemplate"; - _headers = new() - { - new() { Text = T($"{prefix}{nameof(MessageTemplateDto.Code)}"), Value = nameof(MessageTemplateDto.Code), Sortable = false }, - new() { Text = T($"{prefix}{nameof(MessageTemplateDto.TemplateType)}"), Value = nameof(MessageTemplateDto.TemplateType)}, - new() { Text = T($"{prefix}{nameof(MessageTemplateDto.DisplayName)}"), Value = nameof(MessageTemplateDto.DisplayName), Sortable = false }, - new() { Text = T($"{prefix}ChannelDisplayName"), Value = "ChannelDisplayName", Sortable = false }, - new() { Text = T("Modifier"), Value = nameof(MessageTemplateDto.ModifierName), Sortable = false }, - new() { Text = T("ModificationTime"), Value = nameof(MessageTemplateDto.ModificationTime), Sortable = true }, - new() { Text = T("Action"), Value = "Action", Sortable = false, Width = 105, Align = DataTableHeaderAlign.Center }, - }; - } - - void Changed(object? sender, EventArgs args) - { - LoadHeaders(); - } - - protected override async ValueTask DisposeAsyncCore() - { - I18n.CultureChanged -= Changed; - await base.DisposeAsyncCore(); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/WeixinWorkWebhookTemplateManagement.razor b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/WeixinWorkWebhookTemplateManagement.razor deleted file mode 100644 index eb8edf98..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/WeixinWorkWebhookTemplateManagement.razor +++ /dev/null @@ -1,67 +0,0 @@ -@inherits AdminCompontentBase -@page "/messageTemplates/weixinWorkWebhookTemplateManagement" - -@T("WeixinWorkWebhook") - - - - - @T("WeixinWorkWebhook") - - - - - - - - - - - - - - - - - @header.Text - - - @switch (context.Header.Value) - { - case ("ChannelDisplayName"): - - break; - case nameof(MessageTemplateDto.TemplateType): - - break; - case "Action": - mdi-pencil - break; - default: - - break; - } - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/WeixinWorkWebhookTemplateManagement.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/WeixinWorkWebhookTemplateManagement.razor.cs deleted file mode 100644 index 9d496fa9..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/MessageTemplates/WeixinWorkWebhookTemplateManagement.razor.cs +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.MessageTemplates; - -public partial class WeixinWorkWebhookTemplateManagement : AdminCompontentBase -{ - [Inject] - public I18n I18n { get; set; } - - private WeixinWorkWebhookUpsertModal _upsertModal = default!; - private GetMessageTemplateInputDto _queryParam = new() { ChannelType = ChannelTypes.WeixinWorkWebhook }; - private PaginatedListDto _entities = new(); - private List _channelItems = new(); - private DateTimeOffset? _endTime; - private DateTimeOffset? _startTime; - private List> _headers = new(); - - private ChannelService ChannelService => McCaller.ChannelService; - - private MessageTemplateService MessageTemplateService => McCaller.MessageTemplateService; - - protected override string? PageName { get; set; } = "MessageTemplateBlock"; - - protected async override Task OnInitializedAsync() - { - _channelItems = await ChannelService.GetListByTypeAsync(ChannelTypes.WeixinWorkWebhook); - - LoadHeaders(); - - I18n.CultureChanged += Changed; - } - - protected async override Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await LoadData(); - } - await base.OnAfterRenderAsync(firstRender); - } - - private Task DateRangChangedAsync((DateTimeOffset? startDate, DateTimeOffset? endDate) args) - { - (_startTime, _endTime) = args; - _queryParam.StartTime = _startTime?.UtcDateTime; - _queryParam.EndTime = _endTime?.UtcDateTime; - return RefreshAsync(); - } - - private async Task LoadData() - { - Loading = true; - _entities = (await MessageTemplateService.GetListAsync(_queryParam)); - Loading = false; - StateHasChanged(); - } - - private async Task HandleOk() - { - await LoadData(); - } - - private async Task RefreshAsync() - { - _queryParam.Page = 1; - await LoadData(); - } - - private async Task HandlePageChanged(int page) - { - _queryParam.Page = page; - await LoadData(); - } - - private async Task HandlePageSizeChanged(int pageSize) - { - _queryParam.PageSize = pageSize; - await LoadData(); - } - - private async Task HandleClearAsync() - { - _queryParam = new() { ChannelType = ChannelTypes.App }; - await LoadData(); - } - - private void LoadHeaders() - { - var prefix = "DisplayName.MessageTemplate"; - _headers = new() - { - new() { Text = T($"{prefix}{nameof(MessageTemplateDto.Code)}"), Value = nameof(MessageTemplateDto.Code), Sortable = false }, - new() { Text = T($"{prefix}{nameof(MessageTemplateDto.TemplateType)}"), Value = nameof(MessageTemplateDto.TemplateType)}, - new() { Text = T($"{prefix}{nameof(MessageTemplateDto.DisplayName)}"), Value = nameof(MessageTemplateDto.DisplayName), Sortable = false }, - new() { Text = T($"{prefix}ChannelDisplayName"), Value = "ChannelDisplayName", Sortable = false }, - new() { Text = T("Modifier"), Value = nameof(MessageTemplateDto.ModifierName), Sortable = false }, - new() { Text = T("ModificationTime"), Value = nameof(MessageTemplateDto.ModificationTime), Sortable = true }, - new() { Text = T("Action"), Value = "Action", Sortable = false, Width = 105, Align = DataTableHeaderAlign.Center }, - }; - } - - void Changed(object? sender, EventArgs args) - { - LoadHeaders(); - } - - protected override async ValueTask DisposeAsyncCore() - { - I18n.CultureChanged -= Changed; - await base.DisposeAsyncCore(); - } -} - diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/Modules/ReceiverGroupCreateModal.razor b/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/Modules/ReceiverGroupCreateModal.razor deleted file mode 100644 index 578e02f0..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/Modules/ReceiverGroupCreateModal.razor +++ /dev/null @@ -1,28 +0,0 @@ -@inherits AdminCompontentBase -
- - - - - - - - - - - - - - - - - - - - -
\ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/Modules/ReceiverGroupCreateModal.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/Modules/ReceiverGroupCreateModal.razor.cs deleted file mode 100644 index 749fa78a..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/Modules/ReceiverGroupCreateModal.razor.cs +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.ReceiverGroups.Modules; - -public partial class ReceiverGroupCreateModal : AdminCompontentBase -{ - [Parameter] - public EventCallback OnOk { get; set; } - - private ReceiverGroupUpsertDto _model = new(); - private MForm? _form; - private ReceiverSelect _ReceiverSelect = default!; - private bool _visible; - - ReceiverGroupService ReceiverGroupService => McCaller.ReceiverGroupService; - - public async Task OpenModalAsync() - { - await InvokeAsync(() => - { - _visible = true; - StateHasChanged(); - }); - - _form?.ResetValidation(); - } - - private void HandleCancel() - { - _visible = false; - ResetForm(); - } - - private async Task HandleOk() - { - Check.NotNull(_form, "form not found"); - - if (!_form.Validate()) - { - return; - } - Loading = true; - await ReceiverGroupService.CreateAsync(_model); - Loading = false; - await SuccessMessageAsync(T("ReceiverGroupCreateMessage")); - _visible = false; - ResetForm(); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - - private void ResetForm() - { - _model = new(); - _ReceiverSelect.ResetForm(); - } - - private void HandleVisibleChanged(bool val) - { - if (!val) HandleCancel(); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/Modules/ReceiverGroupEditModal.razor b/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/Modules/ReceiverGroupEditModal.razor deleted file mode 100644 index 2c9787d4..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/Modules/ReceiverGroupEditModal.razor +++ /dev/null @@ -1,28 +0,0 @@ -@inherits AdminCompontentBase -
- - - - - - - - - - - - - - - - - - - - -
\ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/Modules/ReceiverGroupEditModal.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/Modules/ReceiverGroupEditModal.razor.cs deleted file mode 100644 index 2873e061..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/Modules/ReceiverGroupEditModal.razor.cs +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.ReceiverGroups.Modules; - -public partial class ReceiverGroupEditModal : AdminCompontentBase -{ - [Parameter] - public EventCallback OnOk { get; set; } - - private ReceiverGroupUpsertDto _model = new(); - private MForm _form = default!; - private ReceiverSelect _ReceiverSelect = default!; - private Guid _entityId; - private bool _visible; - - ReceiverGroupService ReceiverGroupService => McCaller.ReceiverGroupService; - - public async Task OpenModalAsync(ReceiverGroupDto model) - { - _entityId = model.Id; - _model = model.Adapt(); - await GetFormDataAsync(); - await InvokeAsync(() => - { - _visible = true; - StateHasChanged(); - }); - } - - private async Task GetFormDataAsync() - { - var dto = await ReceiverGroupService.GetAsync(_entityId) ?? new(); - _model = dto.Adapt(); - } - - private void HandleCancel() - { - _visible = false; - ResetForm(); - } - - private async Task HandleOk() - { - if (!_form.Validate()) - { - return; - } - Loading = true; - await ReceiverGroupService.UpdateAsync(_entityId, _model); - Loading = false; - _visible = false; - ResetForm(); - await SuccessMessageAsync(T("ReceiverGroupEditMessage")); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - - private async Task HandleDel() - { - await ConfirmAsync(T("DeletionConfirmationMessage",$"{T("ReceiverGroup")}\"{_model.DisplayName}\""), DeleteAsync, AlertTypes.Error); - } - private async Task DeleteAsync() - { - Loading = true; - await ReceiverGroupService.DeleteAsync(_entityId); - Loading = false; - await SuccessMessageAsync(T("ReceiverGroupDeleteMessage")); - _visible = false; - ResetForm(); - if (OnOk.HasDelegate) - { - await OnOk.InvokeAsync(); - } - } - private void ResetForm() - { - _model = new(); - _form.ResetValidation(); - _ReceiverSelect.ResetForm(); - } - - private void HandleVisibleChanged(bool val) - { - if (!val) HandleCancel(); - } -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/Modules/ReceiverSelect.razor b/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/Modules/ReceiverSelect.razor deleted file mode 100644 index 6044de6a..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/Modules/ReceiverSelect.razor +++ /dev/null @@ -1,66 +0,0 @@ -@inherits AdminCompontentBase - - - - - mdi-plus - @T("ExternalMember") - - - -@if (Value.Count > 0) -{ - - - @foreach (var item in Value) - { - - - - @if (item.Type != ReceiverGroupItemTypes.User) - { - mdi-animation - } - else - { - @if (string.IsNullOrEmpty(item.Avatar)) - { - - } - else - { - - } - } - - - - @(item.DisplayName) -
- -
- @T($"DisplayName.MessageTaskReceiverTypes.{item.Type}") -
- @if (item.Type == ReceiverGroupItemTypes.User) - { - - @(item.PhoneNumber) -
- -
- @(item.Email) -
- } -
-
- - mdi-close - -
-
-
- } -
-
-} - \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/Modules/ReceiverSelect.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/Modules/ReceiverSelect.razor.cs deleted file mode 100644 index 914c5df6..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/Modules/ReceiverSelect.razor.cs +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.ReceiverGroups.Modules; - -public partial class ReceiverSelect : AdminCompontentBase -{ - [Parameter] - public List Value { get; set; } = new(); - - [Parameter] - public EventCallback> ValueChanged { get; set; } - - private ExternalUserCreateModal _createModal = default!; - private SubjectAutoComplete _subjectAutoComplete = default!; - - public async Task RemoveValue(ReceiverGroupItemDto item) - { - Value.RemoveAll(x => x.SubjectId == item.SubjectId); - await ValueChanged.InvokeAsync(Value); - } - - private async Task HandleOk(UserDto user) - { - Value.Add(new ReceiverGroupItemDto - { - Type = ReceiverGroupItemTypes.User, - SubjectId = user.Id, - DisplayName = user.GetDisplayName(), - Avatar = user.Avatar, - PhoneNumber = user.PhoneNumber ?? string.Empty, - Email = user.Email ?? string.Empty - }); - await ValueChanged.InvokeAsync(Value); - await SuccessMessageAsync(T("ExternalMemberAddMessage")); - } - - private async Task HandleOnAdd(SubjectDto item) - { - if (!Value.Any(x => x.SubjectId == item.SubjectId)) - { - Value.Add(new ReceiverGroupItemDto - { - Type = (ReceiverGroupItemTypes)((int)item.SubjectType), - SubjectId = item.SubjectId, - DisplayName = item.GetDisplayName(), - Avatar = item.Avatar ?? string.Empty, - PhoneNumber = item.PhoneNumber ?? string.Empty, - Email = item.Email ?? string.Empty - }); - await ValueChanged.InvokeAsync(Value); - } - await ValueChanged.InvokeAsync(Value); - } - - private async Task HandleOnRemove(SubjectDto item) - { - if (Value.Any(x => x.SubjectId == item.SubjectId)) - { - Value.RemoveAll(x => x.SubjectId == item.SubjectId); - await ValueChanged.InvokeAsync(Value); - } - } - - public void ResetForm() - { - _subjectAutoComplete.ResetForm(); - } - - private void HandleOnBlur() - { - _subjectAutoComplete.ResetForm(); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/ReceiverGroupManagement.razor b/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/ReceiverGroupManagement.razor deleted file mode 100644 index 040ba25a..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/ReceiverGroupManagement.razor +++ /dev/null @@ -1,42 +0,0 @@ -@inherits AdminCompontentBase -@page "/receiverGroups/receiverGroupManagement" - -@T("Permission.ReceiverGroupManagement") - - - - - @T("Title") - - - - - - - - @header.Text - - - @switch (context.Header.Value) - { - case "Action": - - mdi-pencil - - break; - default: - - break; - } - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/ReceiverGroupManagement.razor.cs b/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/ReceiverGroupManagement.razor.cs deleted file mode 100644 index 94547d46..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Pages/ReceiverGroups/ReceiverGroupManagement.razor.cs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Pages.ReceiverGroups; - -public partial class ReceiverGroupManagement : AdminCompontentBase -{ - private ReceiverGroupEditModal _editModal = default!; - private ReceiverGroupCreateModal _createModal = default!; - private GetReceiverGroupInputDto _queryParam = new(10); - private PaginatedListDto _entities = new(); - - ReceiverGroupService ReceiverGroupService => McCaller.ReceiverGroupService; - - protected override string? PageName { get; set; } = "ReceiverGroupBlock"; - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await LoadData(); - } - await base.OnAfterRenderAsync(firstRender); - } - - public List> GetHeaders() - { - var _prefix = "DisplayName.ReceiverGroup"; - - return new() - { - new() { Text = T($"{_prefix}{nameof(ReceiverGroupDto.DisplayName)}"), Value = nameof(ReceiverGroupDto.DisplayName), Sortable = false, Width = "14.6875rem" }, - new() { Text = T("Modifier"), Value = nameof(MessageTemplateDto.ModifierName), Sortable = false, Width = "9.625rem" }, - new() { Text = T("ModificationTime"), Value = nameof(ReceiverGroupDto.ModificationTime), Sortable = false}, - new() { Text = T("Action"), Value = "Action", Sortable = false, Width = 108, Align = DataTableHeaderAlign.Center }, - }; - } - - private async Task LoadData() - { - Loading = true; - _entities = (await ReceiverGroupService.GetListAsync(_queryParam)); - Loading = false; - StateHasChanged(); - } - - private async Task HandleOk() - { - await LoadData(); - } - - private async Task SearchKeyDown(KeyboardEventArgs eventArgs) - { - if (eventArgs.Key == "Enter") - { - await RefreshAsync(); - } - } - - private async Task RefreshAsync() - { - _queryParam.Page = 1; - await LoadData(); - } - - private async Task HandlePageChanged(int page) - { - _queryParam.Page = page; - await LoadData(); - } - - private async Task HandlePageSizeChanged(int pageSize) - { - _queryParam.PageSize = pageSize; - await LoadData(); - } - - private async Task HandleClearAsync() - { - _queryParam = new(); - await LoadData(); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Registers/MessageTaskRegister.cs b/src/Web/Masa.Mc.Web.Admin/Registers/MessageTaskRegister.cs deleted file mode 100644 index 17a75415..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Registers/MessageTaskRegister.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Registers; - -public class MessageTaskRegister : IRegister -{ - public void Register(TypeAdapterConfig config) - { - config.ForType().MapToConstructor(true) - .Map(dest => dest.ChannelType, src => src.Channel.Type); - - config.ForType() - .Map(dest => dest.ExtraProperties, src => src.ExtraProperties); - - config.ForType() - .Map(dest => dest.ExtraProperties, src => ExtensionPropertyHelper.ConvertToType(src.ExtraProperties)); - } -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Registers/MessageTemplateRegister.cs b/src/Web/Masa.Mc.Web.Admin/Registers/MessageTemplateRegister.cs deleted file mode 100644 index 4984a04b..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Registers/MessageTemplateRegister.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin.Registers; - -public class MessageTemplateRegister : IRegister -{ - public void Register(TypeAdapterConfig config) - { - config.ForType() - .Map(dest => dest.Options, src => ExtensionPropertyHelper.ConvertToType(src.Options)); - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Shared/AdminCompontentBase.cs b/src/Web/Masa.Mc.Web.Admin/Shared/AdminCompontentBase.cs deleted file mode 100644 index b9f48da7..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Shared/AdminCompontentBase.cs +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -namespace Masa.Mc.Web.Admin; - -public abstract class AdminCompontentBase : Blazor.Core.MasaComponentBase -{ - private GlobalConfig? _globalConfig; - private NavigationManager? _navigationManager; - private McCaller? _mcCaller; - - [Inject] - public McCaller McCaller - { - get - { - return _mcCaller ?? throw new Exception("please Inject McCaller!"); - } - set - { - _mcCaller = value; - } - } - - [Inject] - public IPopupService PopupService { get; set; } = default!; - - [Inject] - public I18n I18n { get; set; } = default!; - - [Inject] - public GlobalConfig GlobalConfig - { - get - { - return _globalConfig ?? throw new Exception("please Inject GlobalConfig!"); - } - set - { - _globalConfig = value; - } - } - - [Inject] - public NavigationManager NavigationManager - { - get - { - return _navigationManager ?? throw new Exception("please Inject NavigationManager!"); - } - set - { - _navigationManager = value; - } - } - - [Inject] - public McApiOptions McApiOptions { get; set; } = default!; - - [Inject] - public JsInitVariables JsInitVariables { get; set; } = default!; - - [CascadingParameter(Name = "Culture")] - private string Culture { get; set; } = null!; - - public bool Loading - { - get => GlobalConfig.Loading; - set => GlobalConfig.Loading = value; - } - - public string LoadingText - { - get => GlobalConfig.LoadingText; - set => GlobalConfig.LoadingText = value; - } - - protected virtual string? PageName { get; set; } - - public string T(string key) - { - if (string.IsNullOrEmpty(key)) return key; - if (PageName is not null) return I18n.T(PageName, key, false) ?? I18n.T(key, false) ?? key; - else return I18n.T(key, true); - } - - public string T(string formatkey, params string[] args) - { - return string.Format(T(formatkey), args); - } - - public HubConnection? HubConnection { get; set; } - - public async Task ConfirmAsync(string messgae, Func callback, AlertTypes type = AlertTypes.Warning) - { - if (await PopupService.SimpleConfirmAsync(I18n.T("OperationConfirmation"), messgae, type)) await callback.Invoke(); - } - - public async Task SuccessMessageAsync(string message) - { - await PopupService.EnqueueSnackbarAsync(message, AlertTypes.Success); - } - - public async Task UpsertSuccessfulMessage(Guid entityId, string displayName) - { - if (entityId == default) - { - await SuccessMessageAsync(T("CreateSuccessfulMessage", displayName)); - } - else - { - await SuccessMessageAsync(T("EditSuccessfulMessage", displayName)); - } - } - - public async Task WarningAsync(string message) - { - await PopupService.EnqueueSnackbarAsync(message, AlertTypes.Warning); - } - - public async Task ErrorMessageAsync(string message) - { - await PopupService.EnqueueSnackbarAsync(message, AlertTypes.Error); - } - - public static List GetEnumList() where TEnum : struct, Enum - { - return EnumHelper.GetEnumList(); - } - - protected async Task HandleErrorAsync(Exception exception) - { - await InvokeAsync(async () => - { - await ErrorMessageAsync(exception.Message); - Loading = false; - StateHasChanged(); - }); - } - - public List> GetEnumMap() where TEnum : struct, Enum - { - return Enum.GetValues().Select(e => new KeyValuePair(e.ToString(), e)).ToList(); - } - - public List> GetBooleanMap() - { - return new() - { - new(T("Enable"), true), - new(T("Disabled"), false) - }; - } - - public async Task HubConnectionBuilder() - { - HubConnection = new HubConnectionBuilder() - .WithUrl(NavigationManager.ToAbsoluteUri($"{McApiOptions.McServiceBaseAddress}/signalr-hubs/notifications")) - .Build(); - await HubConnection.StartAsync(); - } - - protected override ValueTask DisposeAsyncCore() - { - HubConnection?.DisposeAsync(); - return base.DisposeAsyncCore(); - } - - public async Task Throttle(Func callback, int wait = 500, bool immediate = true) - { - if (immediate) - { - if (!GlobalConfig.ThrottleFlag) - { - GlobalConfig.ThrottleFlag = true; - await callback.Invoke(); - await Task.Delay(wait); - GlobalConfig.ThrottleFlag = false; - } - } - else if (!GlobalConfig.ThrottleFlag) - { - GlobalConfig.ThrottleFlag = true; - await Task.Delay(wait); - GlobalConfig.ThrottleFlag = false; - await callback.Invoke(); - } - } -} diff --git a/src/Web/Masa.Mc.Web.Admin/Shared/EmptyLayout.razor b/src/Web/Masa.Mc.Web.Admin/Shared/EmptyLayout.razor deleted file mode 100644 index a8b1229d..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Shared/EmptyLayout.razor +++ /dev/null @@ -1,7 +0,0 @@ -@inherits LayoutComponentBase - - -
- @Body -
-
\ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Shared/MLoading.razor b/src/Web/Masa.Mc.Web.Admin/Shared/MLoading.razor deleted file mode 100644 index 2ac5135d..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Shared/MLoading.razor +++ /dev/null @@ -1,37 +0,0 @@ -@implements IDisposable -@inject GlobalConfig GlobalConfig; - - -
- -
@LoadingText
-
-
- -@code { - [Parameter] - public bool IsLoading { get; set; } - - [Parameter] - public string LoadingText { get; set; } = string.Empty; - - [Parameter] - public EventCallback LoadingChanged { get; set; } - - void Loading(bool loading,string loadingText) - { - IsLoading = loading; - LoadingText = loadingText; - base.StateHasChanged(); - } - - protected override void OnInitialized() - { - GlobalConfig.OnLoadingChanged += Loading; - } - - public void Dispose() - { - GlobalConfig.OnLoadingChanged -= Loading; - } -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Shared/MainLayout.razor b/src/Web/Masa.Mc.Web.Admin/Shared/MainLayout.razor deleted file mode 100644 index 37a42041..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Shared/MainLayout.razor +++ /dev/null @@ -1,58 +0,0 @@ -@using Masa.BuildingBlocks.StackSdks.Config; -@using Masa.Contrib.StackSdks.Config; -@inherits LayoutComponentBase -@inject GlobalConfig GlobalConfig -@inject NavigationManager Navigation -@inject IMasaStackConfig MasaStackConfig - - - @Body - - - -@code { - [Inject] - public IPopupService PopupService { get; set; } = default!; - - [Inject] - public I18n I18N { get; set; } = default!; - - private Task OnErrorAfterHandle(Exception exception) - { - GlobalConfig.Loading = false; - GlobalConfig.ThrottleFlag = false; - return Task.CompletedTask; - } - - private bool SignOut() - { - Navigation.NavigateTo("/Logout",true); - return true; - } - - protected bool TranslateFluentValidationProperty { get; set; } = true; - - private void UsingI18nToResolveFluentValidationDisplayName(I18n i18N) - { - ValidatorOptions.Global.DisplayNameResolver = (type, member, expression) => - { - if (member != null) - { - var memberName = i18N.T(member.Name); - return memberName; - } - return null; - }; - } - - protected override Task OnAfterRenderAsync(bool firstRender) - { - if (TranslateFluentValidationProperty) - { - UsingI18nToResolveFluentValidationDisplayName(I18N); - } - return base.OnAfterRenderAsync(firstRender); - } -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/Shared/MainLayout.razor.css b/src/Web/Masa.Mc.Web.Admin/Shared/MainLayout.razor.css deleted file mode 100644 index 5b076258..00000000 --- a/src/Web/Masa.Mc.Web.Admin/Shared/MainLayout.razor.css +++ /dev/null @@ -1,3 +0,0 @@ -.main-layout ::deep .app-bar .m-toolbar__content { - padding: 0 !important; -} diff --git a/src/Web/Masa.Mc.Web.Admin/_Imports.cs b/src/Web/Masa.Mc.Web.Admin/_Imports.cs deleted file mode 100644 index a27c620d..00000000 --- a/src/Web/Masa.Mc.Web.Admin/_Imports.cs +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) MASA Stack All rights reserved. -// Licensed under the Apache License. See LICENSE.txt in the project root for license information. - -// System Namespaces -global using System.Collections.Concurrent; -global using System.Reflection; -global using System.Text; - -// Microsoft Namespaces -global using Microsoft.AspNetCore.Components; -global using Microsoft.AspNetCore.Components.Forms; -global using Microsoft.AspNetCore.Components.Web; -global using Microsoft.AspNetCore.SignalR.Client; -global using Microsoft.Extensions.DependencyInjection; -global using Microsoft.JSInterop; - -// Third-party Libraries -global using BlazorDownloadFile; -global using FluentValidation; -global using Mapster; - -// MASA Building Blocks and Contrib Packages -global using Masa.BuildingBlocks.StackSdks.Auth; -global using Masa.BuildingBlocks.StackSdks.Auth.Contracts.Model; -global using Masa.Contrib.StackSdks.Config; - -// MASA Blazor Components -global using Masa.Blazor; -global using Masa.Blazor.Components.Editor; -global using Masa.Blazor.Presets; -global using Masa.Stack.Components; -global using Masa.Stack.Components.Extensions; - -// MASA MC Contracts, Infrastructure, Domain, Services, and Application -global using Masa.Mc.ApiGateways.Caller; -global using Masa.Mc.ApiGateways.Caller.Services.Channels; -global using Masa.Mc.ApiGateways.Caller.Services.MessageTemplates; -global using Masa.Mc.ApiGateways.Caller.Services.ReceiverGroups; -global using Masa.Mc.ApiGateways.Caller.Services.MessageTasks; -global using Masa.Mc.ApiGateways.Caller.Services.MessageInfos; -global using Masa.Mc.ApiGateways.Caller.Services.MessageRecords; -global using Masa.Mc.ApiGateways.Caller.Services.Oss; -global using Masa.Mc.Contracts.Admin.Dtos; -global using Masa.Mc.Contracts.Admin.Dtos.Channels; -global using Masa.Mc.Contracts.Admin.Dtos.MessageTemplates; -global using Masa.Mc.Contracts.Admin.Dtos.ReceiverGroups; -global using Masa.Mc.Contracts.Admin.Dtos.MessageTasks; -global using Masa.Mc.Contracts.Admin.Dtos.MessageInfos; -global using Masa.Mc.Contracts.Admin.Dtos.MessageRecords; -global using Masa.Mc.Contracts.Admin.Dtos.Subjects; -global using Masa.Mc.Domain.Shared.Channels; -global using Masa.Mc.Domain.Shared.MessageTemplates; -global using Masa.Mc.Domain.Shared.ReceiverGroups; -global using Masa.Mc.Domain.Shared.MessageTasks; -global using Masa.Mc.Domain.Shared.MessageRecords; -global using Masa.Mc.Domain.Shared.Consts; -global using Masa.Mc.Infrastructure.Common.Helper; -global using Masa.Mc.Infrastructure.Common.Extensions; -global using Masa.Mc.Infrastructure.Ddd.Application.Contracts.Dtos; -global using Masa.Mc.Data; - -// MASA MC Web Admin Pages and Components -global using Masa.Mc.Web.Admin.Global; -global using Masa.Mc.Web.Admin.Pages.Channels.Modules; -global using Masa.Mc.Web.Admin.Pages.MessageTemplates.Modules; -global using Masa.Mc.Web.Admin.Pages.ReceiverGroups.Modules; -global using Masa.Mc.Web.Admin.Pages.MessageTasks.Modules; -global using Masa.Mc.Web.Admin.Pages.MessageRecords.Modules; -global using Masa.Mc.Web.Admin.Components.Modules.Subjects; -global using Masa.Mc.Web.Admin.Model; - -// Validators -global using Masa.Mc.Contracts.Admin.Dtos.MessageInfos.Validator; -global using Masa.Mc.Contracts.Admin.Dtos.MessageTasks.Validator; -global using Masa.Mc.Contracts.Admin.Options.Channels; \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/_Imports.razor b/src/Web/Masa.Mc.Web.Admin/_Imports.razor deleted file mode 100644 index 23284c5b..00000000 --- a/src/Web/Masa.Mc.Web.Admin/_Imports.razor +++ /dev/null @@ -1,55 +0,0 @@ -@using Microsoft.AspNetCore.Components.Web -@using Masa.Blazor -@using Masa.Blazor.Presets -@using Masa.Mc.Web.Admin.Global -@using Masa.Mc.Web.Admin.Shared -@using System.Diagnostics.CodeAnalysis -@using Microsoft.AspNetCore.Components.Authorization -@using Microsoft.AspNetCore.Components.Routing -@using Masa.Mc.Web.Admin.Pages.Channels.Modules -@using Masa.Mc.Contracts.Admin.Dtos.Channels -@using Masa.Mc.Domain.Shared.Channels -@using Humanizer -@using Masa.Mc.Domain.Shared.MessageTemplates -@using Masa.Mc.Web.Admin.Pages.MessageTemplates.Modules -@using Masa.Mc.Contracts.Admin.Dtos.ReceiverGroups -@using Masa.Mc.Web.Admin.Pages.ReceiverGroups.Modules -@using System.Globalization -@using Masa.Mc.Web.Admin.Pages.MessageTasks.Modules -@using Masa.Mc.Domain.Shared.MessageTasks -@using Masa.Stack.Components -@using Masa.Mc.Domain.Shared.MessageRecords -@using Masa.Mc.Web.Admin.Pages.MessageRecords.Modules -@using Masa.Mc.Web.Admin.Components.Modules.Subjects -@using Masa.Mc.Web.Admin.Components.Selects -@using Masa.Mc.Web.Admin.Components.Modules.MessageTemplates -@using Masa.Mc.Web.Admin.Components.Modules.MessageTasks -@using Masa.Mc.Web.Admin.Components -@using Masa.Mc.Web.Admin.Components.ButtonGroup -@using Masa.Mc.Domain.Shared.WebsiteMessages -@using Masa.Mc.Web.Admin.Components.Markdown -@using Masa.Mc.Web.Admin.Components.RichText -@using Masa.Mc.Domain.Shared.Subjects -@using Masa.Mc.Contracts.Admin.Dtos.Subjects -@using Masa.Mc.Web.Admin.Components.TextField -@using Masa.Stack.Components.Layouts -@using Microsoft.AspNetCore.Components.Rendering -@using Masa.Stack.Components.Models -@using Masa.Mc.Web.Admin.Components.Chip -@using Masa.Mc.Web.Admin.Components.Lists -@using Masa.Mc.Web.Admin.Components.Modules.MessageRecords -@using Masa.Mc.Web.Admin.Components.Upload -@using Masa.Mc.Web.Admin.Components.Group -@using System.Net.Http -@using System.Net.Http.Json -@using Microsoft.AspNetCore.Components.Forms -@using Microsoft.AspNetCore.Components.Web.Virtualization -@using Microsoft.JSInterop -@using static Masa.Stack.Components.JsInitVariables -@using Masa.Mc.Web.Admin.Components.GenericColumnRender -@using Masa.Mc.Web.Admin.Components.Default -@using Masa.Contrib.StackSdks.Caller; -@using Masa.Stack.Components.Shared.IntegrationComponents -@using Masa.Mc.Web.Admin.Consts; -@using Masa.Mc.Data; -@using Masa.Mc.Infrastructure.ObjectExtending; \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/css/masa-blazor-pro.css b/src/Web/Masa.Mc.Web.Admin/wwwroot/css/masa-blazor-pro.css deleted file mode 100644 index c482193f..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/css/masa-blazor-pro.css +++ /dev/null @@ -1,575 +0,0 @@ -html { - font-size: 16px; -} - -/*scrollbar*/ -::-webkit-scrollbar-track { - border-radius: 15px; - margin: 5px 0; -} - -::-webkit-scrollbar { - width: 5px; - height: 5px; - margin: 5px 0; -} - -::-webkit-scrollbar-thumb { - margin: 5px 0; - border-radius: 15px; - background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0.44, rgb(170 168 168)), color-stop(0.72, rgb(170 168 168)), color-stop(0.86, rgb(170 168 168))); -} - -.border-b-solid { - /* 分割线/下 */ - box-shadow: inset 0px -1px 0px #F0F3FA !important; -} - -.block-center { - /*flex 布局*/ - display: flex; - /*实现垂直居中*/ - align-items: center; -} - -.block-between { - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; -} - -/*组件样å¼å…¨å±€ä¿®æ”¹start*/ -.m-radio i { - font-size: 21px !important; -} - -.m-input__slot { - margin-bottom: 0px !important; -} - -.m-messages { - min-height: 0px !important; -} - -.m-navigation-drawer__border { - width: 0 -} - -.m-card { - box-shadow: 0px 0px 0px 0px rgb(0 0 0 / 20%), 0px 0px 0px 0px rgb(0 0 0 / 14%), 0px 0px 0px 0px rgb(0 0 0 / 12%) !important; - border-radius: 20px; -} - - .m-card.line { - border-radius: 10px !important; - } - -.m-card__text { - padding: 16px 24px; - height: 100%; -} - -.m-input .m-input__icon .mdi-menu-down { - color: #A3AED0; -} - -.m-input .m-label { - /* BUTTON-按钮 */ - font-family: Roboto !important; - font-style: normal !important; - font-weight: 500 !important; - font-size: 0.875rem !important; - /* line-height: 1rem !important;*/ - /* default color */ - color: #7681AB; -} - -.m-input--checkbox .mdi-checkbox-blank-outline { - color: #A3AED0 !important; - caret-color: #A3AED0 !important; -} - -.theme--light .m-input--is-disabled .mdi-checkbox-blank-outline { - color: #E9EDF7 !important; - caret-color: #E9EDF7 !important; -} - -.theme--light .m-input--is-disabled .mdi-checkbox-marked { - color: #E9EDF7 !important; - caret-color: #E9EDF7 !important; -} - -.m-input--checkbox .m-input--selection-controls__ripple:before { - content: none; -} - -.m-input--selection-controls__input:hover .mdi-checkbox-blank-outline { - color: #4318FF !important; - caret-color: #4318FF !important; -} - -.m-radio .mdi-radiobox-blank { - color: #A3AED0 !important; - caret-color: #A3AED0 !important; -} - - -.table-header-fill .m-data-table-header tr { - background: #F6F8FD; -} - -.table-border-none td, th { - border-bottom: 0px !important; - box-shadow: none; -} - -.table-border-solid td, th { - border-bottom: 0 !important; - box-shadow: none; -} - -.primaryText .primaryText { - color: #4318FF !important; - caret-color: #4318FF !important; -} - -.m-pagination__navigation, .m-pagination__item { - box-shadow: 0px 0px 0px 0px rgb(0 0 0 / 20%), 0px 0px 0px 0px rgb(0 0 0 / 14%), 0px 0px 0px 0px rgb(0 0 0 / 12%) !important; -} - -.m-btn--is-elevated { - box-shadow: none !important; -} - -.hide-shadow { - box-shadow: none !important; - border: none; -} - -/* pagetabs */ - -.m-page-tabs .m-slide-group__prev.m-slide-group__prev--disabled { - flex: none !important; - min-width: 0px !important; -} - -/* pagetabs */ -/*组件样å¼å…¨å±€ä¿®æ”¹end*/ -/*shop*/ -.ml300 { - margin-left: 300px; -} - -.commodity:hover { - height: calc(100% + 10px); -} - - .commodity:hover .content { - transition-property: margin-top; - transition-duration: 0.5s; - box-shadow: 0px 18px 40px rgba(112, 144, 176, 0.12) !important; - margin-top: -4px; - } - -.order:hover { - background-color: #6946FF !important; -} - - .order:hover .white-order { - color: #FFFFFF !important; - caret-color: #FFFFFF !important; - } - -.favorite:hover { - background: #F6F8FD !important; -} -/*shop*/ - -.coupons.m-text-field > .m-input__control > .m-input__slot:before { - border-color: transparent; - border-style: hidden; -} - -.coupons.m-text-field > .m-input__control > .m-input__slot:after { - border-color: transparent; - border-style: hidden; -} - -.coupons .m-input__control .m-text-field__slot input::-webkit-input-placeholder { - font-family: Roboto !important; - font-style: normal !important; - font-weight: bold !important; - font-size: 1rem !important; - line-height: 1.1875rem !important; - letter-spacing: 0.009375rem !important; - color: #323D6F !important; -} - -.m-text-field.m-input--dense:not(.m-text-field--outlined) .m-text-field__prefix, .m-text-field.m-input--dense:not(.m-text-field--outlined) .m-text-field__suffix, .m-text-field.m-input--dense:not(.m-text-field--outlined) input { - padding-top: 0; -} - -.max-height { - height: 100% !important; -} - -.max-width { - width: 100% !important; -} - -.full-width { - width: 100% !important; -} - -.full-height { - height: 100% !important; -} - -.hide { - display: none; -} - -.border-right-solid { - border-right: 1px solid #ebe9f1; -} - -.border-left-solid { - border-left: 1px solid #ebe9f1; -} - -.congratulation-medal { - position: absolute; - top: 0; - right: 37px; -} - -.a { - color: #7367f0 !important; - text-decoration: none; -} - -.border-top-solid { - border-top: 1px solid #d8d6de; -} - -.border-solid { - border: 1px solid #d8d6de; -} - -.card-text { - line-height: 1.5rem; - box-sizing: border-box; - margin-block-start: 1em; - margin-block-end: 1em; - margin-inline-start: 0px; - margin-inline-end: 0px; -} - -.pro-nav > .m-tabs-bar { - background-color: transparent !important; -} - -.pro-nav .m-tab:before { - background-color: transparent; -} - -.m-btn { - text-transform: none !important; -} - -.list-unstyled { - list-style: none; -} - -.vertical-center { - display: flex; - -webkit-box-pack: center; - justify-content: center; - -webkit-box-align: center; - align-items: center; -} - -.linear-gradient-purple { - background: linear-gradient(118deg,#7367f0,rgba(115,103,240,.7)) -} - -.grey-bg { - background-color: #f8f8f8; -} - -.hover-pointer { - cursor: pointer; -} - -.justify-text-align { - text-align: justify !important; -} - -.relate-group .m-icon { - font-size: 40px; -} - -.relate-group .m-slide-group__next { - margin-left: 10px; -} - -.pointer-events-none { - pointer-events: none; -} - -.btn .m-label { - color: #323D6F; - font-family: Roboto; - font-style: normal; - font-weight: 500; - font-size: 14px; - line-height: 16px; -} - -.mtab-tab-linear-primary { - background: linear-gradient(270deg, #4318FF 5.56%, rgba(67, 24, 255, 0) 100%); -} - -.mtab-tab-linear-neutral { - background: linear-gradient(270deg, #E9EDF7 0%, rgba(233, 237, 247, 0) 100%); -} - -.mtab-tab-line { - align-self: stretch; - margin: 10px 0px; - width: 87px; - height: 6px; - border-radius: 60px; -} - -.mtab-tab-indicator { - margin-top: 3px; - margin-left: -1px; - align-self: stretch; - width: 22px; - height: 22px; -} - -.mtab-tab-indicator-primary { - border: 4px solid #4318FF; - box-sizing: border-box; -} - -.mtab-tab-indicator-neutral { - background: #F0F3FA; - border: 4px solid #A3AED0; - box-sizing: border-box; -} - -.mtab-tab-title { - position: absolute; - top: 29px; - font-family: Roboto; - font-style: normal; - font-weight: 500; - font-size: 14px; - line-height: 16px; - color: #1B2559; -} - -.auto-width { - width: auto; - margin: 0px 8px; -} - -.hidden-webkit-scrollbar::-webkit-scrollbar { - display: none; -} - -.hidden-webkit-scrollbar { - -ms-overflow-style: none; /* for Internet Explorer, Edge */ - overflow-y: scroll; -} - -.neutral-lighten-1--text .m-label { - color: #323D6F !important; -} - -.neutral-lighten-4--text .m-label { - color: #A3AED0 !important; -} - -.theme--light.m-text-field--outlined.neutral-lighten-4--text > .m-input__control > .m-input__slot fieldset { - color: #A3AED0 !important; -} - -.task-search.m-text-field > .m-input__control > .m-input__slot:before, .m-text-field > .m-input__control > .m-input__slot:after { - width: 0 !important; -} - -.task-search.m-text-field > .m-input__control > .m-input__slot:before, .m-text-field > .m-input__control > .m-input__slot:after { - width: 0 !important; -} - -.hide-timeline-before.m-timeline:before { - content: none; -} - -.pro-timeline-before.m-timeline:before { - background-color: #E9EDF7 !important; -} - - -.divider-align-start .m-timeline-item__divider { - align-items: start; - margin-top: 8px; -} - -td.text-center .m-input--checkbox .m-input__slot { - justify-content: center !important; -} - -.m-divider { - border-color: #E9EDF7 !important; -} - -.m-application .elevation-6 { - box-shadow: 0 18px 40px 0 rgb(112 144 176 / 12%) !important; -} - -.task-datepicker { - border-radius: 0px !important; -} - -input::-webkit-input-placeholder { - color: #7681AB !important; - font-size: 12px !important; -} - -.m-data-table-header__icon { - position: absolute !important; -} - -.user .m-data-table-header__icon { - margin-top: 1px; -} - -.neutral-lighten-icon .m-icon { - color: #A3AED0 !important; -} - -.m-timeline-flat .m-timeline-item__dot { - box-shadow: none; -} - -.chip-text { - font-style: normal !important; - font-weight: bold !important; -} - -.m-application .remover-ripple a { - color: #4318FF !important; -} - -.remover-ripple .m-list-item:before { - content: none !important; -} - -.remover-ripple .m-ripple__container { - opacity: 0 !important; -} - -.remover-ripple .m-list-item:hover .m-list-item__title { - color: #4318FF !important; -} - -.remover-ripple-with-icon .m-list-item:hover .m-icon { - color: inherit !important; -} - -.cyan { - background-color: #37A7FF !important; -} - -.cyan--text { - color: #37A7FF !important; -} - -.cyan-light { - background-color: #EBF6FF; -} - -.theme--light.m-icon { - color: #7681AB; -} - -.invoice-list-avatar { - width: 32px; - height: 32px; - font-size: .857rem; - font-weight: 600; -} - -.pagetabs .m-item-group.m-slide-group.m-tabs-bar { - margin-top: 4px; -} - -.m-page-tabs .m-page_tab { - background-color: #FFF; - font-family: Roboto; - font-style: normal; - font-weight: bold; - font-size: 14px; - line-height: 16px; - letter-spacing: 0.1px; - /* text/3-1æ¬¡è¦ */ - color: #A3AED0 !important; - border-top-left-radius: 8px !important; - border-top-right-radius: 8px !important; -} - -.m-page_tab .m-icon { - color: #A3AED0 !important; - font-size: 16px !important; -} - -.m-page_tab_active { - background-color: #F0F3FA !important; - font-family: Roboto; - font-style: normal; - font-weight: bold; - font-size: 14px; - line-height: 16px; - letter-spacing: 0.1px; - /* text/1-1强调 */ - color: #1B2559 !important; -} - - .m-page_tab_active > .m-icon { - color: #1B2559 !important; - } - -.m-page-tabs > .m-tabs-bar { - border-bottom-left-radius: 20px !important; - border-bottom-right-radius: 20px !important; - height: 36px; - padding-left: 16px; -} - -.m-page-tabs .m-tab:before { - content: none !important; -} - -.m-page-tabs .m-tab:hover { - background-color: #F6F8FD; - color: #485585 !important; -} - - .m-page-tabs .m-tab:hover > .m-icon { - color: #485585 !important; - } - -.m-app-bar.rounded-b-4 > .m-toolbar__content { - border-bottom-left-radius: 20px !important; - border-bottom-right-radius: 20px !important; -} - -.m-dialog--drawer .m-card { - border-radius: 0; -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/css/mc-admin.css b/src/Web/Masa.Mc.Web.Admin/wwwroot/css/mc-admin.css deleted file mode 100644 index 132fa913..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/css/mc-admin.css +++ /dev/null @@ -1,470 +0,0 @@ -.rounded-2 { - border-radius: 10px !important; -} - -.rounded-4 { - border-radius: 20px !important; -} - -.button { - min-width: 40px; - min-height: 40px; - border: 1px solid #F0F3FA; - box-sizing: border-box; - border-radius: 10px; - cursor: pointer; -} - -.text-btn { - /* BUTTON-按钮 */ - font-family: Roboto !important; - font-style: normal !important; - font-weight: 400 !important; - font-size: 0.875rem !important; - line-height: 1.25rem !important; - /* default color */ - color: #A3AED0 !important; -} - -.m-input.mx-auto .m-text-field__slot { - padding-bottom: 2px; -} - - .m-input.mx-auto .m-text-field__slot input { - text-align: center; - } - -.m-input.mx-auto .m-input__slot::before { - border-color: #E2E7F4 !important; -} - -.m-input.mx-auto .m-text-field__slot input::placeholder { - text-align: center; - color: #A3AED0 !important; - font-family: Roboto !important; - font-size: 24px !important; - font-style: normal !important; - font-weight: 700 !important; - line-height: normal !important; - letter-spacing: 0em !important; -} - -.m-data-table.table-space-v-4 > .m-data-table__wrapper > table { - border-spacing: 0px 16px !important; -} - -.m-data-table.table-space-v-2 > .m-data-table__wrapper > table { - border-spacing: 0px 8px !important; -} - -.justify-center.m-input--checkbox > .m-input__control { - flex-grow: 0 !important; - width: auto !important; -} - -.elevation-tab { - background-color: #F0F3FA !important; - padding: 3px; -} - -.m-item-group.elevation-tab .m-btn.m-btn--has-bg.m-btn--active { - background-color: white !important; - font-family: 'Roboto'; - font-style: normal; - font-weight: 700; - font-size: 14px; - line-height: 16px; - display: flex; - align-items: center; - text-align: center; - letter-spacing: 0.1px; - /* text/1-2强调 */ - - color: #323D6F; -} - -.elevation-tab .theme--light.m-btn--active:hover::before, .elevation-tab .theme--light.m-btn--active::before { - opacity: 0; -} - -.m-item-group.elevation-tab .m-btn.m-btn--has-bg { - background-color: #F0F3FA !important; - font-family: 'Roboto'; - font-style: normal; - font-weight: 500; - font-size: 14px; - line-height: 21px; - /* identical to box height, or 150% */ - - display: flex; - align-items: center; - text-align: center; - /* text/2-2正文 */ - - color: #7681AB; -} - -.remover-hover.m-list-item:hover::before { - opacity: 0 !important; -} - -.max-full-height { - max-height: 100% !important; -} - -.m-stepper__content.full-height .m-stepper__wrapper { - height: 100% !important; -} - -.m-window.m-item-group.flex-grow-1 .m-window__container { - height: 100% !important; -} - -.full-height.d-flex.flex-column .m-data-table__wrapper { - flex-grow: 1 !important; -} - -.m-data-table .m-data-table__wrapper { - border-radius: 20px; -} - -.m-text-field.m-text-field--solo.elevation-0:not(.m-text-field--solo-flat) > .m-input__control > .m-input__slot { - box-shadow: none; -} - -.flex-column { - display: flex; - flex-direction: column; - word-break: break-all; -} - -.flex-height-auto { - flex: auto; -} - -.overflow-y { - overflow-y: scroll; - overflow-x: hidden; -} - -.sheet-dialog { - padding-left: 80px; - padding-right: 80px; - padding-bottom: 24px; - padding-top: 24px; - height: 100%; - width: 100%; - position: absolute; -} - -.m-stepper__content.full-height .m-stepper__wrapper { - height: 100% !important; -} - -.m-window.m-item-group.flex-grow-1 .m-window__container { - height: 100% !important; -} - -.full-height.d-flex.flex-column .m-data-table__wrapper { - flex-grow: 1 !important; -} - -.m-text-field.m-text-field--solo.elevation-0:not(.m-text-field--solo-flat) > .m-input__control > .m-input__slot { - box-shadow: none; -} - -.line-clamp-2 { - word-break: break-all; - text-overflow: ellipsis; - display: -webkit-box; - -webkit-box-orient: vertical; - -webkit-line-clamp: 2; - overflow: hidden; -} - -.m-text-field.m-text-field--solo:not(.m-text-field--solo-flat) > .m-input__control > .m-input__slot { - box-shadow: initial; -} - -.m-data-table > .m-data-table__wrapper > table > thead > tr > th, .m-data-table > .m-data-table__wrapper > table > tbody > tr > td { - padding: 0 24px !important; -} - -.error--text { - color: #FF5252 !important; - caret-color: #FF5252 !important; -} - -.btn-form { - width: 140px !important; - height: 56px !important; - padding: 4px 58px !important; - border-radius: 12px !important; - font-family: 'Roboto'; - font-style: normal; - font-weight: 500; - font-size: 16px; - line-height: 28px; -} - -.btn-form-full { - width: 100% !important; - height: 56px !important; - padding: 4px 58px !important; - border-radius: 12px !important; -} - -.btn-form-rounded { - height: 40px !important; - padding: 8px 14px !important; - border-radius: 99px !important; -} - -/* fill/线 */ -.btn-fill-line { - border: 1px solid #E2E7F4 !important; - border-radius: 8px !important; -} - -/* å°æŒ‰é’®/主è¦/默认 */ -.small-btn { - min-width: 100px !important; - height: 40px !important; - padding: 4px !important; -} - -.linear--text { - color: #A18BFF !important; -} - -.gradient--text { - color: #4318FF !important; -} - -.search-panel { - height: 40px !important; - position: relative !important; -} - -.rounded-5 { - border-radius: 20px !important; -} - -.m-application .overflow-x-visible { - overflow-x: visible !important; -} - -.m-application .overflow-y-visible { - overflow-y: visible !important; -} - -.border-bottom-none { - border-bottom: none !important; -} - -.masa-stack-components .page-select { - margin-top: 2px; -} - -.masa .warning-disabled--text { - color: #FBACA3 !important; -} - -.m-alert__wrapper { - width: 100%; -} - -.m-input--selection-controls__ripple:before { - opacity: 0; -} - -::-webkit-scrollbar { - width: 8px; - height: 8px; - background-color: #F6F8FD; -} - -/*定义滚动æ¡è½¨é“ - -内阴影+圆角*/ - -::-webkit-scrollbar-track { - border-radius: 4px; - background-color: #F6F8FD; -} - -/*å®šä¹‰æ»‘å— - -内阴影+圆角*/ - -::-webkit-scrollbar-thumb { - border-radius: 10px; - background-color: #A3AED0; -} - -.m-text-field__details { - font-weight: 400; - font-size: 10px; - line-height: 15px; - color: #A3AED0; -} - -/*.m-stepper__wrapper { - overflow: visible; -}*/ - -.m-dialog { - border-radius: 20px !important; -} - - .m-dialog .m-sheet.m-card { - border-radius: 20px !important; - } - -.vertical-divider { - width: 0px; - height: 8px; - border: 1px solid #E2E7F4; - flex: none; - order: 1; - flex-grow: 0; - margin-left: 8px; - margin-right: 8px; -} - -.m-card { - box-shadow: 0px 0px 0px 0px rgb(0 0 0 / 20%), 0px 0px 0px 0px rgb(0 0 0 / 14%), 0px 0px 0px 0px rgb(0 0 0 / 12%) !important; - border-radius: 20px !important; -} - -.row-box > .col { - padding-top: 18px; - padding-bottom: 18px; -} - -.outlined-box-medium { - border: 1px solid #E2E7F4; - border-radius: 8px; - height: 48px; - padding-left: 6px; -} - -.m-input--dense-40 .m-input__slot { - height: auto !important; - min-height: 40px !important; -} - -.tag { - border-radius: 18px; - display: inline-flex; - justify-content: center; - align-items: center; - padding: 8px; - min-width: 56px; - border-radius: 18px; - height: 27px; -} - -.table-boder-head thead th { - height: 43px !important; - border-bottom: solid 1px #E2E7F4 !important; -} - -.search { - width: 300px; -} - -.m-application .rounded-r-4 { - border-top-right-radius: 16px !important; - border-bottom-right-radius: 16px !important; -} -.m-application .rounded-r-10 { - border-top-right-radius: 40px !important; - border-bottom-right-radius: 40px !important; -} - -.flex-none { - flex: none; -} - - -.grid-card { - display: grid; - grid-template-columns: repeat(4, 1fr); - gap: 16px; - height: 0; -} - -.grid-card .item { - height: 0; - padding-bottom: 100%; - position: relative; -} - -.grid-card .item .m-card { - width: 100%; - height: 100%; - position: absolute; -} - -.masa .h6 { - font-size: 1.25rem !important; - font-weight: 700 !important; - line-height: 1.875rem !important; - letter-spacing: 0.01em !important; -} -.masa .h8 { - font-size: 1rem !important; - font-weight: 700 !important; - line-height: 1.5rem !important; - letter-spacing: 0.03125em !important; -} - -.m-input__append-outer { - margin-top: auto !important; - margin-bottom: auto !important; -} - -.sheetDialogPadding { - padding-left: 228px; - padding-right: 228px; - padding-bottom: 48px; - padding-top: 48px; - height: 100%; - width: 100%; - position: absolute; -} - - .sheetDialogPadding .m-stepper__content { - padding-left: 0 !important; - padding-right: 0 !important; - padding-bottom: 0 !important; - padding-top: 0 !important; - } - -.grid { - display: grid; - gap: 24px; - width: 100%; - justify-content: center; -} - - .grid .item { - height: 0; - padding-bottom: 100%; - position: relative; - } - - .grid .item .m-card { - width: 100%; - height: 100%; - position: absolute; - } - -.grid-2 { - grid-template-columns: repeat(2, 33.3%); -} - -.form-content > * { - margin-top: 36px !important; -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/i18n/en-US.json b/src/Web/Masa.Mc.Web.Admin/wwwroot/i18n/en-US.json deleted file mode 100644 index 94f12f93..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/i18n/en-US.json +++ /dev/null @@ -1,291 +0,0 @@ -{ - "$Text": "English", - "$DateTimeFormat": "MM/dd/yyyy HH:mm:ss", - "$DateFormat": "MM/dd/yyyy", - "$MonthDayFormat": "MM/dd", - "$TimeFormat": "HH:mm:ss", - "Unit.Bar": "Bar", - "DeletionConfirmationMessage": "Are you sure delete {0}?", - "BasicInformation": "Basic Information", - "DetailInformation": "Detail Information", - "OperationConfirmation": "Operation confirmation", - "NextStep": "Next step", - "PreviousStep": "Previous step", - "DateRange": "Date range", - "Total": "Total", - "Item": "Item", - "All": "All", - "RowsPerPage": "Rows per page", - "Sms": "Sms", - "Email": "Email", - "WebsiteMessage": "WebsiteMessage", - "Permission.Create": "Add", - "Permission.Edit": "Edit", - "Permission.Delete": "Delete", - "EditIn": "Edit in", - "ExternalMember": "External member", - "Permission.ChannelManagement": "Channel management", - "Permission.CreateChannel": "Add channel", - "Permission.EditChannel": "Edit channel", - "SelectChannelType": "Select channel type", - "ChannelConfiguration": "Channel configuration", - "EmailChannelOptions.UserName": "User name", - "EmailChannelOptions.Password": "Password", - "EmailChannelOptions.Smtp": "Smtp", - "EmailChannelOptions.Ssl": "Ssl", - "EmailChannelOptions.Port": "Port", - "EmailChannelOptions.FromNickName": "From nick name", - "WebsiteMessageChannelOptions.Environment": "Environment", - "SmsChannelOptions.AccessKeyId": "Access Key ID", - "SmsChannelOptions.AccessKeySecret": "Access Key Secret", - "WeixinWorkChannelOptions.CorpId": "CorpId", - "WeixinWorkChannelOptions.CorpSecret": "CorpSecret", - "WeixinWorkChannelOptions.AgentId": "AgentId", - "DisplayName.Channel": "Channel", - "DisplayName.ChannelDisplayName": "name", - "DisplayName.ChannelCode": "ID", - "DisplayName.ChannelType": "Channel type", - "DisplayName.ChannelDescription": "Channel description", - "Description.Channel.Type.Required": "Please select the channel type first", - "ChannelCreateMessage": "Add channel data success.", - "ChannelEditMessage": "Edit channel data success.", - "ChannelDeleteMessage": "Delete channel data success.", - "Permission.MessageTemplateManagement": "Channel messageTemplate", - "Permission.CreateMessageTemplate": "Add messageTemplate", - "Permission.EditMessageTemplate": "Edit messageTemplate", - "DisplayName.MessageTemplate": "Message template", - "DisplayName.MessageTemplateId": "Template ID", - "DisplayName.MessageTemplateChannelDisplayName": "Channel", - "DisplayName.MessageTemplateTemplateType": "Type", - "DisplayName.MessageTemplateDisplayName": "Title", - "DisplayName.MessageTemplateTitle": "Title", - "DisplayName.MessageTemplateCode": "ID", - "DisplayName.MessageTemplateContent": "Content", - "DisplayName.MessageTemplateExample": "Example", - "DisplayName.MessageTemplateSign": "Sign", - "DisplayName.MessageTemplateModificationTime": "Recent updates", - "DisplayName.MessageTemplateStatus": "Status", - "DisplayName.MessageTemplateAuditStatus": "Audit status", - "DisplayName.MessageTemplateTemplateId": "Template ID", - "DisplayName.MessageTemplateIsJump": "Is jump", - "DisplayName.MessageTemplateJumpUrl": "Jump url", - "DisplayName.MessageTemplatePerDayLimit": "Day limit", - "DisplayName.MessageTemplateStatus.Normal": "Normal", - "DisplayName.MessageTemplateStatus.Invalid": "Invalid", - "DisplayName.MessageTemplateAuditStatus.WaitAudit": "Wait audit", - "DisplayName.MessageTemplateAuditStatus.Adopt": "Adopt", - "DisplayName.MessageTemplateAuditStatus.Fail": "Fail", - "Permission.AddMessageTemplateItem": "Add variable", - "Permission.EditMessageTemplateItem": "Edit variable", - "MessageTemplateCreateMessage": "Add messageTemplate success.", - "MessageTemplateEditMessage": "Edit messageTemplate success.", - "MessageTemplateDeleteMessage": "Delete messageTemplate success.", - "Description.MessageTemplate.ChannelId.Required": "Please select a channel", - "Description.MessageTemplate.TemplateId.Required": "Please select templateID", - "Description.MessageTemplate.Sign.Required": "Please enter your signature", - "Description.MessageTemplate.PerDayLimit.Tips": "This module can send the same user at most every day", - "DisplayName.MessageTemplateItem": "Template variable", - "DisplayName.MessageTemplateItemCode": "Variable", - "DisplayName.MessageTemplateItemValue": "Value", - "DisplayName.MessageTemplateItemMappingCode": "Mapping variable", - "DisplayName.MessageTemplateItemDisplayText": "Remarks", - "DisplayName.SmsTemplateType.VerificationCode": "Verification code", - "DisplayName.SmsTemplateType.Notification": "Notification", - "DisplayName.SmsTemplateType.Promotion": "Promotion", - "DisplayName.SmsTemplateType.International": "International", - "DisplayName.SmsTemplateType.Digital": "Digital", - "DisplayName.SmsTemplateType.Other": "Other", - "Permission.ReceiverGroupManagement": "Receiver group management", - "Permission.CreateReceiverGroup": "Add receiver group", - "Permission.EditReceiverGroup": "Edit receiver group", - "DisplayName.ReceiverGroup": "Receiver group", - "DisplayName.ReceiverGroupDisplayName": "name", - "DisplayName.ReceiverGroupDescription": "Receiver group description", - "ReceiverGroupCreateMessage": "Add receiver group success.", - "ReceiverGroupEditMessage": "Edit receiver group success.", - "ReceiverGroupDeleteMessage": "Delete receiver group success.", - "Description.ReceiverGroup.SelectUser": "Please select a user", - "Description.ReceiverGroup.AddSelectMember": "Please add / select members", - "ExternalMemberAddMessage": "External user added successfully.", - "Permission.MessageManagement": "Message management", - "Permission.SendMessage": "Send message", - "Permission.MessageRecord": "Message record", - "Permission.SendOrdinaryMessage": "Send ordinary message", - "Permission.SendTemplateMessage": "Send template message", - "Permission.EditTemplateMessage": "Edit template message", - "Permission.EditOrdinaryMessage": "Edit ordinary message", - "Permission.SendMessageTask": "Execute message task", - "Permission.ViewMessageTask": "View message task", - "DisplayName.MessageEntityType.Ordinary": "Ordinary", - "DisplayName.MessageEntityType.Template": "Template", - "DisplayName.MessageTaskDisplayName": "Message title", - "DisplayName.MessageTaskEntityType": "Message type", - "DisplayName.MessageTaskSendTime": "Send time", - "DisplayName.MessageTaskReceiver": "Receiver", - "DisplayName.MessageTaskSendingRule": "SendingRule", - "DisplayName.ReceiverType": "Receiver type", - "DisplayName.ReceiverType.Assign": "Assign", - "DisplayName.ReceiverType.Broadcast": "Broadcast", - "MessageTaskCreateMessage": "Add message task success.", - "MessageTaskEditMessage": "Edit message task success.", - "MessageTaskDeleteMessage": "Delete message task success.", - "DisplayName.MessageTaskList": "Message task list", - "DisplayName.MessageInfoTitle": "Message info title", - "DisplayName.MessageInfoContent": "Message info content", - "DisplayName.MessageTaskIsEnabled": "Status", - "DisplayName.MessageTaskTimeType": "Time type", - "DisplayName.MessageTaskTimeType.ModificationTime": "ModificationTime", - "DisplayName.MessageTaskTimeType.SendTime": "SendTime", - "DisplayName.VariableValueTransfer": "Variable value transfer", - "DisplayName.SendingRule.Timeout": "Timeout", - "DisplayName.SendingRule.RetryInterval": "RetryInterval", - "DisplayName.SendingRule.RetryCount": "RetryCount", - "DisplayName.SendingRule.IsTiming": "IsTiming", - "DisplayName.MessageTaskHistory": "Message task history", - "DisplayName.MessageTaskHistoryNo": "Task history no", - "DisplayName.MessageTaskHistoryStatus": "Message task status", - "DisplayName.MessageTaskHistoryStatus.WaitSend": "WaitSend", - "DisplayName.MessageTaskHistoryStatus.Sending": "Sending", - "DisplayName.MessageTaskHistoryStatus.Completed": "Completed", - "DisplayName.MessageTaskHistoryStatus.Withdrawn": "Withdrawn", - "DisplayName.MessageTaskHistoryStatus.Success": "Success", - "DisplayName.MessageTaskHistoryStatus.Fail": "Fail", - "DisplayName.MessageTaskHistoryStatus.PartialFailure": "Partial failure", - "DisplayName.MessageTaskStatus": "Send status", - "DisplayName.MessageTaskStatus.WaitSend": "Wait send", - "DisplayName.MessageTaskStatus.Sending": "Sending", - "DisplayName.MessageTaskStatus.Completed": "Completed", - "DisplayName.MessageTaskStatus.Withdrawn": "Withdrawn", - "DisplayName.MessageTaskStatus.Success": "Success", - "DisplayName.MessageTaskStatus.Fail": "Fail", - "DisplayName.MessageTaskStatus.PartialFailure": "Partial failure", - "Permission.TestMessageTask": "Test message task", - "DisplayName.MessageRecordSendTime": "Send time", - "DisplayName.MessageRecordExpectSendTime": "Expect send time", - "DisplayName.MessageRecordReceiptTime": "Receipt time", - "DisplayName.MessageRecordSuccess": "Status", - "DisplayName.MessageRecordFailureReason": "Failure reason", - "DisplayName.MessageRecordSuccess.True": "Sent successfully", - "DisplayName.MessageRecordSuccess.False": "Fail in send", - "DisplayName.MessageRecordTimeTypes": "Time type", - "DisplayName.MessageRecordTimeTypes.ExpectSendTime": "Expect send time", - "DisplayName.MessageRecordTimeTypes.SendTime": "Send time", - "DisplayName.MessageRecordUserId": "Addressee", - "DisplayName.MessageRecordMessageTaskHistoryNo": "Message task history no", - "DisplayName.MessageRecordDisplayName": "Message title", - "Description.MessageReceiversImport.Tips": "A total of {0} pieces of data were uploaded.", - "Description.MessageReceiversImport.ErrorMsg": "Upload failed, please check the file data and upload again", - "Description.MessageReceiversUpload.Placeholder": "Please upload the file", - "Description.MessageReceiversUpload.Tips": "Please upload CSV format file", - "Description.MessageReceiversDownload.Name": "Template file csv", - "Description.MessageReceiversDownload.Tips": "Download", - "Description.MessageReceiversUpload.EncodingTips": "Please upload the UTF-8 encoded CSV file", - "DisplayName.SubjectTypes.User": "User", - "DisplayName.SubjectTypes.Department": "Department", - "DisplayName.SubjectTypes.Role": "Role", - "DisplayName.SubjectTypes.Team": "Team", - "DisplayName.MessageTaskReceiverTypes.User": "User", - "DisplayName.MessageTaskReceiverTypes.Organization": "Organization", - "DisplayName.MessageTaskReceiverTypes.Role": "Role", - "DisplayName.MessageTaskReceiverTypes.Team": "Team", - "DisplayName.MessageTaskReceiverTypes.Group": "Group", - "DisplayName.Color.Lable": "Select color", - "Success": "Success", - "Failure": "Failure", - "View": "View", - "UploadComplete": "Upload complete", - "UploadFile": "Upload file", - "Permission.ViewMessageRecord": "View message record", - "ReceiversCount": "Expect {0} people", - "DisplayName.SendingRule.CronExpression": "Cron expression", - "DisplayName.SendingRule.IsCustom": "Is custom", - "DisplayName.SendingRule.SendingCount": "Sending count", - "DisplayName.SendingRule.SendingCount.Tips": "0 is unlimited", - "DisplayName.MessageTaskDetail.ReceiverType": "Type", - "ChannelOptions.Tips": "Please check the filled data carefully. If you fill in the wrong data, the message will fail to be sent", - "SelectTemplate": "Select template", - "CronExpressionInvalid": "Cron expression is invalid", - "CronExpressionNotHasNextRunTime": "Cannot calculate the next run time from this expression", - "ChannelBlock": { - "Title": "Channel", - "SchemeTooltip": "Select third-party-idp as the data source for pushing user IDs", - "SchemeFieldTooltip": "Do not use thridPartyIdentity" - }, - "MessageTaskBlock": { - "Title": "Message task", - "MessageDetails": "Message details" - }, - "MessageRecordBlock": { - "Title": "MessageRecord" - }, - "MessageTemplateBlock": { - "SmsTemplateTitle": "SmsTemplate", - "EmailTemplateTitle": "EmailTemplate", - "WebsiteMessageTitle": "WebsiteMessage", - "AppTitle": "App" - }, - "ReceiverGroupBlock": { - "Title": "ReceiverGroup" - }, - "ChannelDisplayNameRequired": "Please fill in the channel name", - "ChannelDisplayNameChineseLetterNumberSymbol": "Channel name can only be Chinese/letter/number/some special characters", - "ChannelDisplayNameRequiredLength": "The length of channel name can only be between 2 and 50", - "ChannelCodeRequired": "Please fill in the channel ID", - "ChannelCodeLetterNumberSymbol": "Channel ID can only be Chinese/letter/number/some special characters", - "ChannelCodeRequiredLength": "The channel ID length can only be between 2 and 50", - "ChannelTypeRequired": "Please select a channel type", - "ChannelIdRequired": "Please select a channel", - "MessageTemplateRequired": "Please select a message template", - "MessageTypeRequired": "Please select a message type", - "ReceiverTypeRequired": "Please select the receiving type", - "SelectReceiverTypeRequired": "Please select the recipient selection method", - "ReceiversRequired": "Please select a recipient", - "SignRequired": "Please fill in your signature", - "SignLength": "The signature length can only be between 2 and 50", - "SignChineseLetterNumber": "Signature can only be Chinese/letter/number/some special characters", - "TitleRequired": "Please fill in the title", - "TitleLength": "The title length can only be between 2 and 50", - "ContentRequired": "Please fill in the content", - "JumpUrlRequired": "Please fill in the jump address", - "DisplayNameRequired": "Please fill in the name", - "DisplayNameLength": "Name length can only be between 2 and 50", - "DisplayNameChineseLetterNumber": "Name can only be Chinese/letter/number/some special characters", - "CronExpressionRequired": "Please fill in Cron expression", - "MessageTemplateDisplayNameRequired": "Please fill in the template name", - "MessageTemplateDisplayNameLength": "Template name length can only be between 2 and 50", - "MessageTemplateCodeRequired": "Please fill in the template ID", - "MessageTemplateCodeLetterNumberSymbol": "Template ID can only be letters/numbers/some special characters", - "MessageTemplateCodeLength": "Template ID length can only be between 2 and 50", - "MessageTemplateStatusRequired": "Please select a template type", - "MessageTemplatePerDayLimitBetween": "Daily sending limit can only be between 1 and 500", - "MessageTemplateTemplateIdRequired": "Please select a template", - "MessageTemplateItemsCannotRepeated": "Template variables cannot be repeated", - "ReceiverGroupItemsRequired": "Please select a recipient", - "PhoneNumberRequired": "Please fill in your mobile number", - "EmailRequired": "Please fill in the email address", - "EmailInvalid": "Please fill in the correct email address", - "EmailChannelUserNameRequired": "Please fill in the email account", - "EmailChannelPasswordRequired": "Please fill in the email password", - "EmailChannelSmtpRequired": "Please fill in the email Smtp", - "SmsChannelAccessKeyIdRequired": "Please fill in AccessKeyID", - "SmsChannelAccessKeySecretRequired": "Please fill in AccessKeySecret", - "UploadFileSizeExceeded": "Upload file size exceeds limit", - "UploadFileEmpty": "Please select file", - "TaskWithdrawnConfirmationMessage": "Are you sure withdrawn task {0}?", - "DisplayName.AppChannelProviders": "Provider", - "DisplayName.AppChannelProviders.GeTui": "GeTui", - "DisplayName.AppChannelProviders.JPush": "JPush", - "UserDisplayNameRequired": "Please fill in the displayName", - "UserDisplayNameLength": "The length of displayName can only be between 2 and 50", - "UserDisplayNameChineseLetterNumber": "DisplayName can only be Chinese/letter/number", - "CreateSuccessfulMessage": "Create {0} successfully", - "EditSuccessfulMessage": "Edit {0} successfully", - "DeleteSuccessfulMessage": "Deleted {0} successfully", - "NotificationMessage": "Notification message", - "InAppMessages": "In app messages", - "InAppMessagesTips": "Generate internal message or not", - "JumpUrlTips": "Internal message forwarding address", - "OptionalConfiguration": "Optional configuration", - "IntentUrl": "Click on the notification to open the specified page", - "IntentUrlTips": "

Open the specified page

There are two ways to open a specified page

1. Fill in the complete package name and activity in the following format:

intent:#Intent;component=com.jiguang.push/com.example.jpushdemo.SettingActivity;end

2. The client activity is configured in the manifest as:

<activity android:name='.MyActivity' android:exported='true'> <intent-filter> <action android:name='android.intent.action.VIEW' /> <category android:name='android.intent.category.DEFAULT' /> <data android:scheme='app' android:host='example' android:path='/MyActivity/' /> </intent-filter> </activity>

The path filled in is:app://example/MyActivity/

" -} diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/i18n/supportedCultures.json b/src/Web/Masa.Mc.Web.Admin/wwwroot/i18n/supportedCultures.json deleted file mode 100644 index bbb1d45d..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/i18n/supportedCultures.json +++ /dev/null @@ -1,6 +0,0 @@ -[ - "zh-CN", - "en-US" -] - - diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/i18n/zh-CN.json b/src/Web/Masa.Mc.Web.Admin/wwwroot/i18n/zh-CN.json deleted file mode 100644 index 0c07cc5f..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/i18n/zh-CN.json +++ /dev/null @@ -1,425 +0,0 @@ -{ - "$DefaultLanguage": "true", - "$Text": "中文简体", - "$DateTimeFormat": "yyyyå¹´MM月ddæ—¥ HH:mm:ss", - "$DateFormat": "yyyyå¹´MM月ddæ—¥", - "$MonthDayFormat": "MM月ddæ—¥", - "$TimeFormat": "HH:mm:ss", - "Unit.Bar": "æ¡", - "Favorite": "æ”¶è—", - "Source": "æ¥æº", - "Search": "æœç´¢", - "Type": "类型", - "Copy": "å¤åˆ¶", - "CreationTime": "创建时间", - "ModificationTime": "修改时间", - "State": "状æ€", - "Enable": "å¯ç”¨", - "IsEnabled": "å¯ç”¨/ç¦ç”¨", - "Description": "æè¿°", - "Explain": "说明", - "Disabled": "ç¦ç”¨", - "Action": "æ“作", - "New": "新建", - "Submit": "æäº¤", - "Save": "ä¿å­˜", - "SaveSend": "ä¿å­˜å¹¶å‘é€", - "Delete": "删除", - "Edit": "编辑", - "Sync": "åŒæ­¥", - "SyncTemplate": "åŒæ­¥æ¨¡æ¿", - "AddChild": "加å­çº§", - "DeletionConfirmationMessage": "确定删除{0}å—", - "Creator": "创建人", - "Modifier": "最近修改人", - "Rows per page": "列/页", - "Male": "ç”·", - "Female": "女", - "NextStep": "下一步", - "PreviousStep": "上一步", - "PCS": "个", - "Preview": "预览", - "Fill in more": "填写更多", - "Avatar": "头åƒ", - "Icon Code": "ICON代ç ", - "Total": "å…±", - "Item": "æ¡", - "All": "全部", - "RowsPerPage": "æ¯é¡µè¡Œæ•°", - "User": "用户", - "Name": "å§“å", - "Avatr": "头åƒ", - "User.DisplayName": "用户昵称", - "PhoneNumber": "手机å·ç ", - "IdCard": "身份è¯å·", - "Account": "è´¦å·", - "UserId": "用户ID", - "Password": "密ç ", - "CompanyName": "å…¬å¸åç§°", - "Address": "地区", - "BasicInformation": "基础信æ¯", - "DetailInformation": "详细信æ¯", - "OperationConfirmation": "æ“作确认", - "DateRange": "日期范围", - "Sms": "短信", - "Email": "邮箱", - "WebsiteMessage": "站内信", - "WeixinWork": "ä¼ä¸šå¾®ä¿¡", - "WeixinWorkWebhook": "ä¼ä¸šå¾®ä¿¡ç¾¤æœºå™¨äºº", - "WaitAudit": "待审核", - "Adopt": "通过", - "Fail": "未通过", - "Normal": "正常", - "Invalid": "失效", - "Permission.Create": "新建", - "Permission.Edit": "编辑", - "Permission.Delete": "删除", - "Team": "团队", - "Role": "角色", - "Organization": "组织架构", - "ExternalMember": "外部æˆå‘˜", - "EditIn": "编辑于", - "AddExternalMember": "新建外部æˆå‘˜", - "ManualSelection": "手动选择", - "BatchUpload": "批é‡ä¸Šä¼ ", - "Second": "ç§’", - "Send": "å‘é€", - "Each": "æ¯", - "Draft": "è‰ç¨¿", - "Initiate": "å¯åЍ", - "Disable": "ç¦ç”¨", - "Withdraw": "撤销", - "Ok": "确定", - "Cancel": "å–æ¶ˆ", - "StartTime": "开始时间", - "EndTime": "ç»“æŸæ—¶é—´", - "OperationSuccessfulMessage": "æ“作æˆåŠŸ.", - "DeletedSuccessfullyMessage": "删除æˆåŠŸ.", - "ChannelManagement": "渠é“管ç†", - "Permission.ChannelManagement": "渠é“管ç†", - "Permission.CreateChannel": "新建渠é“", - "Permission.EditChannel": "编辑渠é“", - "SelectChannelType": "选择渠é“类型", - "ChannelConfiguration": "渠é“é…ç½®", - "EmailChannelOptions.UserName": "邮箱账å·", - "EmailChannelOptions.Password": "密ç ", - "EmailChannelOptions.Smtp": "SMTPæœåС噍", - "EmailChannelOptions.Ssl": "SSL", - "EmailChannelOptions.Port": "端å£", - "EmailChannelOptions.FromNickName": "å‘件人昵称", - "WebsiteMessageChannelOptions.Environment": "环境", - "SmsChannelOptions.AccessKeyId": "AccessKeyID", - "SmsChannelOptions.AccessKeySecret": "AccessKeySecret", - "WeixinWorkChannelOptions.CorpId": "ä¼ä¸šID", - "WeixinWorkChannelOptions.CorpSecret": "应用密钥", - "WeixinWorkChannelOptions.AgentId": "应用ID", - "DisplayName.Channel": "渠é“", - "DisplayName.ChannelDisplayName": "åç§°", - "DisplayName.ChannelCode": "ID", - "DisplayName.ChannelType": "渠é“类型", - "DisplayName.ChannelDescription": "æè¿°", - "DisplayName.Scheme": "第三方平å°", - "DisplayName.SchemeField": "三方用户字段", - "Description.Channel.Type.Required": "选择渠é“类型", - "ChannelCreateMessage": "æ–°å»ºæ¸ é“æ•°æ®æˆåŠŸ.", - "ChannelEditMessage": "ç¼–è¾‘æ¸ é“æ•°æ®æˆåŠŸ.", - "ChannelDeleteMessage": "åˆ é™¤æ¸ é“æ•°æ®æˆåŠŸ.", - "MessageTemplate": "æ¶ˆæ¯æ¨¡æ¿", - "SmsTemplate": "短信模æ¿", - "EmailTemplate": "邮箱模æ¿", - "WebsiteMessageTemplate": "站内信模æ¿", - "Permission.MessageTemplateManagement": "æ¶ˆæ¯æ¨¡æ¿", - "Permission.CreateMessageTemplate": "æ–°å»ºæ¶ˆæ¯æ¨¡æ¿", - "Permission.EditMessageTemplate": "ç¼–è¾‘æ¶ˆæ¯æ¨¡æ¿", - "DisplayName.MessageTemplate": "æ¶ˆæ¯æ¨¡æ¿", - "DisplayName.MessageTemplateId": "模æ¿ID", - "DisplayName.MessageTemplateChannelDisplayName": "渠é“", - "DisplayName.MessageTemplateTemplateType": "模æ¿ç±»åž‹", - "DisplayName.MessageTemplateDisplayName": "模æ¿åç§°", - "DisplayName.MessageTemplateTitle": "æ¨¡æ¿æ ‡é¢˜", - "DisplayName.MessageTemplateCode": "ID", - "DisplayName.MessageTemplateContent": "模æ¿å†…容", - "DisplayName.MessageTemplateExample": "模æ¿ç¤ºä¾‹", - "DisplayName.MessageTemplateSign": "ç­¾å", - "DisplayName.MessageTemplateModificationTime": "修改时间", - "DisplayName.MessageTemplateStatus": "模æ¿çжæ€", - "DisplayName.MessageTemplateAuditStatus": "审核状æ€", - "DisplayName.MessageTemplateTemplateId": "模æ¿ID", - "DisplayName.MessageTemplateIsJump": "是å¦è·³è½¬", - "DisplayName.MessageTemplateJumpUrl": "跳转地å€", - "DisplayName.MessageTemplatePerDayLimit": "æ¯æ—¥å‘é€ä¸Šé™", - "DisplayName.MessageTemplateStatus.Normal": "正常", - "DisplayName.MessageTemplateStatus.Invalid": "失效", - "DisplayName.MessageTemplateAuditStatus.WaitAudit": "待审核", - "DisplayName.MessageTemplateAuditStatus.Adopt": "æˆåŠŸ", - "DisplayName.MessageTemplateAuditStatus.Fail": "未通过审核", - "Permission.AddMessageTemplateItem": "添加å˜é‡", - "Permission.EditMessageTemplateItem": "编辑å˜é‡", - "MessageTemplateCreateMessage": "æ·»åŠ æ¶ˆæ¯æ¨¡æ¿æˆåŠŸ.", - "MessageTemplateEditMessage": "ç¼–è¾‘æ¶ˆæ¯æ¨¡æ¿æˆåŠŸ.", - "MessageTemplateDeleteMessage": "åˆ é™¤æ¶ˆæ¯æ¨¡æ¿æˆåŠŸ.", - "Description.MessageTemplate.ChannelId.Required": "请选择渠é“", - "Description.MessageTemplate.TemplateId.Required": "请选择模æ¿ID", - "Description.MessageTemplate.Sign.Required": "请输入签å", - "Description.MessageTemplate.PerDayLimit.Tips": "æ­¤æ¨¡æ¿æ¯æ—¥ç»™åŒä¸€ç”¨æˆ·æœ€å¤šå‘é€", - "DisplayName.MessageTemplateItem": "å˜é‡å­—å…¸", - "DisplayName.MessageTemplateItemCode": "å˜é‡", - "DisplayName.MessageTemplateItemValue": "值", - "DisplayName.MessageTemplateItemMappingCode": "映射å˜é‡", - "DisplayName.MessageTemplateItemDisplayText": "备注", - "DisplayName.SmsTemplateType.VerificationCode": "验è¯ç ", - "DisplayName.SmsTemplateType.Notification": "短信通知", - "DisplayName.SmsTemplateType.Promotion": "推广短信", - "DisplayName.SmsTemplateType.International": "国际/æ¸¯æ¾³å°æ¶ˆæ¯", - "DisplayName.SmsTemplateType.Digital": "数字短信", - "DisplayName.SmsTemplateType.Other": "å…¶ä»–", - "ReceiverGroup": "消æ¯ç»„", - "Permission.ReceiverGroupManagement": "消æ¯ç»„", - "Permission.CreateReceiverGroup": "新建消æ¯ç»„", - "Permission.EditReceiverGroup": "编辑消æ¯ç»„", - "DisplayName.ReceiverGroup": "消æ¯ç»„", - "DisplayName.ReceiverGroupDisplayName": "åç§°", - "DisplayName.ReceiverGroupDescription": "æè¿°", - "ReceiverGroupCreateMessage": "新建消æ¯ç»„æˆåŠŸ.", - "ReceiverGroupEditMessage": "编辑消æ¯ç»„æˆåŠŸ.", - "ReceiverGroupDeleteMessage": "删除消æ¯ç»„æˆåŠŸ.", - "Description.ReceiverGroup.SelectUser": "请选择用户", - "Description.ReceiverGroup.AddSelectMember": "请添加/选择æˆå‘˜", - "ExternalMemberAddMessage": "添加外部用户æˆåŠŸ.", - "MessageManagement": "消æ¯ç®¡ç†", - "SendMessage": "å‘逿¶ˆæ¯", - "MessageRecord": "消æ¯è®°å½•", - "Permission.MessageManagement": "消æ¯ç®¡ç†", - "Permission.SendMessage": "å‘逿¶ˆæ¯", - "Permission.MessageRecord": "消æ¯è®°å½•", - "Permission.SendOrdinaryMessage": "å‘逿™®é€šæ¶ˆæ¯", - "Permission.SendTemplateMessage": "å‘逿¨¡æ¿æ¶ˆæ¯", - "Permission.EditTemplateMessage": "ç¼–è¾‘æ¨¡æ¿æ¶ˆæ¯", - "Permission.EditOrdinaryMessage": "编辑普通消æ¯", - "Permission.SendMessageTask": "å‘é€ä»»åŠ¡", - "Permission.ViewMessageTask": "查看任务", - "DisplayName.MessageEntityType": "普通消æ¯", - "DisplayName.MessageEntityType.Ordinary": "普通消æ¯", - "DisplayName.MessageEntityType.Template": "æ¨¡æ¿æ¶ˆæ¯", - "DisplayName.MessageTaskDisplayName": "æ¶ˆæ¯æ ‡é¢˜", - "DisplayName.MessageTaskReceiver": "收件人", - "DisplayName.MessageTaskSendingRule": "å‘é€è§„则", - "DisplayName.MessageTaskEntityType": "消æ¯ç±»åž‹", - "DisplayName.MessageTaskSendTime": "å‘逿—¶é—´", - "DisplayName.ReceiverType": "收件人类型", - "DisplayName.ReceiverType.Assign": "指定收件人", - "DisplayName.ReceiverType.Broadcast": "广播", - "MessageTaskCreateMessage": "新建消æ¯ä»»åŠ¡æˆåŠŸ.", - "MessageTaskEditMessage": "编辑消æ¯ä»»åŠ¡æˆåŠŸ.", - "MessageTaskDeleteMessage": "删除消æ¯ä»»åŠ¡æˆåŠŸ.", - "MessageTaskSendMessage": "å‘逿¶ˆæ¯ä»»åŠ¡æˆåŠŸ.", - "EnableConfirmationMessageTask": "是å¦ç¡®è®¤å¯ç”¨æ¶ˆæ¯ä»»åŠ¡?", - "CouldNotEnableATaskInDraft": "è‰ç¨¿ç®±ä»»åŠ¡ä¸èƒ½è¢«å¯ç”¨", - "DisableConfirmationMessageTask": "是å¦ç¡®è®¤ç¦ç”¨æ¶ˆæ¯ä»»åŠ¡?", - "DisplayName.MessageTaskList": "消æ¯ä»»åŠ¡åˆ—è¡¨", - "DisplayName.MessageInfoTitle": "æ¶ˆæ¯æ ‡é¢˜", - "DisplayName.MessageInfoContent": "消æ¯è¯¦æƒ…", - "DisplayName.MessageTaskIsEnabled": "状æ€", - "DisplayName.MessageTaskTimeType": "时间类型", - "DisplayName.MessageTaskTimeType.ModificationTime": "最近修改时间", - "DisplayName.MessageTaskTimeType.SendTime": "å‘逿—¶é—´", - "DisplayName.Value": "值", - "DisplayName.Variable": "å˜é‡", - "DisplayName.VariableValueTransfer": "å˜é‡ä¼ å€¼", - "DisplayName.SendingRule.Timeout": "è¶…æ—¶æ—¶é—´", - "DisplayName.SendingRule.RetryInterval": "é‡è¯•é—´éš”", - "DisplayName.SendingRule.RetryCount": "é‡è¯•次数", - "DisplayName.SendingRule.IsTiming": "定时å‘é€", - "DisplayName.MessageTaskHistory": "任务历å²", - "DisplayName.MessageTaskHistoryStatus": "å‘é€çжæ€", - "DisplayName.MessageTaskHistoryNo": "消æ¯ä»»åŠ¡æ‰¹æ¬¡", - "DisplayName.MessageTaskHistoryStatus.WaitSend": "å¾…å‘é€", - "DisplayName.MessageTaskHistoryStatus.Sending": "å‘é€ä¸­", - "DisplayName.MessageTaskHistoryStatus.Completed": "å‘é€å®Œæˆ", - "DisplayName.MessageTaskHistoryStatus.Withdrawn": "已撤回", - "DisplayName.MessageTaskHistoryStatus.Success": "å‘逿ˆåŠŸ", - "DisplayName.MessageTaskHistoryStatus.Fail": "å‘é€å¤±è´¥", - "DisplayName.MessageTaskHistoryStatus.PartialFailure": "部分失败", - "DisplayName.MessageTaskStatus": "å‘é€çжæ€", - "DisplayName.MessageTaskStatus.WaitSend": "å¾…å‘é€", - "DisplayName.MessageTaskStatus.Sending": "å‘é€ä¸­", - "DisplayName.MessageTaskStatus.Completed": "å‘é€å®Œæˆ", - "DisplayName.MessageTaskStatus.Withdrawn": "已撤回", - "DisplayName.MessageTaskStatus.Success": "å‘逿ˆåŠŸ", - "DisplayName.MessageTaskStatus.Fail": "å‘é€å¤±è´¥", - "DisplayName.MessageTaskStatus.PartialFailure": "部分失败", - "DisplayName.MessageTaskStatus.Cancel": "已撤销", - "MessageTaskHistoryWithdrawnMessage": "撤回消æ¯ä»»åŠ¡åŽ†å²æˆåŠŸ.", - "MessageTaskWithdrawnMessage": "撤回消æ¯ä»»åŠ¡æˆåŠŸ.", - "Permission.TestMessageTask": "测试消æ¯ä»»åŠ¡", - "DisplayName.MessageRecordSendTime": "实际å‘逿—¶é—´", - "DisplayName.MessageRecordExpectSendTime": "预计å‘逿—¶é—´", - "DisplayName.MessageRecordReceiptTime": "接收时间", - "DisplayName.MessageRecordSuccess": "å‘é€çжæ€", - "DisplayName.MessageRecordFailureReason": "失败原因", - "DisplayName.MessageRecordSuccess.True": "å‘逿ˆåŠŸ", - "DisplayName.MessageRecordSuccess.False": "å‘é€å¤±è´¥", - "DisplayName.MessageRecordTimeTypes": "时间类型", - "DisplayName.MessageRecordTimeTypes.ExpectSendTime": "预计å‘逿—¶é—´", - "DisplayName.MessageRecordTimeTypes.SendTime": "实际å‘逿—¶é—´", - "DisplayName.MessageRecordUserId": "收件人", - "DisplayName.MessageRecordResult": "消æ¯ç»“æžœ", - "DisplayName.MessageRecordDisplayName": "æ¶ˆæ¯æ ‡é¢˜", - "DisplayName.MessageRecordMessageTaskHistoryNo": "消æ¯ä»»åŠ¡æ‰¹æ¬¡", - "Description.MessageReceiversImport.Tips": "共上传{0}æ¡æ•°æ®ã€‚", - "Description.MessageReceiversImport.ErrorMsg": "上传失败,请检查文件数æ®åŽé‡æ–°ä¸Šä¼ ", - "Description.MessageReceiversUpload.Placeholder": "请上传文件", - "Description.MessageReceiversUpload.Tips": "请上传.csvæ ¼å¼çš„æ–‡ä»¶", - "Description.MessageReceiversDownload.Name": "模æ¿file.csv", - "Description.MessageReceiversDownload.Tips": "下载", - "Description.MessageReceiversUpload.EncodingTips": "请上传UTF-8ç¼–ç çš„csv文件", - "Description.PhoneNumber.Required": "手机å·ä¸å…许é‡å¤", - "Description.Email.Required": "邮箱ä¸å…许é‡å¤", - "Permission.WebsiteMessageManagement": "消æ¯ä¸­å¿ƒ", - "Description.Notice.MoreTips": "查看更多消æ¯", - "DisplayName.WebsiteMessageFilterType": "æœç´¢ç±»åž‹", - "DisplayName.WebsiteMessageFilterType.MessageTitle": "æ¶ˆæ¯æ ‡é¢˜", - "DisplayName.WebsiteMessageFilterType.MessageContent": "消æ¯å†…容", - "DisplayName.AllWebsiteMessage": "全部消æ¯", - "DisplayName.WebsiteMessageAction.MarkAllRead": "全部标记已读", - "DisplayName.WebsiteMessageAction.ShowAll": "显示全部", - "DisplayName.WebsiteMessageAction.ShowUnread": "显示未读", - "DisplayName.SubjectTypes.User": "用户", - "DisplayName.SubjectTypes.Department": "部门", - "DisplayName.SubjectTypes.Role": "角色", - "DisplayName.SubjectTypes.Team": "团队", - "DisplayName.MessageTaskReceiverTypes.User": "用户", - "DisplayName.MessageTaskReceiverTypes.Organization": "部门", - "DisplayName.MessageTaskReceiverTypes.Role": "角色", - "DisplayName.MessageTaskReceiverTypes.Team": "团队", - "DisplayName.MessageTaskReceiverTypes.Group": "收件人组", - "DisplayName.Color.Lable": "选择颜色", - "Success": "æˆåŠŸ", - "Failure": "失败", - "View": "查看", - "UploadComplete": "上传完æˆ", - "UploadFile": "上传文件", - "Test": "测试", - "SendTestTask": "å‘逿µ‹è¯•任务", - "SendTestMessage": "å‘逿µ‹è¯•消æ¯", - "Description.MessageTaskHistory.SendTimeTips": "本任务将在{0}执行", - "Retry": "é‡è¯•", - "Current": "当å‰", - "Title": "标题", - "BatchSending.Tips": "æ¯{0}秒,å‘é€{1}æ¡", - "DisplayName.SendingRule.SendingInterval": "分批次å‘é€", - "MessageRecordRetryMessage": "消æ¯å·²é‡æ–°å‘é€.", - "SendStatus": "å‘é€çжæ€", - "Permission.ViewMessageRecord": "查看消æ¯è®°å½•", - "MessageContent": "消æ¯å†…容", - "Description.ChannelType.Required": "请先选择渠é“类型", - "ReceiversCount": "预计{0}人", - "SendingMessage": "正在å‘逿¶ˆæ¯", - "DisplayName.SendingRule.CronExpression": "Cron 表达å¼", - "DisplayName.SendingRule.IsCustom": "自定义设置", - "DisplayName.SendingRule.SendingCount": "æ¯æ¬¡å‘逿¡æ•°", - "DisplayName.SendingRule.SendingCount.Tips": "0为ä¸é™åˆ¶", - "DisplayName.MessageTaskDetail.ReceiverType": "类型", - "TemplateTemplate": "模æ¿", - "ChannelOptions.Tips": "请仔细核对填写数æ®ï¼Œå¡«å†™é”™è¯¯ä¼šå¯¼è‡´æ¶ˆæ¯å‘é€å¤±è´¥", - "SelectTemplate": "选择模æ¿", - "CronExpressionInvalid": "Cron表达å¼ä¸åˆæ³•", - "CronExpressionNotHasNextRunTime": "您的表达å¼è®¡ç®—ä¸å‡ºä¸‹ä¸€æ¬¡è¿è¡Œæ—¶é—´", - "ChannelBlock": { - "Title": "渠é“", - "SchemeTooltip": "选择三方平å°ä½œä¸ºæŽ¨é€ç”¨æˆ·æ ‡è¯†çš„æ•°æ®æ¥æº", - "SchemeFieldTooltip": "ä¸å¡«ä½¿ç”¨ä¸‰æ–¹èº«ä»½æ ‡è¯†" - }, - "MessageTaskBlock": { - "Title": "消æ¯ä»»åŠ¡", - "MessageDetails": "消æ¯è¯¦æƒ…" - - }, - "MessageRecordBlock": { - "Title": "消æ¯è®°å½•" - }, - "MessageTemplateBlock": { - "SmsTemplateTitle": "短信", - "EmailTemplateTitle": "邮箱", - "WebsiteMessageTitle": "站内信", - "AppTitle": "App" - }, - "ReceiverGroupBlock": { - "Title": "消æ¯ç»„" - }, - "Required": "{0}必须填写", - "RequiredLength": "{0}åªèƒ½ä»‹äºŽ{1}å’Œ{2}之间", - "ChannelDisplayNameRequired": "请填写渠é“åç§°", - "ChannelDisplayNameChineseLetterNumberSymbol": "渠é“åç§°åªèƒ½æ˜¯ä¸­æ–‡/å­—æ¯/æ•°å­—/部分特殊字符", - "ChannelDisplayNameRequiredLength": "渠é“å称长度åªèƒ½ä»‹äºŽ2å’Œ50之间", - "ChannelCodeRequired": "请填写渠é“ID", - "ChannelCodeLetterNumberSymbol": "渠é“IDåªèƒ½æ˜¯å­—æ¯/æ•°å­—/部分特殊字符", - "ChannelCodeRequiredLength": "渠é“ID长度åªèƒ½ä»‹äºŽ2å’Œ50之间", - "ChannelTypeRequired": "请选择渠é“类型", - "ChannelIdRequired": "请选择渠é“", - "MessageTemplateRequired": "è¯·é€‰æ‹©æ¶ˆæ¯æ¨¡æ¿", - "MessageTypeRequired": "请选择消æ¯ç±»åž‹", - "ReceiverTypeRequired": "请选择接收类型", - "SelectReceiverTypeRequired": "请选择收件人选择方å¼", - "ReceiversRequired": "请选择收件人", - "SignRequired": "请填写签å", - "SignLength": "ç­¾å长度åªèƒ½ä»‹äºŽ2å’Œ50之间", - "SignChineseLetterNumber": "ç­¾ååªèƒ½æ˜¯ä¸­æ–‡/å­—æ¯/æ•°å­—/部分特殊字符", - "TitleRequired": "请填写标题", - "TitleLength": "标题长度åªèƒ½ä»‹äºŽ2å’Œ50之间", - "ContentRequired": "请填写内容", - "JumpUrlRequired": "请填写跳转地å€", - "DisplayNameRequired": "请填写åç§°", - "DisplayNameLength": "å称长度åªèƒ½ä»‹äºŽ2å’Œ50之间", - "DisplayNameChineseLetterNumber": "åç§°åªèƒ½æ˜¯ä¸­æ–‡/å­—æ¯/æ•°å­—/部分特殊字符", - "CronExpressionRequired": "请填写Cron表达å¼", - "MessageTemplateDisplayNameRequired": "请填写模æ¿åç§°", - "MessageTemplateDisplayNameLength": "模æ¿å称长度åªèƒ½ä»‹äºŽ2å’Œ50之间", - "MessageTemplateCodeRequired": "请填写模æ¿ID", - "MessageTemplateCodeLetterNumberSymbol": "模æ¿IDåªèƒ½æ˜¯å­—æ¯/æ•°å­—/部分特殊字符", - "MessageTemplateCodeLength": "模æ¿ID长度åªèƒ½ä»‹äºŽ2å’Œ50之间", - "MessageTemplateStatusRequired": "请选择模æ¿ç±»åž‹", - "MessageTemplatePerDayLimitBetween": "æ¯æ—¥å‘é€ä¸Šé™åªèƒ½ä»‹äºŽ1å’Œ500之间", - "MessageTemplateTemplateIdRequired": "请选择模æ¿", - "MessageTemplateItemsCannotRepeated": "模æ¿å˜é‡ä¸èƒ½é‡å¤", - "ReceiverGroupItemsRequired": "请选择收件人", - "PhoneNumberRequired": "请填写手机å·", - "EmailRequired": "请填写邮箱", - "EmailInvalid": "请填写正确的邮箱", - "EmailChannelUserNameRequired": "请填写邮箱账å·", - "EmailChannelPasswordRequired": "请填写邮箱密ç ", - "EmailChannelSmtpRequired": "请填写邮箱Smtp", - "SmsChannelAccessKeyIdRequired": "请填写AccessKeyID", - "SmsChannelAccessKeySecretRequired": "请填写AccessKeySecret", - "UploadFileSizeExceeded": "文件过大", - "UploadFileEmpty": "请选择文件", - "TaskWithdrawnConfirmationMessage": "确定撤销任务{0}å—?", - "DisplayName.AppChannelProviders": "æä¾›å•†", - "DisplayName.AppChannelProviders.GeTui": "个推", - "DisplayName.AppChannelProviders.JPush": "æžå…‰", - "UserDisplayNameRequired": "用户昵称是必需的", - "UserDisplayNameLength": "用户昵称的长度必须在 2 到 50 字符。", - "UserDisplayNameChineseLetterNumber": "ç”¨æˆ·æ˜µç§°å¿…é¡»æ˜¯ä¸­æ–‡ã€æ•°å­—ã€å­—æ¯ã€‚", - "Provider": "æä¾›å•†", - "AdditionalFields": "附加字段", - "Key": "é”®", - "Value": "值", - "MessageTask": "消æ¯ä»»åŠ¡", - "Channel": "渠é“", - "CreateSuccessfulMessage": "新建{0}æˆåŠŸ", - "EditSuccessfulMessage": "编辑{0}æˆåŠŸ", - "DeleteSuccessfulMessage": "删除{0}æˆåŠŸ", - "NotificationMessage": "通知消æ¯", - "InAppMessages": "应用内消æ¯", - "InAppMessagesTips": "是å¦ç”Ÿæˆç«™å†…ä¿¡", - "JumpUrlTips": "站内信跳转地å€", - "OptionalConfiguration": "å¯é€‰é…ç½®", - "IntentUrl": "点击通知打开指定页é¢", - "IntentUrlTips": "

打开指定页é¢

æ‰“å¼€æŒ‡å®šé¡µé¢æœ‰ä¸¤ç§æ–¹å¼

1ã€å¡«å†™å®Œæ•´çš„包åå’Œ Activity,具体格å¼ä¸ºï¼š

intent:#Intent;component=com.jiguang.push/com.example.jpushdemo.SettingActivity;end

2ã€å®¢æˆ·ç«¯Activity 在 manifest é…置为:

<activity android:name='.MyActivity' android:exported='true'> <intent-filter> <action android:name='android.intent.action.VIEW' /> <category android:name='android.intent.category.DEFAULT' /> <data android:scheme='app' android:host='example' android:path='/MyActivity/' /> </intent-filter> </activity>

填写的路径为:app://example/MyActivity/

", - "development": "å¼€å‘环境", - "production": "生产环境", - "TemplateType": "模æ¿ç±»åž‹", - "Text": "文本", - "TextCard": "文本å¡ç‰‡", - "ClientId": "客户端注册Id" -} diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/analytics/json.png b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/analytics/json.png deleted file mode 100644 index fee45284..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/analytics/json.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/analytics/left.png b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/analytics/left.png deleted file mode 100644 index ee5e3b2b..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/analytics/left.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/analytics/right.png b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/analytics/right.png deleted file mode 100644 index 30bb2ccb..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/analytics/right.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/auth/forgot-password-v2.9faba3c1.svg b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/auth/forgot-password-v2.9faba3c1.svg deleted file mode 100644 index 030d94c0..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/auth/forgot-password-v2.9faba3c1.svg +++ /dev/null @@ -1,207 +0,0 @@ - - - Illustration - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/auth/register-v2.0a9e487c.svg b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/auth/register-v2.0a9e487c.svg deleted file mode 100644 index d1ac05b0..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/auth/register-v2.0a9e487c.svg +++ /dev/null @@ -1,351 +0,0 @@ - - - Group - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/1.svg b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/1.svg deleted file mode 100644 index a47f78f5..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/1.svg +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/10.svg b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/10.svg deleted file mode 100644 index 082ab6ea..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/10.svg +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/11.svg b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/11.svg deleted file mode 100644 index ed6e9b2a..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/11.svg +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/12.svg b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/12.svg deleted file mode 100644 index 0533369c..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/12.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/13.svg b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/13.svg deleted file mode 100644 index 93b28c41..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/13.svg +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/14.svg b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/14.svg deleted file mode 100644 index fd688f93..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/14.svg +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/2.svg b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/2.svg deleted file mode 100644 index f4a8944d..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/2.svg +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/3.svg b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/3.svg deleted file mode 100644 index b2e10605..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/3.svg +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/4.svg b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/4.svg deleted file mode 100644 index 58e0cfe7..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/4.svg +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/7.svg b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/7.svg deleted file mode 100644 index 6cefecfb..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/7.svg +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/8.svg b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/8.svg deleted file mode 100644 index 61c13aa8..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/8.svg +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/9.svg b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/9.svg deleted file mode 100644 index cb45b1e5..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/avatar/9.svg +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/eCommerce/rectangle.png b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/eCommerce/rectangle.png deleted file mode 100644 index 1ab629b5..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/eCommerce/rectangle.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/eCommerce/trophy.png b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/eCommerce/trophy.png deleted file mode 100644 index 98f0b8d0..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/eCommerce/trophy.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/login/2873.png b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/login/2873.png deleted file mode 100644 index 4b7e7881..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/login/2873.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/login/Gxwd.png b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/login/Gxwd.png deleted file mode 100644 index 503ecde3..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/login/Gxwd.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/login/left.svg b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/login/left.svg deleted file mode 100644 index 103158e7..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/login/left.svg +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/mainLayout/logo-en.png b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/mainLayout/logo-en.png deleted file mode 100644 index 7f0e0076..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/mainLayout/logo-en.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/mainLayout/logo-en.svg b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/mainLayout/logo-en.svg deleted file mode 100644 index fbafb572..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/mainLayout/logo-en.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/mainLayout/logo.svg b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/mainLayout/logo.svg deleted file mode 100644 index 0993edae..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/mainLayout/logo.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/messageTask/send.svg b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/messageTask/send.svg deleted file mode 100644 index 853702e9..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/messageTask/send.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/messageTask/test.svg b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/messageTask/test.svg deleted file mode 100644 index fc68bd37..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/messageTask/test.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/status/401.png b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/status/401.png deleted file mode 100644 index 1f94504e..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/status/401.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/status/404.png b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/status/404.png deleted file mode 100644 index 39f2c595..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/status/404.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/status/500.png b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/status/500.png deleted file mode 100644 index fa65a8f6..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/status/500.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/upload/upload-active.png b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/upload/upload-active.png deleted file mode 100644 index 32c0c57f..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/upload/upload-active.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/upload/upload-complete.png b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/upload/upload-complete.png deleted file mode 100644 index 6bce91f2..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/upload/upload-complete.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/upload/upload-error.png b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/upload/upload-error.png deleted file mode 100644 index fa0df845..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/upload/upload-error.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/upload/upload.png b/src/Web/Masa.Mc.Web.Admin/wwwroot/img/upload/upload.png deleted file mode 100644 index 897cb609..00000000 Binary files a/src/Web/Masa.Mc.Web.Admin/wwwroot/img/upload/upload.png and /dev/null differ diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/js/clamp.js b/src/Web/Masa.Mc.Web.Admin/wwwroot/js/clamp.js deleted file mode 100644 index 71d05f81..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/js/clamp.js +++ /dev/null @@ -1,253 +0,0 @@ -(function () { - /** - * Clamps a text node. - * @param {HTMLElement} element. Element containing the text node to clamp. - * @param {Object} options. Options to pass to the clamper. - */ - function clamp(element, options) { - options = options || {}; - - var self = this, - win = window, - opt = { - clamp: options.clamp || 2, - useNativeClamp: typeof (options.useNativeClamp) != 'undefined' ? options.useNativeClamp : true, - splitOnChars: options.splitOnChars || ['.', '-', '¨C', '¡ª', ' '], //Split on sentences (periods), hypens, en-dashes, em-dashes, and words (spaces). - animate: options.animate || false, - truncationChar: options.truncationChar || '¡­', - truncationHTML: options.truncationHTML - }, - - sty = element.style, - originalText = element.innerHTML, - - supportsNativeClamp = typeof (element.style.webkitLineClamp) != 'undefined', - clampValue = opt.clamp, - isCSSValue = clampValue.indexOf && (clampValue.indexOf('px') > -1 || clampValue.indexOf('em') > -1), - truncationHTMLContainer; - - if (opt.truncationHTML) { - truncationHTMLContainer = document.createElement('span'); - truncationHTMLContainer.innerHTML = opt.truncationHTML; - } - - - // UTILITY FUNCTIONS __________________________________________________________ - - /** - * Return the current style for an element. - * @param {HTMLElement} elem The element to compute. - * @param {string} prop The style property. - * @returns {number} - */ - function computeStyle(elem, prop) { - if (!win.getComputedStyle) { - win.getComputedStyle = function (el, pseudo) { - this.el = el; - this.getPropertyValue = function (prop) { - var re = /(\-([a-z]){1})/g; - if (prop == 'float') prop = 'styleFloat'; - if (re.test(prop)) { - prop = prop.replace(re, function () { - return arguments[2].toUpperCase(); - }); - } - return el.currentStyle && el.currentStyle[prop] ? el.currentStyle[prop] : null; - } - return this; - } - } - - return win.getComputedStyle(elem, null).getPropertyValue(prop); - } - - /** - * Returns the maximum number of lines of text that should be rendered based - * on the current height of the element and the line-height of the text. - */ - function getMaxLines(height) { - var availHeight = height || element.clientHeight, - lineHeight = getLineHeight(element); - - return Math.max(Math.floor(availHeight / lineHeight), 0); - } - - /** - * Returns the maximum height a given element should have based on the line- - * height of the text and the given clamp value. - */ - function getMaxHeight(clmp) { - var lineHeight = getLineHeight(element); - return lineHeight * clmp; - } - - /** - * Returns the line-height of an element as an integer. - */ - function getLineHeight(elem) { - var lh = computeStyle(elem, 'line-height'); - if (lh == 'normal') { - // Normal line heights vary from browser to browser. The spec recommends - // a value between 1.0 and 1.2 of the font size. Using 1.1 to split the diff. - lh = parseInt(computeStyle(elem, 'font-size')) * 1.2; - } - return parseInt(lh); - } - - - // MEAT AND POTATOES (MMMM, POTATOES...) ______________________________________ - var splitOnChars = opt.splitOnChars.slice(0), - splitChar = splitOnChars[0], - chunks, - lastChunk; - - /** - * Gets an element's last child. That may be another node or a node's contents. - */ - function getLastChild(elem) { - //Current element has children, need to go deeper and get last child as a text node - if (elem.lastChild.children && elem.lastChild.children.length > 0) { - return getLastChild(Array.prototype.slice.call(elem.children).pop()); - } - //This is the absolute last child, a text node, but something's wrong with it. Remove it and keep trying - else if (!elem.lastChild || !elem.lastChild.nodeValue || elem.lastChild.nodeValue == '' || elem.lastChild.nodeValue == opt.truncationChar) { - elem.lastChild.parentNode.removeChild(elem.lastChild); - return getLastChild(element); - } - //This is the last child we want, return it - else { - return elem.lastChild; - } - } - - /** - * Removes one character at a time from the text until its width or - * height is beneath the passed-in max param. - */ - function truncate(target, maxHeight) { - if (!maxHeight) { return; } - - /** - * Resets global variables. - */ - function reset() { - splitOnChars = opt.splitOnChars.slice(0); - splitChar = splitOnChars[0]; - chunks = null; - lastChunk = null; - } - - var nodeValue = target.nodeValue.replace(opt.truncationChar, ''); - - //Grab the next chunks - if (!chunks) { - //If there are more characters to try, grab the next one - if (splitOnChars.length > 0) { - splitChar = splitOnChars.shift(); - } - //No characters to chunk by. Go character-by-character - else { - splitChar = ''; - } - - chunks = nodeValue.split(splitChar); - } - - //If there are chunks left to remove, remove the last one and see if - // the nodeValue fits. - if (chunks.length > 1) { - // console.log('chunks', chunks); - lastChunk = chunks.pop(); - // console.log('lastChunk', lastChunk); - applyEllipsis(target, chunks.join(splitChar)); - } - //No more chunks can be removed using this character - else { - chunks = null; - } - - //Insert the custom HTML before the truncation character - if (truncationHTMLContainer) { - target.nodeValue = target.nodeValue.replace(opt.truncationChar, ''); - element.innerHTML = target.nodeValue + ' ' + truncationHTMLContainer.innerHTML + opt.truncationChar; - } - - //Search produced valid chunks - if (chunks) { - //It fits - if (element.clientHeight <= maxHeight) { - //There's still more characters to try splitting on, not quite done yet - if (splitOnChars.length >= 0 && splitChar != '') { - applyEllipsis(target, chunks.join(splitChar) + splitChar + lastChunk); - chunks = null; - } - //Finished! - else { - return element.innerHTML; - } - } - } - //No valid chunks produced - else { - //No valid chunks even when splitting by letter, time to move - //on to the next node - if (splitChar == '') { - applyEllipsis(target, ''); - target = getLastChild(element); - - reset(); - } - } - - //If you get here it means still too big, let's keep truncating - if (opt.animate) { - setTimeout(function () { - truncate(target, maxHeight); - }, opt.animate === true ? 10 : opt.animate); - } - else { - return truncate(target, maxHeight); - } - } - - function applyEllipsis(elem, str) { - elem.nodeValue = str + opt.truncationChar; - } - - - // CONSTRUCTOR ________________________________________________________________ - - if (clampValue == 'auto') { - clampValue = getMaxLines(); - } - else if (isCSSValue) { - clampValue = getMaxLines(parseInt(clampValue)); - } - - var clampedText; - if (supportsNativeClamp && opt.useNativeClamp) { - sty.overflow = 'hidden'; - sty.textOverflow = 'ellipsis'; - sty.webkitBoxOrient = 'vertical'; - sty.display = '-webkit-box'; - sty.webkitLineClamp = clampValue; - - if (isCSSValue) { - sty.height = opt.clamp + 'px'; - } - } - else { - var height = getMaxHeight(clampValue); - if (height <= element.clientHeight) { - clampedText = truncate(getLastChild(element), height); - } - } - - return { - 'original': originalText, - 'clamped': clampedText - } - } - - window.$clamp = clamp; -})(); \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/js/quill/quill-helper.js b/src/Web/Masa.Mc.Web.Admin/wwwroot/js/quill/quill-helper.js deleted file mode 100644 index e9b39492..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/js/quill/quill-helper.js +++ /dev/null @@ -1,19 +0,0 @@ -export function uploadImage(quillElement, element, ossParamter, index = 0) { - let _that = this; - let quill = quillElement.__quill;//get quill editor - let fileInput = element.querySelector('input.ql-image[type=file]')//get fileInput - let files = fileInput.files; - - ossUpload(files[index], ossParamter).then(fileUrl => { - let length = quill.getSelection().index; - quill.insertEmbed(length, 'image', fileUrl);//Insert the uploaded picture into the editor - quill.setSelection(length + 1); - index += 1; - if (index < files.length) { - _that.uploadImage(quillElement, element, ossParamter, index); - } - else { - fileInput.value = ''; - } - }); -} \ No newline at end of file diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/js/util.js b/src/Web/Masa.Mc.Web.Admin/wwwroot/js/util.js deleted file mode 100644 index 900d9dd2..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/js/util.js +++ /dev/null @@ -1,12 +0,0 @@ -var util = { - scrollTop: (dom, id) => { - if (id) { - document.getElementById(id).scrollTop = 0; - } - else { - dom.scrollTop = 0; - } - } -} - -window.util = util; diff --git a/src/Web/Masa.Mc.Web.Admin/wwwroot/js/vditor/vditor-helper.js b/src/Web/Masa.Mc.Web.Admin/wwwroot/js/vditor/vditor-helper.js deleted file mode 100644 index 59facef4..00000000 --- a/src/Web/Masa.Mc.Web.Admin/wwwroot/js/vditor/vditor-helper.js +++ /dev/null @@ -1,24 +0,0 @@ -export function upload(element, ossParamter, index = 0) { - let _that = this; - let vditor = element.Vditor; - let fileInput = element.querySelector('input[type=file]') - let files = fileInput.files; - - UploadImage([files[index]], ossParamter).then(fileUrls => { - let fileUrl = fileUrls[0]; - let succFileText = ""; - if (vditor && vditor.vditor.currentMode === "wysiwyg") { - succFileText += `\n ${fileUrl}`; - } else { - succFileText += `\n![${fileUrl}](${fileUrl})`; - } - document.execCommand("insertHTML", false, succFileText); - index += 1; - if (index < files.length) { - _that.upload(element, ossParamter, index); - } - else { - fileInput.value = ''; - } - }); -} \ No newline at end of file