From 8ef45fb2ebed70cf26d5854db0b1176204eeac3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=90=D0=BB=D0=B5=D0=B9?= =?UTF-8?q?=D0=BA=D0=B8=D0=BD?= Date: Thu, 4 May 2023 23:45:15 +0400 Subject: [PATCH] =?UTF-8?q?=D0=92=D1=80=D0=BE=D0=B4=D0=B5=20=D1=81=D0=B4?= =?UTF-8?q?=D0=B5=D0=BB=D0=B0=D0=BB.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BusinessLogics/BackUpLogic.cs | 103 ++++++ .../Attributes/ColumnAttribute.cs | 26 ++ .../Attributes/GridViewAutoSize.cs | 20 ++ .../BindingModels/BackUpSaveBindingModel.cs | 13 + .../BindingModels/MessageInfoBindingModel.cs | 2 + .../BusinessLogicsContracts/IBackUpLogic.cs | 14 + .../ConfectioneryContracts.csproj | 6 + .../DI/DependencyManager.cs | 67 ++++ .../DI/IDependencyContainer.cs | 38 +++ .../DI/IImplementationExtension.cs | 17 + .../DI/ServiceDependencyContainer.cs | 62 ++++ .../DI/ServiceProviderLoader.cs | 63 ++++ .../DI/UnityDependencyContainer.cs | 43 +++ .../StoragesContracts/IBackUpInfo.cs | 14 + .../ViewModels/ClientViewModel.cs | 10 +- .../ViewModels/ComponentViewModel.cs | 8 +- .../ViewModels/ImplementerViewModel.cs | 12 +- .../ViewModels/MessageInfoViewModel.cs | 16 +- .../ViewModels/OrderViewModel.cs | 24 +- .../ViewModels/PastryViewModel.cs | 9 +- .../Models/IMessageInfoModel.cs | 2 +- .../ConfectioneryDatabaseImplement.csproj | 4 + .../DatabaseImplementationExtension.cs | 27 ++ .../Implements/BackUpInfo.cs | 32 ++ .../20230504194238_migr7.Designer.cs | 298 ++++++++++++++++++ .../Migrations/20230504194238_migr7.cs | 22 ++ .../ConfectioneryDatabaseModelSnapshot.cs | 4 +- .../Models/Client.cs | 10 + .../Models/Component.cs | 8 + .../Models/Implementer.cs | 7 + .../Models/Message.cs | 5 + .../Models/Order.cs | 12 + .../Models/Pastry.cs | 6 + .../ConfectioneryFileImplement.csproj | 4 + .../FileImplementationExtension.cs | 27 ++ .../Implements/BackUpInfo.cs | 34 ++ .../Models/Client.cs | 6 + .../Models/Component.cs | 9 +- .../Models/Implementer.cs | 7 + .../Models/Message.cs | 2 + .../Models/Order.cs | 11 + .../Models/Pastry.cs | 7 +- .../ConfectioneryListImplement.csproj | 4 + .../Implements/BackUpInfo.cs | 22 ++ .../ListImplementationExtension.cs | 26 ++ .../Models/Message.cs | 2 + .../DataGridViewExtension.cs | 55 ++++ .../ConfectioneryView/FormClients.cs | 8 +- .../ConfectioneryView/FormComponents.cs | 17 +- .../ConfectioneryView/FormImplementers.cs | 16 +- Confectionery/ConfectioneryView/FormMails.cs | 16 +- .../ConfectioneryView/FormMain.Designer.cs | 12 +- Confectionery/ConfectioneryView/FormMain.cs | 50 ++- .../ConfectioneryView/FormPastries.cs | 14 +- Confectionery/ConfectioneryView/FormPastry.cs | 6 +- Confectionery/ConfectioneryView/Program.cs | 82 ++--- .../ConfectioneryContracts.dll | Bin 0 -> 31744 bytes .../ConfectioneryDataModels.dll | Bin 0 -> 6144 bytes .../ConfectioneryDatabaseImplement.dll | Bin 0 -> 93696 bytes .../ConfectioneryFileImplement.dll | Bin 0 -> 40448 bytes .../ConfectioneryListImplement.dll | Bin 0 -> 25600 bytes 61 files changed, 1296 insertions(+), 145 deletions(-) create mode 100644 Confectionery/ConfectioneryBusinessLogic/BusinessLogics/BackUpLogic.cs create mode 100644 Confectionery/ConfectioneryContracts/Attributes/ColumnAttribute.cs create mode 100644 Confectionery/ConfectioneryContracts/Attributes/GridViewAutoSize.cs create mode 100644 Confectionery/ConfectioneryContracts/BindingModels/BackUpSaveBindingModel.cs create mode 100644 Confectionery/ConfectioneryContracts/BusinessLogicsContracts/IBackUpLogic.cs create mode 100644 Confectionery/ConfectioneryContracts/DI/DependencyManager.cs create mode 100644 Confectionery/ConfectioneryContracts/DI/IDependencyContainer.cs create mode 100644 Confectionery/ConfectioneryContracts/DI/IImplementationExtension.cs create mode 100644 Confectionery/ConfectioneryContracts/DI/ServiceDependencyContainer.cs create mode 100644 Confectionery/ConfectioneryContracts/DI/ServiceProviderLoader.cs create mode 100644 Confectionery/ConfectioneryContracts/DI/UnityDependencyContainer.cs create mode 100644 Confectionery/ConfectioneryContracts/StoragesContracts/IBackUpInfo.cs create mode 100644 Confectionery/ConfectioneryDatabaseImplement/DatabaseImplementationExtension.cs create mode 100644 Confectionery/ConfectioneryDatabaseImplement/Implements/BackUpInfo.cs create mode 100644 Confectionery/ConfectioneryDatabaseImplement/Migrations/20230504194238_migr7.Designer.cs create mode 100644 Confectionery/ConfectioneryDatabaseImplement/Migrations/20230504194238_migr7.cs create mode 100644 Confectionery/ConfectioneryFileImplement/FileImplementationExtension.cs create mode 100644 Confectionery/ConfectioneryFileImplement/Implements/BackUpInfo.cs create mode 100644 Confectionery/ConfectioneryListImplement/Implements/BackUpInfo.cs create mode 100644 Confectionery/ConfectioneryListImplement/ListImplementationExtension.cs create mode 100644 Confectionery/ConfectioneryView/DataGridViewExtension.cs create mode 100644 Confectionery/ImplementationExtensions/ConfectioneryContracts.dll create mode 100644 Confectionery/ImplementationExtensions/ConfectioneryDataModels.dll create mode 100644 Confectionery/ImplementationExtensions/ConfectioneryDatabaseImplement.dll create mode 100644 Confectionery/ImplementationExtensions/ConfectioneryFileImplement.dll create mode 100644 Confectionery/ImplementationExtensions/ConfectioneryListImplement.dll diff --git a/Confectionery/ConfectioneryBusinessLogic/BusinessLogics/BackUpLogic.cs b/Confectionery/ConfectioneryBusinessLogic/BusinessLogics/BackUpLogic.cs new file mode 100644 index 0000000..31a92ff --- /dev/null +++ b/Confectionery/ConfectioneryBusinessLogic/BusinessLogics/BackUpLogic.cs @@ -0,0 +1,103 @@ +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.BusinessLogicsContracts; +using ConfectioneryContracts.StoragesContracts; +using ConfectioneryDataModels.Models; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.IO.Compression; +using System.Linq; +using System.Reflection; +using System.Runtime.Serialization.Json; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryBusinessLogic.BusinessLogics +{ + public class BackUpLogic : IBackUpLogic + { + private readonly ILogger _logger; + + private readonly IBackUpInfo _backUpInfo; + + public BackUpLogic(ILogger logger, IBackUpInfo backUpInfo) + { + _logger = logger; + _backUpInfo = backUpInfo; + } + + public void CreateBackUp(BackUpSaveBindingModel model) + { + if (_backUpInfo == null) + { + return; + } + try + { + _logger.LogDebug("Clear folder"); + // зачистка папки и удаление старого архива + var dirInfo = new DirectoryInfo(model.FolderName); + if (dirInfo.Exists) + { + foreach (var file in dirInfo.GetFiles()) + { + file.Delete(); + } + } + _logger.LogDebug("Delete archive"); + string fileName = $"{model.FolderName}.zip"; + if (File.Exists(fileName)) + { + File.Delete(fileName); + } + // берем метод для сохранения + _logger.LogDebug("Get assembly"); + var typeIId = typeof(IId); + var assembly = typeIId.Assembly; + if (assembly == null) + { + throw new ArgumentNullException("Сборка не найдена", nameof(assembly)); + } + var types = assembly.GetTypes(); + var method = GetType().GetMethod("SaveToFile", BindingFlags.NonPublic | BindingFlags.Instance); + _logger.LogDebug("Find {count} types", types.Length); + foreach (var type in types) + { + if (type.IsInterface && type.GetInterface(typeIId.Name) != null) + { + var modelType = _backUpInfo.GetTypeByModelInterface(type.Name); + if (modelType == null) + { + throw new InvalidOperationException($"Не найден класс-модель для {type.Name}"); + } + _logger.LogDebug("Call SaveToFile method for {name} type", type.Name); + // вызываем метод на выполнение + method?.MakeGenericMethod(modelType).Invoke(this, new object[] { model.FolderName }); + } + } + _logger.LogDebug("Create zip and remove folder"); + // архивируем + ZipFile.CreateFromDirectory(model.FolderName, fileName); + // удаляем папку + dirInfo.Delete(true); + } + catch (Exception) + { + throw; + } + } + + private void SaveToFile(string folderName) where T : class, new() + { + var records = _backUpInfo.GetList(); + if (records == null) + { + _logger.LogWarning("{type} type get null list", typeof(T).Name); + return; + } + var jsonFormatter = new DataContractJsonSerializer(typeof(List)); + using var fs = new FileStream(string.Format("{0}/{1}.json", folderName, typeof(T).Name), FileMode.OpenOrCreate); + jsonFormatter.WriteObject(fs, records); + } + } +} diff --git a/Confectionery/ConfectioneryContracts/Attributes/ColumnAttribute.cs b/Confectionery/ConfectioneryContracts/Attributes/ColumnAttribute.cs new file mode 100644 index 0000000..f3ea1a8 --- /dev/null +++ b/Confectionery/ConfectioneryContracts/Attributes/ColumnAttribute.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryContracts.Attributes +{ + [AttributeUsage(AttributeTargets.Property)] + public class ColumnAttribute : Attribute + { + public ColumnAttribute(string title = "", bool visible = true, int width = 0, GridViewAutoSize gridViewAutoSize = GridViewAutoSize.None, bool isUseAutoSize = false) + { + Title = title; + Visible = visible; + Width = width; + GridViewAutoSize = gridViewAutoSize; + IsUseAutoSize = isUseAutoSize; + } + public string Title { get; private set; } + public bool Visible { get; private set; } + public int Width { get; private set; } + public GridViewAutoSize GridViewAutoSize { get; private set; } + public bool IsUseAutoSize { get; private set; } + } +} diff --git a/Confectionery/ConfectioneryContracts/Attributes/GridViewAutoSize.cs b/Confectionery/ConfectioneryContracts/Attributes/GridViewAutoSize.cs new file mode 100644 index 0000000..ef57ed1 --- /dev/null +++ b/Confectionery/ConfectioneryContracts/Attributes/GridViewAutoSize.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryContracts.Attributes +{ + public enum GridViewAutoSize + { + NotSet = 0, + None = 1, + ColumnHeader = 2, + AllCellsExceptHeader = 4, + AllCells = 6, + DisplayedCellsExceptHeader = 8, + DisplayedCells = 10, + Fill = 16 + } +} diff --git a/Confectionery/ConfectioneryContracts/BindingModels/BackUpSaveBindingModel.cs b/Confectionery/ConfectioneryContracts/BindingModels/BackUpSaveBindingModel.cs new file mode 100644 index 0000000..6b1aced --- /dev/null +++ b/Confectionery/ConfectioneryContracts/BindingModels/BackUpSaveBindingModel.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryContracts.BindingModels +{ + public class BackUpSaveBindingModel + { + public string FolderName { get; set; } = string.Empty; + } +} diff --git a/Confectionery/ConfectioneryContracts/BindingModels/MessageInfoBindingModel.cs b/Confectionery/ConfectioneryContracts/BindingModels/MessageInfoBindingModel.cs index 22e0745..b4d473c 100644 --- a/Confectionery/ConfectioneryContracts/BindingModels/MessageInfoBindingModel.cs +++ b/Confectionery/ConfectioneryContracts/BindingModels/MessageInfoBindingModel.cs @@ -20,5 +20,7 @@ namespace ConfectioneryContracts.BindingModels public string Subject { get; set; } = string.Empty; public string Body { get; set; } = string.Empty; + + public int Id => throw new NotImplementedException(); } } diff --git a/Confectionery/ConfectioneryContracts/BusinessLogicsContracts/IBackUpLogic.cs b/Confectionery/ConfectioneryContracts/BusinessLogicsContracts/IBackUpLogic.cs new file mode 100644 index 0000000..d0aee14 --- /dev/null +++ b/Confectionery/ConfectioneryContracts/BusinessLogicsContracts/IBackUpLogic.cs @@ -0,0 +1,14 @@ +using ConfectioneryContracts.BindingModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryContracts.BusinessLogicsContracts +{ + public interface IBackUpLogic + { + void CreateBackUp(BackUpSaveBindingModel model); + } +} diff --git a/Confectionery/ConfectioneryContracts/ConfectioneryContracts.csproj b/Confectionery/ConfectioneryContracts/ConfectioneryContracts.csproj index b0b970c..c96077c 100644 --- a/Confectionery/ConfectioneryContracts/ConfectioneryContracts.csproj +++ b/Confectionery/ConfectioneryContracts/ConfectioneryContracts.csproj @@ -6,6 +6,12 @@ enable + + + + + + diff --git a/Confectionery/ConfectioneryContracts/DI/DependencyManager.cs b/Confectionery/ConfectioneryContracts/DI/DependencyManager.cs new file mode 100644 index 0000000..13eeb22 --- /dev/null +++ b/Confectionery/ConfectioneryContracts/DI/DependencyManager.cs @@ -0,0 +1,67 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryContracts.DI +{ + public class DependencyManager + { + private readonly IDependencyContainer _dependencyManager; + private static DependencyManager? _manager; + private static readonly object _locjObject = new(); + private DependencyManager() + { + _dependencyManager = new ServiceDependencyContainer(); + } + public static DependencyManager Instance + { + get + { + if (_manager == null) { lock (_locjObject) { _manager = new DependencyManager(); } } + return _manager; + } + } + /// + /// Иницализация библиотек, в которых идут установки зависомстей + /// + public static void InitDependency() + { + var ext = ServiceProviderLoader.GetImplementationExtensions(); + if (ext == null) + { + throw new ArgumentNullException("Отсутствуют компоненты для загрузки зависимостей по модулям"); + } + // регистрируем зависимости + ext.RegisterServices(); + } + /// + /// Регистрация логгера + /// + /// + public void AddLogging(Action configure) => + _dependencyManager.AddLogging(configure); + /// + /// Добавление зависимости + /// + /// + /// + public void RegisterType(bool isSingle = false) where U : + class, T where T : class => _dependencyManager.RegisterType(isSingle); + /// + /// Добавление зависимости + /// + /// + /// + public void RegisterType(bool isSingle = false) where T : class => + _dependencyManager.RegisterType(isSingle); + /// + /// Получение класса со всеми зависмостями + /// + /// + /// + public T Resolve() => _dependencyManager.Resolve(); + } +} diff --git a/Confectionery/ConfectioneryContracts/DI/IDependencyContainer.cs b/Confectionery/ConfectioneryContracts/DI/IDependencyContainer.cs new file mode 100644 index 0000000..57e48ce --- /dev/null +++ b/Confectionery/ConfectioneryContracts/DI/IDependencyContainer.cs @@ -0,0 +1,38 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryContracts.DI +{ + public interface IDependencyContainer + { + /// + /// Регистрация логгера + /// + /// + void AddLogging(Action configure); + /// + /// Добавление зависимости + /// + /// + /// + /// + void RegisterType(bool isSingle) where U : class, T where T : + class; + /// + /// Добавление зависимости + /// + /// + /// + void RegisterType(bool isSingle) where T : class; + /// + /// Получение класса со всеми зависмостями + /// + /// + /// + T Resolve(); + } +} diff --git a/Confectionery/ConfectioneryContracts/DI/IImplementationExtension.cs b/Confectionery/ConfectioneryContracts/DI/IImplementationExtension.cs new file mode 100644 index 0000000..9ed7f9d --- /dev/null +++ b/Confectionery/ConfectioneryContracts/DI/IImplementationExtension.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryContracts.DI +{ + public interface IImplementationExtension + { + public int Priority { get; } + /// + /// Регистрация сервисов + /// + public void RegisterServices(); + } +} diff --git a/Confectionery/ConfectioneryContracts/DI/ServiceDependencyContainer.cs b/Confectionery/ConfectioneryContracts/DI/ServiceDependencyContainer.cs new file mode 100644 index 0000000..aa8676b --- /dev/null +++ b/Confectionery/ConfectioneryContracts/DI/ServiceDependencyContainer.cs @@ -0,0 +1,62 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryContracts.DI +{ + public class ServiceDependencyContainer : IDependencyContainer + { + private ServiceProvider? _serviceProvider; + + private readonly ServiceCollection _serviceCollection; + + public ServiceDependencyContainer() + { + _serviceCollection = new ServiceCollection(); + } + + public void AddLogging(Action configure) + { + _serviceCollection.AddLogging(configure); + } + + public void RegisterType(bool isSingle) where U : class, T where T : class + { + if (isSingle) + { + _serviceCollection.AddSingleton(); + } + else + { + _serviceCollection.AddTransient(); + } + _serviceProvider = null; + } + + public void RegisterType(bool isSingle) where T : class + { + if (isSingle) + { + _serviceCollection.AddSingleton(); + } + else + { + _serviceCollection.AddTransient(); + } + _serviceProvider = null; + } + + public T Resolve() + { + if (_serviceProvider == null) + { + _serviceProvider = _serviceCollection.BuildServiceProvider(); + } + return _serviceProvider.GetService()!; + } + } +} diff --git a/Confectionery/ConfectioneryContracts/DI/ServiceProviderLoader.cs b/Confectionery/ConfectioneryContracts/DI/ServiceProviderLoader.cs new file mode 100644 index 0000000..e997afb --- /dev/null +++ b/Confectionery/ConfectioneryContracts/DI/ServiceProviderLoader.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryContracts.DI +{ + public class ServiceProviderLoader + { + /// + /// Загрузка всех классов-реализаций IImplementationExtension + /// + /// + public static IImplementationExtension? GetImplementationExtensions() + { + IImplementationExtension? source = null; + var files = + Directory.GetFiles(TryGetImplementationExtensionsFolder(), "*.dll", + SearchOption.AllDirectories); + foreach (var file in files.Distinct()) + { + Assembly asm = Assembly.LoadFrom(file); + foreach (var t in asm.GetExportedTypes()) + { + if (t.IsClass && + typeof(IImplementationExtension).IsAssignableFrom(t)) + { + if (source == null) + { + source = + (IImplementationExtension)Activator.CreateInstance(t)!; + } + else + { + var newSource = + (IImplementationExtension)Activator.CreateInstance(t)!; + if (newSource.Priority > source.Priority) + { + source = newSource; + } + } + } + } + } + return source; + } + private static string TryGetImplementationExtensionsFolder() + { + var directory = new + DirectoryInfo(Directory.GetCurrentDirectory()); + while (directory != null && + !directory.GetDirectories("ImplementationExtensions", + SearchOption.AllDirectories) + .Any(x => x.Name == "ImplementationExtensions")) + { + directory = directory.Parent; + } + return $"{directory?.FullName}\\ImplementationExtensions"; + } + } +} diff --git a/Confectionery/ConfectioneryContracts/DI/UnityDependencyContainer.cs b/Confectionery/ConfectioneryContracts/DI/UnityDependencyContainer.cs new file mode 100644 index 0000000..ecd60bd --- /dev/null +++ b/Confectionery/ConfectioneryContracts/DI/UnityDependencyContainer.cs @@ -0,0 +1,43 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Unity; +using Unity.Microsoft.Logging; + +namespace ConfectioneryContracts.DI +{ + public class UnityDependencyContainer : IDependencyContainer + { + private readonly IUnityContainer _container; + + public UnityDependencyContainer() + { + _container = new UnityContainer(); + } + + public void AddLogging(Action configure) + { + var factory = LoggerFactory.Create(configure); + _container.AddExtension(new LoggingExtension(factory)); + } + + public void RegisterType(bool isSingle) where T : class + { + _container.RegisterType(isSingle ? TypeLifetime.Singleton : TypeLifetime.Transient); + + } + + public T Resolve() + { + return _container.Resolve(); + } + + void IDependencyContainer.RegisterType(bool isSingle) + { + _container.RegisterType(isSingle ? TypeLifetime.Singleton : TypeLifetime.Transient); + } + } +} diff --git a/Confectionery/ConfectioneryContracts/StoragesContracts/IBackUpInfo.cs b/Confectionery/ConfectioneryContracts/StoragesContracts/IBackUpInfo.cs new file mode 100644 index 0000000..8d8a280 --- /dev/null +++ b/Confectionery/ConfectioneryContracts/StoragesContracts/IBackUpInfo.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryContracts.StoragesContracts +{ + public interface IBackUpInfo + { + List? GetList() where T : class, new(); + Type? GetTypeByModelInterface(string modelInterfaceName); + } +} diff --git a/Confectionery/ConfectioneryContracts/ViewModels/ClientViewModel.cs b/Confectionery/ConfectioneryContracts/ViewModels/ClientViewModel.cs index 84d002e..f5f6d18 100644 --- a/Confectionery/ConfectioneryContracts/ViewModels/ClientViewModel.cs +++ b/Confectionery/ConfectioneryContracts/ViewModels/ClientViewModel.cs @@ -1,4 +1,5 @@ -using ConfectioneryDataModels.Models; +using ConfectioneryContracts.Attributes; +using ConfectioneryDataModels.Models; using System; using System.Collections.Generic; using System.ComponentModel; @@ -10,12 +11,13 @@ namespace ConfectioneryContracts.ViewModels { public class ClientViewModel : IClientModel { + [Column(visible: false)] public int Id { get; set; } - [DisplayName("ФИО клиента")] + [Column("ФИО клиента", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string ClientFIO { get; set; } = string.Empty; - [DisplayName("Логин (эл. почта)")] + [Column("Логин (эл. почта)", width: 150)] public string Email { get; set; } = string.Empty; - [DisplayName("Пароль")] + [Column("Пароль", width: 150)] public string Password { get; set; } = string.Empty; } } diff --git a/Confectionery/ConfectioneryContracts/ViewModels/ComponentViewModel.cs b/Confectionery/ConfectioneryContracts/ViewModels/ComponentViewModel.cs index 8706c51..564cbc2 100644 --- a/Confectionery/ConfectioneryContracts/ViewModels/ComponentViewModel.cs +++ b/Confectionery/ConfectioneryContracts/ViewModels/ComponentViewModel.cs @@ -1,4 +1,5 @@ -using ConfectioneryDataModels.Models; +using ConfectioneryContracts.Attributes; +using ConfectioneryDataModels.Models; using System; using System.Collections.Generic; using System.ComponentModel; @@ -10,12 +11,13 @@ namespace ConfectioneryContracts.ViewModels { public class ComponentViewModel : IComponentModel { + [Column(visible: false)] public int Id { get; set; } - [DisplayName("Название компонента")] + [Column("Название бланка", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string ComponentName { get; set; } = string.Empty; - [DisplayName("Цена")] + [Column("Цена", width: 80)] public double Cost { get; set; } } } diff --git a/Confectionery/ConfectioneryContracts/ViewModels/ImplementerViewModel.cs b/Confectionery/ConfectioneryContracts/ViewModels/ImplementerViewModel.cs index ac908ff..c88b511 100644 --- a/Confectionery/ConfectioneryContracts/ViewModels/ImplementerViewModel.cs +++ b/Confectionery/ConfectioneryContracts/ViewModels/ImplementerViewModel.cs @@ -1,4 +1,5 @@ -using ConfectioneryDataModels.Models; +using ConfectioneryContracts.Attributes; +using ConfectioneryDataModels.Models; using System; using System.Collections.Generic; using System.ComponentModel; @@ -10,18 +11,19 @@ namespace ConfectioneryContracts.ViewModels { public class ImplementerViewModel : IImplementerModel { - [DisplayName("ФИО исполнителя")] + [Column("ФИО исполнителя", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string ImplementerFIO { get; set; } = string.Empty; - [DisplayName("Пароль")] + [Column("Пароль", width: 150)] public string Password { get; set; } = string.Empty; - [DisplayName("Стаж работы")] + [Column("Стаж работы", gridViewAutoSize: GridViewAutoSize.AllCells, isUseAutoSize: true)] public int WorkExperience { get; set; } - [DisplayName("Квалификация")] + [Column("Квалификация", gridViewAutoSize: GridViewAutoSize.AllCells, isUseAutoSize: true)] public int Qualification { get; set; } + [Column(visible: false)] public int Id { get; set; } } } diff --git a/Confectionery/ConfectioneryContracts/ViewModels/MessageInfoViewModel.cs b/Confectionery/ConfectioneryContracts/ViewModels/MessageInfoViewModel.cs index 8562902..afb5b2b 100644 --- a/Confectionery/ConfectioneryContracts/ViewModels/MessageInfoViewModel.cs +++ b/Confectionery/ConfectioneryContracts/ViewModels/MessageInfoViewModel.cs @@ -1,4 +1,5 @@ -using ConfectioneryDataModels.Models; +using ConfectioneryContracts.Attributes; +using ConfectioneryDataModels.Models; using System; using System.Collections.Generic; using System.ComponentModel; @@ -10,20 +11,25 @@ namespace ConfectioneryContracts.ViewModels { public class MessageInfoViewModel : IMessageInfoModel { + [Column(visible: false)] public string MessageId { get; set; } = string.Empty; + [Column(visible: false)] public int? ClientId { get; set; } - [DisplayName("Отправитель")] + [Column("Отправитель", gridViewAutoSize: GridViewAutoSize.DisplayedCells, isUseAutoSize: true)] public string SenderName { get; set; } = string.Empty; - [DisplayName("Дата письма")] + [Column("Дата письма", width: 100)] public DateTime DateDelivery { get; set; } - [DisplayName("Заголовок")] + [Column("Заголовок", gridViewAutoSize: GridViewAutoSize.AllCells, isUseAutoSize: true)] public string Subject { get; set; } = string.Empty; - [DisplayName("Текст")] + [Column("Текст", gridViewAutoSize: GridViewAutoSize.AllCells, isUseAutoSize: true)] public string Body { get; set; } = string.Empty; + + [Column(visible: false)] + public int Id => throw new NotImplementedException(); } } diff --git a/Confectionery/ConfectioneryContracts/ViewModels/OrderViewModel.cs b/Confectionery/ConfectioneryContracts/ViewModels/OrderViewModel.cs index a29607d..a38b48e 100644 --- a/Confectionery/ConfectioneryContracts/ViewModels/OrderViewModel.cs +++ b/Confectionery/ConfectioneryContracts/ViewModels/OrderViewModel.cs @@ -1,4 +1,5 @@ -using ConfectioneryDataModels.Enums; +using ConfectioneryContracts.Attributes; +using ConfectioneryDataModels.Enums; using ConfectioneryDataModels.Models; using System; using System.Collections.Generic; @@ -11,37 +12,40 @@ namespace ConfectioneryContracts.ViewModels { public class OrderViewModel : IOrderModel { - [DisplayName("Номер")] + [Column("Номер", gridViewAutoSize: GridViewAutoSize.AllCells, isUseAutoSize: true)] public int Id { get; set; } + [Column(visible: false)] public int PastryId { get; set; } + [Column(visible: false)] public int ClientId { get; set; } - [DisplayName("Фамилия клиента")] + [Column("Данные клиента", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string ClientFIO { get; set; } = string.Empty; + [Column(visible: false)] public int? ImplementerId { get; set; } - [DisplayName("Исполнитель")] + [Column("Данные исполнителя", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string ImplementerFIO { get; set; } = string.Empty; - [DisplayName("Изделие")] + [Column("Изделие", gridViewAutoSize: GridViewAutoSize.AllCells, isUseAutoSize: true)] public string PastryName { get; set; } = string.Empty; - [DisplayName("Количество")] + [Column("Количество", gridViewAutoSize: GridViewAutoSize.AllCells, isUseAutoSize: true)] public int Count { get; set; } - [DisplayName("Сумма")] + [Column("Сумма", gridViewAutoSize: GridViewAutoSize.AllCells, isUseAutoSize: true)] public double Sum { get; set; } - [DisplayName("Статус")] + [Column("Статус", gridViewAutoSize: GridViewAutoSize.AllCells, isUseAutoSize: true)] public OrderStatus Status { get; set; } = OrderStatus.Неизвестен; - [DisplayName("Дата создания")] + [Column("Дата создания", width: 100)] public DateTime DateCreate { get; set; } = DateTime.Now; - [DisplayName("Дата выполнения")] + [Column("Дата выполнения", width: 100)] public DateTime? DateImplement { get; set; } } } diff --git a/Confectionery/ConfectioneryContracts/ViewModels/PastryViewModel.cs b/Confectionery/ConfectioneryContracts/ViewModels/PastryViewModel.cs index 5d1919f..309b530 100644 --- a/Confectionery/ConfectioneryContracts/ViewModels/PastryViewModel.cs +++ b/Confectionery/ConfectioneryContracts/ViewModels/PastryViewModel.cs @@ -1,4 +1,5 @@ -using ConfectioneryDataModels.Models; +using ConfectioneryContracts.Attributes; +using ConfectioneryDataModels.Models; using System; using System.Collections.Generic; using System.ComponentModel; @@ -10,14 +11,16 @@ namespace ConfectioneryContracts.ViewModels { public class PastryViewModel : IPastryModel { + [Column(visible: false)] public int Id { get; set; } - [DisplayName("Название изделия")] + [Column("Название документа", gridViewAutoSize: GridViewAutoSize.Fill, isUseAutoSize: true)] public string PastryName { get; set; } = string.Empty; - [DisplayName("Цена")] + [Column("Цена", width: 100)] public double Price { get; set; } + [Column(visible: false)] public Dictionary PastryComponents { get; set; } = new(); } } diff --git a/Confectionery/ConfectioneryDataModels/Models/IMessageInfoModel.cs b/Confectionery/ConfectioneryDataModels/Models/IMessageInfoModel.cs index b9ef9d2..e005065 100644 --- a/Confectionery/ConfectioneryDataModels/Models/IMessageInfoModel.cs +++ b/Confectionery/ConfectioneryDataModels/Models/IMessageInfoModel.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; namespace ConfectioneryDataModels.Models { - public interface IMessageInfoModel + public interface IMessageInfoModel : IId { string MessageId { get; } int? ClientId { get; } diff --git a/Confectionery/ConfectioneryDatabaseImplement/ConfectioneryDatabaseImplement.csproj b/Confectionery/ConfectioneryDatabaseImplement/ConfectioneryDatabaseImplement.csproj index 78fdc98..53223ac 100644 --- a/Confectionery/ConfectioneryDatabaseImplement/ConfectioneryDatabaseImplement.csproj +++ b/Confectionery/ConfectioneryDatabaseImplement/ConfectioneryDatabaseImplement.csproj @@ -21,4 +21,8 @@ + + + + diff --git a/Confectionery/ConfectioneryDatabaseImplement/DatabaseImplementationExtension.cs b/Confectionery/ConfectioneryDatabaseImplement/DatabaseImplementationExtension.cs new file mode 100644 index 0000000..e9d92b0 --- /dev/null +++ b/Confectionery/ConfectioneryDatabaseImplement/DatabaseImplementationExtension.cs @@ -0,0 +1,27 @@ +using ConfectioneryContracts.DI; +using ConfectioneryContracts.StoragesContracts; +using ConfectioneryDatabaseImplement.Implements; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryDatabaseImplement +{ + public class DatabaseImplementationExtension : IImplementationExtension + { + public int Priority => 2; + + public void RegisterServices() + { + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + } + } +} diff --git a/Confectionery/ConfectioneryDatabaseImplement/Implements/BackUpInfo.cs b/Confectionery/ConfectioneryDatabaseImplement/Implements/BackUpInfo.cs new file mode 100644 index 0000000..6de6211 --- /dev/null +++ b/Confectionery/ConfectioneryDatabaseImplement/Implements/BackUpInfo.cs @@ -0,0 +1,32 @@ +using ConfectioneryContracts.StoragesContracts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryDatabaseImplement.Implements +{ + public class BackUpInfo : IBackUpInfo + { + public List? GetList() where T : class, new() + { + using var context = new ConfectioneryDatabase(); + return context.Set().ToList(); + } + public Type? GetTypeByModelInterface(string modelInterfaceName) + { + var assembly = typeof(BackUpInfo).Assembly; + var types = assembly.GetTypes(); + foreach (var type in types) + { + if (type.IsClass && + type.GetInterface(modelInterfaceName) != null) + { + return type; + } + } + return null; + } + } +} diff --git a/Confectionery/ConfectioneryDatabaseImplement/Migrations/20230504194238_migr7.Designer.cs b/Confectionery/ConfectioneryDatabaseImplement/Migrations/20230504194238_migr7.Designer.cs new file mode 100644 index 0000000..7f47076 --- /dev/null +++ b/Confectionery/ConfectioneryDatabaseImplement/Migrations/20230504194238_migr7.Designer.cs @@ -0,0 +1,298 @@ +// +using System; +using ConfectioneryDatabaseImplement; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace ConfectioneryDatabaseImplement.Migrations +{ + [DbContext(typeof(ConfectioneryDatabase))] + [Migration("20230504194238_migr7")] + partial class migr7 + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.3") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClientFIO") + .IsRequired() + .HasColumnType("text"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text"); + + b.Property("Password") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Clients"); + }); + + modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Component", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ComponentName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Cost") + .HasColumnType("double precision"); + + b.HasKey("Id"); + + b.ToTable("Components"); + }); + + modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Implementer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ImplementerFIO") + .IsRequired() + .HasColumnType("text"); + + b.Property("Password") + .IsRequired() + .HasColumnType("text"); + + b.Property("Qualification") + .HasColumnType("integer"); + + b.Property("WorkExperience") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("Implementers"); + }); + + modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Message", b => + { + b.Property("MessageId") + .HasColumnType("text"); + + b.Property("Body") + .IsRequired() + .HasColumnType("text"); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("DateDelivery") + .HasColumnType("timestamp with time zone"); + + b.Property("SenderName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Subject") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("MessageId"); + + b.HasIndex("ClientId"); + + b.ToTable("Messages"); + }); + + modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("Count") + .HasColumnType("integer"); + + b.Property("DateCreate") + .HasColumnType("timestamp with time zone"); + + b.Property("DateImplement") + .HasColumnType("timestamp with time zone"); + + b.Property("ImplementerId") + .HasColumnType("integer"); + + b.Property("PastryId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Sum") + .HasColumnType("double precision"); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.HasIndex("ImplementerId"); + + b.HasIndex("PastryId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Pastry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("PastryName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Price") + .HasColumnType("double precision"); + + b.HasKey("Id"); + + b.ToTable("Pastries"); + }); + + modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.PastryComponent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ComponentId") + .HasColumnType("integer"); + + b.Property("Count") + .HasColumnType("integer"); + + b.Property("PastryId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ComponentId"); + + b.HasIndex("PastryId"); + + b.ToTable("PastryComponents"); + }); + + modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Message", b => + { + b.HasOne("ConfectioneryDatabaseImplement.Models.Client", "Client") + .WithMany("Messages") + .HasForeignKey("ClientId"); + + b.Navigation("Client"); + }); + + modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Order", b => + { + b.HasOne("ConfectioneryDatabaseImplement.Models.Client", "Client") + .WithMany("Orders") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ConfectioneryDatabaseImplement.Models.Implementer", "Implementer") + .WithMany("Orders") + .HasForeignKey("ImplementerId"); + + b.HasOne("ConfectioneryDatabaseImplement.Models.Pastry", "Pastry") + .WithMany("Orders") + .HasForeignKey("PastryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Client"); + + b.Navigation("Implementer"); + + b.Navigation("Pastry"); + }); + + modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.PastryComponent", b => + { + b.HasOne("ConfectioneryDatabaseImplement.Models.Component", "Component") + .WithMany("PastryComponents") + .HasForeignKey("ComponentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ConfectioneryDatabaseImplement.Models.Pastry", "Pastry") + .WithMany("Components") + .HasForeignKey("PastryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Component"); + + b.Navigation("Pastry"); + }); + + modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Client", b => + { + b.Navigation("Messages"); + + b.Navigation("Orders"); + }); + + modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Component", b => + { + b.Navigation("PastryComponents"); + }); + + modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Implementer", b => + { + b.Navigation("Orders"); + }); + + modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Pastry", b => + { + b.Navigation("Components"); + + b.Navigation("Orders"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Confectionery/ConfectioneryDatabaseImplement/Migrations/20230504194238_migr7.cs b/Confectionery/ConfectioneryDatabaseImplement/Migrations/20230504194238_migr7.cs new file mode 100644 index 0000000..8a77e87 --- /dev/null +++ b/Confectionery/ConfectioneryDatabaseImplement/Migrations/20230504194238_migr7.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace ConfectioneryDatabaseImplement.Migrations +{ + /// + public partial class migr7 : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/Confectionery/ConfectioneryDatabaseImplement/Migrations/ConfectioneryDatabaseModelSnapshot.cs b/Confectionery/ConfectioneryDatabaseImplement/Migrations/ConfectioneryDatabaseModelSnapshot.cs index 0599b8f..04fcf5e 100644 --- a/Confectionery/ConfectioneryDatabaseImplement/Migrations/ConfectioneryDatabaseModelSnapshot.cs +++ b/Confectionery/ConfectioneryDatabaseImplement/Migrations/ConfectioneryDatabaseModelSnapshot.cs @@ -216,7 +216,7 @@ namespace ConfectioneryDatabaseImplement.Migrations modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Message", b => { b.HasOne("ConfectioneryDatabaseImplement.Models.Client", "Client") - .WithMany() + .WithMany("Messages") .HasForeignKey("ClientId"); b.Navigation("Client"); @@ -268,6 +268,8 @@ namespace ConfectioneryDatabaseImplement.Migrations modelBuilder.Entity("ConfectioneryDatabaseImplement.Models.Client", b => { + b.Navigation("Messages"); + b.Navigation("Orders"); }); diff --git a/Confectionery/ConfectioneryDatabaseImplement/Models/Client.cs b/Confectionery/ConfectioneryDatabaseImplement/Models/Client.cs index ed1ca9e..b9e4133 100644 --- a/Confectionery/ConfectioneryDatabaseImplement/Models/Client.cs +++ b/Confectionery/ConfectioneryDatabaseImplement/Models/Client.cs @@ -8,24 +8,34 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Runtime.Serialization; namespace ConfectioneryDatabaseImplement.Models { + [DataContract] public class Client : IClientModel { + [DataMember] public int Id { get; set; } [Required] + [DataMember] public string ClientFIO { get; set; } = string.Empty; [Required] + [DataMember] public string Email { get; set; } = string.Empty; [Required] + [DataMember] public string Password { get; set; } = string.Empty; + [ForeignKey("ClientId")] public virtual List Orders { get; set; } = new(); + [ForeignKey("ClientId")] + public virtual List Messages { get; set; } = new(); + public static Client? Create(ClientBindingModel model) { if (model == null) diff --git a/Confectionery/ConfectioneryDatabaseImplement/Models/Component.cs b/Confectionery/ConfectioneryDatabaseImplement/Models/Component.cs index 2d560d8..3de6777 100644 --- a/Confectionery/ConfectioneryDatabaseImplement/Models/Component.cs +++ b/Confectionery/ConfectioneryDatabaseImplement/Models/Component.cs @@ -8,16 +8,24 @@ using System.Text; using System.Threading.Tasks; using ConfectioneryContracts.BindingModels; using ConfectioneryContracts.ViewModels; +using System.Runtime.Serialization; namespace ConfectioneryDatabaseImplement.Models { + [DataContract] public class Component : IComponentModel { + [DataMember] public int Id { get; private set; } + [Required] + [DataMember] public string ComponentName { get; private set; } = string.Empty; + [Required] + [DataMember] public double Cost { get; set; } + [ForeignKey("ComponentId")] public virtual List PastryComponents { get; set; } = new(); public static Component? Create(ComponentBindingModel model) diff --git a/Confectionery/ConfectioneryDatabaseImplement/Models/Implementer.cs b/Confectionery/ConfectioneryDatabaseImplement/Models/Implementer.cs index 41960b7..a631c12 100644 --- a/Confectionery/ConfectioneryDatabaseImplement/Models/Implementer.cs +++ b/Confectionery/ConfectioneryDatabaseImplement/Models/Implementer.cs @@ -6,26 +6,33 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; namespace ConfectioneryDatabaseImplement.Models { + [DataContract] public class Implementer : IImplementerModel { [Required] + [DataMember] public string ImplementerFIO { get; set; } = string.Empty; [Required] + [DataMember] public string Password { get; set; } = string.Empty; [Required] + [DataMember] public int WorkExperience { get; set; } [Required] + [DataMember] public int Qualification { get; set; } [Required] + [DataMember] public int Id { get; set; } [ForeignKey("ImplementerId")] diff --git a/Confectionery/ConfectioneryDatabaseImplement/Models/Message.cs b/Confectionery/ConfectioneryDatabaseImplement/Models/Message.cs index ae181ae..2d662bc 100644 --- a/Confectionery/ConfectioneryDatabaseImplement/Models/Message.cs +++ b/Confectionery/ConfectioneryDatabaseImplement/Models/Message.cs @@ -5,14 +5,17 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; namespace ConfectioneryDatabaseImplement.Models { + [DataContract] public class Message : IMessageInfoModel { [Key] + [DataMember] public string MessageId { get; private set; } = string.Empty; public int? ClientId { get; private set; } @@ -53,5 +56,7 @@ namespace ConfectioneryDatabaseImplement.Models SenderName = SenderName, DateDelivery = DateDelivery, }; + + public int Id => throw new NotImplementedException(); } } diff --git a/Confectionery/ConfectioneryDatabaseImplement/Models/Order.cs b/Confectionery/ConfectioneryDatabaseImplement/Models/Order.cs index 73a6303..2420422 100644 --- a/Confectionery/ConfectioneryDatabaseImplement/Models/Order.cs +++ b/Confectionery/ConfectioneryDatabaseImplement/Models/Order.cs @@ -6,19 +6,23 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; namespace ConfectioneryDatabaseImplement.Models { + [DataContract] public class Order : IOrderModel { [Required] + [DataMember] public int PastryId { get; set; } public virtual Pastry Pastry { get; set; } = new(); [Required] + [DataMember] public int ClientId { get; private set; } public virtual Client Client { get; private set; } = new(); @@ -26,14 +30,22 @@ namespace ConfectioneryDatabaseImplement.Models public virtual Implementer? Implementer { get; set; } [Required] + [DataMember] public int Count { get; set; } + [Required] + [DataMember] public double Sum { get; set; } + [Required] + [DataMember] public OrderStatus Status { get; set; } + [Required] + [DataMember] public DateTime DateCreate { get; set; } + [DataMember] public DateTime? DateImplement { get; set; } public int Id { get; set; } diff --git a/Confectionery/ConfectioneryDatabaseImplement/Models/Pastry.cs b/Confectionery/ConfectioneryDatabaseImplement/Models/Pastry.cs index 1a96ad9..c059fae 100644 --- a/Confectionery/ConfectioneryDatabaseImplement/Models/Pastry.cs +++ b/Confectionery/ConfectioneryDatabaseImplement/Models/Pastry.cs @@ -7,25 +7,31 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using System.Net; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; namespace ConfectioneryDatabaseImplement.Models { + [DataContract] public class Pastry : IPastryModel { + [DataMember] public int Id { get; private set; } [Required] + [DataMember] public string PastryName { get; private set; } = string.Empty; [Required] + [DataMember] public double Price { get; private set; } private Dictionary? _pastryComponents = null; [NotMapped] + [DataMember] public Dictionary PastryComponents { get diff --git a/Confectionery/ConfectioneryFileImplement/ConfectioneryFileImplement.csproj b/Confectionery/ConfectioneryFileImplement/ConfectioneryFileImplement.csproj index 41b6c3e..69d8853 100644 --- a/Confectionery/ConfectioneryFileImplement/ConfectioneryFileImplement.csproj +++ b/Confectionery/ConfectioneryFileImplement/ConfectioneryFileImplement.csproj @@ -11,4 +11,8 @@ + + + + diff --git a/Confectionery/ConfectioneryFileImplement/FileImplementationExtension.cs b/Confectionery/ConfectioneryFileImplement/FileImplementationExtension.cs new file mode 100644 index 0000000..dc66eaf --- /dev/null +++ b/Confectionery/ConfectioneryFileImplement/FileImplementationExtension.cs @@ -0,0 +1,27 @@ +using ConfectioneryContracts.DI; +using ConfectioneryContracts.StoragesContracts; +using ConfectioneryFileImplement.Implements; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryFileImplement +{ + public class FileImplementationExtension : IImplementationExtension + { + public int Priority => 1; + + public void RegisterServices() + { + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + } + } +} diff --git a/Confectionery/ConfectioneryFileImplement/Implements/BackUpInfo.cs b/Confectionery/ConfectioneryFileImplement/Implements/BackUpInfo.cs new file mode 100644 index 0000000..4f716dd --- /dev/null +++ b/Confectionery/ConfectioneryFileImplement/Implements/BackUpInfo.cs @@ -0,0 +1,34 @@ +using ConfectioneryContracts.StoragesContracts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryFileImplement.Implements +{ + public class BackUpInfo : IBackUpInfo + { + public List? GetList() where T : class, new() + { + // Получаем значения из singleton-объекта универсального свойства содержащее тип T + var source = DataFileSingleton.GetInstance(); + return (List?)source.GetType().GetProperties() + .FirstOrDefault(x => x.PropertyType.IsGenericType && x.PropertyType.GetGenericArguments()[0] == typeof(T)) + ?.GetValue(source); + } + public Type? GetTypeByModelInterface(string modelInterfaceName) + { + var assembly = typeof(BackUpInfo).Assembly; + var types = assembly.GetTypes(); + foreach (var type in types) + { + if (type.IsClass && type.GetInterface(modelInterfaceName) != null) + { + return type; + } + } + return null; + } + } +} diff --git a/Confectionery/ConfectioneryFileImplement/Models/Client.cs b/Confectionery/ConfectioneryFileImplement/Models/Client.cs index 6df7383..474b7d1 100644 --- a/Confectionery/ConfectioneryFileImplement/Models/Client.cs +++ b/Confectionery/ConfectioneryFileImplement/Models/Client.cs @@ -4,20 +4,26 @@ using ConfectioneryDataModels.Models; using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; namespace ConfectioneryFileImplement.Models { + [DataContract] public class Client : IClientModel { + [DataMember] public string ClientFIO { get; private set; } = string.Empty; + [DataMember] public string Email { get; private set; } = string.Empty; + [DataMember] public string Password { get; private set; } = string.Empty; + [DataMember] public int Id { get; private set; } public static Client? Create(ClientBindingModel model) diff --git a/Confectionery/ConfectioneryFileImplement/Models/Component.cs b/Confectionery/ConfectioneryFileImplement/Models/Component.cs index 872b16e..087152c 100644 --- a/Confectionery/ConfectioneryFileImplement/Models/Component.cs +++ b/Confectionery/ConfectioneryFileImplement/Models/Component.cs @@ -4,16 +4,23 @@ using ConfectioneryDataModels.Models; using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; namespace ConfectioneryFileImplement.Models { - internal class Component : IComponentModel + [DataContract] + public class Component : IComponentModel { + [DataMember] public int Id { get; private set; } + + [DataMember] public string ComponentName { get; private set; } = string.Empty; + + [DataMember] public double Cost { get; set; } public static Component? Create(ComponentBindingModel? model) diff --git a/Confectionery/ConfectioneryFileImplement/Models/Implementer.cs b/Confectionery/ConfectioneryFileImplement/Models/Implementer.cs index d9d9c37..c25fb29 100644 --- a/Confectionery/ConfectioneryFileImplement/Models/Implementer.cs +++ b/Confectionery/ConfectioneryFileImplement/Models/Implementer.cs @@ -4,22 +4,29 @@ using ConfectioneryDataModels.Models; using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; namespace ConfectioneryFileImplement.Models { + [DataContract] public class Implementer : IImplementerModel { + [DataMember] public int Id { get; private set; } + [DataMember] public string ImplementerFIO { get; private set; } = string.Empty; + [DataMember] public string Password { get; private set; } = string.Empty; + [DataMember] public int WorkExperience { get; private set; } + [DataMember] public int Qualification { get; private set; } public static Implementer? Create(XElement element) diff --git a/Confectionery/ConfectioneryFileImplement/Models/Message.cs b/Confectionery/ConfectioneryFileImplement/Models/Message.cs index 549654d..e15799c 100644 --- a/Confectionery/ConfectioneryFileImplement/Models/Message.cs +++ b/Confectionery/ConfectioneryFileImplement/Models/Message.cs @@ -76,5 +76,7 @@ namespace ConfectioneryFileImplement.Models new XAttribute("SenderName", SenderName), new XAttribute("DateDelivery", DateDelivery) ); + + public int Id => throw new NotImplementedException(); } } diff --git a/Confectionery/ConfectioneryFileImplement/Models/Order.cs b/Confectionery/ConfectioneryFileImplement/Models/Order.cs index 5c0f00b..bd5dc9e 100644 --- a/Confectionery/ConfectioneryFileImplement/Models/Order.cs +++ b/Confectionery/ConfectioneryFileImplement/Models/Order.cs @@ -5,30 +5,41 @@ using ConfectioneryDataModels.Models; using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; namespace ConfectioneryFileImplement.Models { + [DataContract] public class Order : IOrderModel { + [DataMember] public int Id { get; private set; } + [DataMember] public int PastryId { get; private set; } + [DataMember] public int ClientId { get; private set; } + [DataMember] public int? ImplementerId { get; private set; } + [DataMember] public int Count { get; private set; } + [DataMember] public double Sum { get; private set; } + [DataMember] public OrderStatus Status { get; set; } = OrderStatus.Неизвестен; + [DataMember] public DateTime DateCreate { get; set; } = DateTime.Now; + [DataMember] public DateTime? DateImplement { get; set; } public static Order? Create(OrderBindingModel? model) diff --git a/Confectionery/ConfectioneryFileImplement/Models/Pastry.cs b/Confectionery/ConfectioneryFileImplement/Models/Pastry.cs index 399f1bc..07b8177 100644 --- a/Confectionery/ConfectioneryFileImplement/Models/Pastry.cs +++ b/Confectionery/ConfectioneryFileImplement/Models/Pastry.cs @@ -4,25 +4,30 @@ using ConfectioneryDataModels.Models; using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; namespace ConfectioneryFileImplement.Models { + [DataContract] public class Pastry : IPastryModel { + [DataMember] public int Id { get; private set; } + [DataMember] public string PastryName { get; private set; } = string.Empty; + [DataMember] public double Price { get; private set; } public Dictionary Components { get; private set; } = new(); private Dictionary? _pastryComponents = null; - + [DataMember] public Dictionary PastryComponents { get diff --git a/Confectionery/ConfectioneryListImplement/ConfectioneryListImplement.csproj b/Confectionery/ConfectioneryListImplement/ConfectioneryListImplement.csproj index 41b6c3e..69d8853 100644 --- a/Confectionery/ConfectioneryListImplement/ConfectioneryListImplement.csproj +++ b/Confectionery/ConfectioneryListImplement/ConfectioneryListImplement.csproj @@ -11,4 +11,8 @@ + + + + diff --git a/Confectionery/ConfectioneryListImplement/Implements/BackUpInfo.cs b/Confectionery/ConfectioneryListImplement/Implements/BackUpInfo.cs new file mode 100644 index 0000000..850adf3 --- /dev/null +++ b/Confectionery/ConfectioneryListImplement/Implements/BackUpInfo.cs @@ -0,0 +1,22 @@ +using ConfectioneryContracts.StoragesContracts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryListImplement.Implements +{ + public class BackUpInfo : IBackUpInfo + { + public List? GetList() where T : class, new() + { + throw new NotImplementedException(); + } + + public Type? GetTypeByModelInterface(string modelInterfaceName) + { + throw new NotImplementedException(); + } + } +} diff --git a/Confectionery/ConfectioneryListImplement/ListImplementationExtension.cs b/Confectionery/ConfectioneryListImplement/ListImplementationExtension.cs new file mode 100644 index 0000000..21c6dad --- /dev/null +++ b/Confectionery/ConfectioneryListImplement/ListImplementationExtension.cs @@ -0,0 +1,26 @@ +using ConfectioneryContracts.DI; +using ConfectioneryContracts.StoragesContracts; +using ConfectioneryListImplement.Implements; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryListImplement +{ + public class ListImplementationExtension : IImplementationExtension + { + public int Priority => 0; + public void RegisterServices() + { + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + } + } +} diff --git a/Confectionery/ConfectioneryListImplement/Models/Message.cs b/Confectionery/ConfectioneryListImplement/Models/Message.cs index 675d30e..0c576af 100644 --- a/Confectionery/ConfectioneryListImplement/Models/Message.cs +++ b/Confectionery/ConfectioneryListImplement/Models/Message.cs @@ -49,5 +49,7 @@ namespace ConfectioneryListImplement.Models SenderName = SenderName, DateDelivery = DateDelivery, }; + + public int Id => throw new NotImplementedException(); } } diff --git a/Confectionery/ConfectioneryView/DataGridViewExtension.cs b/Confectionery/ConfectioneryView/DataGridViewExtension.cs new file mode 100644 index 0000000..7840c7a --- /dev/null +++ b/Confectionery/ConfectioneryView/DataGridViewExtension.cs @@ -0,0 +1,55 @@ +using ConfectioneryContracts.Attributes; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryView +{ + public static class DataGridViewExtension + { + public static void FillAndConfigGrid(this DataGridView grid, List? + data) + { + if (data == null) + { + return; + } + grid.DataSource = data; + var type = typeof(T); + var properties = type.GetProperties(); + foreach (DataGridViewColumn column in grid.Columns) + { + var property = properties.FirstOrDefault(x => x.Name == + column.Name); + if (property == null) + { + throw new InvalidOperationException($"В типе {type.Name} не найдено свойство с именем {column.Name}"); + } + var attribute = + property.GetCustomAttributes(typeof(ColumnAttribute), true)?.SingleOrDefault(); + if (attribute == null) + { + throw new InvalidOperationException($"Не найден атрибут типа ColumnAttribute для свойства {property.Name}"); + } + // ищем нужный нам атрибут + if (attribute is ColumnAttribute columnAttr) + { + column.HeaderText = columnAttr.Title; + column.Visible = columnAttr.Visible; + if (columnAttr.IsUseAutoSize) + { + column.AutoSizeMode = + (DataGridViewAutoSizeColumnMode)Enum.Parse(typeof(DataGridViewAutoSizeColumnMode) + , columnAttr.GridViewAutoSize.ToString()); + } + else + { + column.Width = columnAttr.Width; + } + } + } + } + } +} diff --git a/Confectionery/ConfectioneryView/FormClients.cs b/Confectionery/ConfectioneryView/FormClients.cs index 00b5f16..0d474d2 100644 --- a/Confectionery/ConfectioneryView/FormClients.cs +++ b/Confectionery/ConfectioneryView/FormClients.cs @@ -31,13 +31,7 @@ namespace ConfectioneryView { try { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["Id"].Visible = false; - dataGridView.Columns["ClientFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - } + dataGridView.FillAndConfigGrid(_logic.ReadList(null)); _logger.LogInformation("Загрузка клиентов"); } catch (Exception ex) diff --git a/Confectionery/ConfectioneryView/FormComponents.cs b/Confectionery/ConfectioneryView/FormComponents.cs index bf9ea07..f8141ac 100644 --- a/Confectionery/ConfectioneryView/FormComponents.cs +++ b/Confectionery/ConfectioneryView/FormComponents.cs @@ -1,6 +1,7 @@ using Confectionery; using ConfectioneryContracts.BindingModels; using ConfectioneryContracts.BusinessLogicsContracts; +using ConfectioneryContracts.DI; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; @@ -36,14 +37,8 @@ namespace ConfectioneryView { try { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["Id"].Visible = false; - dataGridView.Columns["ComponentName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - } - _logger.LogInformation("Загрузка компонентов"); + dataGridView.FillAndConfigGrid(_logic.ReadList(null)); + _logger.LogInformation("Загрузка компонентов"); } catch (Exception ex) { @@ -54,7 +49,7 @@ namespace ConfectioneryView private void ButtonAdd_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormComponent)); + var service = DependencyManager.Instance.Resolve(); if (service is FormComponent form) { if (form.ShowDialog() == DialogResult.OK) @@ -68,8 +63,8 @@ namespace ConfectioneryView { if (dataGridView.SelectedRows.Count == 1) { - var service = Program.ServiceProvider?.GetService(typeof(FormComponent)); - if (service is FormComponent form) + var service = DependencyManager.Instance.Resolve(); + if (service is FormComponent form) { form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); if (form.ShowDialog() == DialogResult.OK) diff --git a/Confectionery/ConfectioneryView/FormImplementers.cs b/Confectionery/ConfectioneryView/FormImplementers.cs index 17ca717..6c9a628 100644 --- a/Confectionery/ConfectioneryView/FormImplementers.cs +++ b/Confectionery/ConfectioneryView/FormImplementers.cs @@ -1,6 +1,7 @@ using Confectionery; using ConfectioneryContracts.BindingModels; using ConfectioneryContracts.BusinessLogicsContracts; +using ConfectioneryContracts.DI; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; @@ -33,16 +34,7 @@ namespace ConfectioneryView { try { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["Id"].Visible = false; - dataGridView.Columns["ImplementerFIO"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - dataGridView.Columns["Password"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - dataGridView.Columns["WorkExperience"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - dataGridView.Columns["Qualification"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - } + dataGridView.FillAndConfigGrid(_logic.ReadList(null)); _logger.LogInformation("Загрузка исполнителей"); } catch (Exception ex) @@ -54,7 +46,7 @@ namespace ConfectioneryView private void ButtonAdd_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormImplementer)); + var service = DependencyManager.Instance.Resolve(); if (service is FormImplementer form) { if (form.ShowDialog() == DialogResult.OK) @@ -68,7 +60,7 @@ namespace ConfectioneryView { if (dataGridView.SelectedRows.Count == 1) { - var service = Program.ServiceProvider?.GetService(typeof(FormImplementer)); + var service = DependencyManager.Instance.Resolve(); if (service is FormImplementer form) { form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); diff --git a/Confectionery/ConfectioneryView/FormMails.cs b/Confectionery/ConfectioneryView/FormMails.cs index 15174f2..374cdfb 100644 --- a/Confectionery/ConfectioneryView/FormMails.cs +++ b/Confectionery/ConfectioneryView/FormMails.cs @@ -1,4 +1,6 @@ -using ConfectioneryContracts.BusinessLogicsContracts; +using ConfectioneryBusinessLogic.BusinessLogics; +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.BusinessLogicsContracts; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; @@ -17,6 +19,7 @@ namespace ConfectioneryView private readonly ILogger _logger; private readonly IMessageInfoLogic _logic; + public FormMails(ILogger logger, IMessageInfoLogic logic) { InitializeComponent(); @@ -28,14 +31,7 @@ namespace ConfectioneryView { try { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["ClientId"].Visible = false; - dataGridView.Columns["MessageId"].Visible = false; - dataGridView.Columns["Body"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - } + dataGridView.FillAndConfigGrid(_logic.ReadList(null)); _logger.LogInformation("Загрузка списка писем"); } catch (Exception ex) @@ -44,6 +40,6 @@ namespace ConfectioneryView MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); } - } + } } } diff --git a/Confectionery/ConfectioneryView/FormMain.Designer.cs b/Confectionery/ConfectioneryView/FormMain.Designer.cs index a2e3310..9fd560a 100644 --- a/Confectionery/ConfectioneryView/FormMain.Designer.cs +++ b/Confectionery/ConfectioneryView/FormMain.Designer.cs @@ -46,6 +46,7 @@ this.списокЗаказовToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.запускРаботыToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.письмаToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.бэкапToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit(); this.menuStrip1.SuspendLayout(); this.SuspendLayout(); @@ -115,7 +116,8 @@ this.справочникиToolStripMenuItem, this.отчётыToolStripMenuItem, this.запускРаботыToolStripMenuItem, - this.письмаToolStripMenuItem}); + this.письмаToolStripMenuItem, + this.бэкапToolStripMenuItem}); this.menuStrip1.Location = new System.Drawing.Point(0, 0); this.menuStrip1.Name = "menuStrip1"; this.menuStrip1.Size = new System.Drawing.Size(800, 24); @@ -206,6 +208,13 @@ this.письмаToolStripMenuItem.Text = "Письма"; this.письмаToolStripMenuItem.Click += new System.EventHandler(this.MailToolStripMenuItem_Click); // + // бэкапToolStripMenuItem + // + this.бэкапToolStripMenuItem.Name = "бэкапToolStripMenuItem"; + this.бэкапToolStripMenuItem.Size = new System.Drawing.Size(51, 20); + this.бэкапToolStripMenuItem.Text = "Бэкап"; + this.бэкапToolStripMenuItem.Click += new System.EventHandler(this.СreateBackupToolStripMenuItem_Click); + // // FormMain // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); @@ -250,5 +259,6 @@ private ToolStripMenuItem исполнителиToolStripMenuItem; private ToolStripMenuItem запускРаботыToolStripMenuItem; private ToolStripMenuItem письмаToolStripMenuItem; + private ToolStripMenuItem бэкапToolStripMenuItem; } } \ No newline at end of file diff --git a/Confectionery/ConfectioneryView/FormMain.cs b/Confectionery/ConfectioneryView/FormMain.cs index 0b3d4e3..2d07927 100644 --- a/Confectionery/ConfectioneryView/FormMain.cs +++ b/Confectionery/ConfectioneryView/FormMain.cs @@ -2,6 +2,7 @@ using ConfectioneryBusinessLogic.BusinessLogics; using ConfectioneryContracts.BindingModels; using ConfectioneryContracts.BusinessLogicsContracts; +using ConfectioneryContracts.DI; using ConfectioneryDataModels.Enums; using Microsoft.Extensions.Logging; using System; @@ -22,13 +23,16 @@ namespace ConfectioneryView private readonly IOrderLogic _orderLogic; private readonly IReportLogic _reportLogic; private readonly IWorkProcess _workProcess; - public FormMain(ILogger logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess) + private readonly IBackUpLogic _backUpLogic; + + public FormMain(ILogger logger, IOrderLogic orderLogic, IReportLogic reportLogic, IWorkProcess workProcess, IBackUpLogic backUpLogic) { InitializeComponent(); _logger = logger; _orderLogic = orderLogic; _reportLogic = reportLogic; _workProcess = workProcess; + _backUpLogic = backUpLogic; } private void FormMain_Load(object sender, EventArgs e) { @@ -60,7 +64,7 @@ namespace ConfectioneryView private void ComponentsToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormComponents)); + var service = DependencyManager.Instance.Resolve(); if (service is FormComponents form) { form.ShowDialog(); @@ -68,7 +72,7 @@ e) } private void PastriesToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormPastries)); + var service = DependencyManager.Instance.Resolve(); if (service is FormPastries form) { form.ShowDialog(); @@ -77,7 +81,7 @@ e) private void ButtonCreateOrder_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormCreateOrder)); + var service = DependencyManager.Instance.Resolve(); if (service is FormCreateOrder form) { form.ShowDialog(); @@ -201,7 +205,7 @@ e) private void PastryComponentsToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormReportPastryComponents)); + var service = DependencyManager.Instance.Resolve(); if (service is FormReportPastryComponents form) { form.ShowDialog(); @@ -210,7 +214,7 @@ e) private void OrdersToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormReportOrders)); + var service = DependencyManager.Instance.Resolve(); if (service is FormReportOrders form) { form.ShowDialog(); @@ -219,7 +223,7 @@ e) private void ClientsToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormClients)); + var service = DependencyManager.Instance.Resolve(); if (service is FormClients form) { form.ShowDialog(); @@ -228,7 +232,7 @@ e) private void ImplementersToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormImplementers)); + var service = DependencyManager.Instance.Resolve(); if (service is FormImplementers form) { form.ShowDialog(); @@ -237,7 +241,7 @@ e) private void DoWorkToolStripMenuItem_Click(object sender, EventArgs e) { - _workProcess.DoWork((Program.ServiceProvider?.GetService(typeof(IImplementerLogic)) as IImplementerLogic)!, _orderLogic); + _workProcess.DoWork(DependencyManager.Instance.Resolve(), _orderLogic); MessageBox.Show("Процесс обработки запущен", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information); } @@ -249,11 +253,37 @@ e) private void MailToolStripMenuItem_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormMails)); + var service = DependencyManager.Instance.Resolve(); if (service is FormMails form) { form.ShowDialog(); } } + + private void СreateBackupToolStripMenuItem_Click(object sender, EventArgs e) + { + try + { + if (_backUpLogic != null) + { + var fbd = new FolderBrowserDialog(); + if (fbd.ShowDialog() == DialogResult.OK) + { + _backUpLogic.CreateBackUp(new BackUpSaveBindingModel + { + FolderName = fbd.SelectedPath + }); + MessageBox.Show("Бекап создан", "Сообщение", + MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, + MessageBoxIcon.Error); + } + + } } } diff --git a/Confectionery/ConfectioneryView/FormPastries.cs b/Confectionery/ConfectioneryView/FormPastries.cs index eaeec26..51e75ca 100644 --- a/Confectionery/ConfectioneryView/FormPastries.cs +++ b/Confectionery/ConfectioneryView/FormPastries.cs @@ -1,6 +1,7 @@ using Confectionery; using ConfectioneryContracts.BindingModels; using ConfectioneryContracts.BusinessLogicsContracts; +using ConfectioneryContracts.DI; using Microsoft.Extensions.Logging; using Microsoft.VisualBasic.Logging; using System; @@ -35,14 +36,7 @@ namespace ConfectioneryView { try { - var list = _logic.ReadList(null); - if (list != null) - { - dataGridView.DataSource = list; - dataGridView.Columns["Id"].Visible = false; - dataGridView.Columns["PastryName"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; - dataGridView.Columns["PastryComponents"].Visible = false; - } + dataGridView.FillAndConfigGrid(_logic.ReadList(null)); _logger.LogInformation("Загрузка компьютеров"); } catch (Exception ex) @@ -54,7 +48,7 @@ namespace ConfectioneryView private void ButtonAdd_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormPastry)); + var service = DependencyManager.Instance.Resolve(); if (service is FormPastry form) { if (form.ShowDialog() == DialogResult.OK) @@ -68,7 +62,7 @@ namespace ConfectioneryView { if (dataGridView.SelectedRows.Count == 1) { - var service = Program.ServiceProvider?.GetService(typeof(FormPastry)); + var service = DependencyManager.Instance.Resolve(); if (service is FormPastry form) { form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value); diff --git a/Confectionery/ConfectioneryView/FormPastry.cs b/Confectionery/ConfectioneryView/FormPastry.cs index 8494d1f..02407ee 100644 --- a/Confectionery/ConfectioneryView/FormPastry.cs +++ b/Confectionery/ConfectioneryView/FormPastry.cs @@ -13,6 +13,7 @@ using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using Confectionery; +using ConfectioneryContracts.DI; namespace ConfectioneryView { @@ -85,7 +86,7 @@ namespace ConfectioneryView private void ButtonAdd_Click(object sender, EventArgs e) { - var service = Program.ServiceProvider?.GetService(typeof(FormPastryComponent)); + var service = DependencyManager.Instance.Resolve(); if (service is FormPastryComponent form) { if (form.ShowDialog() == DialogResult.OK) @@ -113,8 +114,7 @@ namespace ConfectioneryView { if (dataGridView.SelectedRows.Count == 1) { - var service = - Program.ServiceProvider?.GetService(typeof(FormPastryComponent)); + var service = DependencyManager.Instance.Resolve(); if (service is FormPastryComponent form) { int id = diff --git a/Confectionery/ConfectioneryView/Program.cs b/Confectionery/ConfectioneryView/Program.cs index d8513fb..01a8cf7 100644 --- a/Confectionery/ConfectioneryView/Program.cs +++ b/Confectionery/ConfectioneryView/Program.cs @@ -4,6 +4,7 @@ using ConfectioneryBusinessLogic.OfficePackage; using ConfectioneryBusinessLogic.OfficePackage.Implements; using ConfectioneryContracts.BindingModels; using ConfectioneryContracts.BusinessLogicsContracts; +using ConfectioneryContracts.DI; using ConfectioneryContracts.StoragesContracts; using ConfectioneryDatabaseImplement.Implements; using ConfectioneryView; @@ -15,9 +16,6 @@ namespace Confectionery { internal static class Program { - private static ServiceProvider? _serviceProvider; - public static ServiceProvider? ServiceProvider => _serviceProvider; - /// /// The main entry point for the application. /// @@ -27,13 +25,11 @@ namespace Confectionery // To customize application configuration such as set high DPI settings or default font, // see https://aka.ms/applicationconfiguration. ApplicationConfiguration.Initialize(); - var services = new ServiceCollection(); - ConfigureServices(services); - _serviceProvider = services.BuildServiceProvider(); + InitDependency(); try { - var mailSender = _serviceProvider.GetService(); + var mailSender = DependencyManager.Instance.Resolve(); mailSender?.MailConfig(new MailConfigBindingModel { MailLogin = @@ -57,56 +53,48 @@ namespace Confectionery } catch (Exception ex) { - var logger = _serviceProvider.GetService(); + var logger = DependencyManager.Instance.Resolve(); } - Application.Run(_serviceProvider.GetRequiredService()); + Application.Run(DependencyManager.Instance.Resolve()); } - private static void ConfigureServices(ServiceCollection services) + private static void InitDependency() { - services.AddLogging(option => + DependencyManager.InitDependency(); + DependencyManager.Instance.AddLogging(option => { option.SetMinimumLevel(LogLevel.Information); option.AddNLog("nlog.config"); }); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddSingleton(); - - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(true); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); + DependencyManager.Instance.RegisterType(); } - private static void MailCheck(object obj) => ServiceProvider? - .GetService()?.MailCheck(); + private static void MailCheck(object obj) => DependencyManager.Instance.Resolve()?.MailCheck(); } } \ No newline at end of file diff --git a/Confectionery/ImplementationExtensions/ConfectioneryContracts.dll b/Confectionery/ImplementationExtensions/ConfectioneryContracts.dll new file mode 100644 index 0000000000000000000000000000000000000000..134c90eed6e9d75b6042e34434586086e85e82cb GIT binary patch literal 31744 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%0DC2KO@f6Jg3V46TN7f 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 S!OgS&$?5$6=>J#N!2bci#_N9o literal 0 HcmV?d00001 diff --git a/Confectionery/ImplementationExtensions/ConfectioneryDataModels.dll b/Confectionery/ImplementationExtensions/ConfectioneryDataModels.dll new file mode 100644 index 0000000000000000000000000000000000000000..08a57faaab8e3cf2e8cfceb9d45d3583e18cef7b GIT binary patch literal 6144 zcmeHLeT-aH6+iD|w$t72w%ZR{XiEo{%2H%H{Xz>uce=CNj&!@*&UOpBX8UI5?)1?& z?@iu&({?aoX~AFwAt*#e(KZGRXe^}FA{PDtRALCT5n@b?F_1`t7$A`ZKVtoz``*mF zX)Oi}iGO%^@9&*+?z!ilbMD8y`$j%>FKI-iqn*1BV_>ICtYDVP-I_e4=UTb05wtuh&D%9Nj}ecMPc7miqTgS zM8E4MQdsx_%B5;QdUw*Qd`PH^?_LCRD=*N#`8gQXS6$y|(9YrEv%U&W=03Su2|eI= z_ODN-lIv3I)@)>lVq^g`SQmY_5*^2LYYcSGcTKzGvBtYyL7Mt@<>()vdD{E7?8;{F zoCAY(_|do7a`LQGEpbLMLd9+b^Tiej&?t^9KIR1I$ zz{d@sbvlY39>uZJG{ni=0xjSW3AjYa&6b=Ja$S;pRSh)fO75MITO_$usJWaJxN}tB zr0>883HbP`b{+6pHBB8IW0awZLp`xAz&?p7iSOzx(Lj$S-~@eP$%8TrH#NB(h{bJk z6W|UvIc^Ke&$|!MWQ5y{?b2$yPK$D<+S=Z3<6hQ_k$$V&+S>cQ*f!n)Ejs$GZT%ji zy%C$Qw6(paS0Zgc)T4g>zKwgdZM=utxVzd$_>~^@ zZ<1&LJE#U+M5d(U*zcFgF|GhEp(Jn_tpg_L<7l~vo>5lf2)zLP}`Mc@rmo&yfjr=d597?Lz3treuCASDGVkfR7GKO*Hvr2Giv z4=8s?`7?AWomQTc^sAEA6qfW!EJ!pp_BMtLc3@}D!fuQMXT$GK#B;G4E zU(~s;t+C~Y^+$n8g?pXWj{|2Z-1m9n);shk;CBqWTtx&i8N)1K95JXe4i%AfgYKfa zz&VIY1-}5;gY#E~bTM!qB30406gZ!j0~g>#RE~VALWmr=x`mY0COnlm{ppTJ$h?;8@PNQ6ovyV^uMp;Tr?`wagUbJ%9f!~7Pc?k;q0gs4O%96 z=JvCVsVU0UJYSTPgN|hhX~;`%5w>v60%fzsz)tWO5uRt1L_^pz9!dh+Av0!pzFTWC z-T}uA%#6Xbkal-F?!KXe6^te9P?QsPQMlWUa-cEjlq-%6kDHRfu4FTYFUC!1h9T^% z+CH-!I=2nF0!TyUyeJk$G412WJ70x_t(ul_Wt>onG&PlWai~p>G9q6sl{oz^Sz|(4 zlC5P!r?8BJlJZ*Z4UflMteb-0YG?!pyZjQ_YH0Le%Z6QRHH7Jxa^K9Gmgz@Y zH`kE(Vaq6;HCxFrBD_{nwz0wxG1jrLC_Cz6IfQg%Ifs&9#Wk45S_%1Jr34HwiJ`J# zT9|u#I#}nztznfIQo&0WEi3d)uAf}BOhYz+d+w+jmN{(}Wb&H+i|KH~P_p1VZbP0i zjgswnzFF`ZqA)YqW5K%133osCfETVRgw9TQ%^l8Z@@T{?xQ^#c`{-8`Y1^=Bp6Q)8 zfFO?ZHJ?wOzKUII6>i5ljseYnRRipQ`_) z{&@Z5%x!2t$--~X9D?xl%sn%Q1LddD?@1Ow>oD~0369cZhesb-{Y#_!4md9X~E%%^y&q~mu-n0_e6VyAzkiw0PCA~vEAm(S)_@dqsb^fxr){kEO z=+%#2{b8?u?gdE20||P8i1dmp_|fBXF~5tCs~7Bcjmmb%9y(YM6+S@5_qxsjPl4Vn z>E{N8mL#_ijSo7mNLMN!4L9R;`>#%>V4!DV^U%teUd1wM^59*j(Bkv#BizaqipkRw z*BT772Dd8w1#-#Yx}ebQ`}h_!u6Cy_%Q-MowR{u5RS?Y1+I#VXfJ2$pwk`b6YREWZ z=~D3f&%dxTE>P>|ZM~nAkujd9M^K-|-TK+^ZVp!JEx_|~R2%nGyO*V{5>b`How-cz z?yKH9eoJXM^Vs*g{{GsRZ+CgD!D}XWc{sZ#4NKGtlR2mA7R2OEQE|MEv&olu4bmg^#&u@77XGR*HGbZB4J;a5aU_o@hAB z33+|@zGK~;kG}Ea1=`n7hnI4W?l(*)m^!yKF7H7L+;=mUHDZ`HmAwMijgV(&*ze3r zm^nLjXW3Mw!V;oG?G3@)VX2%WXFdLQaN_{Jd3OGbNL1po!WjpvR za5(ttf_KI@{~649V|4`2O`#p$*1S%lB?Cr*RfAmEG4VY>z@|;pM?;sPVU+@}P;v@P4V_-QS@yRpb~oL}Y*y z(mc1YHv(__jd2CWso`eJo)|O&jUw7Dc!%6cdyPmkkbCIKepQ tNMjB>m|-3`z#CZJ9w+JIcDFi-~+uav$h%QS`vYb!RRHJ+BV_LMCn1e%oqb*9@!= z*Uth&e1nhD&{Oao^;d=N8dzU9F9b#QmEg0)U|uJ^QBlPNJ(S~$KlaU}I2!yi(cPPg z+$BY2k3f;x(1R$kAHMVTcL9Ibo54bSo1UdCHoZ$(YQ`-UAuMMN_R#V8M!gxH(*O$+ zO>5xcR{wFqo~$WWErFpTF!~P;_7XnZv81k0G4u0+CBkRJRs+LOZ-5FTr^3kXC-oer zTT=Yk`Bz_2-1q3CZ#pijl29qsr)joRM+g}kVLMfX0?cN+@pLilq6;(p_3(dTk5#E? zP9R6Qo|s92MR91>N(KYG<^GDKT{(=0%3)zcAXfz}DbolnLe3YgWMJztuJ!UvX;gBi z8CVq0dJJqm#+6>M53F)81od}c{oPN0SLpBl`g?%>9?0KcM0$&hqqn#;dW#F2soter z*i4OE%7x8TYbh5tQ{$IPVTtiJ!~(+!ed&Ww=*#`@1IMbo4NwQ0OZ}Has#DL@oyzrF4Gg7I`_}{q0XG}iA4^~e(?%kaW{B|FKdXUZXejds2Zsrt{k0kx zhK4ggFSw8J*?+5nVQ2(^P8!b5U&A^6EBqzz@k)EWMC^Yt`!SR>AAMX z3r*?KEGyFrEW)LrU?l@vk?{^gW`DGYht2`|`#}D7CNLIbNU#(`LWIuzg%ORM&w$Ym z^B0%08W_6gFE(RIRiR>_k@<`5S`7@lp1-WG>tA%`qL}YIe{mf#<}WcWx!7_3+Ruod zzu4-YiUpOQ7nTae5kJYnIfk`ev}6hSZ}HaG7Uvv zb7rD`{wrR6>by0sKI6(`%pY8Lj6SPkcIWv+>Xi8dgORUA_n>KfCKo9{cRz?#6zk&#_98J|C^W$LQ~|{O$BPtD(2q9t z(C1m5`97% zmPN5kge{c@qS)%1A$7*?bH5qg=Um&K^f@0d ze^21=dm`hV)zSB?jlO4P?t50|b%`iT4y?d9NRS-x>l`@8>VKvl_iV&!V5oASMvr^8 zYKbQ*2gd1f&(&BB3{?&c*5jV5wHg?z14CJUM9&9H;1~ZDzx?^|V_dl* z?sU!#_9@1EAkK8o4e_P(dO}>0^+Z3^&GW>Y_)e60Vl{H6ATm#|7kiR3?AD&-4Ewn! zIm3?cE@uK*BXCQ0yGDpiD2G9tlWU^>o}|AI*WX9z?<4v9EUtAU{`cy}I5CI1y~828mXu3QvH zJLe*M8zUFR&CaWjRz&>x%vUOAbb;8dxsH}2Vy0$v_J^34of zq=X^g%s{sbL%x}TN`xWb%;=*T^39B(X2>@)`f7%Jqp?Rz{fT*Mt}^Ku$x?tIu*94Y zQlrAg%_!Uxg?pp$xG3C;!s8k5hYAa&LbMY#dcpAU4X?DK!e$5pjs7-65HJSV3_-vc zXfp%>W01`d1kK<%1Nlj*+!v-_x*?AINfif#XJOt5n4xKKD1jdFlA%AqmCGg*OyVsbMRmvT6wVm}z9 z#9k1@4Y$IIAqW__l~)Wwz`$LxVhAE}#rl=fI>vQScp+RxC}*SIP#tiNE4~v$b2M=> z6LXo6P>L;7!;cU%$Sw|Lr}!z+#ZgihPplwI#+ymV_>O&%kBD=0tRMl#SjDx%+rb?2pE{56+;k}%Sa^zsY5Q04>!SCggFG)LT3Tzn4=#OL-m?i z#KdAvfSDLNT@zs@&SXOMhBIa|r9ZT3lyyv>#)NGeh8)vpFkzd9Rc%^&ipNZK=YATF zu3=w;Vh{xT8Wdkau&+Te2!eeLim&K)$(uv*&41w~5TOh4WpML1j!ogC1faNb1dK5@Ll7|Fld>TQ7>C#lLBK#JDh)xv7-usC0b{()5Cn_~ zHbW3F4zn48fHBc#2!fdKdad3h@}vL5IR;sYmS^d7Xpz;xU$_z_#rOA-KY8RNsDc(tP6q(03j4{{JIuu zp{uoD=oG6J7x0*VP5t41vGLvcmB@Z2v0u=3{94C;U8ns*Ct0oOUHG-6vtO+}aLXdG z4Z_53!^d^)&dp?YGlku}A==IB+0Eu?4#bI}8>2bvnR8P#2L%#CzmDc?V9qAtBv+8H zALn0}>mD{36oZ(lxnxjEf{>O-)Ua;yQVa5!|HANx=aE}cL1-gzz6K+)EOtu>WQ!HL zSrMUYm^g+3d}MJ5sb+=lVQ`BsfSN3JSj32e6_97paY4Qm1O`~;vUCceMzO!1)iEH1 zfXi0sc1^$?D|Ck@;DHsoQxmAl3Sn5ux*+@;P)kQ4?`5H7@e{J>sb>;MS!fA@0e!g5 z5Cn`PY=$6+ZycS9*ksH6&UY?6q;c;snM^bEAZk13c<=%Pa?8&-4#+O62PT0qMrUH6 zktOGx;1=hzc(aIE62v&F;M-|0$$gPmW_S2887%Qs5HOCi8G^81A^4TU^G<=xJLb|8 z*^Ea`IapLDR~#kr2zWyGqQVer#YM;yx{nEPgt(sx03jX#VePUC*+;Z3F_^~rj3HGK zdWcmd>FRNxBsPL#0|eU$iVduz9|3{9K?JPOqrf?dBqtuz1gf_}k81)oTA?SH=tl*E zee?&DD3{w*ByI98oq;x4=F%EzT4+4fTm6wC{u_HrOi5_{EkqrLr_~y?Rn>&Z#-b)f zj!K6jt_d+=LokB_kZDH&Q+ZN+XbXzv>@x8{foI}Mj05cZiEHr)UM~(FhE!rOi{rMH z+vW*v!&f=Qhn~cDR$RrQnQ_6V7_}(FvKrX05C=cQVofXbJKzmZ12AUcTGC1583@Y> zW}XEy;O=+QGUImT^umM|dJYVF%dXPXgqJVrO zy$nvd9b~lX51{wU{{H*#(G&5za(X*GVftl!_ambaPSQIxb*O=+G5)Oa#bc)6ztu}6 zo`!S*eP_etU$1w0t2T1Oek1n;{4o$Jz`*z?fz;1Ubu; z`@f|uHPz(GeA@}W{`lk=2e$`LQ+|g5dCn|o$b>i($S$jt2gEA~PoR+{{&UcS(eg5u z|54;D@rN+}E6P3fZ?mmBw{C!SUlm=J_|G}nEiY&JYa(ZfKa{6z{e^AKaqISB-Pc8z zCH`|xam#}&e?#Of@rSTnV86a&TXWsIeOdQS(PfGM99%P^+t`ogZ;6~G{!qTM)ytxV zVz7P&Fn^BUA9@>FsO5}^WV1`s?+t{RL*oyr(>d)q2YY}EsOP+j0w9q6dC#HAW?s}6EhSz@b7vlhBl2Ro`Pu~o&_ zMQ+t0jw(x(Du!clJ3@i08OJ-5a2X@yAf7wcZ$c}i=jtB?mPxy^2Vj!0GL2o?ybz7g z@#p&e{sXNfOX>=|c3AX3%T=dlUiAbb%?2g}GeOqbwOKeq%z&UQ!gB?|t zDAnjenKihCctL^@$73>*zmcqpB#DgDR-O*!7BP_rArIL2Oj8Y5UyeT~N9Iev-%?|` zvx*Gq2-`+5&ixTH-63{?NadlPYOqEeSJO)Lz>5qjZY!=|KT}(|C0#ZX7cQBuRDf)+ z|Ed(Gsw}ZpC4-l_ zRmVE2EU{H(v@Lh59^$C7#8wpt&U33C>Zr2BRu!w~yH&?Isw}ZpWei{7RvquCvcy)E zU|r}|o#3dl#8#CET;x_g%u!{DQgy~KuC4f=uNObM&sW$LUJPWHb+}U@OKjhy87tkY zM>wi1u~jAHtK6zbI;t$ORi(wN-KvuvRhHPQ(mR*9RgZF1Sz@b-1DCp0r#PxCu~o(D z8n^0HN0lYEs`U9~Zq=h5RhHPQ60FPJs>e90EU{H30&Cr>$2zJkQL0X#tF=@c<}$sO z`YN)f`1#gS8Hu>0UupYw1(03VaqQP8SS$n@S>iwED!2T2mVYX8miYOE1FxkjU`ws_ z*wg5>)bTD!Jy+Uc#U!~s7HyS3Pkp3BnJg5}Xd}oIz&9<{q#8B?W%v zZuALGXR*ZYS4n}Z-Kr-#sw}ZpZ{kp2<5oS%QDup(Dw%z)TXlw`$`V^u5^J4XwZ>6p ziLEMw;5xTzt)t2kTU8vm-mN;*QDup(DpqfBtIl#%Sz@b7T-Uo*XFIAau~j9m&2Clv zg2Gr}SznT!XP_|Li7E&m0}|0;5p_(Q$acqxD_F(}I!XT0<~2#YkX$i9u`dH=j0o5#O) zJASBbs~6h=me{H?IySpiPj^&VVyjAT-Q!k0!%=04tt!2BuUqv@N0lYEs>Jm^x9So{ zl_g5m86D2Lg1C>`Y>b ztt!4g;Z|MlsItUX6$gIfR>d#HY^yA>RV6>SxK+=0R9RxHN^iBeRWEQyiLENF z{heENwWG=sTUGk|X}9Vnjw(xRRq5|%+^Uy4sw}ZpC5F$sRo6JGEU{H3HJ)>;UgoH> z#8wqwpLeTX?x?cFRux}gaI3C$R9RxHiUYrQt6t%#vcy)E+;3-IK%H&zz;{9Gn{Bz9jC ztxz!*2Ye{FBI%tZtAD(ux3=P;Z>017Nj#-y^YLTOZIfo;yMW8L_Oy3{LSMi>Ed32% zNfe))lTtC%mvBv%momJeFTw1ep5gU`z5?bC{vD7v_2M$(`o}{d%c@AHgxqN<3BJ{H zhd%8Gjomu-x)7SwuVAo62q%Hc2(Lp66LI$A6*NyZ06T@Fc^fO$cE&lufo-g*owu>9 z)?v1)+Qnj9QM*{vP-}N+BMy625??>v(W2s8FgStUGKmn`jPP~3t$%ddYBews`X{Qu zQQ_d%_)hj!Vr{Bxj}-+u#}XqBoz7(pcZY>*iV6$Y*_W1+V?6(uqB<=b) zFw;L>6aNB%0CF~18CGSsvD==!N$5Y2 zOjRWKSLpDBGaz0{Riw&SAR{hB2IiRLk(_!;H^hm-QRa-qT!meAo+mlzT~0K-<=z@A z+y<;W-S4F4KJKB$&59aoU8ZIv+&(?ldSecXIp*1+nQ+^wT+XgV8z|*Ttc*c`XR>#) zGjM_qjl^XZ2OCs$`Sg>TqgGP;d?SU!!SitqzI*XCz`llbH3cWdcjrd@hG0i8qOU-9 z-SISWiakG?@;-rLr*2OW&R9wD=(1!VreRBZDL&*u=*#7t2cHO$X*gb{;S|?ZEcZ1HqS2_Qru|MK^Gs4~5Y%8j_kvCB}BHh%@^=5!sk>ax~R| zj!6JZ#l&*gg~sc?(0Fwl{dDsqs*RD0E81!ICvwT@&#^Ea>tqP}Gt_ljp+Czxq53cg zN>=TzKYdh!p@%HU2yf7_ew|}&HSkx+%L6D50DX%gZvjggxf5R7ebJSpa@9Mzv#YIL z4at%2PU705I!XMv9D#ODwWzB_WJKZem(9)Y3lJ-E;!roS60%KhO?EY7S}=?)=RwlAy6&zpN5W}_47}E_(Zy-$H~Q%ihu@}(6-3bDJ|{1NQsO$Ki&2lcUv*RWrT0iZGEeowniVFjFCWA>;CSxvaO%cR&_7Z z3oYY$(HBaJ>QJBE%vcMu7;Wu%jesq}oSqTBMYsE%=yo55`eL05M;|vp)M1?2d5)u> z6+CJ7=Sh?Ah141R=%_8}T-s_q&{kDlWud=U`_id2M-Irl$1MbZFvd$X>>vIVW|7#0LUZqP3M&qlx=QQh?7JN_`T z2k57h5xIu&{n&-b-*xyn*AO4!2{AuD$_U@8bGnUl+G^mh$o*Ib@*sKSbV(H! zgd(Yen4~0B?hA>!Ch&|bV=ZR7<36psIU@tt##obvGhWz0jO6Na>36Vu+_3La<0eMV zby)hrA<2*d?pe(3P-Ex(jPw}{4CD!E5QD)yE8%X;i@PzeeK#htRlh~CulM5-&E5zp zHv9NDpz_CS`RjopKF(U6C$(6C##+9csTpheZljFSja@ehr8~CBeJ5bAW$|vaHTK-8 z)++tkcTaFBjK^N9aC@v!CbG?0tFS9SV6B3l$_U@4bGe;!*3IFdLwQ1Tm@xZl8!)Str>O`T~Ahj2~mg3iPbvFR#n$!HX0QTHs7I$>k5R`zz`k*Ljmjy z&>C*8m#@B^SH5-*`RUh>+BswqDkTi0jPPB$o$ovC?7BtCzSiZjS~S|-BDNLPBL8k$ zgy%HUqG4!JtT>`pZeWL?*z*EP;~8cJzd^1dh=&Ljoif~BfBg1OPWx-ne#{}x`0uI{ zF@n3P93$9Wd9v%dNvvlxKH}$PXmCdOZXNp%oY-3pOayUVw6Ny68k$}AhTJU2$gnP- z^^S3Olhkx2F9WXvXoaPYiPvEY$J$3aYF|VdZ*#=MLw&=beDsBKqNW>Ph~pM(5Ze9m z%15d{I*!3~lL*Ji0orj;?NIwOb1sYmoiL)2y0gfivf&#w~8QcYAT`{5?%V5Zc87)rLnm0 zsx+=`-PDb>V?_`b^R7z&n}cXiS$D$8tT+`zUnn;!aWdkvES}0N_X^DFXJ6BK{q-4o zz(k%T0p~xyrq{(0VGhX%->38DBhDMEfxkj|sKLIQz)CCfIA;h7smq#H>=C8dKSwk1 zOG*4bF4GF)=Z*HhT;=b&&jMcHc9#bkm^`{o1ToM}DzJfWb3qJrlMQU3+jI~E>pG{C z)q1FVRB?!-Mis}f!*s3gK;m0BcDB~(7Oi{Z+!q~;cd#IJx$jTV(#SY=rJ(oiK_0lI zk|etCdAp(#$40vw=zF_3`dP1Q;^f@wD&mhLs$I{X{}Vyo-3a07sACd;%~#-PsU!{=SJ>_u^gacOryu*6Fnb~Ng#d?QbzcGJs*F}^RYeI zGU1w)vEIQ(Qn#7GFPrG*%F4I(-Os3Opt~6r2D+b7*+6$QDhzZ#qq2cL>CJKO36`T3 zHNnP6ANS~kA2Rx?y13BG+L5op9g@&qRdXn-d8IIl0oL~wS#fVKj^~+DI<64;n-!1W z8utXkmr3CkMRV-~3njQrcQ@SsM>_T9&cWm-u&$SSbl<5Q(+=H{)7s0;ECz`T`stN% zS9PikyNuCHJUB^oUq=5eY1I?+hEAYT)M&5L)y9_0?`P3qSsnz7~u(+^E|7oXA^jy)y)bDi}r38P$=Ea@(HE8 zT|J?6H)|)9?sn;f(%mdrP};p->G&khS+8OhLpUQt*uiwg@Mh2>c)f~|VkO!O)p$?v zcIYqtGge?$14DH*0Pj&tdHXaJQFk&*6e`0sY(H@C<`(CFWX%&}A#1gccduMIVo@vC z7)4@_CVt`;eW%{(v2Nu4BL)45-vH3n9r|+u7M{2_$p}BF??3(mS0Z~DT@4UCyz3^# z@$jzO6i4Y8EwoxExP!u;Leu;8;d+IM(L-!EsZDO6+zTp5yZu@;+#*BDe_9BPk`*Q9>L%Umt)!rG_oX! z;ad?zK(W2rVKY)aw~wcL_4!CXSGNM$hmo2QeoT+CzrqGq^ZXU+!)sDL1) zQDl1`v8#Z{-Dx)=;k(mrVJ@grWIeo@wA%)YIyDj!vNc_+xGM{$YmweEmyS~J}e)oOJ2DVVdafH0Iqg61d}SI(8vgj94^JoFm3LQ$=AdAeMp5UV}#Ru5!W0~&+EqR?_ ze5fCSVjp6U=eIfXA&02nXz`(7d+r)qsfGg2&p1&_xR_^zpU~rACyxVrZmNLQ5Z)J- zn2Z%(hvbfII?6N=Bg$6m;qJs@(@}|a?{2mod47rnGbMq~XJQn{cB}QyRJ@^=?S&pg zQ{mh;7%NYR*UTrF=?e{j=aeAPz)o68IamXkwJYD(KVIH$h~FU#T@&iJRS|gE;?C|#IbB^2!UuY1bX0PadDxQ0I&M~qch#&*QcyMbq z9tRJdpY9dOn;Wfu6Fi}(QKKjH6kvETs&#bmo5FZ{7`=l#q>M10xyrnK670wuE0f~Q zh7&<_d{<>Ne&{c+X~q$X*|6GS>abe-xI@PVqeAy0Z%CAO-jHxD*m3?sP7>!}*sE7n z##?8Lp_fp+0Zq~`4vlx36A8$vrt>yY6^76dG#neWj`F}To^^#*kK~7sJ{vE%3rx0xgQz^H$3&*!HB#CFY@X;ylji#F|}ugF~3%L z>OcMIhA^X4gokrlpxvAgJa=LvpWhvpmP`xzT#?~vOBI$ilLWx?@70xd+?B%7k zA&3D~5gGx#a=h;)hq5sj=fUp3F|J*`Ddz{ol{@Tb^YCZupr6qryutRT=H8JKqpl47 zfLA=Sp)ii7#>%}DIrlJe$H={roO>ebGWRBP?p5mC`@cD+_lq6ZMI2YGgJQ&We~zn& zx{T{l9M=PMT(byu{NEeXKhrD|K2UWKzjNptXU@Hd`)6Ft{yB*IM?_ur&lK*TgSme^ z^_#o4RJCW8vD?u?%97gc7-{j>pwF zkRzrxgvP0s@tcK%;~7`i!Z`ZFkMm~<*U7%S+&+)FsJEh?r_SIB;z|9r%*858bFswX z7V&#zJ6m`#rrjr*yJs!rw<_B${0Z@Xfotp{-rM)w8%_h;8`b}~8&iK#oxBJA&u^CQ z9Ie>B5Hqqd^C7}y^BY2V=7CWaVX_^YDet$oTf%W&?X-j6KvMr#4$5Jin*1v3&_rMn zL(2LjuzG|JXF=!)K;!_wWu)GdYM12fbeB{v#3(7%9jUB{0m1w2hb5iV?~r0tkpsh6 zoLY_bt_3mLku~@~GSB~PYvTVlL*dEj2$|npYwHYjY%5lqF|NaS17@NUbve(^z%&t> z!aa<&bsXL338 zG4o5U{OTIP(Ra`Es>gVy?{r=8yEVJKCPZBa)V21%_ZlVbcdk+0U9zwywHomwt*8fI zd*?%0LH?w5?@yTzJFR>7&WHAW%HDNzj?Am}#i!G{`C|8cSU;T?8nSNgZcglW-Mpvs zqf{l6jz=xJ)dciEG*{yCVKpMcd*@1AM}NL&1bgR7_n799`ZKKc_s*5OnJc5#Z@hN= zIp#`vpZ^}NC;#W>%TuukcOHkRe}ODyKN^|NbLSNu=1xB?!+qnwc~9%V?QzD>xE1wt zJxHI5`Mh7py~{aRI`DCc7|&OZhQ1PY`FsW2!WAL>Ompw^m7nD~Iu53&zaRE|<$|uC zGu3zV466PnF4yTkq$L(Na`PU2M=$?oN%S=gJ1;-Re|bLC$&a6YKg9q1N$2NIeCyx2 z)jxI5AQGUMPmS0Udo>@??DA34Pub(yyB^rhdH_da>>T~^>j8cVdi}dRP`bG5QXL-i zNz{*BJxFz(@4WuI_ffikMinLPc3Cl(mlYdb%LseY!Wg^%S03GeIkzKlLg^$!fHR`?rZJu;2gBO>Z@Ju-{e zBUps;^WU_zE-f9mXO`-DKSpoB=Y;SUZ{G3V``q-WKR5mV`#R_M&NXB_vP|{{T~A6* zw7D@(TF7dr28rt04V%LyI-PoG>c-AhUCSa%4EE06U5qfJS19sNYS~LT$?d&sxE%SX z$2u+7_O9XF=X7GP&ttBxBdHgC_Yh(Jp#8x2^d6w|9H+yRYn9!4<>fqmk^TR@Yd@Y2 zI5yqx1*qpcuG2SN?w59Rh9+ut7vo4xl(gHmUjwiG?(ewv+k2J+E1aLSce(c(y!RU1 zX}uBql;z&%DDHi*|LbQrzvy%gmSv=SM`Z7H*nT?nU8i$O|GBfQd}&Rkd)_07y0*Gldt7#GJc2^b!;v2L+@^of#GH@_}Y&s_-iis_Kzrd2N!&A zPYVtV-^2Pl_Ef)fV+V#GW(%LVEZ~R#kK;%A{p|0~#X56FO__k-?x{`gWL)M>A3kvK zz+r=j4XNadUL4H>TsH;(R^T~!D-B;X;Ai86mn{%p z0YUhcx%@k&*rK2mkL;z0ZTw1(F2@Hy^ObTb`0kHS2|m~=;Xk|*f&VNT>K|BS(cc8d zWfc^q(TpPIpO`f-+oCu8SLIvueip;k0&f#|itrB+{N+rxaEHGD@UNvK@+@k|WV`~_ zEIM6ad^YoaBK|QxE)|cHY zA1&+SOQo?n^}SN5Irq_CndE^^5pBu5x1@-k^0&n2(4o*zrD>wG89F(XE1UtsX%NoW zIoZ7|I>Tg7CS{DsOC^s;kA<{|Uhv;rl0!*S?^~sB!&(8Pz3HpGFN#xXo>+JV(tI+! zeS8*u;9(03#KJa6!{kBS{vZ%DO+-z@mA1piX-4}rtC{4>(>=?jzF zc%k&#wnA=82Jn7#e(|b|el(}&ZK(bJo+Hqr&8aNil+W;z^bvWzX=slxiY-dX)M*D3wUR z_Z(ZENJpl%p>>(%pT(C`W_}`iq|M}L-zlwrSu~q_GH0~lYk?=?pTuT(Am9kviA=^D zV1V=J>J!gUW)8dx=Q%IGwacbfSWJ1z2ZeNM7g-Wz33UkG&09&S{BNN{c7jlu1e2gz zgv#N6^9oeCSSjFtfdSODng1vnk5PW0P(88+3U!cBYmtlNVWSEjq*EZXuIy<1+osh* z-IZ5YRtbxfg_=?}ycbhbg?d(~!8BW_4|=j}I4u&&lg`wB^h=@c5?M8^73%hKmQA9& zh1w=orqC9lLYZ?);*9C^f>3_1qFxf}ADa53Q1x+2_PS87YU*vF4zQH0U8rVFeSnCk z(?84Rl=MXnAB*h6{2`^4G@bq;)GKL<`b?jPsOvT5F*s)TXv!zlSDH#Q zJc#^Bm`=Hd9K%zRPQB2nm2@2CitIUfR7odNfl$eq+$-rM>M0a{S`BIj6$!=fPOPL_ zDvq);6aNaWW3!%yMp5TdRTOnGO^l+hplMOmMmi;mx}VO9qPEe+QPdyk8u8^+@%j~7 zClr1|1ke76f5nqq`+!h?qU(hkCT)0?Ziuq-8m*5i_d0EeD)$E6C{&S@dy_UsS$T_Y zin8)H-7GTY%R6+7P|BBgX_HXOmo~aJ%1S%k7G>oy959scw zayw{qRJjl7-l%dP(S1Ux+CQfIg;Fj0Gd&=bipyWcq&SK9gTEm0VZhSF#{t(QwnQ{j6S?d| z2_4IxEu2kKR@odbHb;uhn-bWj;ui@2CeeRd_{T_HM~iQBMcOXXSH;@7B7GX3l+(LK zJ27+bm;F_?K_{jB6Yz`_3>ivI@c~|*k`7pvk_Q+}DF*y9ISAM{X)s`F(kRoQmB|dB z7Ce|TOmy~-=8KjlNL|Wu&(sT`$v#-rp1UGv1btv#nv;Wn-|7m$-sTP9 zHwHEX-VwN8be;nIw21Xb`R*6}=b$;7S^>8je+N9(QWpNB|5a_k0<*`3A!5K|+0Jj=f0Pbno9GVLYC?zm1 zURitcCtG;-CtG+C7Dm%6?30I|cqd3hor?zl1|rSGMOW7?;mB6NR%vMopUF z3~%r0*L>E=!`;cLo}PdgdV31LZxrOQ)}H%R&XL8qpwRig@xFcWD%NS5O3HW;RE?&N z4g~Pys8bY`ms<2`xu33-+9beE={Dm@64g+(R%IXQDQs8mfYFB=CcM^W%>eTGF- zg;JiSP+6(+g*{89*EGeRrBX&f+2ppTQ4dWGLfg}*L{kZAfvhy@t0-xE8jTZ5)sRVd zYl>^gA|LLk?Y3vp^+Kt(`{`y)aohcLr=~Xh0$F}~KvQjHmHB>pLQ$yix0!x=Uno^y z9?ix*IM=}S^`KWY#VzVVmjzj->dU8VG_@}N!MJ?dps5dY16lcWtEQe!t<2A-dlV)0 z<UZ8V!BdO&!z^lis^by^-HVFFQ%I{ zbzqN!K;5Y*)P9q{nBEdf)gGY56;AEt^sT12cHBYnqXM+{SoB{X`irKnLUjAk-!%1U zdLXM0{Yz5~<(2t;$TL8d`#UnL4<%{puE1zeS&D)$M`ZV*aY89yfDUwg8A$6i#l8%r z+XsnFl(XOsz>R} z{2??T{x0@MMTI==L@{Gl{PQ_V%^fSRPKwM7@^52K?sbwlYIP$y~X;?isLhttWL zx~=y{P$5lS)BDc+edr8LUDEqOP>q^e-n#`e(1n_6D0&vu8ci)IdL@5fx>~67B@+A6 z2BCH&w3HuY?n}2Q$~YWR+LscCI5FFovV_`^Fy6) z@#&!U(XtP7S7YUWpqA~-O$T*|mOY!g8h3w(YuT%*>7b4k>Zyd~z2DB?pJr(4lHNN& zoua7)MW5#%Knpe1Q1msZvxT~nPRaBX97wMSbv{kVOe{E<{6nQhzDsk{3##Y{MM)&8 z=n|n+`>N^srFp`%VhX1oc~?o=Uj5 zG`nClJ*%l3N{c|fA{6@>EEq$@xbY@pYH-0JR3j97J+k0Xx?EB4`rv|b)S@WydK|S0 zwIktlM1CB7q%|)>@o8$sbBkG~xWe=l84$54ru znPusq`f1r+fz@;@4b`%T0_mXk7wUZ9n6jA#(`dAo9Z@z1)I^~;67vhD(>ASnY3^wS z$5Yw9sy>eH@zh@^HByhKrCRoq$j(zT-#du>@w8f~rxLC!Zzwo{uGG{m<&B_j(B-Z| zxfAKvLN)m|qTGpex7K7oPojskjQu=`T6DQE;yHt!5$b&3d5Gr>dRdoyspt6xHS~t2 z+Iy}5wOyBMD?7-nrN8KMf5tzpQA=NH*@V35=1lrl%Z|#M2`X-+YWq{AO`chlBGmc5 zmr5@Km7`^oGcPn}Q<0X{WNrl2N6VI%UErysL0WcY+0~#%Y8l7#WUA6K&eoG@qEOrq zYYOJj^ZRk_oP*aE%%$Z0g+dN)C^(f~SCr)7sq{~w)I4#jyn>oY%@e0m0$xbX`7#Le z#4jjAs3zY*m?wTgn3_bEkT%_%N4>QyD{UsI{#tf%X^wY3Z4m0IgyS)5ETCI8bt-0! z1$3{bcvcM2qnhF|7NTuJaf@y#SV#xs;hk#HJq7i2f}+r(hYP~=D=k}6`WsMdt3*@U zcN#sZD6BXSGEbuyG{rGHjsB!5&cV~^9Zhi#o=zWXYBOYK&|fvx0@)e#Pfc-7oQZ$R zh46R2k8|Qo!Yw}jo=Ui-?CF9fl%c5y%3c7KuPM&!v#7VNiM&3GDuhy_qk$$0wT-^X z|3g6oJu!-HZle}ZXVX75)i?Kzf~9lJC~9VQ52VJq@9O4 z<(lYQp;Wmh`e>X}?w7>>h6>lt<(AR?_%{LU`j*oZLaB1gsYO%l=XtbEQ(W$R+BC^2 zcLCielqz=ttv{S)s(lyImzv^o7tx@}PPvO|q)@8d#dN!-xV{zin5MYgN}4p)DYuG_ z5lWR?MbkCK?nf*q=rF0QqmuRXKmqK zw0NN^*Dr8t;bvOANKyL*&M3TxKG#%1pb3;W>{z*v(uHC_FD|@~#+|0h9anaF;RE#A zS+>n}g%8n~<+jaDg%8t(=P9Zna51Q97bt21tUOB3U&NI1^Kp7jD30~Lg^$x?7c0$v zfyY5DT&bwz%APHJg8Y{#svz)(!Yy>BrY2Zxud8-?(I+%edS!>}0e-hQt%9zqzCEcT^;lviS`0o7Y)$vGHZ$GxTYc>{W`kQf9(JNH8PEmJy&MNvN-KVL0yk`~tiO#-G$p*xoRrD(5T(78G zK)pr*O{G|86}?Wwg;K43gQ|p5k$8h9YRwtcRP+X|y+K)d*SM|dP5MMr?AcqiZoQJR zXKz#gW<{}Q@6f~ziek^+rMEQ2p0&}&8)jJ&rhP4@GzlqHn%^KytSD~7xAd*1 zxDDUY%6pWI+pvo!-m55X!}s*7`xM1(AR~CcqPPu)@wukB4W_Z}0VU%$c#M-CR1~+t zYs}Xaw;|3rTT^}Ei)F0P)F${6Z`>@DYM;-zM<~@kpYfR1oIwZo@)^q?RyDk9Ea{bC z41YvX+`dHPeNA!ul8nWVDjByg*%Bhak zQ8I2{hVhA}xP6(%mMu!g?aMNbYf%)p&u`4t6t^$iI8##-;7g8ifu;_HFS*7Bp;X)R zj5~!=ZO=0v(wf}9JmZw#sv5X`J&b>9irbfOJhWBGxP1l2+HH#B_7xg!Pb!Mr*V9<| zl%lwOMaI6rQxvzam$6t=+`eLC+|x?N?JF_f(-gO_xAC2(xP7HY@-s@4+gD~3Xo}kx zFh&Ta+E;Fj5=ynN+?c2}C&FgA@vWwwhs{35%4e0$Fl+{miO(tORM_lm1fN%wg%y(H1!3jLB{E=N|pp)1{-TMwF15j zG1hCUKYST#+@-0$@MW0stWc_b!;L=)rP?>#c-KXJ)9|~pH@Hdz2TcMWG8qWj0h8y0ORTixAKG16)BUvaF`4L98i^5_6 zf3~cTi^9@~KJwvTmZ6di9K@!X0p<+I<`Vp8OW%WzhdwLAsWUnzk58|)m-2b9*_rr9 zHR&4gW0e{uHgnTrOO?$hVc9E|V_CQ}p6mT8mv!DujcsR@=&;mF)u=0uru68jIak_v zi?jm&3JWwZEoV&&o?G--r&gcW)3%_z`svV)C-#mID+M{uoh`@G>`p)0!cQry?6@t& z_At7}J;NIjVN_xylN_!w`p=*@(rsGhfTHYt z;K)RCqVdl9(b6A^@42;~OLNcdM7PBt{NqXbPvHhmC~!ZPVl3l1G~)R~U{5KvCotOb zp6LI#>HItV|99B@Z;RWW_@grLjz9{Ya;MTDfS*K z4c=v(Zt$Mkbc1)@rW?GUH{IYJzv%|=-%U4or*5+GMCxj@R`Rpf;9a*`gZJfX4c_sq zHF!_3*5Dn!T7&oUGCW-GWaGlXZDx~r*ktf7#!lnu^xv2zp5OI++U)DOFa2fU+soes z+`sHYbF!y7eJAkSQojNGBHQwmcpiz*^epo9FB{}(f^P@G8t;&mczOrwz~LQ^CWH64 znhf5_YBG4ws>$HpsWsy58fp6)gLh5Vz*~mgYikVNCt73h4%-@u%o>AtNY)sWW`p;cHXFR7^uE?fEj!qIk>`-W z0`J4($;0Bw!&2|V2Jb{YY}`<~+`GtgLB>noZNzQ)M3=oF<7@Ail$4$yw}~z+ItZCS zMS-|)>6Nm57?=E%M9>4DxslDw-ANH(n__ zH?GiV3G5rk(Y_XVPWFRwU(&yPk3q_%%HUgzr@z1qGdJCD4Hx_Xfnx+t6gXAj2?8_B zO9Sb?46`D=)YrotmOt3n;_()b^vxD&5A*ls6MPAn!SMS7^SHc_Z?W*t)@7dw3`xi^ zUk!{0To*VNaCTlDU?}grgyo{MQs7#F>jX{~Ynv#$Y+TY#V{rNWq+0XNqA>8sdSfgb z-(p{5r*Ut2Q_@Dn*gQJFH62pG@Hb7iRa6*`;w8jnU?1< z(R@tmP4I@&GE=q*zD6|Hm^^aVNbS#yg>9nWZ1N~;HhIJ?@*G%Rk@|}8-;%PMrR-*t zvwgGqRO#!&##(?wN z%rU~5s5yM{YohsapkLM)lh1^WH@BBh%$jQc#Wy3X(mO9>ZdSFoA@A(06U^^@S7ePh zzYMI;n(Qr2zXkZsfyV*sGM>z;^;Va^kTuu4Bk&5~WtndQe((DL(%K%MWX+a(XG^{F zq~68g+~i*@oU?_q9GoMvm!o&~ja#WXe2QwN_*R0w(2+adi|=?5Y;3~sN-U~fIfEc$g>oWb6f2)|VLrN*C)lS%@@uNMAj;g1&n zXrqCq1;&cBR;05;I!mOpAU!uwC(Pz+>$!sG>OhK(OD*(^8_{v|3>psx;b#8 zxs}=iTcpMo;cpfGR`993P5AA?-!A;^;P)ygkF?YyE%mS+k7p}YmKO`ZMEIq`F9m-} zd6|d3suuoe;g1G?etE5MW(j8&I2V*R31^vbng!n?Hd_SW>fxwvg|&hCZNhIC{&wMS z7ykQF7jKTDFTCQRSNg)srHX}LDx6Z`j23*f;I&@P##$*gOZc;d-z5Ad;V%=sSwpse zqu^V_a*N?pjj<= zweUv^K0fYp@W+d^RyegHohA5Ok|ux=iqkM0$}(n}yRX(i;We6n8CcEpHLL zMfh6<-xkO1dPbye;%&R|+eK%);P@A`xm}jD&XU#%o?vk+ibYx?oDz|i3f|Y^w)7R9 zD$%JHezoX~7JR(uj2E3+;na$Bmf&-(Yw4x(Cc&G8zfACE4W-uv-z0W6iJcbVw21yz z!JiT7Ga_vlPP<6A3;wZ4KNhJGFKvvMHVU2)&#g#^mzKtJ97=>=B08ml_Z6MKqEjV0 z)xxh9oza4ikH41QE3Xl0t#E2ZI!o|I;Wr81B>ZK9Ule~MYP?7+Hw&j(q&Et_G5!l< zR!NKCEyCX_c)Nz&itU0MKGrmR(mJ2CPVf>9nNuowmB4BZnLk?a@nWGy@LCO7I!o|I zflV4Rf0^LRrPO-Cn>A$Vje>9TacnpFIJR4a(<1sU8fVR|g0~55*O2+!1^-wqd@L3y zL0YFF>v#k&7FePo^GgM<5?HMv^G6FlK7nIZBY3TbES)9z+ywS{ZUXz6yolT;%MK~=Qvd&h)w}~guh~_h**(UsU4Ow%$;2(?BNc_e) zv!o=E<4}^w(rUr01s|WtKGzDTRycDLr7gm56n>M2T=pW7UL?}>!f)1)rJGP!bNQyk zdtq~v=xh;bi-xT8OyaflRe76m+BIbU$HJ#1=`RhLUo3b@63_5ufU`=fgi|e?@k#7$ zjc{s(Ggml`!f8snjh2@*3I8JDuNQu^aJC5EB6yqN?SdQ0Tvti*H^$nMTEO)sjmhj) zli=$GZx(!u;4Ol;3EnRF`>-&#gi@p}DQuxw@DjnR1g{pnM(|qTx0f^tY!Z8J^rmpC1g{ZT3l6*$yh-r&f;Wri7QtHtZxg&-a7q(D)7XBo;3a}r z30^IDjo`I{HwxY)c(cG3fkrx8C=pnd&NizBuMxaf@J7L#1Ya+Bv*23;wz&pyT z1s{{i`Bp1qk`@W4ML63;zfJgU!fzKo`K5M0*Y5Rmjm5$#5l)rh)q;-^ zX^n7dh0`eba^bHRyczuUC0hh<5qz6S+l13Dr6^l!%$6FnrAFbD2&YQ$YQbv+uN8c@ zXf|eZyPAZvUhrnYH;S}H@OFXk3x{%~t{jQ2;3a}r30^Jum>l+@MmV*?X%xIk@Z}<1 zFPs+PY!gnKaN31Kxl&86)FOC^;AOeegTkp6PE9WRUn}@*kv0maNjS{{TLf+sX}jQ* zC-(CsVtEoV;gkrcO7LpI$B48>IJLrQ6nwex*9+b({4IjF2;L@myWsEV@q9=hq^yE8>TEQCyZxXy&V2i+Zfku&(6<95BOfU9xb}#nOTf%r* z3FF13ra3UbN?@bFHi0z(uB%btdVyO6wh5$imKF=#BCt&$^%1_nDuFcu8wIWxxJ6)_ zz^WkY*9dGBxL)8Efo%e*uhNEdtvVe}LE#xJ6)_KpH4^1Xc;G5!fhjy}&I3+XT`e(HGb# zaJ|4S0^0=AV9^m+C9pf<(=*eCmfh`Y|@IP4M{H~4NN{D`HX@`CX*1KpXU!&6FavaoW$@_5>8^I z;v7aM&XVNd-6jRtdBUQHg5dVWuG(PisO^J&u>+tnma_2sA3xrjK{&bcL@&IbC}S(& z%)rxtiu0b2IiHm==a{?~0NYDn2ArMwD&RF`ZviUJQBpQHtz+3Iea!i+jLRy`JLB2r zSGml8Gu7d*68@X1%&$&k{*)eE*Ie=K7V(5KSbAwWORX}NJ{Dk4`j)l>K3e)`z?+Kx z26$uXw}5x`jw{Byn0luIo?Da)_+)u8;72}&cgB|iewEAc%~Xb$_YMM{TQmf4ZSH=6 zO0y(`r85Hu1KwCVTBH*JSBV8xwmOY%PU+#;SJu|%9tHkfA6vM^Hw}=)+NI^Sz^yXo zKNes(rECu1+T3}7s^0g+&)duE!MR0nrE`(k`Jm?+;D1)eH6D}4zO|R04LCcq7Vw&~ zUjiySYjamc@KI8GZklS#<={UmEwa76DWa)re^TmIwLDvP8>H-y$~hBfQR49NAm2>n zTLNGLve2YNWSt2t4KNuQXM)ZGOr>nVEXoD+V{g_3T>zMm{ah1RFTg_NtO>dlur~z& zOQ{cF8FJVJT>;pS1^`yzSE(l6tu+L201X2ii2OEz?F%>@zm+sW?+-WvZ{;z;Js5B# z_I^z~&mE0%GYZheSQra@44_Ge;y;590W|T8zwyAw0h)9e{^Q^I9R_?7{^Q^7O#*%d z{xj%sKof89nG86Urhs!apow3+9S!_gK$E878~b#CCf-gn9r*EpCY^w9{$1Jez)!-r zfwS!=0-uR*6L0>h1*Z*r%=oekyndp8U=M9sXzbRnG!{31Y;E~X~nD*#RG5ibM23ecq0C}-e3YUcr8gK{Qah7u=tfZ_s=6XS|Cp z$w)Oa48M_U3^I-}>Wv$WvF1c`j(L*jA4VbmO>a%_oiQup9~qUI4Vl+v{ws4@*6OUkWsUWp>Ho-|pS>>I+sJ2#qW|j3_*9_t z_owV*aAuHCI`U~m_4jV}D&e_H?(EG{ci9JvnCI3z4zqkmJ#UP%Yf3uneNoIjw=Xx# ziOp!!e=x-WAGV^x%3cx4#j62KKwSa3HTg_*>xg5lkhnlpCj<$KQ9e0Fy#C7 z0#m*(lT&zj3n0do zLfK2y_7bVCfbAv1F3Xd(94i?qmrQw5Uox$f@~K*$N(mxQ1)s~O(j5it59DGeovOs| zbebZ1>GY)NrPH0_cRC#}ey7uV==Nh?l89F zvmpKsNn5%J=b!cNkXEcH^j|Fh1vs?Y}3*nZ1+4M&ION#_Z%ca}n?* z$>+k>KKKkX%#Q^zr^=yd|!d@=G1dVW~IfMS!rRTAPw@g9_D5EzAo)B^JVbHqn$hO z{aM<%!0XIgeRby3>2>Dw>BEfg@O@&&FykJ4j>&`{nHNC50-sg*TmZcl_*?+p75H2L z-4*y;VBV9p0-s?H4!82kohX_+D zwGDQvGe)tYv1|<;7K^KxsA0%(7Na>cj;swYu3s`bG=E`eLEVDIVRl(bJNhg|Ix_c( zRn5?SV{wO%WbWwty4uBc5|~K*@uH4S@dr=G-2xrY!y zT@KLz)=jKfuS5SL0^lCKa5mc7A+~h*Y4hgQ&YV|QGla&EU2xj`x_X1Rf zb76g5I6ODB0D9H47Ar(WZz}6Z#OmrF(NkDLiK8l)A+*GI4I0zs4?D3^`!^5>WO485$$L;OP#srJch%l*TVuJWOj2o?$CS z#*nb=VFKx)b&C%{bl4X)bac_7k)oaI7)pnnwqRBbY8t;_*1XeZb7-764y9vi=bctJ z^|XbE_fR^lZi&!G*3PX5IcBcJwH9qf`NehfhtmAHb5s~3P7fItqw(PB#@o_Pj&V6P zJJ>2w%?8VEwpJT50|>W&F85~LY&!KxlKG+2!c&(ltQ%Yt zi#rrtZX(NM?i=2@abVfL0aaDoYMrWPjgD0htBJ)O4lY-%Z4REXPv@$^va1HFsu1vDG?N!Wtbb8BsGrD$%6}&)BzfC1BZ=09BRP zYMm-!jgFNJso7U5(WM8^7}>cJu#{z6*2%JHD6PRWDmz;MOIfgGoh(3ryghAR-9c1e zH|t2;<%SlVTqolOlNE@?^|iAWhX;-sPlqp@6J9iLpqfGssjr=1cSflG7o$VJJ%z1cf`ZSZnmWxlpkc9BL{}tern|b}da=62_n% z7@1&YfDIf|ySTP`!Gh3YnGVAPr_4H~Zhq~ac{gxU-QrqI+O@b@#-z?oc50b7PqjPz z|Ju7A*fx*re*E-@lx)$`N2{@0$)V9WO#nxwY}t`hIgxDHmQcxNEID3Q2P!3gmY7ha zLQ=N5%ou63K#Mg%J#4^&ML-8E*g7m*46IuR%64bm2yjBZ3%8CE1Q&+&5*fS zxbDod2OPD{&owk&;VpG2ZnCioZ8EGBJyUC>l_$KM&lS>S*z2*>n2@sP3KQ9^m@c39 zUR=+?*T@Exsb_P`>jW6HL_!BVnOj&mo%8ZQm~OCO(^)HH8f(FH3v7@tw*}P#2SH`n zkzGX^y7w%Si!d|Hm*^6&5J1d%g{)UP3rn=9jkz?yW!()x7?Y<$7GDRaRx`Q0#c^(Z z)yh3hbL{2Z5}Tg|pMycJmuag%g>j7w}U1P|t=?=-?2{@8=N8s;OB?V-2B#rfZrNGqw>b28=Y3 zForE91a2^x5Zax0S;fmOSS* z!JI2$6g7cc6*a-iZf=IqL%#`5s?X@S356O)p;phS(G)^RIl}D?4z_SHEoHc*9F9#& zU{r>nJUBzpz!(i-r4~ZGsL*_F)%$d=kQH-l-cs&zmD9@c^B~|E2MlE9j8~y(@I;m8 zMnvOY>2hYt6M*{}E>0swmgN+|rVHgt1|F5?hv1lD$_5a`%PeNf-s#LzCd*Y!Wy&ij zv8WdFD_%jy=bo6&EtQJp;^j)yNMWv0EMevp)7rljE*A}q4bkK*^D{8n*?v}cqJc=& z>a40nocC6XSG@C?0&2F_SYp1&Yb`N}rIbwhD>gArEBa!YRvZE?$5jO+Gr7WxLuL^o z&ck`5*VxTYWeQmkDiETLm0~ssqwZ1=bP^XjT`I2nAXz8~qe2#Bl{PX=|B|EPF7(|R zcb}D|-Zq1d=_zgrLfA@px4;lcWpY;Arq+RKp@0dTD|mD}SQUy`W<}8OAiMcCIz$1M0!5Tq%KfkYH~^vvR)sicPM;FNM0W`Q7(I{i}~t& zu440$3kkCd@aZ+HsT>+u@Zp*d7Qo&!m~OC@5k{iZiltSKtTOo!mDFz2f;zV4qCQ{h z&{>G@m3$a)7Mzmn6Ef|xkCOUj9_PJ$<{GCgJh9VDBEOVw8TMncFijsZxk$v`H4CIw zA3|ugsa-^$$!V;wa?1s5ZTK)FLt5|L!)8N%LPth+{(-q z+DB1-Qk>3bmbVyQCs)Xs&SP;%A!dVD7*btFn0dH&`e`K?zwRW;oiFC|izvKBHPj8X z>y^oi;@ZL)-drrrqi&2)+Uz3e3>ITH$lq%e)+BQRlPW6ac~bC16M$HgO#m(@oFGU~ zIsvHkl>v}d`<$04Ev;CU+W@O>8?5F!t0eU+Z{ylzYR0q3?73A|In51LX{$O3VTD;c z17ccMt>{gyGHSQLLZ|>TSWJ6hyTqt{TSA)6G7NN3a&SSXqtjifh>T*`a9m{Ju+i~EalDti; z(%?G{??-#BC#sX)<;;4%qEORD0ygYZ*D79toS`7+Lg7^_yo?K|W&YkV44j;s1xROT zV+M1t1;e&4DU>(AZ4?@mnuH=@v6@CC^_Njd(`5+3jq#Asf zr8XZZr_^bz?yvbkD%}7=NBI6RNZAYya_lXvqNQ-BKDn7!D2(y9mKvSf95x`Z^#29f z;`82R#5L&ROkQr^ixY@?3h;=9GIq?UN2kpMU_(_9iSlZ{iROOO>0b8KwIy$j%TE@s z7K|az7X=54G)1D@DX`?^G_CS4KrsMM6tWZfauM;0mYqV?&~DH33k&nG6MM7AfUq(* zX+6>{kQ}l$k?{^TP>#|Dh+M-P?sAvMWP^(hUkE>n^@5Ix8KhG4*q7 zy9QefW_kSTk{E_1>w7<2?9?9q&lrp$J;jO?g z6-%@RR;xLzImOVDyz)(r!O2`^xq!X4+)`N&7!^VBrZa`w81z@LaxR-SjRDArO@$O? z7ETSAGD~JMbD1li43{Jon<+M8n95`zEp=;1kbu`2BKMW6VC%1JzGtLht&H95k%fiI zO0H}LRJ1goK=ClE%aV z4HPtWs&-J1Gq#e+70NWhx0r~b5uTsT62>g(&6G@?uES4BYz;h%N{#>)K-qH$*22|4?636*3;sxUY07jRiLL; zI8mllu{lDkQn_-jq_faOnIdMUk?LV)DtQJoi`+m6>O7<~S%)1OFdNYM!Gf$qYfn~V zat&IOwCg1bJXJYtKB_X5LMYi>Bpz#Xh0I!c1ti${#gijMi7$~VG*jBoC2(Fnr-Ai5 zJ*q$;zEgKl6r<`yf>nnwe3bxc0X3v0Mt`~5DPEi3F{=D(#+yY&vw3qr$VpeNzo*p=q%z{?loKsc>245XM)e- z>F`ygHRZ5HSq5Ii4*{OU=eiKJ@3gKU4R%zlga^KD0c^JGT(QlVM4Q7y@(YIS1XmJAx91m z*!#+~ly-f4yj$rk*l9Ku)uFpKs9DmXYFV{)?I-bQI2{Ebot#FWoim!zeRc{u%YY_t zFuG3J+hsiHUqst|bF*r$eWP{N;ZE_urnwNUs?wrdWD#D#v&z?C-^52Y%I*$rR8Pa4 zGTiLT++k!oIUW<*D9FULwg0tjz$}2bZr&8?W^^$6C&^aE&&ko1txb z5>&+P3R72&=5-Tjv@GKAh6j7|ZCQ_u6KG5pBTzSoMuTcj{Wp5>d~|Y~|E9o*hVyX< zQ$$sywG{>X6wc*rpHmv8O3dj9o=HC}4&mwZdnqp!Ll5hagYh5{`LY7ewMZ4n{-b`c z;+b{oQJ;2(({!5WUTVC+^^{PD^pMBdZ<02aQ41Nvz42?b;4nYYhTrOm67MA;`oq4u zEJV*a)GbX2xjx_BlC=Y}--lr8gNA~R0~Ak9<22EN*otnUNog`_@j#d>!;fv3uU#{j zv|1r24KYZrluUS?&HEX&t%TOeJ{CJ3$7zQYK8J-kejd0y_qW87g+7532^shS;w~Lq z4t7EsD&f2WL6*^rE0`&_Z$n{UHH2D7MykIIX~KFD7e7q?e$R_%KTN)Me~1_Ur#Ls! zPMCPWdL0(OH zcW~Lqo0auzkYh18#<<*v+HZEd#mB<-N!HG_?rn~PK0nz^pUtV6({!_TH>W4Soy`>1ShBRtseEZ=87O!+IZ%kUd7vcGx;{wfb|hev7H zKT+TLQ3(aXGEXA|rMoE9y#}b*pM?*iP=G?)BzVf%Bjs1XlHSfl-mPc*_?%t#lcRr%$c(=~5HGbs1q zr?<=1ueas6#jl4p&ZIhk6J3NO{fQlvk|DV0*MXe9I1%{WQMpVBTde4zUM4IpbwpGy zheW?GUDd4B#14O{ArfKPM2}sHct{KI!&B6Na(-UM++v3x>g(9T5AH>eT|zu4xrSRJ z=V~$79HVN&?~b;L!NuTavAlSoIbUss!Lf#R9+P&^2oH|=roKKAEW=jSr9*46SNCOO zs4n`O1^QxFFk~0v?Z0^K3$qV@=hI*OR`2)DeDfR6i}qwB5^GC}NCy&qeUy!J@;F~- z={gwi#MQ06-`(%V+7coWNjPnt34u=pA7^JY;v=H{Zao)C;9R{>sc6!1P)I0DMBN>* zj^VeuqlzPFAV=IuM4W`vCEDU{{l)m;fZOlxjLJF_Z3!F>PIRKqHhkLg>AXaiR#(dH!DodgaLcA}xZN-S=i$@IIs+qE!ps@BhTM-66Yzq`j| zn9R!dy8|7XMWVfznAm`wQ5)OuCZT9jxNN*j(u5P{Fk#ZstC)(|}^&{>zz8`mgF-G}QZmq_NS-18%PF!$nU*N=ZZtY7< z` ztRpG#M&4W^VmA-TFe7>h}X(omce8Q9aSvIc*kx2=tf?2GK9=GHG)J=IR zTXF}s`YdYdW~qRIE92hz0a8&VMtc(eY*&NO=s65j(FGdWNf>f)YCE{}yW|2RyBegI zxE~putzEVnGGv&yY2X-J4F(mM!9>u4Z==eDc!>MQt@n{52DBf8U~l97VE_iH%zj*2 zlYKlD>0qLL0^WlRzuw15T^JesnB8V9CUrUT%Z*}eH-8$0M%?>n^CXFS|HUoM_HIwJ zt;twxt!S8PJGbWnWO*H`}`{`Vxcar_Hle(pzs+#q7i-+05cA^Uu=jhZu{h8zGz9f z;O&W~>7KMjy!YZqNz{8U)*W@+l$_7HQV~p<&&nwc(_1v^)`t;1yicDPKA5%N$6OC+ zXHpOlvjwhkL?(p7|6S2exAs?V${nTo&aKLMXtY0y;(z0&)Ig#rr|LL}s+>55csF1) z6yXfw_OWP}Tl-s#Rzzb}O<#qKC?n61A5c`>0!eP)^~PDFM^-=GP>if`v{* zg&?Duy4nNNC1#RWSG1j^g{W}~%D$^ar>sR*ySY=>Hs;oDQUFQ!4)CkpbgAI?sc|G7 z^0l|x={JbrggC#Obn*{YxUT<6q&*2j%56)82*NH?0Gh-J0oAE7?_u_Y!V(G4tmNSdFhwr$9MP%Yaq zN`V|3q!hZdQZ|C>+n`pCb1OHfHFaSLPl~U{7>O!xnJ{6J!-UB`6s_+Bz3Q^sEmQ3z z$f;VobG5gE)!yQ|dQo-~dL-t15LwYo5Q?d!5+)O5^LtQ$0&|qPga1aLDHdqT7~YgS zLxzQ$1sav0Q42IKLF2NHseQ2U`hcbAJJQViYPYFUKa9RDogd&IM<`iOT1BMw)=bH- zI*!o_M888?p*w5kj^^`K8mNfH@qd?qR@G_&vtdJj-QhlYi2DR8c#HM;h^3aGp6?p_ zn_>GyEQ8;xV$c9q^7}6gQiy?St^dDrz+({ z5hdI>Fi2s7TR(vRadN2?7Q?a_`Pd)_8zX(F*dyfcrB|9xi6CGnl z)_dnQa7@X3??q#8JhkvkeQ$R^5qtels-utI{r%6zp8Mr5zx~P6KmF~t&cP0+vm+`! z`KY>&sr!t&r`3I2-KW%j(&>y*62TdRa0jSIfv6O(*xEZ`oo$`iAnbH!@EIq-?JkK0 zsuwH*+gYF)Ye%s3CS86NggkYnV|_XWzH(0mlqnPsZbVV3cj)pv2ULO0H$pxEDt}4S zdMD(R#qIuG<(WWj_s_>}TWhBoY+Gx($E>z(?E*g;Xv5a@)P-_ifV$=P?8>(G62Z#0 zrl%_2pvxc9&Ko*(o5LyH0XLZ-`>6nn=|Qa=cO%Uu8gt>V6Y*DI&<1 zDcr@H7Dz1LUQzcAiF}2T8^m#xnU4}4>#f%raf=W$jF_P$z6k)!ahm9-5INW0lw96q z;yVPMA@DmA{0@Wf#t>IClsJqrhcPCocgb6i+?b#(cL3a~yH3$T6~@84$7mX*b%U!M zuK7{)h zVD4MH_#pSK>4!<^?K^R>AMu6Xez{{*&AmHpR5#{VckktC4A<_uGwt+ZX1YY^;?Sjy zF70&bpi5`$5#@e$VoWDybRw-2<2o^=6O(O^h!{R`2EZLi3=)&z?pA^7(WrC>AlTTW z>jnWi6hsyQ9}$l-<`yMMa5y|d-R@SDpkjhMeI#)pI%N1=Dl>*3QjXCagpEnOS$p33 z$i-4-?QF4N4lU2G&?`?Opo{WkbtEG844pkSPbbYL*47THH$xo1a&!n=w)64b=KP&{ z^98?c=HvJwW1QjGDu)V*j=-OZh$k<-l$_2ck0)Q6&R##5G>6(qeu4%7 zOi->!c)4;td7awcPR9v*$IN>@lazn5_C`e1ekI6V9uJY#=`{1inIFj%2>@`EnXc}@XDM^NNxXaf5=g)%3+G}Zt%mH1*rJkd;EtqLhIRIhp_prp-IpO1)h!3yPpFT5g=BsLi|gU^r?kQ3CdjC>^*H%+BCZC&km z(a&EBR%i6h@9-m5K}f554km-g=c!~6f|7xw?L-j(Y%c2`K-Qa()w~jb%9{+BOWi2_ z^NT%M`TpsBD&Xf(!afc~NIMU-I>X1sQq8hek(^ESRJChlJQ05xXV&(8%y;>hZ&e7=5?_b1XG{e62OcMA3dzO9c{oI8##1%l*>GB93Xjn?EoD=Np7(RQ-bb&A$lWt zBvKz=#A`~08xcL05fg|?XfH+%6@P#9cd74-$ZVP%?AP%b`5aV!nb^xeN+t051U~Np z_nw6#3jTQoN~pi{bCYuq@B7~Tb1TWS8~^-|Hz(iw&mR+ylTTd2k?>OaQYP7G&J&3aUDd7xCTTc=LPnhkUqY6KH zOY&W2{#qV-8n%p6J0#~CVQRLylLeNCo}4E* z^&(O0_UKb)AFMxYxn#cwPg0qu)*;ge?e`RZpCy8GWSgASvid~emuIN|CSV(f@OhC=6cWZlb0AWuHgKi2^Qp0Q5W;UDuu3)D8N!s{kOAwramY z$tO;b2qwxZ*`<%f-sRU4-4 zP$XTBIf`FYL;i`sHxoXv&CLkEH-kbOwjKj){G`|sTc-m#Y~2ZQHj1W?&#@!{of_hD zK`Dnc_GV&SZbo6bySQALlw(N(F;M0FQVz9xGZVPn%))X%;Bw_sjwJ~=tjZxo@Kegc zkqujqEi8vTwz3scjwJ~+$Xy?D)|)wz%YC7+9P-4jk0tr~l%Hs&HKV_8NG&6r;lxsEzOP;Oe0J*b(#qI*29QpEU_sx44va&sZ*Xd||2kxfC)2rC7oRY7(ePN=c9> zbEy*wOFh7)hDj-wB;a{X0zOMAZbs&dT&kh46dGw|hf67zaDkcx5?o42$DGWi8VgH3 z#HB_^DVA`))g+MgQcAj|l}lmdyQA?im#UIdEa4{ABrs1}G!cDc(y81pJT}b4NN8bX zGy)yP1txiqD6gqcjCSyGo&Bocr`6GO3yuwnZP6chCXh$_<< z^wGc(8qP;6JzW!V zCNSlRWDFCSP_Yt8u5Cu${E>ktAsDW6EguwRe8)nhU>0*~=!WsJd_YuXS>!DEL-WBf z*_fsI!}5VJ6YPTGOX^O%+2lDjw1x9Vqnt4s)P8FEmij3CG%B%)#n0tOONF$Ce9 zIsxs&{8X4zM`aNb&MC~kAr7x(4rag*=YSBH*g|QffledD%S-1DW^1jsl@D3}Jks_v zw+xaGy1L9017!)gUf_b{3x<0Cd>M`uVc!#C3sWCaF{m2L#iDS{lb z(wO3eK*C$;*-WT;!=m-50~2y-hL;Sx#x$I_(wQxJ48RvpC<1Pm-FiXjLXSSu7m5HPR|D25>1kN2T{SUQ}X2w zaU+=76XD)?GoRq;{D?=Ia$@9@*(F2tMfRCf2}X`6JZ}dyUs%mG=owLX`?C~~40b9a z4?MJ@UmIkuY}O4(&p~+8y3+JqCbWxbv@pbZz_q34F`*llZf3$=jpQ3t`{&y~rkCBP*WKRNtsr7`ad(ZIw4O<+>7(wKIT zmb@LKnOA(n!OC6+M@ zwp?rN&->LYW9u<6b=4WaIbgZ9J;{^~BGZm#st3ws=wwf2C$z_zsROm_24qegM5f!5 z`O-jH;h9D{*a%gF&|2W%_JqIzu&`LtcIUr+Z4HM{gAzGP0$b@KP0vsVyOaKV6 zmWg$mz%`U^*Th*&tY<>+bA8lo5Ea?J6bEaAR9@ztF%4Yp&u8yZw2ztdoN?f+d}@Kx ze&>^_{|cttlG*-Q7IgbEI|orX!PVx>u7L`fyTL0@pzS&UAv1ITK((lmI2$TQSpF;` zqr+onUK~VI(yONOuun0_>=8~0CNjw5-Z&WoL5Rr9#%T7 z3CtH(dV?lbGl7H?H8^FZGn#-?RywN*_+h2HHG!(F^hQk}W>y-TTl>CX1~LYdMQMg_ z;}dZRMhERl$l2m3_X-zVCwr8;N+|0i?hc#@+)S|hZsD-ZA-juYcF=Q`Dmgr#Qf7ji z$NR_g;FMmoN8~fgOmK^fkOob8c~!pu%>)M_95oMDPQd(?-jvrGnNK@2!OdJ;W( z`KWxpnVe)uk*N1@WijSdml-t|o^4iaNnox}Gu;+c<(|!I>{&z*Oe?iELl7_~*$hFz zsIwV@AXj_@7YUVP54#!Letl54DEkz*pZt8@Xl=m+?lsK>T4`-XK-5vkY#@iNAA*-X zAI%$|V~PK;^)z#kfuRKU+BI9)sJ0!hp@6JSUq_u0dw#L+&%d0_p(N(IEhx*$CiB)- zCXio3e3=RKm=MqoZJkr-&0~;ddm$K~W69RJh2s5rF-sEIUe%=0H}-~@_lK|c^G)_0 zKLt~}_t{gQb~*Ejor3w9&2B-a%wum_^3$TsS-Mr3(FF>bMu)8C=AKyCo<45Rh0 zY@JsqempN`Nn%*P=1Tt~!2Rc>b1=Vf+!GRa5FB?NDKgpQ*pcSKnx5dARNPsz^`t`a zfxMU{5_cXGuvab#f=&HJ+zc~;8OKU*1I|+wCK)Szu_iFDSm{eNfsC`#UtwY*{4c8y z(CxSm;kjn4J=Y9&2EpbFry8fXRCUh2-sveb!8I4&YmOh5? zcL2y)>}5a>TbBc7F~m?cOA;ect2!*Sti+YzbQfW=(MN@dok^=;8w0(ReukOAOnd`6 z>2Cs{maA~VJP@udu9*@DURUPDa+cl+W^GBS*OR^)Sb5?<0Bej&Spoe}D6?uxC>UE_ z91L9EKINHm&{S&W5Bg5g4MSZrztp42svkYn24AA^CHr%Zy5-q|I|QCUSSJm~E$guL zA_w;xRGPq+5D~=*XE;zBcWe36*Ft`TE?0p9IEt9$DX+2oe28fk*H931k%#_>`pUSz zUx3T?E#vyE&3s8;2OF5>6W_wM$X{Dm=*CM0ZrJCsVtoc;XdAg6g=aDFQwD`-Y9Mt^(g1vppEZT>Y1aGOt6ZRQJ357AOQ zsrfeQ3D5Yhw1Wi_3|_1x8rT)qkZEmZNdlwNVt*$2rBqEsF5^pm>F>Y@g=U*9 zm0GpU?(RaTzU(+Z5}mqr2@Fe8F9veh!VGL>_rTit9836cvWCw!Yr;7C7FT(3;l4!s zj>Q#S&TE>JHd{|AH2AZ;L6+nVhHA)yA-?y;AfigP<8c{E-vBQv>piiW$u92JmO}Fg zv6a11{AEcZ4p(E#(>HNEJPC|_#2vkeP#2`FmA;uZv|+RXX=_Q^T9UT1gi0HE%*MD6 zUlCiLEvKOxyPzH?zkz7rI2l2HYcp%76Kubrt^q@&|4^Nbax!i>##lc&#>`9mU~B6N zVA5&JfgHAe&-LFTL0}0VJ=gHbZH*IS4{d~GQ081*2~7+gzNC?Tp~S5Kh*OZV z-vbt|ndhnzdGjh)@_kku3(H$iM>&@Zf5^MQlDrElk}6-)@L@Rn@S64kn{oDmFL@to zhicAk?1r8du<^%OhI=>{DXzhIbbFX?+=!_F?`71kW50=V%(fg5&8iFLi^h>?3?gx4G)?gLS{=D02X=Vx2wHODdM zT65gR|N1$_`>#21Zu5t_&1+Sg`QofO_jB9zn!^GK#(*`4C5fwGMz1+s3TqBuc+GhL zSGDGd2@VDOZm&6R=Rb0sKN6j~6}hP9j@3X8TYqBdgKRa&5`HdP!?UogIpS)+HK!Ww zbEnPLHH8M>%^PG%-k>udsx=2wq|677tLcZ}g*_iQ+^wyJ=Ksv*9~OUEl0bIzeDDZ3 zm=9({>RxjkGgkUh*3fyT($-#cII#-XoUz=8|0T9OTh^f(yPzH?e`6PQkdrOjDZur>=iJ*Kcj+OZtbXQ?01Au+L@qIW-U6PuQi$ z*rggo#2z!Jf*Y>!Vq%ny1J46kwP-xsKdkL{u>C?~pE|~BVQgzVG-SCs3&>&X?=0Pq zs>bJ7l9&V?eoBTX^yGKe%_F#fU1qnQU1;SWc`Gc*TXFKlq~qZ$k`{TASSsEY&h+{A zr~BZJU0V#QnCVs9(eD1Co`&l949P3!(@6NztjADu6c$O2HDA(?!=yb&VFk38zwvn4 zgDs@}s0M-eqG(ll(prB=LIY(8)lvKmVC*OjJNwwBy zVIBY>Q^J!#YAZGODK{4@GS-J<(P+0fmg7x5yn%auW;~68d@@>V^f%w{a_%?{GY?xgqjbM^s6^p@ybNWK_A;M1h0;HUWqUqxxLdp6izIU=ki(YA zPCp0D@i~?xkW)OLJkMTv5*QmYpXlBXqcwT2tn^P?pTLsVV*5msvaS)hpGLn?oy43ES}i9IK@jPmA}~cYwK!Y+8L%(~_>|T1@IxKzuz~xk62kFu zH>XBx)S4gy|9K7g_dOyVXUk{tK{h;5-?(XfHA9L*Aq@U&8pA zVq9{ylq|4Eae-g54Yu!1{0iu#r(hpvkqESH-zxJX`}{~c1Din;yX2WIe9Xf5Mmqj( zh2w2PiT8l%H(d5epS{B6(f!Wkz7;}ykFD-8Fy>3M6}s*oRX1Pqb*p=f-*ClzkKwMQ(y0X8nynjA zPR0p(3FD-MrN2eF@i~?xrb8!j41hb=k45`2&G6WDEN?xx&`@dK5KHogoOxf}FHDi# zav4hh4z=6kIdA^FLi15J|9kP1CHw%L$MYY+!Fb+`kn#S&8PB+1a7 zaFC^m+`mX)n#wVbp%xy?=c5X{fbOfI?10l(1!I}-7q|qU{_ zG&@Y!1Hb#%GyL=G;S!%)PhIv7c#%Ut@}oZc?KBU+3}sCmCFh}X#oR4dq<8_X`8;7V zKXHM+VpFYAS)@2{XC5LUAtI{z;jKm>Cej+2UGBO>=Yd|)?&eYdDnWS?> zjI_`%5c;@k_4XO7wEqj0&oGX0Ytbo)H-GX+(L?P=I8M#lN%xbOSiVw7-+(tRsd~EM zL{{bp9v|rR(k#|j$)5!Xgt>V>_mvMU40SAyuG>xP0@e`I**7^Bj=fXlwKvOD3LL(} z2EzMCAi1{+H1G4I-v%T74nQqBR){}=sJ!lH7#$m$}I;g zuZb|A7bP6_6)U_e9H@ko9Fuk(6SLnb%p^2a8TgWIAn`t&o%BVm zc^e3h8;7fQyiNsW#1<8X6d|fHV)-W6>7&jsj)NI@hdI(!T)mdoWsyNvZgu}q%+aB+ zugED^C}4^i=H@mw1)YM5bR6=zp>$KMdyj5oVM91KFpOYOlYcjFXd~9x^v~u>J?oFVX`AJEek{faW|nY^=iQHLxt?I{UkHI=ke!BDsfP z$#^vLcRTKk;u8Ht1(mMiz~(Kgd`9>PJy>ey?_xrpGy=qrkrV%^+wdf=lRT9*#c0o8 zf%_950@l_k%_3d+De%}KN87K}MVo7%Zf-sY4b|JS!a3$laUW}xH~ow@ROo)c(oRdz z)2itiE}KNzegi{Evo2{}7O#FoR=jiS&Hm#LyQDJlYkAGyNs=(PE_M4#)2W9kp_H4_*I4G&T&EP2E$3ZP8 z%`)^af5OOxbEnnS*G;XTI(a4tJb^_j({ot0$08&%rr~ExLxHz+XWF~gA)rLd=M!!6 zfVZrLezr*c&T8z5%bJ@YI|%x?A&|}L;Fn3{V`9sGTI_~kFaq-L##DZgfm?3*?E%co zJ0jR8(X+tI@%<3rmq5?JHGnVctiYFPE{EGOs>augFY}1@Vc*Lii|#FMk6JW6!tn0! zsnH>HU6lDn#aBcu8W~w%YSFr4hT{Y_3jCA655vsQg}LlWk>^S*3RN)tR+!=FN``Y_ z)1sFFL-f9<*Jsh`-segpl&gHDG)fCJt8Sh*FgLN`C~-KVaFS@5Q+7&zG)8D`tj% z1e+HPc?X`%6MU!O;|1>!+#`6C;4#6^0KSNhN3^4Kx^TV+jzvo)lJ|y&`Xcluq7roX|U{HySH5$f^M zc@>RRPrX7N8&cFZp_+x7OqU9EgiurH8$x-7no8FSHB_i+^lhQe5b9{Ug*??I#6PiW z#0qk|i<(W3kOys_jSw{A7b;IF3M0A^&-R}Y&7TOh5a$PZD~suQ(Yy??YQ(AB&xLwi zsAcpEp>Sgd*{Sqvp)9H4GuYcZd2eae@0^j|J3XVHJVtgNShx~z22VV7nnvW2av`qI$L zw_yYMgi>B-C?u4sFH2z~?{zmtTvj$wnafHKRk*C2PcfI3%{0t7f~J>+14q!Mk&-|u zJr^tsRMWVkhmC6bYlz`=!7BtB0{;NMLFWfzI0LK+j0P+X90`~V90fQ#a17wz{3igO zY_aBTeui%ezScSsdKU^`Fvxt6N~rvqN$=dw=+RspI~-D1-eo$~|j;J;jvK^*=e(fFr8 zg}XV-pH3fmFAP-DLb?R-2D$?9S9BfVNyc8lod)A?3S42{4t#~@0l-f^j{{!eeGc$3 z?=Jy=?L8>g-T^+sd=D^V{*$4HAz~b?q~}eB(}+2L6zP%1@SsKPiA7aICj{A_M?A1V zKkzU<1^Qz=(*fHJh7TGI(Enyhv%m!|*eqpFfzAdx70~c7Y&TYmPP+?s3En088R(4h zoF|$LA2co$>7@d%aKTGOex@Hv2 z<3RmV%PuXS8}iZbwe0%xMWFtuWw%CGge>}tmfaU!1M0tpx|;R}J3@XsvYPO@gmzb0 z*wL)g)H`UqpZ-HrIjqlq`l+U-il%>zDz{H$Cur&kDYr?eUWuTe%Ez(hm9*A(4(i*a zskHB6yhimyq23I7hF)n5p#zFCw!_L0I%2%kAXbLZQ9`{LoafsK&0~b>4V>yLfo6l2 zU0bpfbK^WMyRoDM>)sMATOHhKl+p?<>kO9Q;Bk$X?e<-1MCoiTy9Li*qSP(a)pUIL zx=6?E1Ss_pUccSAAyuA&07N^TDgrPnppQ`v{NLDu77%g&{tv{R@zgIwQG z+9gzPfa@DdH)~mI(N1F+-L7RDi%Re=$o*ROrPu*uI6WrRC4sfE=RrLq6#IF1Xatof zxIU&H3RTfHLR~`fa9?N?{a8`(^XbrN`lqJY&(V~{NsaC2X!?p!%FogCb)l4>qv;wg z8-sp`({3$08vPKbTeXa1T}^js8OOSs9@4Uxf>#=2=y5H33nOI={aDK;mR@O$r5CmA zxKabZng6X&+@k03R~&ZZzCpF`#n2HHz}XS!Zan;(P=b~z3hjF}G=Z+r6t`~z&8!to z$)yRjT&OpLx1$XcXthwifk)7W3DmA-@A+QEP0Bf1_77jFIg!rSvN`CZ8oE%+mZFbp z=u$1)AN!M0OW)M87h)sKTDo4#j;P#eOrpJ7Hl?xz&tLXw*^bywqmJ&?vYoLKJTKWV z6u14Y&`~sF61Rb=_d}CuD2{y4cC_|yp{cYysss5Wv#|fq8v#E4hfo!Kx zs&A*#x3w%_U1?0Co3*S0j|r#I9a{Dta`$MuU(5c1+&!B1YuS$wv+4AVmi-nnn@%ri znH9UzIEG%_02&%$f8Lp)Lu0QgJ>gZ@p^Y zk>NiX$5L3RO9IowBg|u|Ld)*2oMwK3Mrzr!mA#<&HvDHgL_JMZ&Idq}6Lm#%=uU^4 zUNo0>PZvMYqAwQBqlq{sQu)$U)J$h-id)o7W90T#Wk@s46Y5Q4S?nZe?$y-!!Lidw1BD?>P=&1cxlmm+O4VWm1h(!q^pkQ+TS#$#9E6MQ}-7XH7k}bT0)O# zYHVyNsO5ar1kE_Cw9pemsrr`DueEGeY*W!PihogQPKot`+N-JUm6sKrO7Y{BY;0_2 z(QC?R8|=7oADv4N7x+DY4s&*3es; zniYGvsFmtxDcRWA^`M^9R6KlrQHqY4%`#QPI+`!ko5uFaCyUn6ZJL@A`$J1r^T8Y8#@8iTbhc8PY7Q?i%(XXD?x3g2ZXwE=%VPnaE=ZL zrRvMk^Fm#Ow^8Op_L8PP1YZuoMl(A0I_E#a@zNKHNK-4?!r#%tnI`AMYO}y7ru_VT(axwJS`jQ zeKCAJ?GQ?}VHaKF(%eORwB|TE;Mqk#b!mQ^e&f>oHodMjYdkN9zfJFIs@Hfq{2lsG zQ;!=5!@KF9u5x?Gw@~%NwdR}QJv3Y>)rK2roR-}T*$uQ*Q@42D4Btp!(bQD$o8i6m z9ap)V=(}2WKg!)i`(3h|=~*q?0ol#;d!ba@Z=rWwnzztjwPp{!8@`49p{bDP-SBtG zvq*WJG5#99m5PK?UVo3uwd{WL#qjs2)+PHs&Cs%&A^Se_g;HMMMWeOs zTGL;A7fo}?en1Ucb~9u@pbeV3#p5r&n{L$9RIk7I9(veS?p`{eW%r}pz4Tj`>^^!! z%XUC^AN^e@)uQ{!TEbo{&+exoLS2Nv%2Hf>KgBe4n2L)ZpwTYP2PvUtH=7m34^o3m z_7Kh2vil)>h%OUK)%P%6>(YFfZqS+;V?^=8^gWmC5xPgqZZ@lnAEAG`WRFtd6cy|H zA$ye0*VF@^SonwZRZTT{tBW6_2Q+o7Hx}McPYI=3+ebguvK_F}N3XkNkJF#E>{`ek zC$oj?Q*C&HB0?!EPf$!Kj@gmLPta&h9i}6T573dC${0r#KS@Wq$~{FhwCrZ{=;Ehn zpG)>M-KS;uL-sWN#3g%%ex+qQAbW=1b;+KkkF@Ms$exAA2K7Y#737w&&P_%9md%SH z{yRQfN}03C#~kK+gzwe-!EM@hzFDF$ws4g^1z^r#p13uY&Sz=nYqV=&%QpT$EvtNR zm$Gr?XTFxfy!|YxyA_|`UbbM@ICv>r&R2u>qc7CQz$sB7K9J+q{Cuff^M8W>&#isF z=I2Y@o){F4as)1nDK6vrUUqB#E8K12-@%m+|GUukxoRl4Ym`9t?SHqH|5L45cn;{N zB)%y;8Qh3(3V#u#7vB_K3A+s66#iPk9(+^ywf9~4rtpj6=P5$J!)etUIFOc$~l{f%63}6*$5CQ^mbB*&Jg% z1UNj_M>EYil}}Nlc|yhWw8T8V@)f{^v47y*H@3ON+!h;e+zNb#G1+X6HUfS*QbH@t zyMrehE6i7l78oxOpN73ae6IHb@d@4w#OFu1;@Ri5M$%jn*=e+!fAid6G@3gqZvme< zFN^(`iOb=|OF^3L)*!Vzd`GELz?E~U-w085Wp=XSb z#m>iK=VRj2wvUO=)q2hEp_ZV*z6Ein%{ZS<1r0v;3L1QhRf^bJRBEsfrG}g+8hmC| zYVc{;WP?w1CL4U_GuhzNq{#-KH%&J9^k}ld=R^~XrNIx3Hu&H*+s)gHLgq}dIn&_t zpP2@q5Y06B>}jUKr&BWxK5Lq3@Tt<3Xro0Fj7_mI<`VI9iNWVKOHda>K5toK@X5*& zgU?Ww7<^i?#Ncz02}XJ4LcmCPh1nss?=d6c_2vqxeTB4Wg~8`OD^NQ_KFe8Q@TtuT zgU@GH7<>}5!r(KP6$YQKoFftIC63z!gJCx;Pp1n6E-~+py=3-?pFIYjhx8bH^3h}P zImR~8*&(o3eCQP)dJR4+={5LNq}Mo5vBGne=v)tIVZ8mZ=-Zw>#^0iQJ$vN|#$I`v zu@`TT9q`;HnoG>q%3pZyGB!lsgXWE)pm&dPb1dq;)$o-K1^&bG(SYB;*~T8@qu506 zJyPls+7?;h?Sr?kqIX&&qk(f~_DLojklL|xvb^RJlfpUgbGj7A{1>|3Tg?|d?11bBVl>Jcr@gg$Q@f?qRJ0!jxl59LA zUX@GS$_@6aN^7#Uae@aWo?(%GAbD6T{AmJ@6TV@x4^6@`%oj_hAvd_~hIwDPEh~lJVSFL_XRF)zd*!Fr3hBpgBOM#9QrGo@_efnGQrBMN+p$lr+caDex!!+|@ip)F{Cf?B zV>a+VB6c1z_<7e|#$P0Jo+;wq@2cQTcpJUnMoZvrkC`g_iND8OSkCb6*o*!TWc*Gr zVi-XkqBFs`JMyu=4m128it8|kzXgb2^hD}#VqF4QLvsPA(ptbT&^ds!X)EB#!fyeb zO=r+{z!2aZtORcdTL3SQBn7sLv{j_7)JjiBQlgU;=|v*Neja6UWoE*9x-;opc8 z^{XN`3g;$)`-T6c;0FbNO>|xp&TEu~o!9Xud&Q79ghK}V=D|7rRe|;)sXcs68(!r=OWR+Sn%DVvqwYLyh-@`h0~`Y^Pdn4Pl)tcspX(Z4{69cuZhlU zqVtBpw?&goj+mh#YkEwHp2^Yk2@IMXw`$R;Hd$w^=!_NVc!7-~Z4~KjkA97Q8|5M!{DLo)kPMc(35Q1>Xbw z;mBURS$cV7zi|45b5QU@f>S_h39x2d@M^&u1ttURPp`mj;KYaQ5xh^}0l>>6hXkjf z*a@QaCxmdj;Pn(%r(@Bb@z$9}xaQ!6_tl;SEvL zC3v;q;{XwD;WP?owcts?+eF$c_#T0M0uKoPkl+ShLVi2w1-v{`EqFr_*VQO^lkisy zCn=nq;Jt!x6X|Z@>=Dj>!TSV1Aku@vIV2nkODk|wjv4_kkHm#jEu03y8wFo2cvA2- z(aZ^_S2()`-y`^5k?t2xpKuNeen{}wMM}j|FJ4bZ^aQUKyg~3r!J7clN5V-8Cs)il z+$;Dtk?s+^Pv9YeuM6LZu;prj;{eek5s9I2RtugKyiKGz;q(e;x8QpO-!FKd;0Fai zB>3xqmq%!bv|@;~Lhx$A8wEB2!v7)cb5c0lgtJ>X2L$)x4bQ70@e*G38U!{8XPdwS z0=;;<@~TLaz-I5qec*oWQ2Ci>P+U{_-)1!2WXfkSZCE3v3X$T3}A# zZh`v+9u!D1(HGbtaJ9hw0uKtLp`s(OLEvhEIf1(c9uycK#+nBO(r_syaJ9hQ0{06% zC@?;Pbyf@9FYus1s$zbFz?{JS0%@e^3(N`JE%2bg_$VnQaJ9hQ0uL(wXeldjx4?q} z8{*8*3EVI6pg^i-eq7*cfx89L7~uH9R)xYW4A_@VK0gDd%yP;@9SREH_}(@o9$cZTjA^WUE+Jp_pI*~ z-xP)xL~yb18V=mNlFDozEwt9%vU)6ug4{X@?IJl(eu z@RkyW=L8v!wwOP+qz7f47AFDXzQ)@Ypb0d%kiX z;M|f20Nr-3lN$F0S^r?g4*{R4ct$i|)|&k9aCjuP9x@SKj&lIeM1=joLx3it90VQ) zG;x+y1Uv$0;ykMucnP3MBS4vWGr1I;(SRo22`U3#4QSFB`~@O@qo)G+IJ~87;4cfr zfKR}gmx*6-j{vO2Up_JLR?JA?b+BR3QGh1Z!-j$Luxj8(!-k1>iN^!Zz%Tysjwhgr zzi~7H_!j_8I*w|9e-V)XF2E$3JxS^{X&DX?u&3n2eH291EH;cm~w)9N{Zr_+g$ zo&jj`sTlAt0h)9sYB2D3#!d#l8a3d3SU{83paui?bc=xFeiV2L(4@7f!Ju`3CjLU< zGT`liCY_Di4E$a3(}1UOE{Q+2huTcM+5IK(vw$XbqaFk2l&gTBi+T(?574Ads0Ysx z08Kg{^_a93HJJ2e*q(%zEJEq^D7^*m#e5xqC%V-5#8_kAWA>S2Jtuk2@m%WpzURlD zF}*k9q&>jrb~j(|lj>rF@;f@Az)<{oMDy&u7(JCt7LiE7lFxt=5~?-z=}c z%0I<_tUu+y*ngRSkN;u+<9=_BPnX@F>+$@=axpxC2l1SzKku~ifxO?ylb1qke;q_G zQpRNq_4Wy`u-g>OAZ&18J1;5!xH zY51}i_0)!^Ui{l)bv;_H<#-po%{L91KMff?4cRvhIWq zp&Ps>(yiWR!T$^RC*DTmII70CS+3VW?;7ac>lGfy?K(<7ci~HKl%4JsmeYlS+1{j$dQbED^zpsqXph z*>08yEk!1Ck!2g&>>@(5Wa<=_v?R|>%}#f2NOz^Wy0ctV@ue&)!06nK9UZn|DRg}6 zs#Q(x*$o}Zp4lDAY*sPZ=2Y9};$#-TT1qL4!tGy3F}ct*yU?OcTPmZ92#=i*q@NQ? z*v|>4#FV4i-nvxxDim8jrz6#grb)O&AZ-^++TPLbG~5vj(%h9zWu%;t{akQ#r%t!M zZ|>Zn>ayD)60S~=ygkM5=f0yn^%&dWf>bt}T&H6w-2O3COw=%WhTUcfd{1GQDrx`1 zn#(;PrR!R|(;3MCA=&ZCGudoD;S`sL>vg&0}MH61CS&2zdocBV3#;$VTfG~L|QJrxt0_7a%eOOT)C z3q+{e<%?qUkK7cRyRoZv^%Oca*|9OTbR#kt#L1~1p%*9HGa#GVTf5uSUCB%ji01B8 zCv0hl@TRTXA&`SK7+kH6soJd$QVWhQ6o5Q_CLOmR-L|nKbv(^Zcdbo{52*}NyQ@2s zZ0*k0H8oR9PZs{vH7_C#glh!O1uHv{#agpv$lD5eYAMZ6C)=8m-AUq^K@d!vN%+!g zS2R1_(V;xa)}5H@N@dzxskymL)!wFRRFodPkg*$is-K@)?($q)Q+{c&LvU%8dRpQT z>^n8Kwb5}dTWI9*>sPIsm26#)Uy#miPjx`a3DKu@H)29vj>y0EA$Om+@Z)|n*-7b`CZmmxb+dR`b1 z;5nVi_Kty`wruPi$Xv29+0nkXy*0@rY@pa#0tQqf&hY{}K%!UC0en|)4N^*V)?kAC z?qGn)mhNQt#zD%oY+Q3ThRHzRIBbp|1I4q`8?jUmsAhH=yP5&qS?RW(fn2TuYf}5U zm?{QHS-7;lGj(!%R~xl#NVT@F?Gap$D@i>Wun4arPE2(#?b(o;)q}|>)q&|am06o? zO%eEcLW*;Ks#Kh?;q;m(KFagaxT7y^)bq&`}5^hh|=~s|_3k zgsHiibf@NEu}RT#9zVqYCTTu+!rIi?u@GFrT}|Uc!jq;sl&fhDPfuia0cSKj3aV)i z$??ul2NG)+$x_FJc)$~PA%}I8QAfc=u7xLE+*(9QCz`!(=y0iZBCA&p4i}x0T8Fhh zl@UV6P}CM@(wNn{dqi;BS=d5hA?A*N{Y=l|WCjTP!&Q;mEjhHBnWTj*)?`y^&Bk@> zQkhwq^m)>qJbYnQc5t-3u^T(~H5d6aq)(OA6eNB5ud$&tEs|Q`p86 z!R95iia;VNMF@`mHTG5nyT2%aZlW;N;Pe3+*O_CsG4lTu0+wUMx5H7I!`eretFVmG0)_V z=3aFQsajmLT~VH;+LEW66+>0p$y2&yjqG=1vQZe19%sAGqtS7wuC1d(=Z-U1@q!@) z_D5JY^?1&Y8g3mHg%`EcvMq?&3-a&XThdQY!-6*Wp4{MkJyEsFP5CtPOa5D zeHdVjZsikRZ<~{hb4LtpjJ+lj; zeOcbwQ8&N6>m0j!!JFsGTm}7e+p&pNTx@T$&T{22)C8`F za#otGb2KZFcL=_xatMx$BolV9qUI2+<`D2*2aEMU@nSf@$%6i?!+k<$dpGufS?Bhe zr>rb)WJgaHY?-98g?F3Wsgm#6I&~=&7i8j~ z8hHbSCGCknTj!pn`qiFSa!n|ospAaPej0ff>Npcb%8B9x(sfrW9VqjO>KBc2uV|FJ z&Xr$Et$@MG1q>;Ym7~JX3WDB$W}Oy)h9Wtuo7xAcj8k)&a>d5k3mez#bHBJ0cAn$0 zB%0o$HD=b~R0b!b5*KH}*EQKQCIZQoRQ0nH)*@XR|s!!cs zNkNTDA81^*fO9tCD1;Wt?UwkcZ@p9@bsI)4GJ)}m%#CbsZSUr>Bn$kaOjBxYa$`p~ zCe=)~J5Q?6iAm_%$EY%!s8ddYQ4UREM-{|WO7jHh#8%uYxe28jGnr(M@c7B4;^(-3xQ(qCOE-Z?SFm0)g5XP9Wt@@^3Os?H6d@E6D`X5&d%C!T|)sS8iFy6^-m zi@!6s7|*=2z%zKdg_~16K3xR74S0sBA+zxp$5^8Ehc%0h4sbd(S8J9o0FAVVy>)`o zh=DcM;pti@{|z(zH7dInhgXsJr3cS@v?lz{d*E4#XQNa~+aeEsdOgCH42(Gyx4;Isd?RP-h=CgHgVb4&S&rBE%{|9P;!^GI z`+>Ou`}pyvJyLq`B)k7uBLB(o94*H0?73$)g5uBEsy|G5;_DOU+_ty%n8)UKy+q!) zVFWyJGJHTvOPP!aI#b{rh9e_BziCFx0~OIFW;7mM=8Ky~)lhH9h{hGKKDvyldPUVL zs#Z}|imFo7GP}q!TYFhlD=v#VI^)>dIJ-oGsYDPyR74jTqwojV3=@B$&xrO8i+JM{ zT_*U*NH}g(M0>{@(Ph!zk;6(@9n>hr97XK?C_GEWpWuux8$~501|)1xsS#=!MV4Z5 zgGW|Da}>-MLvy5CExIg#2%wUYRT7^nJnN12PV&{8hGF_)KKHxm47t7$Jx;EFjyA~k zqiB;{KZ(xcD_#JcFZA=#X%gcqbOm=uBoK%F$*2O24MhB)xKSQI?5nD)OiOi39O}i; zDn=~uD`BVYw}6M;BYl;*B90=_tv=62$B5J3LFcaCKX45JKB@eObzLD*1i3m7

;wKR7V#3ueAH!~yA-UR_N%}5ETfLLRs#9-Da@`YgcCT0Gn zBD+3lME$-%F+@P^LS=rB8C_lx&E0FVp$E) z9B?{cCxICad2ADQF==Cc30hZBovQ|0GvJhVH~~LfMq*eY4`85_+f`r(=8H#G6}$Y6 zF2k>hv=`B3Fu<)0g!~w4It!89xfiTBjg01AMrN)?f(CI#MY)$vzi`lVaf4|!TEH(u zpq*@0?KKf|s31YAsw({cXznFge1X3Kd{O#^0EScUh0*4>P-y1zET4hE%RhyBC>~56Df>}mGkP{u;EaY6Y6N3=-ZIF=*%3-S_okQWP9)8Y+ zM=5%nTUizDN^?Dx1G2t;89C3v*!o(`~=-J)cd+M;a6qg&V}E^Kp4 z5lmg6+}om@+M=2jHzP2S%h^6};Y#BsN=s|wS_}OJt!*L^^s9mvG53n-IK*tb(j2G5 zG_Di@%3Wof&22Z$q1+|cC?`PcAOS;31U9!lDA5?lw%|Hnr9-y|bwG0418~k=SwI}P zUh#qu=J4}@+%Dxx!VDwHa^F?fcPZ-$7Q;GU#riJC`YyJf;PR^Ni6Pv&I~_;&DYLca zXl}?o(cC^Ql9uprmS*fTRZX=};F|a7^2sRU$4#h5^|m49`*VsXzW>aYtH~^aaA8sdlzEPwGaSlel^I^Y z5najie;FhQ%xWMQah%{X+%Ue)2wn;_Baw*T-35UXKTmh~J*1lZb31uBD?|~f{e;G_m(UpY5gNlD!olhttk%J*9BiC}B~Z`OV$_{qI?7#? z?M;CFlzBYjk_LEQhYGJau+yfkVp`JbRm^VpVq6~rvPsJ^#b|jvz_Pa?>tSR^NY%mv zS!;|Fjf+|O0fXIIg-0XPA2Ya3E7!7euK{!On0+gQ{ki~WqE@RHwPKb&ieHH0!#f0@ zY*~D~FOWW#6<;u$RqL>7Z5GCk+AU$%rVCa%tSXx|&S8zSSqX=g@M4oxj>QRUGw-@0 z5f$lCR9<3u^;S$VdDF#vx~gcqx?oi@3RX*<5;Sq?S8rB4q=BQf$l_d*iq@UkuA1#3(|v2@Rbd0iT3aoFt;5|u#pdB zgDVRHvP3)-Lgc%UBaWO2N50FJUn|HyWR9cAgrm4m%X7D~C%JvtnDezS+FR@tV8SWT zr{%dvJ$OZv-Nw*VmwI)nRhKHhV0iOI1x^PXT`WxW8_Uo&p}5R>Jk+p<;_1&dB_a(l z77?@PGCdrjV~<_U;a!OGqEogc0ktuSiVs_&aj_AX7H*G@6N(|0RpIT5CWK-b;4LpC zwIb<@)(ejzX8b@x4aNWzoA{ysqwZvv^zU>T@lMz;6>Fdx9I%%UJM zjS6#@;5Xs#CyK~s?+daEl9?qoW(Pyc_2IAH26)`#t_QEsE;TDp%Op1}Om{gC0hXS{ z&sGiS;hz=5=V<(y%esYgmd;LRQjHrn)anOiUp#ku9rAl=q}+Lqso$rR=gOlE8jf?U z&v=M}zcg=P%}mZ%RqSBCGA_}1Qo@70QLL+8)2XvQfmO)V{B ze|z$p8~)yK)jwM9D}8Lm6KrGlu`8El@r-z7vLn^gy0S%Hu~>OZ3Xj)UE^c1aHfhR~ zRgE2~cDy#VssDcB~mFYESuaurz*_G->pBI)a(5>6hwuV~fHBLEt zI%$_Tlxvp}7W3T&Gj6->rQF5mman^aGn#IHb}}Bfslw}5TzW)kM5d{uV*!r-sWaP( zluXG3IVtn$co^v)zCvsNkNRJT0RL`8{>|iEp)nZ}c+Z^%@L6vjzRUL$b@R~GpKi}I zV5d?Ge&cW|&I3;Y#%GWVK{o@=-PVX;Zlz$_lPM`5KbP!8-icUS+t^S*a zGfTt(HS=Hox6k3Yjvll~pOiw*5|*RGmrYz2(zz_enOpb*9+0b@)6pixWaV zC)@x(^%?8`5Bv349}K6Rr@}s;v*+zj#u;_J^JRbd_dXoiZqe;R8#`Pr{dd|~hjZ8t z{Kp^s>&UP_AGX(tWwy5gvE&x7!*6Q3p%ce>S{KkSDcC#K|#`rnGX+aJ}h zd@{@D)Enh&`hTNe>-oG5zff}9?H~Po?D^j=;eKjF-((S+PGnsNq7p~m74}%Z4ENi= V`MDFzG>U$ghwK0Q{9hM={}0U*O}795 literal 0 HcmV?d00001 diff --git a/Confectionery/ImplementationExtensions/ConfectioneryListImplement.dll b/Confectionery/ImplementationExtensions/ConfectioneryListImplement.dll new file mode 100644 index 0000000000000000000000000000000000000000..6fc7964fba945b20061d0c29dff960f695f7b631 GIT binary patch literal 25600 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 V|7So%{ubn2+W60A|IcRNe*>orjQjuq literal 0 HcmV?d00001