From f385a1b5556ebaab0242800a30df3447e5ff130b Mon Sep 17 00:00:00 2001 From: "ashutosh.nehete" Date: Fri, 7 Nov 2025 17:16:05 +0530 Subject: [PATCH] Added Finance related model and migrations --- .../Data/ApplicationDbContext.cs | 256 +- ...3_Added_Finance_Related_Tables.Designer.cs | 7494 +++++++++++++++++ ...1107110903_Added_Finance_Related_Tables.cs | 950 +++ .../ApplicationDbContextModelSnapshot.cs | 931 +- .../Dtos/Expenses/CreateExpensesDto.cs | 3 +- .../Expenses/CreateRecurringTemplateDto.cs | 22 + .../Dtos/Expenses/ExpenseConversionDto.cs | 13 + .../Dtos/Expenses/ExpenseRecordDto.cs | 3 + .../Masters/ExpenseCategoryMasterDto.cs | 11 + .../Expenses/PaymentRequestConversionDto.cs | 7 + .../Dtos/Expenses/PaymentRequestDto.cs | 19 + .../Dtos/Expenses/PaymentRequestRecordDto.cs | 15 + .../Expenses/UpdateRecurringTemplateDto.cs | 22 + .../Entitlements/PermissionsMaster.cs | 4 + .../Expenses/AdvancePaymentTransaction.cs | 36 + Marco.Pms.Model/Expenses/Expenses.cs | 28 +- .../Expenses/Masters/ExpenseCategoryMaster.cs | 14 + .../{ => Masters}/ExpensesStatusMapping.cs | 2 +- .../Masters/RecurringPaymentStatus.cs | 8 + .../{ => Masters}/StatusPermissionMapping.cs | 2 +- Marco.Pms.Model/Expenses/PaymentRequest.cs | 72 + .../Expenses/PaymentRequestAttachment.cs | 22 + Marco.Pms.Model/Expenses/RecurringPayment.cs | 62 + Marco.Pms.Model/Filters/ExpensesFilter.cs | 1 + .../Filters/PaymentRequestFilter.cs | 14 + .../Filters/RecurringPaymentFilter.cs | 14 + Marco.Pms.Model/Master/PaymentModeMatser.cs | 6 +- Marco.Pms.Model/Master/StatusUpdateLog.cs | 22 + .../MongoDBModels/DocumentMongoDB.cs | 1 + .../Expenses/ExpenseDetailsMongoDB.cs | 11 +- .../Masters/ExpenseCategoryMasterMongoDB.cs | 11 + .../TenantModels/SubscriptionPlan.cs | 2 +- .../Expenses/AdvancePaymentTransactionVM.cs | 21 + .../Expenses/BasicPaymentRequestVM.cs | 9 + .../Expenses/BasicRecurringPaymentVM.cs | 10 + .../ViewModels/Expenses/ExpenseList.cs | 13 +- .../Masters/ExpenseCategoryMasterVM.cs | 11 + .../Expenses/PaymentRequestAttachmentVM.cs | 12 + .../Expenses/PaymentRequestDetailsVM.cs | 39 + .../Expenses/PaymentRequestUpdateLog.cs | 15 + .../ViewModels/Expenses/PaymentRequestVM.cs | 29 + .../Expenses/RecurringPaymentDetailsVM.cs | 36 + .../ViewModels/Expenses/RecurringPaymentVM.cs | 33 + .../Controllers/AuthController.cs | 36 +- .../Controllers/DashboardController.cs | 6 +- .../Controllers/ExpenseController.cs | 10 +- .../Controllers/MasterController.cs | 51 +- .../Controllers/TenantController.cs | 35 +- .../Helpers/CacheUpdateHelper.cs | 26 +- .../MappingProfiles/MappingProfile.cs | 53 +- Marco.Pms.Services/Service/ExpensesService.cs | 862 +- .../Service/MasterDataService.cs | 61 +- Marco.Pms.Services/Service/MasterService.cs | 170 +- .../ServiceInterfaces/IExpensesService.cs | 7 +- .../ServiceInterfaces/IMasterService.cs | 22 +- Marco.Pms.Services/Service/TenantService.cs | 35 +- 56 files changed, 10901 insertions(+), 779 deletions(-) create mode 100644 Marco.Pms.DataAccess/Migrations/20251107110903_Added_Finance_Related_Tables.Designer.cs create mode 100644 Marco.Pms.DataAccess/Migrations/20251107110903_Added_Finance_Related_Tables.cs create mode 100644 Marco.Pms.Model/Dtos/Expenses/CreateRecurringTemplateDto.cs create mode 100644 Marco.Pms.Model/Dtos/Expenses/ExpenseConversionDto.cs create mode 100644 Marco.Pms.Model/Dtos/Expenses/Masters/ExpenseCategoryMasterDto.cs create mode 100644 Marco.Pms.Model/Dtos/Expenses/PaymentRequestConversionDto.cs create mode 100644 Marco.Pms.Model/Dtos/Expenses/PaymentRequestDto.cs create mode 100644 Marco.Pms.Model/Dtos/Expenses/PaymentRequestRecordDto.cs create mode 100644 Marco.Pms.Model/Dtos/Expenses/UpdateRecurringTemplateDto.cs create mode 100644 Marco.Pms.Model/Expenses/AdvancePaymentTransaction.cs create mode 100644 Marco.Pms.Model/Expenses/Masters/ExpenseCategoryMaster.cs rename Marco.Pms.Model/Expenses/{ => Masters}/ExpensesStatusMapping.cs (92%) create mode 100644 Marco.Pms.Model/Expenses/Masters/RecurringPaymentStatus.cs rename Marco.Pms.Model/Expenses/{ => Masters}/StatusPermissionMapping.cs (93%) create mode 100644 Marco.Pms.Model/Expenses/PaymentRequest.cs create mode 100644 Marco.Pms.Model/Expenses/PaymentRequestAttachment.cs create mode 100644 Marco.Pms.Model/Expenses/RecurringPayment.cs create mode 100644 Marco.Pms.Model/Filters/PaymentRequestFilter.cs create mode 100644 Marco.Pms.Model/Filters/RecurringPaymentFilter.cs create mode 100644 Marco.Pms.Model/Master/StatusUpdateLog.cs create mode 100644 Marco.Pms.Model/MongoDBModels/Masters/ExpenseCategoryMasterMongoDB.cs create mode 100644 Marco.Pms.Model/ViewModels/Expenses/AdvancePaymentTransactionVM.cs create mode 100644 Marco.Pms.Model/ViewModels/Expenses/BasicPaymentRequestVM.cs create mode 100644 Marco.Pms.Model/ViewModels/Expenses/BasicRecurringPaymentVM.cs create mode 100644 Marco.Pms.Model/ViewModels/Expenses/Masters/ExpenseCategoryMasterVM.cs create mode 100644 Marco.Pms.Model/ViewModels/Expenses/PaymentRequestAttachmentVM.cs create mode 100644 Marco.Pms.Model/ViewModels/Expenses/PaymentRequestDetailsVM.cs create mode 100644 Marco.Pms.Model/ViewModels/Expenses/PaymentRequestUpdateLog.cs create mode 100644 Marco.Pms.Model/ViewModels/Expenses/PaymentRequestVM.cs create mode 100644 Marco.Pms.Model/ViewModels/Expenses/RecurringPaymentDetailsVM.cs create mode 100644 Marco.Pms.Model/ViewModels/Expenses/RecurringPaymentVM.cs diff --git a/Marco.Pms.DataAccess/Data/ApplicationDbContext.cs b/Marco.Pms.DataAccess/Data/ApplicationDbContext.cs index 22bd018..5d2ab7f 100644 --- a/Marco.Pms.DataAccess/Data/ApplicationDbContext.cs +++ b/Marco.Pms.DataAccess/Data/ApplicationDbContext.cs @@ -7,6 +7,7 @@ using Marco.Pms.Model.DocumentManager; using Marco.Pms.Model.Employees; using Marco.Pms.Model.Entitlements; using Marco.Pms.Model.Expenses; +using Marco.Pms.Model.Expenses.Masters; using Marco.Pms.Model.Forum; using Marco.Pms.Model.Mail; using Marco.Pms.Model.Master; @@ -106,6 +107,7 @@ namespace Marco.Pms.DataAccess.Data public DbSet Expenses { get; set; } public DbSet ExpenseLogs { get; set; } public DbSet ExpensesTypeMaster { get; set; } + public DbSet ExpenseCategoryMasters { get; set; } public DbSet PaymentModeMatser { get; set; } public DbSet ExpensesStatusMaster { get; set; } public DbSet BillAttachments { get; set; } @@ -113,6 +115,20 @@ namespace Marco.Pms.DataAccess.Data public DbSet ExpensesReimburseMapping { get; set; } public DbSet StatusPermissionMapping { get; set; } public DbSet ExpensesStatusMapping { get; set; } + public DbSet PaymentRequests { get; set; } + public DbSet PaymentRequestAttachments { get; set; } + public DbSet RecurringPayments { get; set; } + public DbSet AdvancePaymentTransactions { get; set; } + public DbSet RecurringPaymentStatus { get; set; } + + public DbSet StatusUpdateLogs { get; set; } + + // Collection + public DbSet Invoices { get; set; } + public DbSet InvoiceComments { get; set; } + public DbSet InvoiceAttachments { get; set; } + public DbSet ReceivedInvoicePayments { get; set; } + public DbSet PaymentAdjustmentHeads { get; set; } public DbSet FCMTokenMappings { get; set; } @@ -135,13 +151,6 @@ namespace Marco.Pms.DataAccess.Data public DbSet ProjectServiceMappings { get; set; } public DbSet ProjectOrgMappings { get; set; } - // Collection - public DbSet Invoices { get; set; } - public DbSet InvoiceComments { get; set; } - public DbSet InvoiceAttachments { get; set; } - public DbSet ReceivedInvoicePayments { get; set; } - public DbSet PaymentAdjustmentHeads { get; set; } - public DbSet PaymentDetails { get; set; } public DbSet TenantEnquires { get; set; } @@ -484,6 +493,64 @@ namespace Marco.Pms.DataAccess.Data }); + modelBuilder.Entity().HasData( + new CurrencyMaster + { + Id = Guid.Parse("78e96e4a-7ce0-4164-ae3a-c833ad45ec2c"), + CurrencyCode = "INR", + CurrencyName = "Indian Rupee", + Symbol = "₹", + IsActive = true + }, + new CurrencyMaster + { + Id = Guid.Parse("2f672568-a67b-4961-acb2-a8c7834e1762"), + CurrencyCode = "USD", + CurrencyName = "US Dollar", + Symbol = "$", + IsActive = true + }, + new CurrencyMaster + { + Id = Guid.Parse("4d1155bb-1448-4d97-a732-96c92eb99c45"), + CurrencyCode = "EUR", + CurrencyName = "Euro", + Symbol = "€", + IsActive = true + }, + new CurrencyMaster + { + Id = Guid.Parse("3e456237-ef06-4ea1-a261-188c9b0c6df6"), + CurrencyCode = "GBP", + CurrencyName = "Pound Sterling", + Symbol = "£", + IsActive = true + }, + new CurrencyMaster + { + Id = Guid.Parse("297e237a-56d3-48f6-b39d-ec3991dea8bf"), + CurrencyCode = "JPY", + CurrencyName = "Japanese Yen", + Symbol = "¥", + IsActive = true + }, + new CurrencyMaster + { + Id = Guid.Parse("efe9b4f6-64d6-446e-a42d-1c7aaf6dd70d"), + CurrencyCode = "RUB", + CurrencyName = "Russian Ruble", + Symbol = "₽", + IsActive = true + }, + new CurrencyMaster + { + Id = Guid.Parse("b960166a-f7e9-49e3-bb4b-28511f126c08"), + CurrencyCode = "CNY", + CurrencyName = "Chinese Yuan (Renminbi)", + Symbol = "¥", + IsActive = true + } + ); modelBuilder.Entity().HasData( new ExpensesStatusMaster @@ -500,7 +567,7 @@ namespace Marco.Pms.DataAccess.Data { Id = Guid.Parse("6537018f-f4e9-4cb3-a210-6c3b2da999d7"), Name = "Review Pending", - DisplayName = "Submit", + DisplayName = "Submit for Review", Description = "Reviewer is currently reviewing the expense.", Color = "#696cff", IsSystem = true, @@ -555,10 +622,27 @@ namespace Marco.Pms.DataAccess.Data Color = "#71dd37", IsSystem = true, IsActive = true + }, + new ExpensesStatusMaster + { + Id = Guid.Parse("b8586f67-dc19-49c3-b4af-224149efe1d3"), + Name = "Done", + DisplayName = "Create Expense", + Description = "Create new Expense.", + Color = "#0E9F6E", + IsSystem = true, + IsActive = true } ); modelBuilder.Entity().HasData( + // processed to Done + new ExpensesStatusMapping + { + Id = Guid.Parse("a1cc95ed-b276-4a3e-9f00-0a249b522d64"), + StatusId = Guid.Parse("61578360-3a49-4c34-8604-7b35a3787b95"), + NextStatusId = Guid.Parse("b8586f67-dc19-49c3-b4af-224149efe1d3") + }, // Process to processed new ExpensesStatusMapping { @@ -666,10 +750,17 @@ namespace Marco.Pms.DataAccess.Data Id = Guid.Parse("214354e5-daad-4569-ad69-eb5bf4e87fbc"), PermissionId = Guid.Parse("ea5a1529-4ee8-4828-80ea-0e23c9d4dd11"), StatusId = Guid.Parse("61578360-3a49-4c34-8604-7b35a3787b95") + }, + // Done Permission Mapping + new StatusPermissionMapping + { + Id = Guid.Parse("de04b6c7-a5cd-4a61-88b0-b43b0008202e"), + PermissionId = Guid.Parse("ea5a1529-4ee8-4828-80ea-0e23c9d4dd11"), + StatusId = Guid.Parse("b8586f67-dc19-49c3-b4af-224149efe1d3") }); - modelBuilder.Entity().HasData( - new ExpensesTypeMaster + modelBuilder.Entity().HasData( + new ExpenseCategoryMaster { Id = Guid.Parse("5e0c6227-d49d-41ff-9f1f-781f0aee2469"), Name = "Procurement", @@ -679,7 +770,7 @@ namespace Marco.Pms.DataAccess.Data IsAttachmentRequried = true, TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26") }, - new ExpensesTypeMaster + new ExpenseCategoryMaster { Id = Guid.Parse("2de53163-0dbd-404b-8e60-1b02e6b4886a"), Name = "Transport", @@ -689,7 +780,7 @@ namespace Marco.Pms.DataAccess.Data IsAttachmentRequried = false, TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26") }, - new ExpensesTypeMaster + new ExpenseCategoryMaster { Id = Guid.Parse("dd120bc4-ab0a-45ba-8450-5cd45ff221ca"), Name = "Travelling", @@ -699,7 +790,7 @@ namespace Marco.Pms.DataAccess.Data IsAttachmentRequried = false, TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26") }, - new ExpensesTypeMaster + new ExpenseCategoryMaster { Id = Guid.Parse("52484820-1b54-4865-8f0f-baa2b1d339b9"), Name = "Mobilization", @@ -709,7 +800,7 @@ namespace Marco.Pms.DataAccess.Data IsAttachmentRequried = true, TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26") }, - new ExpensesTypeMaster + new ExpenseCategoryMaster { Id = Guid.Parse("fc59eb90-98ea-481c-b421-54bfa9e42d8f"), Name = "Employee Welfare", @@ -719,7 +810,7 @@ namespace Marco.Pms.DataAccess.Data IsAttachmentRequried = true, TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26") }, - new ExpensesTypeMaster + new ExpenseCategoryMaster { Id = Guid.Parse("77013784-9324-4d8b-bd36-d6f928e68942"), Name = "Maintenance & Utilities", @@ -729,7 +820,7 @@ namespace Marco.Pms.DataAccess.Data IsAttachmentRequried = true, TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26") }, - new ExpensesTypeMaster + new ExpenseCategoryMaster { Id = Guid.Parse("1e2d697a-76b4-4be8-bc66-87144561a1a0"), Name = "Vendor/Supplier Payments", @@ -739,7 +830,7 @@ namespace Marco.Pms.DataAccess.Data IsAttachmentRequried = true, TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26") }, - new ExpensesTypeMaster + new ExpenseCategoryMaster { Id = Guid.Parse("4842fa61-64eb-4241-aebd-8282065af9f9"), Name = "Compliance & Safety", @@ -757,32 +848,49 @@ namespace Marco.Pms.DataAccess.Data Id = Guid.Parse("24e6b0df-7929-47d2-88a3-4cf14c1f28f9"), Name = "Cash", Description = "Physical currency; still used for small or informal transactions.", - IsActive = true, - TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26") + IsActive = true }, new PaymentModeMatser { Id = Guid.Parse("48d9b462-5d87-4dec-8dec-2bc943943172"), Name = "Cheque", Description = "Paper-based payment order; less common now due to processing delays and fraud risks.", - IsActive = true, - TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26") + IsActive = true }, new PaymentModeMatser { Id = Guid.Parse("ed667353-8eea-4fd1-8750-719405932480"), Name = "NetBanking", Description = "Online banking portals used to transfer funds directly between accounts", - IsActive = true, - TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26") + IsActive = true }, new PaymentModeMatser { Id = Guid.Parse("2e919e94-694c-41d9-9489-0a2b4208a027"), Name = "UPI", Description = "Real-time bank-to-bank transfer using mobile apps; widely used for peer-to-peer and merchant payments.", - IsActive = true, - TenantId = Guid.Parse("b3466e83-7e11-464c-b93a-daf047838b26") + IsActive = true + }, + new PaymentModeMatser + { + Id = Guid.Parse("a820f240-5e9a-4ae9-9091-8a7aa7720cea"), + Name = "Credit card", + Description = "A credit card is a payment card that allows you to borrow funds from a financial institution to pay for goods and services", + IsActive = true + }, + new PaymentModeMatser + { + Id = Guid.Parse("95697409-baf6-4f78-86ab-42d93d9569a8"), + Name = "Debit Card", + Description = "A debit card is a payment card that deducts funds directly from the cardholder's bank account when a purchase is made.", + IsActive = true + }, + new PaymentModeMatser + { + Id = Guid.Parse("f67beee6-6763-4108-922c-03bd86b9178d"), + Name = "Advance Payment", + Description = "When a bill is paid using the amount received in advance from a company.", + IsActive = true } ); @@ -1075,6 +1183,29 @@ namespace Marco.Pms.DataAccess.Data } ); + modelBuilder.Entity().HasData( + new RecurringPaymentStatus + { + Id = Guid.Parse("da462422-13b2-45cc-a175-910a225f6fc8"), + Name = "Active" + }, + new RecurringPaymentStatus + { + Id = Guid.Parse("3ec864d2-8bf5-42fb-ba70-5090301dd816"), + Name = "De-Activated" + }, + new RecurringPaymentStatus + { + Id = Guid.Parse("306856fb-5655-42eb-bf8b-808bb5e84725"), + Name = "Completed" + }, + new RecurringPaymentStatus + { + Id = Guid.Parse("8bfc9346-e092-4a80-acbf-515ae1ef6868"), + Name = "Paused" + } + ); + modelBuilder.Entity().HasData( new Module { @@ -1103,14 +1234,24 @@ namespace Marco.Pms.DataAccess.Data Name = "Tenant", Description = "Tenant Module", Key = "504ec132-e6a9-422f-8f85-050602cfce05" + }, + new Module + { + Id = new Guid("0a79687a-86d7-430d-a2d7-8b8603cc76a1"), + Name = "Finance", + Description = "Finance Module", + Key = "504ec132-e6a9-422f-8f85-050602cfce05" }); modelBuilder.Entity().HasData( // Project Module new Feature { Id = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), Description = "Manage Project", Name = "Project Management", ModuleId = new Guid("bf59fd88-b57a-4d67-bf01-3780f385896b"), IsActive = true }, + new Feature { Id = new Guid("9d4b5489-2079-40b9-bd77-6e1bf90bc19f"), Description = "Manage Tasks", Name = "Task Management", ModuleId = new Guid("bf59fd88-b57a-4d67-bf01-3780f385896b"), IsActive = true }, + + // Finance Module new Feature { Id = new Guid("a4e25142-449b-4334-a6e5-22f70e4732d7"), Description = "Expense Management is the systematic process of tracking, controlling, and reporting business-related expenditures.", Name = "Expense Management", ModuleId = new Guid("bf59fd88-b57a-4d67-bf01-3780f385896b"), IsActive = true }, new Feature { Id = new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"), Description = "Collection Management is a feature that enables organizations to track, organize, and manage the status and recovery of receivables or assets efficiently throughout their lifecycle, supporting systematic follow-up and resolution of outstanding accounts.", Name = "Collection Management", ModuleId = new Guid("bf59fd88-b57a-4d67-bf01-3780f385896b"), IsActive = true }, - new Feature { Id = new Guid("9d4b5489-2079-40b9-bd77-6e1bf90bc19f"), Description = "Manage Tasks", Name = "Task Management", ModuleId = new Guid("bf59fd88-b57a-4d67-bf01-3780f385896b"), IsActive = true }, + new Feature { Id = new Guid("86e80017-0698-4efe-93d0-806de67266e0"), Description = "Recurring Template Management is the automated creation and scheduling of repetitive tasks, processes, or transactions using predefined templates at set intervals to ensure consistent and efficient workflow execution without manual recreation each time.", Name = "Recurring Template Management", ModuleId = new Guid("bf59fd88-b57a-4d67-bf01-3780f385896b"), IsActive = true }, // Employee Module new Feature { Id = new Guid("81ab8a87-8ccd-4015-a917-0627cee6a100"), Description = "Manage Employee", Name = "Employee Management", ModuleId = new Guid("2a231490-bcb1-4bdd-91f1-f25fb7f25b23"), IsActive = true }, @@ -1188,6 +1329,11 @@ namespace Marco.Pms.DataAccess.Data new FeaturePermission { Id = new Guid("455187b4-fef1-41f9-b3d0-025d0b6302c3"), FeatureId = new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"), IsEnabled = true, Name = "Edit Collection", Description = "Ability to modify collection properties, content, and access rights." }, new FeaturePermission { Id = new Guid("061d9ccd-85b4-4cb0-be06-2f9f32cebb72"), FeatureId = new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"), IsEnabled = true, Name = "Add Payment", Description = " Enables entry and processing of payment transactions." }, + // Recurring Template Management + new FeaturePermission { Id = new Guid("6382ea8b-aff2-4cd2-a48f-a652b35825d8"), FeatureId = new Guid("86e80017-0698-4efe-93d0-806de67266e0"), IsEnabled = true, Name = "Manage Recurring", Description = "Manage Recurring Template payment permission allows authorized users to set up, modify, and execute automated recurring payments using predefined templates, ensuring secure and controlled handling of repetitive financial transactions." }, + new FeaturePermission { Id = new Guid("7ddf2fba-c44d-4fe3-b4ec-690ff70be2e3"), FeatureId = new Guid("86e80017-0698-4efe-93d0-806de67266e0"), IsEnabled = true, Name = "View All Recurring", Description = "The \"View All Recurring Template payment permission\" generally allows users to see and access all recurring payment templates in the system, enabling them to review, manage, and process recurring transactions efficiently." }, + new FeaturePermission { Id = new Guid("e5d21efe-573d-4a16-a0f8-414d3e442e78"), FeatureId = new Guid("86e80017-0698-4efe-93d0-806de67266e0"), IsEnabled = true, Name = "View Self Recurring", Description = "View Self Recurring Template payment permission allows a user to view and access their own recurring payment templates without editing rights." }, + // Organization Management Feature new FeaturePermission { Id = new Guid("068cb3c1-49c5-4746-9f29-1fce16e820ac"), FeatureId = new Guid("6d4c82d6-dbce-48ab-b8b8-f785f4d8c914"), IsEnabled = true, Name = "Add Organization", Description = "Allow user to create new organization" }, new FeaturePermission { Id = new Guid("c1ae1363-ab8a-4bd9-a9d1-8c2c6083873a"), FeatureId = new Guid("6d4c82d6-dbce-48ab-b8b8-f785f4d8c914"), IsEnabled = true, Name = "Edit Organization", Description = "Allow the user to update the basic information of the organization" }, @@ -1195,64 +1341,6 @@ namespace Marco.Pms.DataAccess.Data ); - modelBuilder.Entity().HasData( - new CurrencyMaster - { - Id = Guid.Parse("78e96e4a-7ce0-4164-ae3a-c833ad45ec2c"), - CurrencyCode = "INR", - CurrencyName = "Indian Rupee", - Symbol = "₹", - IsActive = true - }, - new CurrencyMaster - { - Id = Guid.Parse("2f672568-a67b-4961-acb2-a8c7834e1762"), - CurrencyCode = "USD", - CurrencyName = "US Dollar", - Symbol = "$", - IsActive = true - }, - new CurrencyMaster - { - Id = Guid.Parse("4d1155bb-1448-4d97-a732-96c92eb99c45"), - CurrencyCode = "EUR", - CurrencyName = "Euro", - Symbol = "€", - IsActive = true - }, - new CurrencyMaster - { - Id = Guid.Parse("3e456237-ef06-4ea1-a261-188c9b0c6df6"), - CurrencyCode = "GBP", - CurrencyName = "Pound Sterling", - Symbol = "£", - IsActive = true - }, - new CurrencyMaster - { - Id = Guid.Parse("297e237a-56d3-48f6-b39d-ec3991dea8bf"), - CurrencyCode = "JPY", - CurrencyName = "Japanese Yen", - Symbol = "¥", - IsActive = true - }, - new CurrencyMaster - { - Id = Guid.Parse("efe9b4f6-64d6-446e-a42d-1c7aaf6dd70d"), - CurrencyCode = "RUB", - CurrencyName = "Russian Ruble", - Symbol = "₽", - IsActive = true - }, - new CurrencyMaster - { - Id = Guid.Parse("b960166a-f7e9-49e3-bb4b-28511f126c08"), - CurrencyCode = "CNY", - CurrencyName = "Chinese Yuan (Renminbi)", - Symbol = "¥", - IsActive = true - } - ); } } } \ No newline at end of file diff --git a/Marco.Pms.DataAccess/Migrations/20251107110903_Added_Finance_Related_Tables.Designer.cs b/Marco.Pms.DataAccess/Migrations/20251107110903_Added_Finance_Related_Tables.Designer.cs new file mode 100644 index 0000000..ac6fca7 --- /dev/null +++ b/Marco.Pms.DataAccess/Migrations/20251107110903_Added_Finance_Related_Tables.Designer.cs @@ -0,0 +1,7494 @@ +// +using System; +using Marco.Pms.DataAccess.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Marco.Pms.DataAccess.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20251107110903_Added_Finance_Related_Tables")] + partial class Added_Finance_Related_Tables + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.12") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + //MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + + modelBuilder.Entity("Marco.Pms.Model.Activities.TaskAllocation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ApprovedById") + .HasColumnType("char(36)"); + + b.Property("ApprovedDate") + .HasColumnType("datetime(6)"); + + b.Property("AssignedBy") + .HasColumnType("char(36)"); + + b.Property("AssignmentDate") + .HasColumnType("datetime(6)"); + + b.Property("CompletedTask") + .HasColumnType("double"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("ParentTaskId") + .HasColumnType("char(36)"); + + b.Property("PlannedTask") + .HasColumnType("double"); + + b.Property("ReportedById") + .HasColumnType("char(36)"); + + b.Property("ReportedDate") + .HasColumnType("datetime(6)"); + + b.Property("ReportedTask") + .HasColumnType("double"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("WorkItemId") + .HasColumnType("char(36)"); + + b.Property("WorkStatusId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("ApprovedById"); + + b.HasIndex("AssignedBy"); + + b.HasIndex("ReportedById"); + + b.HasIndex("TenantId"); + + b.HasIndex("WorkItemId"); + + b.HasIndex("WorkStatusId"); + + b.ToTable("TaskAllocations"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.TaskAttachment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("DocumentId") + .HasColumnType("char(36)"); + + b.Property("ReferenceId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.ToTable("TaskAttachments"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.TaskComment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Comment") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("CommentDate") + .HasColumnType("datetime(6)"); + + b.Property("CommentedBy") + .HasColumnType("char(36)"); + + b.Property("TaskAllocationId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("CommentedBy"); + + b.HasIndex("TaskAllocationId"); + + b.HasIndex("TenantId"); + + b.ToTable("TaskComments"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.TaskMembers", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("EmployeeId") + .HasColumnType("char(36)"); + + b.Property("TaskAllocationId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("TaskAllocationId"); + + b.HasIndex("TenantId"); + + b.ToTable("TaskMembers"); + }); + + modelBuilder.Entity("Marco.Pms.Model.AttendanceModule.Attendance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Activity") + .HasColumnType("int"); + + b.Property("ApprovedAt") + .HasColumnType("datetime(6)"); + + b.Property("ApprovedById") + .HasColumnType("char(36)"); + + b.Property("AttendanceDate") + .HasColumnType("datetime(6)"); + + b.Property("Comment") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("EmployeeId") + .HasColumnType("char(36)"); + + b.Property("InTime") + .HasColumnType("datetime(6)"); + + b.Property("IsApproved") + .HasColumnType("tinyint(1)"); + + b.Property("OutTime") + .HasColumnType("datetime(6)"); + + b.Property("ProjectID") + .HasColumnType("char(36)"); + + b.Property("RequestedAt") + .HasColumnType("datetime(6)"); + + b.Property("RequestedById") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("ApprovedById"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("RequestedById"); + + b.HasIndex("TenantId"); + + b.ToTable("Attendes"); + }); + + modelBuilder.Entity("Marco.Pms.Model.AttendanceModule.AttendanceLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Activity") + .HasColumnType("int"); + + b.Property("ActivityTime") + .HasColumnType("datetime(6)"); + + b.Property("AttendanceId") + .HasColumnType("char(36)"); + + b.Property("Comment") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("DocumentId") + .HasColumnType("char(36)"); + + b.Property("EmployeeID") + .HasColumnType("char(36)"); + + b.Property("Latitude") + .HasColumnType("longtext"); + + b.Property("Longitude") + .HasColumnType("longtext"); + + b.Property("Photo") + .HasColumnType("longblob"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("UpdatedBy") + .HasColumnType("char(36)"); + + b.Property("UpdatedOn") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.HasIndex("AttendanceId"); + + b.HasIndex("DocumentId"); + + b.HasIndex("EmployeeID"); + + b.HasIndex("TenantId"); + + b.HasIndex("UpdatedBy"); + + b.ToTable("AttendanceLogs"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Authentication.MPINDetails", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("MPIN") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("MPINToken") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TimeStamp") + .HasColumnType("datetime(6)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.ToTable("MPINDetails"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Authentication.OTPDetails", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ExpriesInSec") + .HasColumnType("int"); + + b.Property("IsUsed") + .HasColumnType("tinyint(1)"); + + b.Property("OTP") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TimeStamp") + .HasColumnType("datetime(6)"); + + b.Property("UserId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.ToTable("OTPDetails"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Authentication.RefreshToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("ExpiryDate") + .HasColumnType("datetime(6)"); + + b.Property("IsRevoked") + .HasColumnType("tinyint(1)"); + + b.Property("IsUsed") + .HasColumnType("tinyint(1)"); + + b.Property("RevokedAt") + .HasColumnType("datetime(6)"); + + b.Property("Token") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RefreshTokens"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Collection.Invoice", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("BasicAmount") + .HasColumnType("double"); + + b.Property("ClientSubmitedDate") + .HasColumnType("datetime(6)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("CreatedById") + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("EInvoiceNumber") + .HasColumnType("longtext"); + + b.Property("ExceptedPaymentDate") + .HasColumnType("datetime(6)"); + + b.Property("InvoiceDate") + .HasColumnType("datetime(6)"); + + b.Property("InvoiceNumber") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("MarkAsCompleted") + .HasColumnType("tinyint(1)"); + + b.Property("ProjectId") + .HasColumnType("char(36)"); + + b.Property("TaxAmount") + .HasColumnType("double"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UpdatedAt") + .HasColumnType("datetime(6)"); + + b.Property("UpdatedById") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("ProjectId"); + + b.HasIndex("TenantId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("Invoices"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Collection.InvoiceAttachment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("DocumentId") + .HasColumnType("char(36)"); + + b.Property("InvoiceId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.HasIndex("InvoiceId"); + + b.HasIndex("TenantId"); + + b.ToTable("InvoiceAttachments"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Collection.InvoiceComment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Comment") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("CreatedById") + .HasColumnType("char(36)"); + + b.Property("InvoiceId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("InvoiceId"); + + b.HasIndex("TenantId"); + + b.ToTable("InvoiceComments"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Collection.PaymentAdjustmentHead", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("PaymentAdjustmentHeads"); + + b.HasData( + new + { + Id = new Guid("dbdc047f-a2d2-4db0-b0e6-b9d9f923a0f1"), + Description = "An advance payment is a sum paid before receiving goods or services, often to secure a transaction or cover initial costs.", + IsActive = true, + Name = "Advance payment", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("66c3c241-8b52-4327-a5ad-c1faf102583e"), + Description = "The base amount refers to the principal sum or original value used as a reference in financial calculations, excluding taxes, fees, or additional charges.", + IsActive = true, + Name = "Base Amount", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("0d70cb2e-827e-44fc-90a5-c2c55ba51ba9"), + Description = "TDS, or Tax Deducted at Source, is a system under the Indian Income Tax Act where tax is deducted at the point of income generation—such as salary, interest, or rent—and remitted to the government to prevent tax evasion and ensure timely collection.", + IsActive = true, + Name = "Tax Deducted at Source (TDS)", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("95f35acd-d979-4177-91ea-fd03a00e49ff"), + Description = "Retention refers to a company's ability to keep customers, employees, or profits over time, commonly measured as a percentage and critical for long-term business sustainability and growth.", + IsActive = true, + Name = "Retention", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("3f09b19a-8d45-4cf2-be27-f4f09b38b9f7"), + Description = "Tax is a mandatory financial charge imposed by a government on individuals or entities to fund public services and government operations, without direct benefit to the taxpayer.", + IsActive = true, + Name = "Tax", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("ec5e6a5f-ce62-44e5-8911-8426bbb4dde8"), + Description = "A penalty in the context of taxation is a financial sanction imposed by the government on individuals or entities for non-compliance with tax laws, such as late filing, underreporting income, or failure to pay taxes, and is typically calculated as a percentage of the tax due or a fixed amount.", + IsActive = true, + Name = "Penalty", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("50584332-1cb7-4359-9721-c8ea35040881"), + Description = "Utility fees are recurring charges for essential services such as electricity, water, gas, sewage, waste disposal, internet, and telecommunications, typically based on usage and necessary for operating a home or business.", + IsActive = true, + Name = "Utility fees", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Collection.ReceivedInvoicePayment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Amount") + .HasColumnType("double"); + + b.Property("Comment") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("CreatedById") + .HasColumnType("char(36)"); + + b.Property("InvoiceId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("PaymentAdjustmentHeadId") + .HasColumnType("char(36)"); + + b.Property("PaymentReceivedDate") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("TransactionId") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("InvoiceId"); + + b.HasIndex("PaymentAdjustmentHeadId"); + + b.HasIndex("TenantId"); + + b.ToTable("ReceivedInvoicePayments"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.Bucket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("CreatedByID") + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedByID"); + + b.HasIndex("TenantId"); + + b.ToTable("Buckets"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.Contact", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Address") + .HasColumnType("longtext"); + + b.Property("ContactCategoryId") + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("CreatedById") + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Designation") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Organization") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime(6)"); + + b.Property("UpdatedById") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("ContactCategoryId"); + + b.HasIndex("CreatedById"); + + b.HasIndex("TenantId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("Contacts"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.ContactBucketMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("BucketId") + .HasColumnType("char(36)"); + + b.Property("ContactId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("BucketId"); + + b.HasIndex("ContactId"); + + b.ToTable("ContactBucketMappings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.ContactCategoryMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("ContactCategoryMasters"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.ContactEmail", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ContactId") + .HasColumnType("char(36)"); + + b.Property("EmailAddress") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsPrimary") + .HasColumnType("tinyint(1)"); + + b.Property("Label") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("ContactId"); + + b.ToTable("ContactsEmails"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.ContactNote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ContactId") + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("CreatedById") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Note") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime(6)"); + + b.Property("UpdatedById") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("ContactId"); + + b.HasIndex("CreatedById"); + + b.HasIndex("TenantId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("ContactNotes"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.ContactPhone", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ContactId") + .HasColumnType("char(36)"); + + b.Property("IsPrimary") + .HasColumnType("tinyint(1)"); + + b.Property("Label") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("PhoneNumber") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("ContactId"); + + b.ToTable("ContactsPhones"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.ContactProjectMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ContactId") + .HasColumnType("char(36)"); + + b.Property("ProjectId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("ContactId"); + + b.HasIndex("ProjectId"); + + b.HasIndex("TenantId"); + + b.ToTable("ContactProjectMappings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.ContactTagMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ContactId") + .HasColumnType("char(36)"); + + b.Property("ContactTagId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("ContactId"); + + b.HasIndex("ContactTagId"); + + b.ToTable("ContactTagMappings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.ContactTagMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("ContactTagMasters"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.DirectoryUpdateLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("RefereanceId") + .HasColumnType("char(36)"); + + b.Property("UpdateAt") + .HasColumnType("datetime(6)"); + + b.Property("UpdatedById") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("UpdatedById"); + + b.ToTable("DirectoryUpdateLogs"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.EmployeeBucketMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("BucketId") + .HasColumnType("char(36)"); + + b.Property("EmployeeId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("BucketId"); + + b.HasIndex("EmployeeId"); + + b.ToTable("EmployeeBucketMappings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.DocumentManager.AttachmentTagMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AttachmentId") + .HasColumnType("char(36)"); + + b.Property("DocumentTagId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("AttachmentId"); + + b.HasIndex("DocumentTagId"); + + b.HasIndex("TenantId"); + + b.ToTable("AttachmentTagMappings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.DocumentManager.AttachmentVersionMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ChildAttachmentId") + .HasColumnType("char(36)"); + + b.Property("ParentAttachmentId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("Version") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ChildAttachmentId"); + + b.HasIndex("ParentAttachmentId"); + + b.HasIndex("TenantId"); + + b.ToTable("AttachmentVersionMappings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.DocumentManager.Document", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Base64Data") + .HasColumnType("longtext"); + + b.Property("BatchId") + .HasColumnType("char(36)"); + + b.Property("ContentType") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FileName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FileSize") + .HasColumnType("bigint"); + + b.Property("S3Key") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("ThumbS3Key") + .HasColumnType("longtext"); + + b.Property("UploadedAt") + .HasColumnType("datetime(6)"); + + b.Property("UploadedById") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.HasIndex("UploadedById"); + + b.ToTable("Documents"); + }); + + modelBuilder.Entity("Marco.Pms.Model.DocumentManager.DocumentAttachment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("DocumentDataId") + .HasColumnType("char(36)"); + + b.Property("DocumentId") + .HasColumnType("longtext"); + + b.Property("DocumentTypeId") + .HasColumnType("char(36)"); + + b.Property("EntityId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("IsCurrentVersion") + .HasColumnType("tinyint(1)"); + + b.Property("IsVerified") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime(6)"); + + b.Property("UpdatedById") + .HasColumnType("char(36)"); + + b.Property("UploadedAt") + .HasColumnType("datetime(6)"); + + b.Property("UploadedById") + .HasColumnType("char(36)"); + + b.Property("VerifiedAt") + .HasColumnType("datetime(6)"); + + b.Property("VerifiedById") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("DocumentDataId"); + + b.HasIndex("DocumentTypeId"); + + b.HasIndex("TenantId"); + + b.HasIndex("UpdatedById"); + + b.HasIndex("UploadedById"); + + b.HasIndex("VerifiedById"); + + b.ToTable("DocumentAttachments"); + }); + + modelBuilder.Entity("Marco.Pms.Model.DocumentManager.DocumentCategoryMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("EntityTypeId") + .HasColumnType("char(36)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("EntityTypeId"); + + b.HasIndex("TenantId"); + + b.ToTable("DocumentCategoryMasters"); + + b.HasData( + new + { + Id = new Guid("cfbff269-072b-477a-b48b-72cdc57dd1d3"), + CreatedAt = new DateTime(2025, 9, 15, 12, 42, 3, 202, DateTimeKind.Utc), + Description = "Project documents are formal records that outline the plans, progress, and details necessary to execute and manage a project effectively.", + EntityTypeId = new Guid("c8fe7115-aa27-43bc-99f4-7b05fabe436e"), + Name = "Project Documents", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("2d9fb9cf-db53-476b-a452-492e88e2b51f"), + CreatedAt = new DateTime(2025, 9, 15, 12, 42, 3, 202, DateTimeKind.Utc), + Description = "Employment details along with legal IDs like passports or driver’s licenses to verify identity and work authorization.", + EntityTypeId = new Guid("dbb9555a-7a0c-40f2-a9ed-f0463f1ceed7"), + Name = "Employee Documents", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.DocumentManager.DocumentTagMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("DocumentTagMasters"); + }); + + modelBuilder.Entity("Marco.Pms.Model.DocumentManager.DocumentTypeMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AllowedContentType") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("DocumentCategoryId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("IsMandatory") + .HasColumnType("tinyint(1)"); + + b.Property("IsSystem") + .HasColumnType("tinyint(1)"); + + b.Property("IsValidationRequired") + .HasColumnType("tinyint(1)"); + + b.Property("MaxSizeAllowedInMB") + .HasColumnType("double"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("RegexExpression") + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("DocumentCategoryId"); + + b.HasIndex("TenantId"); + + b.ToTable("DocumentTypeMasters"); + + b.HasData( + new + { + Id = new Guid("336225ac-67f3-4e14-ba7a-8fad03cf2832"), + AllowedContentType = "application/pdf,image/jpeg", + CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc), + DocumentCategoryId = new Guid("2d9fb9cf-db53-476b-a452-492e88e2b51f"), + IsActive = true, + IsMandatory = true, + IsSystem = true, + IsValidationRequired = true, + MaxSizeAllowedInMB = 2.0, + Name = "Aadhaar card", + RegexExpression = "^[2-9][0-9]{11}$", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("6344393b-9bb1-45f8-b620-9f6e279d012c"), + AllowedContentType = "application/pdf,image/jpeg", + CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc), + DocumentCategoryId = new Guid("2d9fb9cf-db53-476b-a452-492e88e2b51f"), + IsActive = true, + IsMandatory = true, + IsSystem = true, + IsValidationRequired = true, + MaxSizeAllowedInMB = 2.0, + Name = "Pan Card", + RegexExpression = "^[A-Z]{5}[0-9]{4}[A-Z]{1}$", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("2d1d7441-46a8-425e-9395-94d0956f8e91"), + AllowedContentType = "application/pdf,image/jpeg", + CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc), + DocumentCategoryId = new Guid("2d9fb9cf-db53-476b-a452-492e88e2b51f"), + IsActive = true, + IsMandatory = true, + IsSystem = true, + IsValidationRequired = true, + MaxSizeAllowedInMB = 2.0, + Name = "Voter Card", + RegexExpression = "^[A-Z]{3}[0-9]{7}$", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("16c40b80-c207-4a0c-a4d3-381414afe35a"), + AllowedContentType = "application/pdf,image/jpeg", + CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc), + DocumentCategoryId = new Guid("2d9fb9cf-db53-476b-a452-492e88e2b51f"), + IsActive = true, + IsMandatory = true, + IsSystem = true, + IsValidationRequired = true, + MaxSizeAllowedInMB = 2.0, + Name = "Passport", + RegexExpression = "^[A-PR-WY][1-9]\\d\\s?\\d{4}[1-9]$", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("f76d8215-d399-4f0e-b414-12e427f50be3"), + AllowedContentType = "application/pdf,image/jpeg", + CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc), + DocumentCategoryId = new Guid("2d9fb9cf-db53-476b-a452-492e88e2b51f"), + IsActive = true, + IsMandatory = true, + IsSystem = true, + IsValidationRequired = true, + MaxSizeAllowedInMB = 2.0, + Name = "Bank Passbook", + RegexExpression = "^\\d{9,18}$", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("260abd7e-c96d-4ae4-a29b-9b5bb5d24ebd"), + AllowedContentType = "application/pdf,application/msword,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.openxmlformats-officedocument.wordprocessingml.document", + CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc), + DocumentCategoryId = new Guid("cfbff269-072b-477a-b48b-72cdc57dd1d3"), + IsActive = true, + IsMandatory = false, + IsSystem = true, + IsValidationRequired = false, + MaxSizeAllowedInMB = 1.0, + Name = "Bill of Quantities (BOQ)", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("a1a190ba-c4a8-432f-b26d-1231ca1d44bc"), + AllowedContentType = "application/pdf,application/msword,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.openxmlformats-officedocument.wordprocessingml.document", + CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc), + DocumentCategoryId = new Guid("cfbff269-072b-477a-b48b-72cdc57dd1d3"), + IsActive = true, + IsMandatory = false, + IsSystem = true, + IsValidationRequired = false, + MaxSizeAllowedInMB = 1.0, + Name = "Work Order", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("07ca7182-9ac0-4407-b988-59901170cb86"), + AllowedContentType = "application/pdf,application/msword,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.openxmlformats-officedocument.wordprocessingml.document", + CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc), + DocumentCategoryId = new Guid("cfbff269-072b-477a-b48b-72cdc57dd1d3"), + IsActive = true, + IsMandatory = false, + IsSystem = true, + IsValidationRequired = false, + MaxSizeAllowedInMB = 1.0, + Name = "Letter of Agreement", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("846e89a9-5735-45ec-a21d-c97f85a94ada"), + AllowedContentType = "application/pdf,application/msword,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.openxmlformats-officedocument.wordprocessingml.document", + CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc), + DocumentCategoryId = new Guid("cfbff269-072b-477a-b48b-72cdc57dd1d3"), + IsActive = true, + IsMandatory = false, + IsSystem = true, + IsValidationRequired = false, + MaxSizeAllowedInMB = 1.0, + Name = "Health and Safety Document", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("7cc41c91-23cb-442b-badd-f932138d149f"), + AllowedContentType = "application/pdf,application/msword,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.openxmlformats-officedocument.wordprocessingml.document", + CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc), + DocumentCategoryId = new Guid("cfbff269-072b-477a-b48b-72cdc57dd1d3"), + IsActive = true, + IsMandatory = false, + IsSystem = true, + IsValidationRequired = false, + MaxSizeAllowedInMB = 1.0, + Name = "Standard Operating Procedure (SOP)", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("5668de00-5d84-47f7-b9b5-7fefd1219f05"), + AllowedContentType = "application/pdf,image/vnd.dwg,application/acad", + CreatedAt = new DateTime(2025, 9, 3, 10, 46, 49, 955, DateTimeKind.Utc), + DocumentCategoryId = new Guid("cfbff269-072b-477a-b48b-72cdc57dd1d3"), + IsActive = true, + IsMandatory = false, + IsSystem = true, + IsValidationRequired = false, + MaxSizeAllowedInMB = 20.0, + Name = "Drawings", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Employees.Employee", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ApplicationUserId") + .HasColumnType("varchar(255)"); + + b.Property("BirthDate") + .HasColumnType("datetime(6)"); + + b.Property("CurrentAddress") + .HasColumnType("longtext"); + + b.Property("Email") + .HasColumnType("longtext"); + + b.Property("EmergencyContactPerson") + .HasColumnType("longtext"); + + b.Property("EmergencyPhoneNumber") + .HasColumnType("longtext"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Gender") + .HasColumnType("longtext"); + + b.Property("HasApplicationAccess") + .HasColumnType("tinyint(1)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("IsPrimary") + .HasColumnType("tinyint(1)"); + + b.Property("IsSystem") + .HasColumnType("tinyint(1)"); + + b.Property("JobRoleId") + .HasColumnType("char(36)"); + + b.Property("JoiningDate") + .HasColumnType("datetime(6)"); + + b.Property("LastName") + .HasColumnType("longtext"); + + b.Property("MiddleName") + .HasColumnType("longtext"); + + b.Property("OrganizationId") + .HasColumnType("char(36)"); + + b.Property("PermanentAddress") + .HasColumnType("longtext"); + + b.Property("PhoneNumber") + .HasColumnType("longtext"); + + b.Property("Photo") + .HasColumnType("longblob"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationUserId"); + + b.HasIndex("JobRoleId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("TenantId"); + + b.ToTable("Employees"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Employees.EmployeeRoleMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("EmployeeId") + .HasColumnType("char(36)"); + + b.Property("IsEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("RoleId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("RoleId"); + + b.HasIndex("TenantId"); + + b.ToTable("EmployeeRoleMappings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Employees.WorkShift", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("EndTime") + .HasColumnType("time(6)"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("StartTime") + .HasColumnType("time(6)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("WorkShifts"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.ActivityCheckList", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ActivityId") + .HasColumnType("char(36)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("IsChecked") + .HasColumnType("tinyint(1)"); + + b.Property("IsMandatory") + .HasColumnType("tinyint(1)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.ToTable("ActivityCheckLists"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.CheckListMappings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CheckListId") + .HasColumnType("char(36)"); + + b.Property("TaskAllocationId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.ToTable("CheckListMappings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.FeaturePermission", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("FeatureId") + .HasColumnType("char(36)"); + + b.Property("IsEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("FeatureId"); + + b.ToTable("FeaturePermissions"); + + b.HasData( + new + { + Id = new Guid("d032cb1a-3f30-462c-bef0-7ace73a71c0b"), + Description = "Able add, modify and suspend any tenant.", + FeatureId = new Guid("2f3509b7-160d-410a-b9b6-daadd96c986d"), + IsEnabled = true, + Name = "Manage Tenants" + }, + new + { + Id = new Guid("00e20637-ce8d-4417-bec4-9b31b5e65092"), + Description = "Modify only his tenant.", + FeatureId = new Guid("2f3509b7-160d-410a-b9b6-daadd96c986d"), + IsEnabled = true, + Name = "Modify Tenant" + }, + new + { + Id = new Guid("647145c6-2108-4c98-aab4-178602236e55"), + Description = "Asscess information related to tenant.", + FeatureId = new Guid("2f3509b7-160d-410a-b9b6-daadd96c986d"), + IsEnabled = true, + Name = "View Tenant" + }, + new + { + Id = new Guid("6ea44136-987e-44ba-9e5d-1cf8f5837ebc"), + Description = "Access all information related to the project.", + FeatureId = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), + IsEnabled = true, + Name = "View Project" + }, + new + { + Id = new Guid("172fc9b6-755b-4f62-ab26-55c34a330614"), + Description = "Potentially edit the project name, description, start/end dates, or status.", + FeatureId = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), + IsEnabled = true, + Name = "Manage Project" + }, + new + { + Id = new Guid("b94802ce-0689-4643-9e1d-11c86950c35b"), + Description = "The \"Manage Team\" feature allows authorized users to organize project personnel by adding, removing, and assigning employee to projects.", + FeatureId = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), + IsEnabled = true, + Name = "Manage Team" + }, + new + { + Id = new Guid("8d7cc6e3-9147-41f7-aaa7-fa507e450bd4"), + Description = "Grants a user comprehensive read-only access to all details concerning the project's underlying systems, technologies, resources, and configurations", + FeatureId = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), + IsEnabled = true, + Name = "View Project Infra" + }, + new + { + Id = new Guid("cf2825ad-453b-46aa-91d9-27c124d63373"), + Description = "This allows them to create, modify, and manage all aspects of the supporting infrastructure.", + FeatureId = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), + IsEnabled = true, + Name = "Manage Project Infra" + }, + new + { + Id = new Guid("9fcc5f87-25e3-4846-90ac-67a71ab92e3c"), + Description = "Grants a user comprehensive read-only access to all details associated with tasks within a project. This includes task descriptions, statuses, assignees, due dates, dependencies, progress, history, and any related attachments or discussions.", + FeatureId = new Guid("9d4b5489-2079-40b9-bd77-6e1bf90bc19f"), + IsEnabled = true, + Name = "View Task" + }, + new + { + Id = new Guid("08752f33-3b29-4816-b76b-ea8a968ed3c5"), + Description = "This allows them to create new tasks, modify existing task attributes (description, status, assignee, due date, etc.),", + FeatureId = new Guid("9d4b5489-2079-40b9-bd77-6e1bf90bc19f"), + IsEnabled = true, + Name = "Add/Edit Task" + }, + new + { + Id = new Guid("6a32379b-8b3f-49a6-8c48-4b7ac1b55dc2"), + Description = "Grants a user the ability to designate team members responsible for specific tasks and to update the completion status or provide progress updates for those tasks", + FeatureId = new Guid("9d4b5489-2079-40b9-bd77-6e1bf90bc19f"), + IsEnabled = true, + Name = "Assign/Report Progress" + }, + new + { + Id = new Guid("db4e40c5-2ba9-4b6d-b8a6-a16a250ff99c"), + Description = "Grants a user the authority to officially confirm the completion or acceptance of a task, often signifying that it meets the required standards or criteria", + FeatureId = new Guid("9d4b5489-2079-40b9-bd77-6e1bf90bc19f"), + IsEnabled = true, + Name = "Approve Task" + }, + new + { + Id = new Guid("60611762-7f8a-4fb5-b53f-b1139918796b"), + Description = "Grants a user read-only access to details about the all individuals within the system. This typically includes names, contact information, roles, departments, and potentially other relevant employee data", + FeatureId = new Guid("81ab8a87-8ccd-4015-a917-0627cee6a100"), + IsEnabled = true, + Name = "View All Employees" + }, + new + { + Id = new Guid("b82d2b7e-0d52-45f3-997b-c008ea460e7f"), + Description = "Grants a user read-only access to details about the individuals within the system which are is assigned to same projects as user. This typically includes names, contact information, roles, departments, and potentially other relevant employee data", + FeatureId = new Guid("81ab8a87-8ccd-4015-a917-0627cee6a100"), + IsEnabled = true, + Name = "View Team Members" + }, + new + { + Id = new Guid("a97d366a-c2bb-448d-be93-402bd2324566"), + Description = "Grants a user the authority to create new employee profiles and modify existing employee details within the system. This typically includes adding or updating information such as names, contact details, roles, departments, skills, and potentially other personal or professional data", + FeatureId = new Guid("81ab8a87-8ccd-4015-a917-0627cee6a100"), + IsEnabled = true, + Name = "Add/Edit Employee" + }, + new + { + Id = new Guid("fbd213e0-0250-46f1-9f5f-4b2a1e6e76a3"), + Description = "Grants a user the authority to manage employee application roles, enabling them to assign or revoke access privileges within the system.", + FeatureId = new Guid("81ab8a87-8ccd-4015-a917-0627cee6a100"), + IsEnabled = true, + Name = "Assign Roles" + }, + new + { + Id = new Guid("915e6bff-65f6-4e3f-aea8-3fd217d3ea9e"), + Description = "Team Attendance refers to tracking and managing the attendance of all team members collectively, often monitored by a team lead or manager.", + FeatureId = new Guid("52c9cf54-1eb2-44d2-81bb-524cf29c0a94"), + IsEnabled = true, + Name = "Team Attendance " + }, + new + { + Id = new Guid("57802c4a-00aa-4a1f-a048-fd2f70dd44b6"), + Description = "Grants a user the authority to approve requests from employees to adjust or correct their recorded attendance. This typically involves reviewing the reason for the regularization, verifying any supporting documentation, and then officially accepting the changes to the employee's attendance records", + FeatureId = new Guid("52c9cf54-1eb2-44d2-81bb-524cf29c0a94"), + IsEnabled = true, + Name = "Regularize Attendance" + }, + new + { + Id = new Guid("ccb0589f-712b-43de-92ed-5b6088e7dc4e"), + Description = "Team Attendance refers to tracking and managing the attendance of all team members collectively, often monitored by a team lead or manager.", + FeatureId = new Guid("52c9cf54-1eb2-44d2-81bb-524cf29c0a94"), + IsEnabled = true, + Name = "Self Attendance" + }, + new + { + Id = new Guid("5ffbafe0-7ab0-48b1-bb50-c1bf76b65f9d"), + Description = "Grants a user read-only access to foundational or reference data within the system. \"Masters\" typically refer to predefined lists, categories, or templates that are used throughout the application to standardize information and maintain consistency", + FeatureId = new Guid("be3b3afc-6ccf-4566-b9b6-aafcb65546be"), + IsEnabled = true, + Name = "View Masters" + }, + new + { + Id = new Guid("588a8824-f924-4955-82d8-fc51956cf323"), + Description = "Grants a user the authority to create, modify, and delete foundational or reference data within the system. These \"masters\" are typically the core lists, categories, and configurations that other data and functionalities rely upon, such as departments, job titles, product categories", + FeatureId = new Guid("be3b3afc-6ccf-4566-b9b6-aafcb65546be"), + IsEnabled = true, + Name = "Manage Masters" + }, + new + { + Id = new Guid("71189504-f1c8-4ca5-8db6-810497be2854"), + Description = "Grants a user the authority to view all documents related to employees and projects", + FeatureId = new Guid("a8cf4331-8f04-4961-8360-a3f7c3cc7462"), + IsEnabled = true, + Name = "View Document" + }, + new + { + Id = new Guid("3f6d1f67-6fa5-4b7c-b17b-018d4fe4aab8"), + Description = "Grants a user the authority to upload the document", + FeatureId = new Guid("a8cf4331-8f04-4961-8360-a3f7c3cc7462"), + IsEnabled = true, + Name = "Upload Document" + }, + new + { + Id = new Guid("c423fd81-6273-4b9d-bb5e-76a0fb343833"), + Description = "Grants a user the authority to modify document", + FeatureId = new Guid("a8cf4331-8f04-4961-8360-a3f7c3cc7462"), + IsEnabled = true, + Name = "Mofify Document" + }, + new + { + Id = new Guid("40863a13-5a66-469d-9b48-135bc5dbf486"), + Description = "Grants a user the authority to delete the document", + FeatureId = new Guid("a8cf4331-8f04-4961-8360-a3f7c3cc7462"), + IsEnabled = true, + Name = "Delete Document" + }, + new + { + Id = new Guid("404373d0-860f-490e-a575-1c086ffbce1d"), + Description = "Grants a user the authority to download the document", + FeatureId = new Guid("a8cf4331-8f04-4961-8360-a3f7c3cc7462"), + IsEnabled = true, + Name = "Download Document" + }, + new + { + Id = new Guid("13a1f30f-38d1-41bf-8e7a-b75189aab8e0"), + Description = "Grants a user the authority to verify the document", + FeatureId = new Guid("a8cf4331-8f04-4961-8360-a3f7c3cc7462"), + IsEnabled = true, + Name = "Verify Document" + }, + new + { + Id = new Guid("4286a13b-bb40-4879-8c6d-18e9e393beda"), + Description = "Full control over all directories, including the ability to manage permissions for all directories in the system.", + FeatureId = new Guid("39e66f81-efc6-446c-95bd-46bff6cfb606"), + IsEnabled = true, + Name = "Directory Admin" + }, + new + { + Id = new Guid("62668630-13ce-4f52-a0f0-db38af2230c5"), + Description = "Full control over directories they created or have been assigned. Can also manage permissions for those directories.", + FeatureId = new Guid("39e66f81-efc6-446c-95bd-46bff6cfb606"), + IsEnabled = true, + Name = "Directory Manager" + }, + new + { + Id = new Guid("0f919170-92d4-4337-abd3-49b66fc871bb"), + Description = "Full control over directories they created. Can view contacts in directories they either created or were assigned to. Can manage permissions only for directories they created.", + FeatureId = new Guid("39e66f81-efc6-446c-95bd-46bff6cfb606"), + IsEnabled = true, + Name = "Directory User" + }, + new + { + Id = new Guid("385be49f-8fde-440e-bdbc-3dffeb8dd116"), + Description = "Allows a user to view only the expense records that they have personally submitted", + FeatureId = new Guid("a4e25142-449b-4334-a6e5-22f70e4732d7"), + IsEnabled = true, + Name = "View Self" + }, + new + { + Id = new Guid("01e06444-9ca7-4df4-b900-8c3fa051b92f"), + Description = "Allows a user to view all expense records across the organization or project, regardless of who submitted or paid them", + FeatureId = new Guid("a4e25142-449b-4334-a6e5-22f70e4732d7"), + IsEnabled = true, + Name = "View All" + }, + new + { + Id = new Guid("0f57885d-bcb2-4711-ac95-d841ace6d5a7"), + Description = "Allows a user to create and submit new expense records, including attaching relevant documents like receipts or invoices.", + FeatureId = new Guid("a4e25142-449b-4334-a6e5-22f70e4732d7"), + IsEnabled = true, + Name = "Upload" + }, + new + { + Id = new Guid("1f4bda08-1873-449a-bb66-3e8222bd871b"), + Description = "Allows a user to examine submitted expenses for accuracy, completeness, and policy compliance before they are approved or rejected.", + FeatureId = new Guid("a4e25142-449b-4334-a6e5-22f70e4732d7"), + IsEnabled = true, + Name = "Review" + }, + new + { + Id = new Guid("eaafdd76-8aac-45f9-a530-315589c6deca"), + Description = "Allows a user to authorize or reject submitted expenses, making them officially accepted or declined within the system.", + FeatureId = new Guid("a4e25142-449b-4334-a6e5-22f70e4732d7"), + IsEnabled = true, + Name = "Approve" + }, + new + { + Id = new Guid("ea5a1529-4ee8-4828-80ea-0e23c9d4dd11"), + Description = "Allows a user to handle post-approval actions such as recording payments, updating financial records, or marking expenses as reimbursed or settled.", + FeatureId = new Guid("a4e25142-449b-4334-a6e5-22f70e4732d7"), + IsEnabled = true, + Name = "Process" + }, + new + { + Id = new Guid("bdee29a2-b73b-402d-8dd1-c4b1f81ccbc3"), + Description = "Allows a user to configure and control system settings, such as managing expense types, payment modes, permissions, and overall workflow rules.", + FeatureId = new Guid("a4e25142-449b-4334-a6e5-22f70e4732d7"), + IsEnabled = true, + Name = "Manage" + }, + new + { + Id = new Guid("dbf17591-09fe-4c93-9e1a-12db8f5cc5de"), + Description = "Collection Admin is a permission that grants a user full administrative control over collections, including creating, editing, managing access, and deleting collections within a system.", + FeatureId = new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"), + IsEnabled = true, + Name = "Collection Admin" + }, + new + { + Id = new Guid("c8d7eea5-4033-4aad-9ebe-76de49896830"), + Description = "View Collection is a permission that allows users to see and browse assets or items within a collection without making any modifications or edits to its contents.", + FeatureId = new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"), + IsEnabled = true, + Name = "View Collection" + }, + new + { + Id = new Guid("b93141fd-dbd3-4051-8f57-bf25d18e3555"), + Description = "Authorizes users to create new collections for organizing related resources and managing access", + FeatureId = new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"), + IsEnabled = true, + Name = "Create Collection" + }, + new + { + Id = new Guid("455187b4-fef1-41f9-b3d0-025d0b6302c3"), + Description = "Ability to modify collection properties, content, and access rights.", + FeatureId = new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"), + IsEnabled = true, + Name = "Edit Collection" + }, + new + { + Id = new Guid("061d9ccd-85b4-4cb0-be06-2f9f32cebb72"), + Description = " Enables entry and processing of payment transactions.", + FeatureId = new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"), + IsEnabled = true, + Name = "Add Payment" + }, + new + { + Id = new Guid("6382ea8b-aff2-4cd2-a48f-a652b35825d8"), + Description = "Manage Recurring Template payment permission allows authorized users to set up, modify, and execute automated recurring payments using predefined templates, ensuring secure and controlled handling of repetitive financial transactions.", + FeatureId = new Guid("86e80017-0698-4efe-93d0-806de67266e0"), + IsEnabled = true, + Name = "Manage Recurring" + }, + new + { + Id = new Guid("7ddf2fba-c44d-4fe3-b4ec-690ff70be2e3"), + Description = "The \"View All Recurring Template payment permission\" generally allows users to see and access all recurring payment templates in the system, enabling them to review, manage, and process recurring transactions efficiently.", + FeatureId = new Guid("86e80017-0698-4efe-93d0-806de67266e0"), + IsEnabled = true, + Name = "View All Recurring" + }, + new + { + Id = new Guid("e5d21efe-573d-4a16-a0f8-414d3e442e78"), + Description = "View Self Recurring Template payment permission allows a user to view and access their own recurring payment templates without editing rights.", + FeatureId = new Guid("86e80017-0698-4efe-93d0-806de67266e0"), + IsEnabled = true, + Name = "View Self Recurring" + }, + new + { + Id = new Guid("068cb3c1-49c5-4746-9f29-1fce16e820ac"), + Description = "Allow user to create new organization", + FeatureId = new Guid("6d4c82d6-dbce-48ab-b8b8-f785f4d8c914"), + IsEnabled = true, + Name = "Add Organization" + }, + new + { + Id = new Guid("c1ae1363-ab8a-4bd9-a9d1-8c2c6083873a"), + Description = "Allow the user to update the basic information of the organization", + FeatureId = new Guid("6d4c82d6-dbce-48ab-b8b8-f785f4d8c914"), + IsEnabled = true, + Name = "Edit Organization" + }, + new + { + Id = new Guid("7a6cf830-0008-4e03-b31d-0d050cb634f4"), + Description = "Allow the user to view information of the organization", + FeatureId = new Guid("6d4c82d6-dbce-48ab-b8b8-f785f4d8c914"), + IsEnabled = true, + Name = "View Organization" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.ProjectLevelPermissionMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("EmployeeId") + .HasColumnType("char(36)"); + + b.Property("PermissionId") + .HasColumnType("char(36)"); + + b.Property("ProjectId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("PermissionId"); + + b.HasIndex("ProjectId"); + + b.HasIndex("TenantId"); + + b.ToTable("ProjectLevelPermissionMappings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.RolePermissionMappings", b => + { + b.Property("ApplicationRoleId") + .HasColumnType("char(36)"); + + b.Property("FeaturePermissionId") + .HasColumnType("char(36)"); + + b.HasKey("ApplicationRoleId", "FeaturePermissionId"); + + b.HasIndex("FeaturePermissionId"); + + b.ToTable("RolePermissionMappings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.AdvancePaymentTransaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Amount") + .HasColumnType("double"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("CreatedById") + .HasColumnType("char(36)"); + + b.Property("CurrentBalance") + .HasColumnType("double"); + + b.Property("EmployeeId") + .HasColumnType("char(36)"); + + b.Property("FinanceUIdPostfix") + .HasColumnType("int"); + + b.Property("FinanceUIdPrefix") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("PaidAt") + .HasColumnType("datetime(6)"); + + b.Property("ProjectId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("ProjectId"); + + b.HasIndex("TenantId"); + + b.ToTable("AdvancePaymentTransactions"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.BillAttachments", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("DocumentId") + .HasColumnType("char(36)"); + + b.Property("ExpensesId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.HasIndex("ExpensesId"); + + b.HasIndex("TenantId"); + + b.ToTable("BillAttachments"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.ExpenseLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Action") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Comment") + .HasColumnType("longtext"); + + b.Property("ExpenseId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("UpdateAt") + .HasColumnType("datetime(6)"); + + b.Property("UpdatedById") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("ExpenseId"); + + b.HasIndex("TenantId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("ExpenseLogs"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.Expenses", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Amount") + .HasColumnType("double"); + + b.Property("ApprovedById") + .HasColumnType("char(36)"); + + b.Property("BaseAmount") + .HasColumnType("double"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("CreatedById") + .HasColumnType("char(36)"); + + b.Property("CurrencyId") + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ExpenseCategoryId") + .HasColumnType("char(36)"); + + b.Property("ExpenseUId") + .HasColumnType("longtext"); + + b.Property("ExpensesTypeId") + .HasColumnType("char(36)"); + + b.Property("GSTNumber") + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Location") + .HasColumnType("longtext"); + + b.Property("NoOfPersons") + .HasColumnType("int"); + + b.Property("PaidById") + .HasColumnType("char(36)"); + + b.Property("PaymentModeId") + .HasColumnType("char(36)"); + + b.Property("PaymentRequestId") + .HasColumnType("char(36)"); + + b.Property("PreApproved") + .HasColumnType("tinyint(1)"); + + b.Property("ProcessedById") + .HasColumnType("char(36)"); + + b.Property("ProjectId") + .HasColumnType("char(36)"); + + b.Property("ReviewedById") + .HasColumnType("char(36)"); + + b.Property("StatusId") + .HasColumnType("char(36)"); + + b.Property("SupplerName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TDSPercentage") + .HasColumnType("double"); + + b.Property("TaxAmount") + .HasColumnType("double"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("TransactionDate") + .HasColumnType("datetime(6)"); + + b.Property("TransactionId") + .HasColumnType("longtext"); + + b.Property("UIDPostfix") + .HasColumnType("int"); + + b.Property("UIDPrefix") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ApprovedById"); + + b.HasIndex("CreatedById"); + + b.HasIndex("CurrencyId"); + + b.HasIndex("ExpenseCategoryId"); + + b.HasIndex("PaidById"); + + b.HasIndex("PaymentModeId"); + + b.HasIndex("PaymentRequestId"); + + b.HasIndex("ProcessedById"); + + b.HasIndex("ProjectId"); + + b.HasIndex("ReviewedById"); + + b.HasIndex("StatusId"); + + b.HasIndex("TenantId"); + + b.ToTable("Expenses"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.ExpensesReimburse", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ReimburseById") + .HasColumnType("char(36)"); + + b.Property("ReimburseDate") + .HasColumnType("datetime(6)"); + + b.Property("ReimburseNote") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ReimburseTransactionId") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("ReimburseById"); + + b.HasIndex("TenantId"); + + b.ToTable("ExpensesReimburse"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.ExpensesReimburseMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ExpensesId") + .HasColumnType("char(36)"); + + b.Property("ExpensesReimburseId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("ExpensesId"); + + b.HasIndex("ExpensesReimburseId"); + + b.HasIndex("TenantId"); + + b.ToTable("ExpensesReimburseMapping"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.Masters.ExpenseCategoryMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("IsAttachmentRequried") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("NoOfPersonsRequired") + .HasColumnType("tinyint(1)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("ExpenseCategoryMasters"); + + b.HasData( + new + { + Id = new Guid("5e0c6227-d49d-41ff-9f1f-781f0aee2469"), + Description = "Materials, equipment and supplies purchased for site operations.", + IsActive = true, + IsAttachmentRequried = true, + Name = "Procurement", + NoOfPersonsRequired = false, + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("2de53163-0dbd-404b-8e60-1b02e6b4886a"), + Description = "Vehicle fuel, logistics services and delivery of goods or personnel.", + IsActive = true, + IsAttachmentRequried = false, + Name = "Transport", + NoOfPersonsRequired = false, + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("dd120bc4-ab0a-45ba-8450-5cd45ff221ca"), + Description = "Delivery of personnel.", + IsActive = true, + IsAttachmentRequried = false, + Name = "Travelling", + NoOfPersonsRequired = true, + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("52484820-1b54-4865-8f0f-baa2b1d339b9"), + Description = "Site setup costs including equipment deployment and temporary infrastructure.", + IsActive = true, + IsAttachmentRequried = true, + Name = "Mobilization", + NoOfPersonsRequired = false, + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("fc59eb90-98ea-481c-b421-54bfa9e42d8f"), + Description = " Worker amenities like snacks, meals, safety gear, accommodation, medical support etc.", + IsActive = true, + IsAttachmentRequried = true, + Name = "Employee Welfare", + NoOfPersonsRequired = true, + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("77013784-9324-4d8b-bd36-d6f928e68942"), + Description = "Machinery servicing, electricity, water, and temporary office needs.", + IsActive = true, + IsAttachmentRequried = true, + Name = "Maintenance & Utilities", + NoOfPersonsRequired = false, + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("1e2d697a-76b4-4be8-bc66-87144561a1a0"), + Description = "Scheduled payments for external services or goods.", + IsActive = true, + IsAttachmentRequried = true, + Name = "Vendor/Supplier Payments", + NoOfPersonsRequired = false, + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("4842fa61-64eb-4241-aebd-8282065af9f9"), + Description = "Government fees, insurance, inspections and safety-related expenditures.", + IsActive = true, + IsAttachmentRequried = true, + Name = "Compliance & Safety", + NoOfPersonsRequired = false, + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.Masters.ExpensesStatusMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("NextStatusId") + .HasColumnType("char(36)"); + + b.Property("StatusId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("NextStatusId"); + + b.HasIndex("StatusId"); + + b.ToTable("ExpensesStatusMapping"); + + b.HasData( + new + { + Id = new Guid("a1cc95ed-b276-4a3e-9f00-0a249b522d64"), + NextStatusId = new Guid("b8586f67-dc19-49c3-b4af-224149efe1d3"), + StatusId = new Guid("61578360-3a49-4c34-8604-7b35a3787b95") + }, + new + { + Id = new Guid("5cf7f1df-9d1f-4289-add0-1775ad614f25"), + NextStatusId = new Guid("61578360-3a49-4c34-8604-7b35a3787b95"), + StatusId = new Guid("f18c5cfd-7815-4341-8da2-2c2d65778e27") + }, + new + { + Id = new Guid("4ddddc10-0ffd-4884-accf-d4fa0bd97f54"), + NextStatusId = new Guid("6537018f-f4e9-4cb3-a210-6c3b2da999d7"), + StatusId = new Guid("d1ee5eec-24b6-4364-8673-a8f859c60729") + }, + new + { + Id = new Guid("36c00548-241c-43ec-bc95-cacebedb925c"), + NextStatusId = new Guid("d1ee5eec-24b6-4364-8673-a8f859c60729"), + StatusId = new Guid("4068007f-c92f-4f37-a907-bc15fe57d4d8") + }, + new + { + Id = new Guid("1fca1700-1266-477d-bba4-9ac3753aa33c"), + NextStatusId = new Guid("f18c5cfd-7815-4341-8da2-2c2d65778e27"), + StatusId = new Guid("4068007f-c92f-4f37-a907-bc15fe57d4d8") + }, + new + { + Id = new Guid("9e2ec648-1ca2-4747-9329-e911b18edb3e"), + NextStatusId = new Guid("6537018f-f4e9-4cb3-a210-6c3b2da999d7"), + StatusId = new Guid("965eda62-7907-4963-b4a1-657fb0b2724b") + }, + new + { + Id = new Guid("6b867bec-66e6-42a7-9611-f4595af9b9ce"), + NextStatusId = new Guid("965eda62-7907-4963-b4a1-657fb0b2724b"), + StatusId = new Guid("6537018f-f4e9-4cb3-a210-6c3b2da999d7") + }, + new + { + Id = new Guid("ef1fcfbc-60e0-4f17-9308-c583a05d48fd"), + NextStatusId = new Guid("4068007f-c92f-4f37-a907-bc15fe57d4d8"), + StatusId = new Guid("6537018f-f4e9-4cb3-a210-6c3b2da999d7") + }, + new + { + Id = new Guid("af1e4492-98ee-4451-8ab7-fd8323f29c32"), + NextStatusId = new Guid("6537018f-f4e9-4cb3-a210-6c3b2da999d7"), + StatusId = new Guid("297e0d8f-f668-41b5-bfea-e03b354251c8") + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.Masters.RecurringPaymentStatus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("RecurringPaymentStatus"); + + b.HasData( + new + { + Id = new Guid("da462422-13b2-45cc-a175-910a225f6fc8"), + Name = "Active" + }, + new + { + Id = new Guid("3ec864d2-8bf5-42fb-ba70-5090301dd816"), + Name = "De-Activated" + }, + new + { + Id = new Guid("306856fb-5655-42eb-bf8b-808bb5e84725"), + Name = "Completed" + }, + new + { + Id = new Guid("8bfc9346-e092-4a80-acbf-515ae1ef6868"), + Name = "Paused" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.Masters.StatusPermissionMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("PermissionId") + .HasColumnType("char(36)"); + + b.Property("StatusId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("PermissionId"); + + b.HasIndex("StatusId"); + + b.ToTable("StatusPermissionMapping"); + + b.HasData( + new + { + Id = new Guid("722b0c3c-5a78-456d-b9bb-b6ba1b21d59b"), + PermissionId = new Guid("0f57885d-bcb2-4711-ac95-d841ace6d5a7"), + StatusId = new Guid("297e0d8f-f668-41b5-bfea-e03b354251c8") + }, + new + { + Id = new Guid("7deb0945-e1c9-411f-8b3c-c9bdbe3c3c2d"), + PermissionId = new Guid("0f57885d-bcb2-4711-ac95-d841ace6d5a7"), + StatusId = new Guid("6537018f-f4e9-4cb3-a210-6c3b2da999d7") + }, + new + { + Id = new Guid("9e2ec648-1ca2-4747-9329-e911b18edb3e"), + PermissionId = new Guid("1f4bda08-1873-449a-bb66-3e8222bd871b"), + StatusId = new Guid("965eda62-7907-4963-b4a1-657fb0b2724b") + }, + new + { + Id = new Guid("0b7926fc-a34b-4a5b-8c7d-1003480cf0fa"), + PermissionId = new Guid("1f4bda08-1873-449a-bb66-3e8222bd871b"), + StatusId = new Guid("4068007f-c92f-4f37-a907-bc15fe57d4d8") + }, + new + { + Id = new Guid("cd15f9b9-be45-4deb-9c71-2f23f872dbcd"), + PermissionId = new Guid("eaafdd76-8aac-45f9-a530-315589c6deca"), + StatusId = new Guid("d1ee5eec-24b6-4364-8673-a8f859c60729") + }, + new + { + Id = new Guid("f6f26b2f-2fa6-40b7-8601-cbd4bcdda0cc"), + PermissionId = new Guid("eaafdd76-8aac-45f9-a530-315589c6deca"), + StatusId = new Guid("f18c5cfd-7815-4341-8da2-2c2d65778e27") + }, + new + { + Id = new Guid("214354e5-daad-4569-ad69-eb5bf4e87fbc"), + PermissionId = new Guid("ea5a1529-4ee8-4828-80ea-0e23c9d4dd11"), + StatusId = new Guid("61578360-3a49-4c34-8604-7b35a3787b95") + }, + new + { + Id = new Guid("de04b6c7-a5cd-4a61-88b0-b43b0008202e"), + PermissionId = new Guid("ea5a1529-4ee8-4828-80ea-0e23c9d4dd11"), + StatusId = new Guid("b8586f67-dc19-49c3-b4af-224149efe1d3") + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.PaymentRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Amount") + .HasColumnType("double"); + + b.Property("BaseAmount") + .HasColumnType("double"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("CreatedById") + .HasColumnType("char(36)"); + + b.Property("CurrencyId") + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("DueDate") + .HasColumnType("datetime(6)"); + + b.Property("ExpenseCategoryId") + .HasColumnType("char(36)"); + + b.Property("ExpenseStatusId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("IsAdvancePayment") + .HasColumnType("tinyint(1)"); + + b.Property("IsExpenseCreated") + .HasColumnType("tinyint(1)"); + + b.Property("PaidAt") + .HasColumnType("datetime(6)"); + + b.Property("PaidById") + .HasColumnType("char(36)"); + + b.Property("PaidTransactionId") + .HasColumnType("longtext"); + + b.Property("Payee") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ProjectId") + .HasColumnType("char(36)"); + + b.Property("RecurringPaymentId") + .HasColumnType("char(36)"); + + b.Property("TDSPercentage") + .HasColumnType("double"); + + b.Property("TaxAmount") + .HasColumnType("double"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UIDPostfix") + .HasColumnType("int"); + + b.Property("UIDPrefix") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UpdatedAt") + .HasColumnType("datetime(6)"); + + b.Property("UpdatedById") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("CurrencyId"); + + b.HasIndex("ExpenseCategoryId"); + + b.HasIndex("ExpenseStatusId"); + + b.HasIndex("PaidById"); + + b.HasIndex("ProjectId"); + + b.HasIndex("RecurringPaymentId"); + + b.HasIndex("TenantId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("PaymentRequests"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.PaymentRequestAttachment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("DocumentId") + .HasColumnType("char(36)"); + + b.Property("PaymentRequestId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.HasIndex("PaymentRequestId"); + + b.HasIndex("TenantId"); + + b.ToTable("PaymentRequestAttachments"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.RecurringPayment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Amount") + .HasColumnType("double"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("CreatedById") + .HasColumnType("char(36)"); + + b.Property("CurrencyId") + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ExpenseCategoryId") + .HasColumnType("char(36)"); + + b.Property("Frequency") + .HasColumnType("int"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("IsVariable") + .HasColumnType("tinyint(1)"); + + b.Property("LatestPRGeneratedAt") + .HasColumnType("datetime(6)"); + + b.Property("NotifyTo") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("NumberOfIteration") + .HasColumnType("int"); + + b.Property("Payee") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("PaymentBufferDays") + .HasColumnType("int"); + + b.Property("ProjectId") + .HasColumnType("char(36)"); + + b.Property("StatusId") + .HasColumnType("char(36)"); + + b.Property("StrikeDate") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UIDPostfix") + .HasColumnType("int"); + + b.Property("UIDPrefix") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UpdatedAt") + .HasColumnType("datetime(6)"); + + b.Property("UpdatedById") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("CurrencyId"); + + b.HasIndex("ExpenseCategoryId"); + + b.HasIndex("ProjectId"); + + b.HasIndex("StatusId"); + + b.HasIndex("TenantId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("RecurringPayments"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Forum.TicketAttachment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CommentId") + .HasColumnType("char(36)"); + + b.Property("FileId") + .HasColumnType("char(36)"); + + b.Property("FileName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TicketId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("CommentId"); + + b.HasIndex("TicketId"); + + b.ToTable("TicketAttachments"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Forum.TicketComment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AuthorId") + .HasColumnType("char(36)"); + + b.Property("MessageText") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ParentMessageId") + .HasColumnType("char(36)"); + + b.Property("SentAt") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("TicketId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("TicketComments"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Forum.TicketForum", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("CreatedById") + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("LinkedActivityId") + .HasColumnType("char(36)"); + + b.Property("LinkedProjectId") + .HasColumnType("char(36)"); + + b.Property("PriorityId") + .HasColumnType("char(36)"); + + b.Property("StatusId") + .HasColumnType("char(36)"); + + b.Property("Subject") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("TypeId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("PriorityId"); + + b.HasIndex("StatusId"); + + b.HasIndex("TenantId"); + + b.HasIndex("TypeId"); + + b.ToTable("Tickets"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Forum.TicketTag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("TagId") + .HasColumnType("char(36)"); + + b.Property("TicketId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TagId"); + + b.HasIndex("TicketId"); + + b.ToTable("TicketTags"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Forum.TicketTypeMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("IsDefault") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.ToTable("TicketTypeMasters"); + + b.HasData( + new + { + Id = new Guid("c74e5480-2b71-483c-8f4a-1a9c69c32603"), + Description = "An identified problem that affects the performance, reliability, or standards of a product or service", + IsDefault = true, + Name = "Quality Issue", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("d1f55eab-9898-4e46-9f03-b263e33e5d38"), + Description = "A support service that assists users with technical issues, requests, or inquiries.", + IsDefault = true, + Name = "Help Desk", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Mail.MailDetails", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("MailListId") + .HasColumnType("char(36)"); + + b.Property("ProjectId") + .HasColumnType("char(36)"); + + b.Property("Recipient") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Schedule") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("MailListId"); + + b.ToTable("MailDetails"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Mail.MailLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Body") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("EmailId") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("EmployeeId") + .HasColumnType("char(36)"); + + b.Property("ProjectId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("TimeStamp") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.ToTable("MailLogs"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Mail.MailingList", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Body") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Keywords") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Subject") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("MailingList"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.ActivityGroupMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("IsSystem") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ServiceId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("ServiceId"); + + b.HasIndex("TenantId"); + + b.ToTable("ActivityGroupMasters"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.ActivityMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ActivityGroupId") + .HasColumnType("char(36)"); + + b.Property("ActivityName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("IsSystem") + .HasColumnType("tinyint(1)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("UnitOfMeasurement") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ActivityGroupId"); + + b.HasIndex("TenantId"); + + b.ToTable("ActivityMasters"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.CurrencyMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CurrencyCode") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("CurrencyName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Symbol") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("CurrencyMaster"); + + b.HasData( + new + { + Id = new Guid("78e96e4a-7ce0-4164-ae3a-c833ad45ec2c"), + CurrencyCode = "INR", + CurrencyName = "Indian Rupee", + IsActive = true, + Symbol = "₹" + }, + new + { + Id = new Guid("2f672568-a67b-4961-acb2-a8c7834e1762"), + CurrencyCode = "USD", + CurrencyName = "US Dollar", + IsActive = true, + Symbol = "$" + }, + new + { + Id = new Guid("4d1155bb-1448-4d97-a732-96c92eb99c45"), + CurrencyCode = "EUR", + CurrencyName = "Euro", + IsActive = true, + Symbol = "€" + }, + new + { + Id = new Guid("3e456237-ef06-4ea1-a261-188c9b0c6df6"), + CurrencyCode = "GBP", + CurrencyName = "Pound Sterling", + IsActive = true, + Symbol = "£" + }, + new + { + Id = new Guid("297e237a-56d3-48f6-b39d-ec3991dea8bf"), + CurrencyCode = "JPY", + CurrencyName = "Japanese Yen", + IsActive = true, + Symbol = "¥" + }, + new + { + Id = new Guid("efe9b4f6-64d6-446e-a42d-1c7aaf6dd70d"), + CurrencyCode = "RUB", + CurrencyName = "Russian Ruble", + IsActive = true, + Symbol = "₽" + }, + new + { + Id = new Guid("b960166a-f7e9-49e3-bb4b-28511f126c08"), + CurrencyCode = "CNY", + CurrencyName = "Chinese Yuan (Renminbi)", + IsActive = true, + Symbol = "¥" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.EntityTypeMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("EntityTypeMasters"); + + b.HasData( + new + { + Id = new Guid("c8fe7115-aa27-43bc-99f4-7b05fabe436e"), + Description = "Emtities related to project.", + Name = "Project Entity" + }, + new + { + Id = new Guid("dbb9555a-7a0c-40f2-a9ed-f0463f1ceed7"), + Description = "Employee related entitie", + Name = "Employee Entity" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.ExpensesStatusMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Color") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("IsSystem") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("ExpensesStatusMaster"); + + b.HasData( + new + { + Id = new Guid("297e0d8f-f668-41b5-bfea-e03b354251c8"), + Color = "#8592a3", + Description = "Expense has been created but not yet submitted.", + DisplayName = "Draft", + IsActive = true, + IsSystem = true, + Name = "Draft" + }, + new + { + Id = new Guid("6537018f-f4e9-4cb3-a210-6c3b2da999d7"), + Color = "#696cff", + Description = "Reviewer is currently reviewing the expense.", + DisplayName = "Submit for Review", + IsActive = true, + IsSystem = true, + Name = "Review Pending" + }, + new + { + Id = new Guid("965eda62-7907-4963-b4a1-657fb0b2724b"), + Color = "#ff3e1d", + Description = "Expense was declined, often with a reason(review rejected).", + DisplayName = "Reject", + IsActive = true, + IsSystem = true, + Name = "Rejected by Reviewer" + }, + new + { + Id = new Guid("4068007f-c92f-4f37-a907-bc15fe57d4d8"), + Color = "#03c3ec", + Description = "Review is completed, waiting for action of approver.", + DisplayName = "Mark as Reviewed", + IsActive = true, + IsSystem = true, + Name = "Approval Pending" + }, + new + { + Id = new Guid("d1ee5eec-24b6-4364-8673-a8f859c60729"), + Color = "#ff3e1d", + Description = "Expense was declined, often with a reason(approval rejected).", + DisplayName = "Reject", + IsActive = true, + IsSystem = true, + Name = "Rejected by Approver" + }, + new + { + Id = new Guid("f18c5cfd-7815-4341-8da2-2c2d65778e27"), + Color = "#ffab00", + Description = "Approved expense is awaiting final payment.", + DisplayName = "Mark as Approved", + IsActive = true, + IsSystem = true, + Name = "Payment Pending" + }, + new + { + Id = new Guid("61578360-3a49-4c34-8604-7b35a3787b95"), + Color = "#71dd37", + Description = "Expense has been settled.", + DisplayName = "Mark as Processed", + IsActive = true, + IsSystem = true, + Name = "Processed" + }, + new + { + Id = new Guid("b8586f67-dc19-49c3-b4af-224149efe1d3"), + Color = "#0E9F6E", + Description = "Create new Expense.", + DisplayName = "Create Expense", + IsActive = true, + IsSystem = true, + Name = "Done" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.ExpensesTypeMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("IsAttachmentRequried") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("NoOfPersonsRequired") + .HasColumnType("tinyint(1)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("ExpensesTypeMaster"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.Feature", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("ModuleId") + .HasColumnType("char(36)"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ModuleId"); + + b.ToTable("Features"); + + b.HasData( + new + { + Id = new Guid("53176ebf-c75d-42e5-839f-4508ffac3def"), + Description = "Manage Project", + IsActive = true, + ModuleId = new Guid("bf59fd88-b57a-4d67-bf01-3780f385896b"), + Name = "Project Management" + }, + new + { + Id = new Guid("9d4b5489-2079-40b9-bd77-6e1bf90bc19f"), + Description = "Manage Tasks", + IsActive = true, + ModuleId = new Guid("bf59fd88-b57a-4d67-bf01-3780f385896b"), + Name = "Task Management" + }, + new + { + Id = new Guid("a4e25142-449b-4334-a6e5-22f70e4732d7"), + Description = "Expense Management is the systematic process of tracking, controlling, and reporting business-related expenditures.", + IsActive = true, + ModuleId = new Guid("bf59fd88-b57a-4d67-bf01-3780f385896b"), + Name = "Expense Management" + }, + new + { + Id = new Guid("fc586e7d-ed1a-45e5-bb51-9f34af98ec13"), + Description = "Collection Management is a feature that enables organizations to track, organize, and manage the status and recovery of receivables or assets efficiently throughout their lifecycle, supporting systematic follow-up and resolution of outstanding accounts.", + IsActive = true, + ModuleId = new Guid("bf59fd88-b57a-4d67-bf01-3780f385896b"), + Name = "Collection Management" + }, + new + { + Id = new Guid("86e80017-0698-4efe-93d0-806de67266e0"), + Description = "Recurring Template Management is the automated creation and scheduling of repetitive tasks, processes, or transactions using predefined templates at set intervals to ensure consistent and efficient workflow execution without manual recreation each time.", + IsActive = true, + ModuleId = new Guid("bf59fd88-b57a-4d67-bf01-3780f385896b"), + Name = "Recurring Template Management" + }, + new + { + Id = new Guid("81ab8a87-8ccd-4015-a917-0627cee6a100"), + Description = "Manage Employee", + IsActive = true, + ModuleId = new Guid("2a231490-bcb1-4bdd-91f1-f25fb7f25b23"), + Name = "Employee Management" + }, + new + { + Id = new Guid("52c9cf54-1eb2-44d2-81bb-524cf29c0a94"), + Description = "Attendance", + IsActive = true, + ModuleId = new Guid("2a231490-bcb1-4bdd-91f1-f25fb7f25b23"), + Name = "Attendance Management" + }, + new + { + Id = new Guid("a8cf4331-8f04-4961-8360-a3f7c3cc7462"), + Description = "Manage Document", + IsActive = true, + ModuleId = new Guid("2a231490-bcb1-4bdd-91f1-f25fb7f25b23"), + Name = "Document Management" + }, + new + { + Id = new Guid("be3b3afc-6ccf-4566-b9b6-aafcb65546be"), + Description = "Global Masters", + IsActive = true, + ModuleId = new Guid("c43db8c7-ab73-47f4-9d3b-f83e81357924"), + Name = "Masters" + }, + new + { + Id = new Guid("39e66f81-efc6-446c-95bd-46bff6cfb606"), + Description = "Managing all directory related rights", + IsActive = true, + ModuleId = new Guid("c43db8c7-ab73-47f4-9d3b-f83e81357924"), + Name = "Directory Management" + }, + new + { + Id = new Guid("6d4c82d6-dbce-48ab-b8b8-f785f4d8c914"), + Description = "Managing all organization related rights", + IsActive = true, + ModuleId = new Guid("c43db8c7-ab73-47f4-9d3b-f83e81357924"), + Name = "Organization Management" + }, + new + { + Id = new Guid("2f3509b7-160d-410a-b9b6-daadd96c986d"), + Description = "Managing all tenant related rights", + IsActive = true, + ModuleId = new Guid("f482a079-4dec-4f2d-9867-6baf2a4f23d9"), + Name = "Tenant Management" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.GlobalActivityGroupMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ServiceId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("ServiceId"); + + b.ToTable("GlobalActivityGroupMasters"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.GlobalActivityMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ActivityGroupId") + .HasColumnType("char(36)"); + + b.Property("ActivityName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("UnitOfMeasurement") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ActivityGroupId"); + + b.ToTable("GlobalActivityMasters"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.GlobalServiceMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("GlobalServiceMasters"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.Industry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Industries"); + + b.HasData( + new + { + Id = new Guid("15436ee3-a650-469e-bfc2-59993f7514bb"), + Name = "Information Technology (IT) Services" + }, + new + { + Id = new Guid("0a63e657-2c5f-49b5-854b-42c978293154"), + Name = "Manufacturing & Production" + }, + new + { + Id = new Guid("bdc61e3b-69ea-4394-bab6-079ec135b5bd"), + Name = "Energy & Resources" + }, + new + { + Id = new Guid("5ca200ac-00d7-415e-a410-b948e27ac9d2"), + Name = "Finance & Professional Services" + }, + new + { + Id = new Guid("d5621700-cd87-441f-8cdb-6051ddfc83b4"), + Name = "Hospitals and Healthcare Services" + }, + new + { + Id = new Guid("23608891-657e-40f0-bbd4-2b0a2ec1a76f"), + Name = "Social Services" + }, + new + { + Id = new Guid("a493f4e3-16b1-4411-be3c-6bf2987a3168"), + Name = "Retail & Consumer Services" + }, + new + { + Id = new Guid("e9d8ce92-9371-4ed9-9831-83c07f78edec"), + Name = "Transportation & Logistics" + }, + new + { + Id = new Guid("8a0d6134-2dbe-4e0a-b250-ff34cb7b9df0"), + Name = "Education & Training" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.Module", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("Key") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Modules"); + + b.HasData( + new + { + Id = new Guid("bf59fd88-b57a-4d67-bf01-3780f385896b"), + Description = "Project Module", + Key = "b04da7e9-0406-409c-ac7f-b97256e6ea02", + Name = "Project" + }, + new + { + Id = new Guid("2a231490-bcb1-4bdd-91f1-f25fb7f25b23"), + Description = "Employee Module", + Key = "0971c7fb-6ce1-458a-ae3f-8d3205893637", + Name = "Employee" + }, + new + { + Id = new Guid("c43db8c7-ab73-47f4-9d3b-f83e81357924"), + Description = "Masters Module", + Key = "504ec132-e6a9-422f-8f85-050602cfce05", + Name = "Masters" + }, + new + { + Id = new Guid("f482a079-4dec-4f2d-9867-6baf2a4f23d9"), + Description = "Tenant Module", + Key = "504ec132-e6a9-422f-8f85-050602cfce05", + Name = "Tenant" + }, + new + { + Id = new Guid("0a79687a-86d7-430d-a2d7-8b8603cc76a1"), + Description = "Finance Module", + Key = "504ec132-e6a9-422f-8f85-050602cfce05", + Name = "Finance" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.PaymentModeMatser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("PaymentModeMatser"); + + b.HasData( + new + { + Id = new Guid("24e6b0df-7929-47d2-88a3-4cf14c1f28f9"), + Description = "Physical currency; still used for small or informal transactions.", + IsActive = true, + Name = "Cash" + }, + new + { + Id = new Guid("48d9b462-5d87-4dec-8dec-2bc943943172"), + Description = "Paper-based payment order; less common now due to processing delays and fraud risks.", + IsActive = true, + Name = "Cheque" + }, + new + { + Id = new Guid("ed667353-8eea-4fd1-8750-719405932480"), + Description = "Online banking portals used to transfer funds directly between accounts", + IsActive = true, + Name = "NetBanking" + }, + new + { + Id = new Guid("2e919e94-694c-41d9-9489-0a2b4208a027"), + Description = "Real-time bank-to-bank transfer using mobile apps; widely used for peer-to-peer and merchant payments.", + IsActive = true, + Name = "UPI" + }, + new + { + Id = new Guid("a820f240-5e9a-4ae9-9091-8a7aa7720cea"), + Description = "A credit card is a payment card that allows you to borrow funds from a financial institution to pay for goods and services", + IsActive = true, + Name = "Credit card" + }, + new + { + Id = new Guid("95697409-baf6-4f78-86ab-42d93d9569a8"), + Description = "A debit card is a payment card that deducts funds directly from the cardholder's bank account when a purchase is made.", + IsActive = true, + Name = "Debit Card" + }, + new + { + Id = new Guid("f67beee6-6763-4108-922c-03bd86b9178d"), + Description = "When a bill is paid using the amount received in advance from a company.", + IsActive = true, + Name = "Advance Payment" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.ServiceMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("IsSystem") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("ServiceMasters"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.StatusMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Status") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("StatusMasters"); + + b.HasData( + new + { + Id = new Guid("b74da4c2-d07e-46f2-9919-e75e49b12731"), + Status = "Active" + }, + new + { + Id = new Guid("cdad86aa-8a56-4ff4-b633-9c629057dfef"), + Status = "In Progress" + }, + new + { + Id = new Guid("603e994b-a27f-4e5d-a251-f3d69b0498ba"), + Status = "On Hold" + }, + new + { + Id = new Guid("ef1c356e-0fe0-42df-a5d3-8daee355492d"), + Status = "In Active" + }, + new + { + Id = new Guid("33deaef9-9af1-4f2a-b443-681ea0d04f81"), + Status = "Completed" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.StatusUpdateLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Comment") + .HasColumnType("longtext"); + + b.Property("EntityId") + .HasColumnType("char(36)"); + + b.Property("NextStatusId") + .HasColumnType("char(36)"); + + b.Property("StatusId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime(6)"); + + b.Property("UpdatedById") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("StatusUpdateLogs"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.SubscriptionStatus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("SubscriptionStatus"); + + b.HasData( + new + { + Id = new Guid("cd3a68ea-41fd-42f0-bd0c-c871c7337727"), + Name = "Active" + }, + new + { + Id = new Guid("4ed487b1-af22-4e25-aecd-b63fd850cf2d"), + Name = "InActive" + }, + new + { + Id = new Guid("1c0e422e-01b6-412f-b72a-1db004cc8a7f"), + Name = "Suspended" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.TenantStatus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("TenantStatus"); + + b.HasData( + new + { + Id = new Guid("62b05792-5115-4f99-8ff5-e8374859b191"), + Name = "Active" + }, + new + { + Id = new Guid("35d7840a-164a-448b-95e6-efb2ec84a751"), + Name = "Suspended" + }, + new + { + Id = new Guid("c0b5def8-087e-4235-b3a4-8e2f0ed91b94"), + Name = "In Active" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.TicketPriorityMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ColorCode") + .HasColumnType("longtext"); + + b.Property("IsDefault") + .HasColumnType("tinyint(1)"); + + b.Property("Level") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.ToTable("TicketPriorityMasters"); + + b.HasData( + new + { + Id = new Guid("188d29b3-10f3-42d0-9587-1a46ae7a0320"), + ColorCode = "008000", + IsDefault = true, + Level = 1, + Name = "Low", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("0919bc84-9f82-4ecf-98c7-962755dd9a97"), + ColorCode = "FFFF00", + IsDefault = true, + Level = 2, + Name = "Medium", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("a13b7e59-16fd-4665-b5cf-a97399e8445a"), + ColorCode = "#FFA500", + IsDefault = true, + Level = 3, + Name = "High", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("f340fbc3-c9fd-46aa-b063-0093418830e4"), + ColorCode = "#FFA500", + IsDefault = true, + Level = 4, + Name = "Critical", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("44a7b91d-a0dd-45d1-8616-4d2f71e16401"), + ColorCode = "#FF0000", + IsDefault = true, + Level = 5, + Name = "Urgent", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.TicketStatusMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ColorCode") + .HasColumnType("longtext"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("IsDefault") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.ToTable("TicketStatusMasters"); + + b.HasData( + new + { + Id = new Guid("6b0c409b-3e80-4165-8b39-f3fcacb4c797"), + ColorCode = "#FFCC99", + Description = "This is a newly created issue.", + IsDefault = true, + Name = "New", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("6c5ac37d-5b7d-40f3-adec-2dabaa5cca86"), + ColorCode = "#E6FF99", + Description = "Assigned to employee or team of employees", + IsDefault = true, + Name = "Assigned", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("7f96bcd5-0c66-411b-8a1d-9d1a4785194e"), + ColorCode = "#99E6FF", + Description = "These issues are currently in progress", + IsDefault = true, + Name = "In Progress", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("5c72b630-6923-4215-bf2c-b1622afd76e7"), + ColorCode = "#8592a3", + Description = "These issues are currently under review", + IsDefault = true, + Name = "In Review", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("8ff85685-a875-4f21-aa95-d99551315fcc"), + ColorCode = "#B399FF", + Description = "The following issues are resolved and closed", + IsDefault = true, + Name = "Done", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.TicketTagMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ColorCode") + .HasColumnType("longtext"); + + b.Property("IsDefault") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.ToTable("TicketTagMasters"); + + b.HasData( + new + { + Id = new Guid("ef6c2a65-f61d-4537-9650-a7ab7f8d98db"), + ColorCode = "#e59866", + IsDefault = true, + Name = "Quality Issue", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("5a168569-8ad7-4422-8db6-51ef25caddeb"), + ColorCode = "#85c1e9", + IsDefault = true, + Name = "Help Desk", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.WorkCategoryMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsSystem") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("WorkCategoryMasters"); + + b.HasData( + new + { + Id = new Guid("86bb2cc8-f6b5-4fdd-bbee-c389c713a44b"), + Description = "Created new task in a professional or creative context", + IsSystem = true, + Name = "Fresh Work", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("9ebfa19c-53b9-481b-b863-c25d2f843201"), + Description = "Revising, modifying, or correcting a task to improve its quality or fix issues", + IsSystem = true, + Name = "Rework", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("11a79929-1d07-42dc-9e98-82d0d2f4a240"), + Description = "Any defect, deviation, or non-conformance in a task that fails to meet established standards or customer expectations.", + IsSystem = true, + Name = "Quality Issue", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.WorkStatusMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsSystem") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("WorkStatusMasters"); + + b.HasData( + new + { + Id = new Guid("030bb085-e230-4370-aec7-9a74d652864e"), + Description = "Confirm the tasks are actually finished as reported", + IsSystem = true, + Name = "Approve", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("2a1a5b96-cf93-4111-b4b1-76c19d6333b4"), + Description = "Not all tasks are actually finished as reported", + IsSystem = true, + Name = "Partially Approve", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("00a062e6-62e6-42c5-b6b1-024328651b72"), + Description = "Tasks are not finished as reported or have any issues in al the tasks", + IsSystem = true, + Name = "NCR", + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.OrgServiceMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("OrganizationId") + .HasColumnType("char(36)"); + + b.Property("ServiceId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("ServiceId"); + + b.ToTable("OrgServiceMappings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.OrgTypeMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("OrgTypeMasters"); + + b.HasData( + new + { + Id = new Guid("5ee49bcd-b6d3-482f-9aaf-484afe04abec"), + Name = "Service Provider" + }, + new + { + Id = new Guid("a283356a-9b02-4029-afb7-e65c703efdd4"), + Name = "Sub-Contractor" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.Organization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Address") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ContactNumber") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ContactPerson") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("CreatedById") + .HasColumnType("char(36)"); + + b.Property("Email") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("SPRID") + .HasColumnType("double"); + + b.Property("UpdatedAt") + .HasColumnType("datetime(6)"); + + b.Property("UpdatedById") + .HasColumnType("char(36)"); + + b.Property("logoImage") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Organizations"); + + b.HasData( + new + { + Id = new Guid("4e3a6d31-c640-40f7-8d67-6c109fcdb9ea"), + Address = "2nd Floor, Fullora Building, Tejas CHS, behind Kothrud Stand, Tejas Society, Dahanukar Colony, Kothrud, Pune, Maharashtra 411038", + ContactNumber = "123456789", + ContactPerson = "Admin", + CreatedAt = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), + Email = "admin@marcoaiot.com", + IsActive = true, + Name = "MarcoBMS", + SPRID = 5400.0 + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.ProjectOrgMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AssignedById") + .HasColumnType("char(36)"); + + b.Property("AssignedDate") + .HasColumnType("datetime(6)"); + + b.Property("CompletionDate") + .HasColumnType("datetime(6)"); + + b.Property("OrganizationId") + .HasColumnType("char(36)"); + + b.Property("OrganizationTypeId") + .HasColumnType("char(36)"); + + b.Property("ParentOrganizationId") + .HasColumnType("char(36)"); + + b.Property("ProjectServiceId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("AssignedById"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("OrganizationTypeId"); + + b.HasIndex("ParentOrganizationId"); + + b.HasIndex("ProjectServiceId"); + + b.HasIndex("TenantId"); + + b.ToTable("ProjectOrgMappings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.ProjectServiceMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ActualEndDate") + .HasColumnType("datetime(6)"); + + b.Property("ActualStartDate") + .HasColumnType("datetime(6)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("PlannedEndDate") + .HasColumnType("datetime(6)"); + + b.Property("PlannedStartDate") + .HasColumnType("datetime(6)"); + + b.Property("ProjectId") + .HasColumnType("char(36)"); + + b.Property("ServiceId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.HasIndex("ServiceId"); + + b.HasIndex("TenantId"); + + b.ToTable("ProjectServiceMappings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.TenantOrgMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AssignedById") + .HasColumnType("char(36)"); + + b.Property("AssignedDate") + .HasColumnType("datetime(6)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("OrganizationId") + .HasColumnType("char(36)"); + + b.Property("ReassignedDate") + .HasColumnType("datetime(6)"); + + b.Property("SPRID") + .HasColumnType("double"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("AssignedById"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("TenantId"); + + b.ToTable("TenantOrgMappings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.PaymentGetway.PaymentDetail", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("EncryptedDetails") + .HasColumnType("longblob"); + + b.Property("Method") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Nonce") + .HasColumnType("longblob"); + + b.Property("OrderId") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("PaymentId") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Status") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Tag") + .HasColumnType("longblob"); + + b.HasKey("Id"); + + b.ToTable("PaymentDetails"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Building", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ProjectId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("Buildings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Floor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("BuildingId") + .HasColumnType("char(36)"); + + b.Property("FloorName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("BuildingId"); + + b.HasIndex("TenantId"); + + b.ToTable("Floor"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Project", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ContactPerson") + .HasColumnType("longtext"); + + b.Property("EndDate") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("PMCId") + .HasColumnType("char(36)"); + + b.Property("ProjectAddress") + .HasColumnType("longtext"); + + b.Property("ProjectStatusId") + .HasColumnType("char(36)"); + + b.Property("PromoterId") + .HasColumnType("char(36)"); + + b.Property("ShortName") + .HasColumnType("longtext"); + + b.Property("StartDate") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("PMCId"); + + b.HasIndex("ProjectStatusId"); + + b.HasIndex("PromoterId"); + + b.HasIndex("TenantId"); + + b.ToTable("Projects"); + + b.HasData( + new + { + Id = new Guid("85bf587b-7ca9-4685-b77c-d817f5847e85"), + ContactPerson = "Project 1 Contact Person", + EndDate = new DateTime(2026, 4, 20, 10, 11, 17, 588, DateTimeKind.Unspecified), + Name = "Project 1", + PMCId = new Guid("4e3a6d31-c640-40f7-8d67-6c109fcdb9ea"), + ProjectAddress = "Project 1 Address", + ProjectStatusId = new Guid("b74da4c2-d07e-46f2-9919-e75e49b12731"), + PromoterId = new Guid("4e3a6d31-c640-40f7-8d67-6c109fcdb9ea"), + StartDate = new DateTime(2025, 4, 20, 10, 11, 17, 588, DateTimeKind.Unspecified), + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.ProjectAllocation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AllocationDate") + .HasColumnType("datetime(6)"); + + b.Property("EmployeeId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("JobRoleId") + .HasColumnType("char(36)"); + + b.Property("ProjectId") + .HasColumnType("char(36)"); + + b.Property("ReAllocationDate") + .HasColumnType("datetime(6)"); + + b.Property("ServiceId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("ProjectId"); + + b.HasIndex("ServiceId"); + + b.HasIndex("TenantId"); + + b.ToTable("ProjectAllocations"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.WorkArea", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AreaName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FloorId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("FloorId"); + + b.HasIndex("TenantId"); + + b.ToTable("WorkAreas"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.WorkItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("ActivityId") + .HasColumnType("char(36)"); + + b.Property("CompletedWork") + .HasColumnType("double"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("ParentTaskId") + .HasColumnType("char(36)"); + + b.Property("PlannedWork") + .HasColumnType("double"); + + b.Property("TaskDate") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("WorkAreaId") + .HasColumnType("char(36)"); + + b.Property("WorkCategoryId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("ActivityId"); + + b.HasIndex("TenantId"); + + b.HasIndex("WorkAreaId"); + + b.HasIndex("WorkCategoryId"); + + b.ToTable("WorkItems"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Roles.ApplicationRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("IsSystem") + .HasColumnType("tinyint(1)"); + + b.Property("Role") + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("ApplicationRoles"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Roles.JobRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("Name") + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("JobRoles"); + }); + + modelBuilder.Entity("Marco.Pms.Model.TenantModels.SubscriptionPlan", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("PlanName") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("SubscriptionPlans"); + }); + + modelBuilder.Entity("Marco.Pms.Model.TenantModels.SubscriptionPlanDetails", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("CreateAt") + .HasColumnType("datetime(6)"); + + b.Property("CreatedById") + .HasColumnType("char(36)"); + + b.Property("CurrencyId") + .HasColumnType("char(36)"); + + b.Property("FeaturesId") + .HasColumnType("char(36)"); + + b.Property("Frequency") + .HasColumnType("int"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("MaxStorage") + .HasColumnType("double"); + + b.Property("MaxUser") + .HasColumnType("double"); + + b.Property("PlanId") + .HasColumnType("char(36)"); + + b.Property("Price") + .HasColumnType("double"); + + b.Property("TrialDays") + .HasColumnType("int"); + + b.Property("UpdateAt") + .HasColumnType("datetime(6)"); + + b.Property("UpdatedById") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("CurrencyId"); + + b.HasIndex("PlanId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("SubscriptionPlanDetails"); + }); + + modelBuilder.Entity("Marco.Pms.Model.TenantModels.Tenant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("BillingAddress") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ContactName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ContactNumber") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("CreatedById") + .HasColumnType("char(36)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("DomainName") + .HasColumnType("longtext"); + + b.Property("Email") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IndustryId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("IsSuperTenant") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("OfficeNumber") + .HasColumnType("longtext"); + + b.Property("OnBoardingDate") + .HasColumnType("datetime(6)"); + + b.Property("OrganizationId") + .HasColumnType("char(36)"); + + b.Property("OrganizationSize") + .HasColumnType("longtext"); + + b.Property("Reference") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TaxId") + .HasColumnType("longtext"); + + b.Property("TenantStatusId") + .HasColumnType("char(36)"); + + b.Property("logoImage") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("IndustryId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("TenantStatusId"); + + b.ToTable("Tenants"); + + b.HasData( + new + { + Id = new Guid("b3466e83-7e11-464c-b93a-daf047838b26"), + BillingAddress = "2nd Floor, Fullora Building, Tejas CHS, behind Kothrud Stand, Tejas Society, Dahanukar Colony, Kothrud, Pune, Maharashtra 411038", + ContactName = "Admin", + ContactNumber = "123456789", + Description = "", + DomainName = "www.marcobms.org", + Email = "admin@marcoaiot.com", + IndustryId = new Guid("15436ee3-a650-469e-bfc2-59993f7514bb"), + IsActive = true, + IsSuperTenant = true, + Name = "MarcoBMS", + OnBoardingDate = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), + OrganizationId = new Guid("4e3a6d31-c640-40f7-8d67-6c109fcdb9ea"), + OrganizationSize = "100-200", + Reference = "Root Tenant", + TenantStatusId = new Guid("62b05792-5115-4f99-8ff5-e8374859b191"), + logoImage = "data:image/jpeg;base64,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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1U94Htf+1fs26iz6Uc+nyze85xsKznbPXcb1FczE1lvJpWVizl5sZ3KW8udukL1caVmMo2Ltm75rGdKMW9XeLnS3R/ITxW/O3n3q0i+THrYfPTFFvxMXvEz2vMdp8sxE+WYt8pTy9nf3d/jx7R/R1evuk6cBxXS2fZy6ujuc1yEa+xvZMExGXJr6tq0m+vS/mx/HjJNZy0yU7RNJYVZ3vIfahZ9X0Hp31DzfHn0/EjTF8/g8+dbd8ef8377pd/aL6Wr+I47kL/nx5Pt/bxz9z9tJjV9zJ4+ZO31V1j0frd/n5JnP2/a3ad/+n63D833lnoFZ9X0HoZzbN8fqa3OSWMTz/lcbu+HEv7SHAx38nB7t/td9mtO/7etPZ2LV9yr4s5O31V4pdMa3f5+Thcux2/a5rH3/APc4fne83dNLPq+g9r3Kc3x58fE6lYWJ6vwfquE3vHn9/wCr/RxL+0txte/k6Y2r/a78lSv+HRn/AAuxavuRetsnb6q8c+B1u/z8nRW1sdv2up8ff9v/AJXD9h7zvp7lPGs7StvjVpStPVldWMDJpKvmviXphwWxWlPHj5ea18/f+84WT2mMUx/S+lMtZ/4XK47fr9o0Y/a7y7Fqe4/5Gk9932gePzxMxPbB0BtYJiPTvHe3VWXvPfv69v1vpcOyPeauQSlWuN21WLUPP6GN3nNm7WlPn4pWseN2/Nfq+9T/AOPFt7SmeZny9N1iPo770T/g14djw+5I4itYjP415clvpmnS2THE/nRPNX7fty+dc95l5pXz8Lt110Pwevl0Jfz+NHH97734f3vHqn2k936Onsfb7u3H+LA5lPcmdNR/tnjHu2/Q9PWr3/W/BSf8P7b0bnvMHUStP0vt/wBNCv8A53JaT/0amPn/ADPCfaS5CflwGGP+6e//ALJyqe5P6Pjt5/Fzk7fb8vCeXv8Ar/V8/wCD9t6Vz3l3qpX/AAXQfjsP428nP/RgxeE+0jyn0cFr/r55+f61HJp7lLoOPxfitzNv0PFVr+t2nbt/hejc95Y6x18/D6I8Vh+D1bO7P+f/AHvT9/8Azfv+fXPtIcx9HC6sfn5Jn/8ATDlU9yr4cR+L8T+ft+h0cdf/AG0/9PpeKHvK/Wmlf0zopxKVPNflHYXY18fg81tS/n8fyVfn88hzP08Lqf8AhJj/ABS9lvcreGkx9Z4mdQ1n7c6eO0d/zviV/wAL3bfvLfVqn+F6F8Zl+H0bicf9OHL/AOX4avOPaR5aPnwetP7NMf8A6P8Ap9txr+5T8Ppj6zxS5us/R5uNpb9vtsVe9b95f6lU8fF6BaKX4fTyGsf9Otk849pLkvp4HBP/AHR//wA/+Rxb+5Q6Kn8R4s8rX9Fw8W//AG2PT997tv3mPndP8J286qX8XlcY/wCnS1eyPaT3vp6fxT+dtdv/AGMuLf3JvSs9/J4wb9ftebgJt/g5Kr3rfvM/KqePiduGHP8AD6eaW4fw+PPH5POPaU2o+fTtJ/7siP2v9T/9PuOLf3JfAz+I8Ztmv6Lpq9v/APbw5Fge843LXj80u1nIyqU/VfRupWLi+f4PXw+/6fw/f/hcjH7S0x/tnS9rfb8vJUr/AIdOz5G37kSl+/1F47Ytf7Xx+i8+ft+f5eosPf8Ae7/cc0wveduEXfFM3tM5HiePFKyt9WcDJpX5U8ypGPArdaU8+fFK1rXx99zKe0xpT/tnSmxX7sctjt+99Qf43Wtn3IHU2PvOr7QHDbHzmK38P9vDMevpE2nqy8T6fOe0fnOYYPvMXRe94+n9vPMcLz+q+HzTFy/H+TxO15cyntJ8Nb8X0/uU/O3a3/wakOu7XuTvErH3+pfGDpza+15+mc+v3/b6gydv+Vy/B95M7Zr3j6d0n59hefr+HnQy/T+H9TprXn+ann6/k5lPaN6an8XxW/T7fa8X/wDYw65te5d8bcff6l6/6S2vtefUvr9/X7vJZO3o5jg+8b9md70/TuK9TMLz+q+HqJ5Vafh8emxa8uXT2iOj57efV5Kn2+2Gbfv9o/wOu7XubfaRx9/qXn+idn7Xn5CNfv8An98uTs5hg+8Q9gV6sfp1zqzhUr49Xw+BZOX6fw+PGZZ8+P5PLmU9oPoK34ueVp+doWv/AILQ67te589rTH3+paeH+z2+Xn6sw6/f8+Z18nbv+d9LuDi3tz/Z3cq+H6OqW50HxPH/ANlPHo6P0ea//hK5GylSH4a+fq+++vq+N/h7tdu3KZtfv/bWv8Dt+f5sk9mO+e91v7YXA+fzdC8by3k/KHmJ5TzfoPg6dfN+t9LJfiftMewzmdLUNN3TdHfpd6tKW9dmcz0+Nsa1lTzTziSypTp+D+GlaOyaviT0Ludvg9UcP55+WO+5hrk9f+B5pn/3+jCnP+xN7VvTc5Lcl4E+I31PjiZvua3TfI59OIifX/VFcEUn7f53aWUvDOrXTLqJa+PwXnfGOV2fT6viaPb4mfH0+PV582bkvl4+fn8DtGny3GcjXzaO9q7dft4MtMkfvSwT1J0B1t0ff4XVPS3OcBk79vJynH7Gpbv37du2Wkevf07OwYyjL5xlGVPwxrSv+ir6HeJ+U93UZiY+cTH58TH+F/Q/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH5WtI081rSlKfXWtaUp/PUfsRM/KJn871df836sdNOmuLHN5/znjPEMSUayjkb7bYuvtVjTz5rSd+5Gninita/vUrV8/d5XjeNr59/e1tSk+vmz5aY4/btMO29MdA9a9aZ51uk+lub6h2KzFZw8Tx+fcyRMz2iJripae8zPZiBzP2pXYHwf4sNn3P9KthlWPNL2v0XKtTtdhblGvj0TxbWXCcZV+9Gvzq6jueKHQel5oydTcXkvX0tjwbWHLkiftTWLxPdIjpv2FPaz6n+HbS8DuvdTBl7Tj2+V4HkNDUvE/11c+TXtWax9M/Jj1uvbq+zt0vr9XUzkG09Hn/6l41TZerx5/UfC2UfV58fLx9f8rr+fxx8PcHfvyWxl7f7jrfE7/ndsjL/ABnusvbC5Py9uieI0fN2/HPm/qPy9+34rz6U9u3f1/Ol1lne8N+z3x6yjh7Dq1m1jWtPNenWVjwlWlfH6GVdhc80r96vjxWnir5t/aB8P69/Jk5a/b/sfasT+v8AEn9t3bV90D7XmWKzsanh9rRaIn+rHBmtET6+tY1Kdpj6Y7+k94/P49T3ivsX+N6K6/qnSz//ABv7kr1Zf/6vXSv/AO395x/54Xofzdpx8p5f7L6ln/B37vsT7nb2pPh+aNvoScn+5/hgx9v/AO/ydv3nJMD3hj2euTWMcvZ9WcGU60p8+nOVetxrX/p3KbG3SMafP9F4/k+fy5OP2gfD+3aL5OWxzP8A2OtaP15+JH+B8Tb90F7XuCJtr6Xh/tVr6+nWODHeY/4NJ07zM/c7uztL7dH2du69Hp6obvWevx/9dccprfT5+/P4uyr6fH3/AD86fgfSw+OHh7m7duTz4u/+7a/w/wBvvk9HSeS91r7YXGebzdD8XveXv+NvMzu+bt/Y/D04833O3zZEcM9qH2D85pahqe6DpRiZd/00ta7c8r1Ot2Nysv8AmxxLmXO5WVPqrT71XYdLxO6D3u0YupuKpe3yx5trFiyT+dSbzP8A72HupPYZ9rHpf4lt/wADevtjXxd5ybnG8ByG7p0iP662xTXrWK/amWXvC+qHTrqNiVz+Cc045yzCpGkq5Wi2mLsLNI1rSlJfEsTlHxWtaU8+frrR23S5TjuRp8TQ3dbbp/ZYMtckft1lHjqXobrHo3YjU6r6a5np/ZmZrGDldDPqZZtHrMeXLSs9/RzulaV+dK0rT8NK0r/oc91aYmPnEx+f6P0fgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACvn9uZ+yG9XPnX/B6D7/AP8AaHWfV+BAPxu+yBy37B/AYm3P7rj8iB4ffo+W++280/sRrEQAAAAAAAAAAAAAAAAAAAH927ly1L1Wrk7cqfVK3OUJU/ljWlf879iZie8TMT9uJ7T+3DxvSl48t6VvWfnW9YtE/rTEw5BreYcs0961kavk2+196zONy1PE22dZrCca+YypSF+kfNK/hpWj349zbw2i2LZz47RMTE0y3r6x8p9Ldv23ydzp3gORxZMO/wAJxW3jy1mmSmxx+rli1bfOJm+KZ9e8/KYllz0x9o73s9IJ2I8H7h+oGuwLVY0nqb+zpl6zJhD9TaybNy3S7O3StKV8Rvwr5p59TtvGeInWnETX6h6g38dI7d8VsvnxWiPlFqzHeY/OtH56PfXHsa+zL4h1y26o8H+kdzayeaa8hi0fqfdw2t874cuO3w63nvMd7YrR2mfRs66I+8V92HCb2LidXOK8J6o6SxKFLlcHEy+N8iyLdPHrpe3ORnbrGrcl8/E6aylI18foK+GS+F9obqvStWnLaulymCvbv8Ol9bYtH3c1r5qzPz9fhoQeJ3udfALqbHn2PD7nup+heUzRby/VWxr81w2G09/L8PjcWrxuaK1+ms7szMR+Kj6N13bp7fzs16wzw9V1HubboXyPKrbhK3ynJsZ3GLNZeI1le5VPH0+Lb/RefMZYnyp4+dfLM/T3j10fy/kxcjOXg9i0xExtWrfWjv6d52prhrHr/wAD0VneMfulvaP8Oq7O/wBGV4/xT4bBFrVvwODLq85kiO8xGPga5eRz3nt29Y2PWe/aPRug4J1G4J1P0GJyrp5y3Q8y45nRpPD3PHtjj7LX5EZU80raycec7c/NPn8qsyaPI6PJ69Nrj9vBua+SO9M2vkrkx2+n0tWZifRWx1V0d1V0Py2xwPWHAcr05zOraa7HG8vp5dLbw2ie0xfDmrW1e0+nrDmjmutAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOBdQuqPTvpPoMjlPUrmfHeE8dxKVrkbjkezxtZg2vEay8SyMmcIUrWlK1pStfn4cDkOU47ide21yW5r6WvT8Vm2MtcVI9O/rNpj6Ha+kOhusOv+Ww8D0V03zHU/MbExGHjuG0c+9tZO8xWJriw0taY7zHeYj0ai+tvt7OxTpX9MweK8k3XVveY9blMe1w3Et3+P5dbfmlPTyWzPOx7cbkqUpCX0WfmNfV48U8VxLzXjv0Pxfnpq7Gbls9e8Vrp0ide3b/AOc1nJWIn6PrZ+2sJ8MvdRe1P159T7XPcNxnh9xeXyTlydSbF8XL68X7T68Jkrq57zWJnzR9UV7Wjy9+/rGnzrb7yb1u5BPLx+hXSTifAMadZ2bGVzTIv81yq2/NY0yIfQKcXpZuTjT4kISjP4UpUjKtz0+ZYj5r2jeb2JvXg+J1OPrPeItu2tu37fLzR8P6l8s9vWI9e3ftMz27rEvDH3LvhhxFNfN4qeIPUHV2evlyZMHTOHF0zr+ftFpw3+q552ctKz9Za1Zp8SImYivmiI1WdVvas9+XV+eTa5H3Acs1epyqzrd49xm/XU6Snr80/QYtyWZfjSMa1hD/AH1XxGtafOvzYu5TxT665ebRsc/t4sVu/fX1p+Fh9f8Agz57fL0j675J49BewX7Kfh3XDfhvCTp/e38EVinL83ijkOTny9vxWesa+KfNMRa39IjvaIn0+TBre885rybMv5/IOV8h2+Zkzrcv3s7bZt+V2dfrlKMr3o81/ejSjo+fe3dm9r7G1sZr2nva2TLe3ef17dv3ko+L6V6a4TXxanEcDxHH6+CsUxYtXj9bFFKx8oia4/NPb6O9plxWc53JVlOUpyr9cpyrKVf4a1rWtf5auLMzPrM95+3L7ta1rEVrWK1j5RWIiI/OiO0Q/kfoAAAD+oXJ25UnbnO3Kn1ShKsZU/grGtK0/nImY9YntP24flq1vE1vWtqz862iLRP58T3iXLdB1A5xxbMx9hx3l3ItPmYs6XMe/g7fNsytTjXzSsYxveiviv3qxrT95y8G/u6t65Nfb2MN6T3rOPNevafzot2/edf5XpLpfnNbLp8x0/w/I62es1y4trj9XLF6z84m04/NHf7cWifus5OlftW+/TpHcx4ce7gOWbXV43p+HoeT367bSypGtPFLmNblh35fKlaf+M0+Uq/h807vxfin11xM1jX5/by4q9u2DZn4uGe3y71jyW+5+K+lF3rv2CfZS8QqZrcv4ScBob2fzefluDxRoclHm795rmvXZxVnv69/gT6xH5zab0P95L658fu4eP146T8Q6gYVuUbN/J4TdyOE5lbFP0Eb1yWfLlMb1+EfE7tYwt0vzpKtKW/VSkcocJ7RvOa80rzvFanIUjtFraU20r+Xv280/E+qotaI9Z9I809/SEE/E/3L3hby+PZy+FXX3UPSOzeLZMWHqfHi6n1oyz9dOKkakcFbHitbvXH3tecdfL3m/aZnc70G9uv2K9Y6YWByLmOb0h5BkVt28jE57bs6/SWL12tKRt2eRZFzDsZVPVWkfXTEtfOvj0sx8F449D8x5MexuX4nYt2i1N+K48FbT8orsWmlb/a7xSPX6IVteKvusfan8OZ2dvh+ndXxD4jDF74djpO+Xb5PLjpEzN8nDYa7ObBPaJntOxf09e7bjw7nPD+oWiwuT8H5LpuV8e2Nul3B3Gjz7Gw1+XalSlaXLGRYnO3chWlaeJRrWlfLLOnvafIYKbOjs4drXyR5qZsGSuTHaJ+mLVmYmFfPUfS/UXSHK7PB9UcLyPA8xp3nHt8bymrl1NvXvE9pplw5a1vS0T84mHKnKfBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAV8vtyv2Q7q99X6jQf+4NX9f7/wDR4QD8bvsgct+wfwGJt0e65/If+Hn6Ll/vvvtQLEaxAAAAAAAAAAAAAAAAAAAAAAAAA+r6gd5dHu5brx0C3djkHSHqjy3hGyszty9ep2d6Nm7C3Wla2LuPerds1sXI0rbuQhGFZW5SjSUa180+3xHUnO8DnrscRye3pZKzE98WWYiYiYnyzWe8eWe3aYiI7x9LF3iL4K+FXizxmXiPEPobp/qfSy1vXy8ho47ZaWtExGXHmxxTJGWkz56Wta0VvETNZjvEyWOyX3iWlu1q+Ed5PHqzn6rGHa6ocPxrtKUjKsbNq5vNBell3L06zrS5m7OO0xrNuEp3vo1I26xrJDov2hO0YtLrDX7/AImkcnqVn6e0RObBPnmZ7+t8kZaxET38sRClb2m/c8ze+91P7OHMRWO2XZydC9RZqTMzHfJkpxfLY416Y6+XvTV0baObJa1a44zzN4mJPfSHrZ0s688Qwed9JObaHnPF8+EJWtnodhj59m1dlCkp4uTXHuXI2cqxWtbd+xKVZWrkZQl86JM8RzXF87p03uJ3cG9q5IiYy4MlckRMx61t5ZmItX5Wjv6TEwo88Q/DPrvwp6i2ulfEHpjluluc1LWi+jy2nm1MmTHFprXPhjNSk5dfLHa+LLERF6TW0eku031HRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGEvdN7QrtX7QMLI+6/1J1WJyWGPS/icG1F/G2XMM6Ny3SdmdjSRyLeVXHn6oevIpCUbcZ0nWNafKvSuqPEDpbpGlvwX5LFTZivmro4bVybl4mO8TXDFov5Z7x9d2nt37+qTXgT7IXjv7RGzh/md9F72xwts3wc/VPI4s2l05q2rea5K5eTtitg+LTy37YZtWb2rNYtE+sRku7j3iXrLz6Wfxrtg4ridKuO3fi4suV727d3fLMqzTzSGdqp2I6azo7860jP4WRj7L4cJStVlKtfXSNXVntCcxvzfW6Z1acVrz3rO3nmc23aPovi8sYYwzPaJ7Wrk7RMx6z6xd17PvuefDfpOupzXjjz2x17zFIpnjgOLpTjOn8OSe021d+uWeSycpipE2r58ObS89oreIiPrWg7qn3Adaetu6v8AIeq3UvlnN9tkVnW7lbra373q9dfNafBt1tWPH3qUrbrXx9+vzYI5TnuZ5rNbY5XktvdzW7+a+bLM9+/z9I7V7frLYOhPCXw18MuNxcR0F0V0/wBL8fhisY9fjNDFj8vljtE/Ev8AEy9/tz53T75DIgAAAAAAAAAAAABStaVpWla0rSvmlafKtK0+qtK/erQPn82QfRXur7he3jcWt30f6rct4ZlwuQncta/Z3pYeTCHj9IyMa9W5CVidKemcLfw61j8qSo+/wvVPUHT2aM/Ecrt6V4mJmMeW3ktEf1tq27x2nt2mI7fnsReJngN4Q+MHHX4zxF6C6f6l17VtWl9zRxxsYbW7/wBNxZ8cUvGWsz3ra/niJ+cSkC9qHvHHO+O0weO91fAcPmWBT4WNXm3CZXdNs8OxCtI1y9hqMmO7nusqVuP6ZSxl6+ly7KU6UjTxGmfelfaJ3tfya/VOhTcx+lfq3SmcOWlY/r8mG3xpzW7R6+W2PvMzPp8lSHj57mvpXmJ2uY8Berdnpvbnz5o6Z6nrj5LS2ctomfqfT5HBbjK8bgi8/WTl19yaUiKzNpjzTJI7Ye/ftd7vMCF/ov1L1W33NMeOTl8Q2N7H1/Ltfbl6aVlnaOuReyrEYynGFZT8U8yj8qeqiRnTPXnTHVuOLcNyWLLm8vmvqZJrj28cekd8mDzWtWImYjvP24Uw+OPsn+Ofs87dsXiV0Vv8fxs5rYdfqLSx5tzp3cvHm7V1eVjDjwZbTWs2ite/pFp7zEd2ZDuCOIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACvl9uV+yHdXv4mg8f/cDV/0oB+N32QOW/YP4DE26Pdc/kP8Aw8/Rcv8AfffagWI1iAAAAAAAAAAAAAAAAAAAAAAAAAAADI3t27sevPaxzDC5n0Y59t+MZ+NdtyyddTIv3tLtseE6SuYOz19L1qN/EyI0rbvQtXLFyUJSpG7GtfNOxdPdVc70vt03OG382resxNscWtODLWJ7zTLj7xE0t8rRWazMT82G/GLwC8KvHfp3Z6a8Suk+P5zUzY71wbk4cWPk9DLas1ptaO58O9sWxhntfFbJTLStqxM0mPRMv9nh7bno73SfmF0y6zVwOlPWi/GxgY9zNzrVri3M9hOkYwrpr2RGxXX5uVcr8KzqJ39hfncpSUcivxaQjMPw+8auI6n+BxnMzj4vmbRXHWb3iNXcyT6R8G1or8O9p9K4ptktM+vm9Yhre+2B7sbxG8CvwU638N/qvr7w1xWy7eamtqZMnPdNalZm1o5LHhtljb1cGOPiZOQri1MVaTMTij4czO9uMoyjSUa0lGVKVjKlaVpWlfnStK0+VaVp9VWc/n8lV0xNZmtomJiZiYn0mJie0xMfRMT6S/R+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMQO6zvo7b+zfj/5sdaee6/UbTJxrl/TcRw71jK5VvKwjWsaa7UfGt5N61WfiNy/CM42o+qdYypGtK9R6p646c6P1/jczv48WW1Zth1KWrbaz9v8Ac8Pmi1o7+k2iJ8sevaUiPAX2W/Gb2j+X/A7w06V2+Q0cOamLkuodnHlwcDxcWmPNO5yHw7YceSK95pitas5LdqRaJtEolnez7fLr/wBcMnZ8S7eLd7oj07u0u4ktlYyZ53ONtYpStmt+u2jDAxtfi51v1Xbmvlq792zS5G19LlW3Wc4o9aePHP8AN2y6nT8TwnHT3p8WtvPvZax6Tb4valcdMkd5nHOKZrExXzT2mZ2AfZl9074SeF+HR6g8X8mPxP6xx/D2I0suCur0vx+XvGSMUcfa+3m28+rfy0ptxvYseSaTk+BWLxWuhTkHJN/yrZ5W55LudlvNrm372TlZ+zy72Xk3r+RcldvXJXL05VpW5cnKVaR9MaVr4pSlKUpTBOxs59rLfNs5smfLe02vky3te1rWnvaZm0z859fT0WucTw3E8Do4ON4XjtPi9DVxY8GDU0dfHr4ceLFSMeOkUx1rExWlYrE2729PWZnvL4j0vpgAAAAAAAAAAAAAAAAAOR8W5fynhG5wuQ8Q3+145u9dkW8rC2WpzL2Hk4+Rar5t3IytSpSVY1+dKTjKP4aVcjV29rSzU2NTPl182O0XpkxXmlq2j5T3ifXt93u+NzvT3B9T8btcP1DxOhzPGbuG+Da0uQ18exgzYskdr0tW8TMRaPSZrNZ+1KQt2N+8BdYOlWVrOFd02Nf6s8GpSxhWuYY8543NdLajWMfpmfdnHOs721at0lCmJZxdbPxWE/pFfh1jKQHRHj3y/FWx6XVFbcto9q0rt1nybuGPpvkmYvXPER6RStcX0T5vT1qF9qH3SXh117g3upvAnPi8P+qe+XZv05mrXP0zyd581vqbUx1nVycVkveYvOxlz7tfS1fhfXxNZa/bn3V9Cu6zh1rm3RHnmp5frKQs12GHjZOP+bGjv34euOHu9dbvXruuzI+JRnYvVpOMoTpWnySv6d6p4PqnTjd4Tew7eLtX4lK2r8bBa0d/JmxxaZx3j1ia29YmJa/XjJ4DeKfgJ1HfpjxP6V5Dp7em2T6j2c2HN+B3KYsVvLbZ4zdvix49zWnvWa5cceWYtWfphkQ7Cw+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr5fblfsh3V7+JoP/AHBq/wCf/vRAPxu+yBy37B/AYm3R7rn8h/4efouX++++1AsRrEAAAAAAAAAAAAAAAAAAAAAAAAAAAAHsYuVk4OTZzMPIvYuVjXIXsfIx7k7V6zdtypKFy3chWM4TjKlKxlGtK0rR5UvbHat6Wml6zFq2rMxasx8piY9YmHqz4MG1hy6+zix58GalseXDmpXJjyY7xNbUvS0TW1bRMxMTExMJK/stvbgci6WZem6Jd2+9zOSdO7tcbU8X6jZU5T2/EfVKFnEs767crO3m6SzXxYlfpXBrgY06ZN25kRxpxuSQ8MPGzY4u+HherM99njp8uLW5G0zObUmZitIzzPeMmCvpWZ/pfw6z55m3lmJpW9ur3YPD9ea/JeJ3s+cXrcL1jj+PyPO9G4KxTjuovLW2TYycVSkVvq8pkjvljF22o281fgY6YpzVmkxzjHJ9BzPQanlPFtthbzj+9wcfZanba6/bycLPwcq3G7YyMe/alKFy3chKkoyjWtK/eql/rbODc18O1q5aZ9fPjrlw5cdotTJS0d62raPSYmPpa5XN8Jy3TfLchwXO6GzxfL8VtZtLkOP3MV8GzqbWC848uHNiyRW9L0tWYmLREvuve+UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9DabTXaTW5242+bja7V6zFv52wz8y7Cxi4eJjW5XcjJyL060has2bcZTuTlWkYxjWta0pR68uXHgx3zZr1x4sVbXyZLzFaUpWO9rWtPpERHrMz8nL0dHc5Pd1eO4/Wzbu9u58Wrqamvjtlz7OxmvGPFhw46xNr5Ml7RWlaxMzMxEIw/tF/b56LhU910n7N7uu5NyS1LI1246sZUvpmg1l2Hqs37XGsbFuWqZ+VbuUrW1tI7H4NmcKxriXK180jP4h+PGDSnNxXR849nZjzY83LWnz4MUx6WjWrWYjJaJ+WWMnlrMdppPdeB7HPuneU6mpxvX/tHU3OE4XJGHc47oDBH1Ny27S3lyYsnN5s9Mk6mC9O0ZNCdP4uSt4mNikR3mJd1K6qdQusPK9nzbqXy3c8x5PuMm5lZ213OXcyb9y7dlWUvRGVaW7UKefTGNuEaUjSlK+frRS5LlOQ5fay7vJbebc2c1pvky5rzaZmftRPpEfRHaPk2AOiuhOkPDrgdHpjonp/jenOD47DTX1NDjdemDFTHSIiPNaIm+S09u82va095mY7Ov3AdtAAAAAAAAAAAAAAAAAAAAAAd29Ce4rrF22c213PujvNtvxDf6+7GdZYWRcphZ1mk4zuYmwxKThbyMW/6KRuwpW3OUfNI3I+a1fa4PqHmOnN3Hv8Pu5tTYxzE96WnyXr37zTJTvEWpbt2tHpMx8phjLxT8HfDnxo6Z3OkvEbpnj+ouI3KWr5dnDSdnVyTWa02NTYmtrYc+LzTOO0xekT281LR6Jn/s1/bY9Ne6WOm6UddZ6rpv1wu2rOLgZc8qGLxfnWXGNI3I6imVWk9fsp+K3reqll7G9etRyLtLsY2JUlMjw48aON6o+DxXOTi47m5iK47zaKa29aI7T8LzzE48k/ioxefJa0eaYmIhrZe2l7szrTwKnkuvvCyu/wBZ+GFL5M+3r1wWz850tr2tM0nkbYImm3pV9Mdt+uvp48eScWOcczliY32fX9TOyqEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABXy+3K/ZDur378NB4/f/4A1dP9NPH8iAfjd9kDlv2D+AxNuj3XP5D/AMPf0XL/AH332oFiNYgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfV9QN0vswPa39Q+y/ket6f8AUfL2PN+3/aZkbGbpb+RdubLh/wBKn4ntdBfnS/GljGuy+lZOBPHnXIt1yLVvIx63ITt5l8MvFjkOjdnHx/I2ybvAZbxW+G1pnLp+afXLr2nzR5azPmtjmszaPNWLV7xMVq+3H7vro/2lOG3erejdfT6Y8XNHXnLq8liw46aXUcYK966HLYqfCmcubHHwMO3XNWMNvhZL4s3ktW867pR1W4H1t4DxvqZ015Bg8m4dyrX29jqdrgXrV61ctyrK3esXa2p3I28rEyLd7Ey7FZVlYyrF6zL9FCqcXFcro81oa3J8bsU2dPaxxkxZcdotEx8prPaZiL0tE1vXv3raJrPrEtWLr7oLqrwy6s5ronrTiNrhOo+B3L6fIaG3iviyUvWIvjy44vWs319jDfHn18sViuXBkx5K/W2h2K+i6cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6c67de+lnbf073PU/q7yrW8U4rprM5yyc/Js2LuflUjWtnXa63duW/pWfky8RsY8K1nOvnxSvjw+PznPcX05x+bk+W2serq4azM2yWiJyW+jHjiZjzZLT6VrHrLI3hX4Udd+M/WHG9DeHvA7nP89yWSta4NXDky49TB37ZNzcvjpf6n1MMd7ZM148tfpn1QcfaT+2G6td42823BOmmbtOm/QGxfli4ugxMm7b3PL7GPP0w2PJcuEcenwcy7CmdY1trFszwYysYt3Kyq2J3bsJfEfxe5bq/Pl0eNvl47ga28tcFLzGbbrWfTJs3iK/W3mPPXFFYmn1tZvfyzM7Q3sXe7r8P/AGcuL4/qrrXW0etPFnLirnz8tsYMd+N6dy5q97afC4LTm/pmvS06uXdvmyV2rVyZ8eDBGWtMelmtayrWUq1rKta1rWta1rWta+a1rWvzrWtfnWtfnWrDPz+ayuIiIiIiIiIiIiI7RER6RERHpERHyh+D9AAAAAAAAAAAAAAAAAAAAAAAAe1g52ZrMzG2Gvyr+FnYd63kYuXjXZ2b+PftSpO3dtXYVpKE4SpStK0r/meVL3x3rkx2tS9Ji1b1mYtW0fKYmPWJh6NrV1t3Xzam3gxbOrs474c+vnpXJizYrxNb48lLRNbVtE9piYSmfZS+29yOOfmD2+93u9u5unnXE0/Buq2bd8XdVGPpx8TT8ru3pSt3cT4fotYez+LhxxqWbWLcs5FzIjcjKDws8a7a3wOA6uzzfDPkw6PK3mInFEdq0w7c2ntNO3pTL3p5e0VtFptFoon9vX3YeHmfwV8XPZ44rHrclH1TyPVXQOtjicfIWt5suxyPAUxxW9Nib98mzo/D2LZpyZM9MmGmKaWlz6zZ6/da7B2+pzcbY6vZ4ljO1+fh3Y38XMw8q1G9jZOPehWsLtm/anC5buRrWM4SpKla0qlliy482OmbDeuTFlpW+PJSYtW9LR3rasx6TW0TExMfOGvhvaW3xu5tcfyGtm097R2MuruamxS2LPrbOC9sebBmx2iLY8uLJW1L0tETW0TEx3h7z2OKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr5vbl+f74d1d/iaDx/B+YGs/p8oB+N32QOW/YP4DE26Pdc/kP/AA9/Rcv3/uvv/wCJqAYjWIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANufsufag847GuoGNx3k+Rm8m6C8q2Fq1yvjE79yV3RXMj0WP7otDKXxYY+Rh1jav5WPWxchm4tq/jxlj3L/ANIhlnwx8Td7ojfrr7Nr7PA7WSI29abTNsE27V+qME+sVtTtE3r5Zi9YtWJra3mivj26PYb6X9qPpLNzHCYtbg/FfgdS+TgOcphpFOVx4fNl/AblYjyXy4dmJyY9fNGWk62fJizWrmpinDefH0r6pcG60cC431L6cb/B5Lw/leutbLUbXX37d+zct3PMLti5K1OcbeViZELuJl2KyrKxk2btqX6KFU7+L5TR5nQ1uS47PTZ1NrHGTFlx2i0TE/Os9pmIvS0TS9e/1tqzWfWJannXfQvVPhr1ZzXRPWfE7XCdRcBuZNLkNDbxXxZKXp2tTLSMlazfBsYrY8+vliIrlwZMeSv1todhPoOogAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMRu8bvR6MdlPTDN6idWN7Yx8m/bu4/FOLWci1Hd8s3Pw7k7Gt1eNOsrtytaWrt7Iu27N/6Pi2L+RK3KFqVHUusOsuG6L4y/IcrnrW1omupq1tHx9vN2ny48VZ7zPym1pitvLWtrTHaEg/Zz9mvxJ9pjrjW6O6A4rLmw4r483P8AO5cOS3F9P8d56Vy7u/mr5cdPW9MeHHfJi+Nny4sUXrbJVAK75u/vrR3zdSc7lfPtrc1vEMHLybfC+Ba+9ehpuPailycMO3ctyuyjmbKeNSE9hm1hat5OZO/ftYuNCcLNuBnW/XnM9b8lk29/LOPUpe0aWhjtaMOvh7zFImO8+fLNe05L9oi15mYrWO1Y2z/Zc9k3w19lzovV4DpPQpudRbWvhv1N1Xt48duS5jkPJW2xel4pE62lXN5q6erFsl8OtXFiyZ89qTktgq6OlMAAAAAAAAAAAAAAAAAAAAAAAAAAA/YylGVJRrWMo1pKMo1rSUZUr5pWlafOlaV+dK0+dK/Oh8vk/JiJiYmImJiYmJjvExPpMTE+kxMekxPzSTvY4e15y+i+y0vbT3GbzIzume4y7Gt4HzHYZMpXeG5+RdpDH1mxvX5ShPT5NZ1sWJ1lj/AuRxbVZXKy/RSO8H/Fu/DZMPTfUWe2Tjc1649HcyWmZ08lp7VxZJt3icNu/aJmazWYrHefppd9437vTX8StLkvGvwb4vDq9bcdr5d3qvpzTwRFOpNTDjm2be08eKK2ryOGKRly1iuX4tJz5O1IjtE0HEysbOxcfNw79rJxMuzbyMbIszpcs37F6FLlq7anGtYzt3ISpKMqVrStK0rRMil65K1vS0WpesWras94tW0d4mJ+mJie8S1sNjBm1c+bW2cV8Gxr5L4c2HLWaZMWXHaa3x3rPaa3paJras+sTExL2Hk9IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACvm9uXTx7Q7q7+/DQV/9Qaun9CAfjd9kDlv2D+AxNuj3XP5D/w9+5blvvvvz/jagGI1iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADb77LP2oXNux/qDh8W5ZmZnIugXLNnYs8p49ev3JXOO3cqtvHpyTSTlW5bsXcGVLWRm48rM4ZeJayLEJY929TIt5c8L/E7d6J36au3e+xwO1lrG1rzae+vN+1fqnDM94rNPS16+WfPSLViazaLRXj7dnsNdMe0/0hs89wGvr8N4s8BpZcvA8xjw0inM48HmzTwvKVr8O+am1E5MWtm+LW2vsXw5bVzUxzhvPq6f8+4l1R4ZxzqBwXc4nIOKcq1eNt9LtcK7C9YycTKhSdKVlblOMb1mXqsZFr1VrZv27lqVfVCqeGhv6nKaevv6OamfV2sVc2HLSYmtqWjv84mY81Z71tHf620TWfWGpx1d0n1B0L1JzPSXVPG7HE8/wO9n4/k9DZx3x5cOxgtNZmIvWtrYslfLlw5PLEZMV6ZK+locxcx1wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABif3jd4PSnsu6Qbfqn1P2tmxKMLmFxXj0L9u3tOVchnauXMTUay1P1Tu3Kxt3cnIlbtXq2MPGyciVusLUvHVesOr+K6N4jLynJ5Yj0mmrrxaIy7WxMTNcWKJ7zM9om1u0TNaVtbt2iWffZz9nbr32lPETjuhOh9DJlibU2ue5e2K99HgeHrkpTY5DeyV7Vx0i16YMMXvjjLs5sOKLRbJXvXo95neV1Z71urm36m9TNpc+h0ycrH4hxbHuXaari2gpdrHA1+NancnG5lxxYWaZ+ZSkKZeX8e/bs41u7THhX71j1hy3WfLZuS5LLPk81q6mrWZ+Fq68T2x46xMz3v5Ij4l/TzX81orWJ8sbfHs3ezh0B7M/h7x/RHROjX6onDgzdQ87mpSeQ53lvhxO1t58laVmmvOe2T6k1u9vqfX+FivkzXx/FtiK6mkGAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/qE525wuW5ShOEozhONaxlCca0lGUZU8VpKNaUrStPnStKVoRMxMTEzExPeJj0mJj5TE/RMPy1a3raloi1bRNbVtETW1bR2mJifSYmJmJifSY9Eun2HHtULm9hpuz/r/wAi+PuLdm3g9HeWbPK9N7Mx8O3WkOHZ079a/Sb9jCj6tXehctytYetuWZ2b8p/GhLPwS8UZzxh6R5/Y82aKxTiNvLbta9aR6aeSZ/FWrT1xTExMUxTE1tM92vf70P2EKcXbkfaJ8JOH+Fx18l9rxG6f0cEzj1s2xfvbqTVriiPg4suzMV38dqXjJs7lMlMuKtfh2lWpSqGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFfL7cr9kO6vfxdB9/wD/ABf1f838H8v30A/G77IHLfsH8BibdHuufyH/AIe/ouX++++1AsRrEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEmP2BntCdj0/6gU7SeqXILt/g/NpZFzplk7HIrS3xvk0YTzb2qjkXpVtw120jZyY42L4hcnts6HouypKNlJPwH8QMmhv8A4U+Uz2tpbs2njLZLemts9pvbF5rT2jHl7WitfSZy5I7T6xWaTvexeyHp9W9Iz7QPQvE0xdU9MRhp1vg08Pe/NcJNq62PfnFjiL23NG2XDOfP3tSuhqzFscTWcsTNUxWtwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6m649aeCdvfS3l/VzqPtsfT8U4dqruyz8i/et2K37nrt4+Hg48rtaRrk52bfx8SxGlJVrdvx8QlX9DX5PN8zo9P8AF7fLcjlrh1dPFOTJa0xHmnvFaUr3+dr3tWlY9Z7z8p+Tv/hf4a9VeL3XXTvh70Zx+bkef6k36aWphxY75YxU8t8uxtZa0jvGHV1sWbYyz3iPJit3tWPWK7f2g/fd1C76utO05xyHJyNfwbT5OVr+nfD4XbtMLSaG1clZxb9y1KXpns8+xCOXsL1YQrXKyMikLduEvRSvjr/rnkOuOay72xa2PRw2tj4/TiZ8mDBEzFbTE/PLkrEXyW7R9da3aIj0jcK9kT2VukPZZ8NNDpfh8OLb6p5HBg2+sOorUpOzyfK3pGTPipkrHeujqZbW19TH5rdsGLF5r3tHnnAh0RK8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB9fQb7bcX3eq5Foc7I1m50udjbLWZ+LclayMTMxLsbti9auQrGUZRnGnnxWnmlaxr8q1e3Bny6ufFsYL2x5sOSuTFkrMxal6T3rMTH2pj9f5Pn8txXH85xm/w/K6uHd43k9XNpb2pnpXJh2NbYpOPLjvS0TExatp+cek9pj1iFgZ7Ib2guH3rdBsXU8v2WPTrZ01xMPT82w53Y0yt5iWIUxcPlNq1KVbl2mfC1av7K7GlbdjMzbdmtaVlSlZ8+EvX9OtOCpi28lfwa42lMO7SZjz56VjyU2ojv3n4kRFskx6VveI7+rUg94Z7I2z7M3itn3+ndLNPhl1rsbPI9MbNaTODi9jLec+xwOS8R5Mf1JbJfFpUt2vl1ta2SImKy26stK9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFfL7cr9kO6vfxdB5/J/V/0fw/0IB+N32QOW/YP4DE26Pdc/kP/AA9/Rcv9999qBYjWIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOTcL5ZueB8u4zzXj2TLD3nE99qORanIhWVK2thps/H2OJKXolCVYfHx4UuRpKPrh6o1rSlXJ0tvNo7etu69ppn1M+HYxWjv6ZMOSuSnymPTzVjvHf1h8XqTgOO6q6e5zpnl8Ndji+f4nkOH5DDaKzGTU5LUy6exEeaLRFvhZreW0xPlt2nt6LMbsn7jNF3UdtHSvrFpsqN/I33GsPF5Dbrdjcv2OS6ektPvvjRjSlbVMnaYGXlWLc6eqmPetVrKfn1ysm6L6iwdUdN8Xy+G3mtn1qU2ImYm1dnDHws/mj5x5stLWrE+vltHz+bSb9prwb5XwI8bOvPDrksE4sPFc1sZ+IvFLUxZeF5Hy8jxXw7TMxknDo7evgy3rPac2O/pX8TGVjtLAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD1szMxdfiZWfm37WLhYONfzMvJvTpbs4+LjWpXsi/duSrSMLVm1Cdy5OVaUjCNZVr4o8b3rjpfJe0UpStr3tae1a1rE2taZ+iIiJmZ+iIe7W18+5sYNTVxXz7O1mxa+vgxVm+TNnz3rixYsdI7za+TJatKViJmbTER6ygke2p9pDkd1vVi90a6YbnJj0R6X7XJwbk8e/KOPzDlmB8bA2O2uUtypbvYOHkzz8TX183LeTjxsZca08xog14zeI1uquVtw/GZrRwvGZbY5mtpiu5tU82PJlmI9JpS05KU+cWrFbxLak92j7GWLwE6BxeJHXHHYZ8TuudDBtUrlx1tl6d6f2/h7enx9JtE3x7Wzhrq7G3H1l8OW2XXtE9plonYOWnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMu+yHuu5p2ddwXC+rnFc6/b1+Jn2ddy/UUuzjh73i+ZetR2GFmW4ypS5CzKFnOt/8742Hap58VrSvbeiuqtzpDn9PltXJaMdckY9vD3mKZ9a8x8Sl4+mK9q3j/hUhHv2nfAPpr2jPCPqXw95/VxX29jVybnTvITSs7HFc5rY7zqbOteYmaWyRbJq5Po+FsZJ7d+0xZM9JuqPEetPTnh/VHguxtbPi3NdFrd/qcm3OE5Rx9liWcuGPkUhWtLeXjxvRtZNmviVq7GUJUpWixrieU1OZ47U5PRyRl1d3Bjz4rRPeYrkpW8Vt9q9YtEWj6J7w0vOv+huoPDXrLqLoXqnTvo870zyu7xPIYb1tWs5tLYya9suGbRE3wZpxzfDkj62+Oa2iZiXYj6LpwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACvl9uV+yHdXv4ug+z+rQD8bvsgct+wfwGJt0e65/If8Ah5+i5f7777UCxGsQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAShPdzO7enGufc17UuVbSkddzm3kcs6f2r92tZf3Ra3Ct3NrrMaEpUjDH/MfXZ2wlGEayrflOVa+K1Sa9njqyNbf3eldrL2x70TtcfFp9fqjHSJy4qxM+lfg48mT0j8VMzKjf3yHs+zzfSfTXj3wOjNtzpa+Hp/q7Jhx9o/Afd2b00N3NNa97ZvwR3NXUi1p7Riisdu8R3mKJfNc8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABHa9u57RHK6BdPLfbL0t28MbqZ1N1vq5hssS95zOLcNvw+NKzbrbnGWJstx4w7cfjer4upzsiULXmULsY9+OfiFbgePjpri80V5Lk8f+rMtLfX6unMeaax2/EZc31kes+uK9pivymLhvdW+x7g8WesL+N3XfH3zdEdEbs16c0tjH21ue6kxWnFGW8XiY2NLje+zefh9vJyGthi1/rZpaEdOUpylOcpTnOVZTnOtZSlKVa1lKUq1rWUpVrWta1rWta1rWtfKFczMzMzPeZ9ZmfnM/bls41rWta1rWK1rEVrWsRFa1iO0VrEdoiIiIiIiO0R6Q/kfoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACV77vB3xfRsve9nPUDdebeZW/yTpNPNyPTSGTS/wDE3PG8Wl2Va38nNlmXdlYtWpQraxtddpS1ONKzhKj2fetvJbP0fv5vS/m2eJ89vlbzd82vTzT9da83nJWK9u1ccx2n5qDvfBey/wDHwcV7RvSXGdsmtGHhfECurhifNhnF5ON5rPOOIjFh1o16aWW94t8TPuY5+JWZitpbaWDX4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAV8vtyv2Q7q9/F0H2f1aAfjd9kDlv2D+AxNuj3XP5D/w8/Rcv9999qBYjWIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO1eh/VfkPQ/q1wDqrxjLv4e24TyjUbyMse5W3PJw8PNs3Njr5Sj8/g7HApkYN+nivqtX508fN9ThOV2OE5bQ5XWvamXS2sOePLPabUpeJyY+/wBrJj81Lfbi0uh+J/QXEeJ/h/1b0Fzmvi2OP6n4LkeLtGakXph2NjWyU09uKz6fE09qcO1in6MmKsrODt+6w8e6+9GOnXV7jGXYzNVzfjGt29bmNKM7VjZSsRs7jBjKMpUrXX7a1mYU/NaVpKxWkqRr5pSyzgOX1+e4fj+W1b1vi3dbHl71mJiuSaxGbH6TP+15YvSfu1aRPi54dcv4T+JPWXh5zmvl1t/pfnN3jvJmrNcmXTrlnJx21MTEem3oZNbar2jtNcsdpmO0u432GOQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHQvc5154t2z9C+o3Wnl2VZxtZwnj2Tn2Ld6cYUzNrfnawNPhR9Vaer6VtcvDszpHzKluc5UpXw+F1Nzur01wfI8zt3rXFpa9slYtMR58tprjw09f7LLekT9yZn6GV/BDwp53xs8UujfDTp7Blzb3U3L4dTLfFWbTraGKuTb5LamYiYr8DQ19nJXv2ib1rX6VaT3Cdc+bdyHV/nHWHn2xyM/fcx3mdsaQv3pXo6zWzv3PzK02NWtfFMXUa+mNr8fxSnmzjQrLzXzVW71Bzm71Fy+9y+/ktkz7me+Ttae8Ysc2n4WGv/BxY/Ljr9uKxM+rdX8IfC3pnwZ8O+l/DnpPTw6nE9OcXq6c2xY4xzvbtcVPq/ks0R88/I7nxtzN3me2TNaI9Ozpd8ZkoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2X0c6ock6L9UOD9UeJZ9/W77hfIcDdYeTjzlC56bFz0ZdnzGtPMcnDuZGPKlfNPTdr8q/U+lw/J7HDcnpcnqXtjz6WxjzUtWZie1Z7Xr6fRak2rP57pXiN0PwviT0N1R0N1BqYt3iepeI2+M2cGasWp3y082vk7T9OHZphzV+Xrjj1hZndrnXvjnc10I6cdaeM37FzD5nxzXZ+fj49yNyGs3lcSxXdaico1r+m6zPnexLtK+mUZ2q0lGNaVpSyfpjntbqXguO5nWtWabmvjyZK1mJjFn8lfjYZmJn1xZJmk/T3j5R8mkt46eFHM+CXir1n4ac5iy02OmuZ3NTUzZqTS29xcbGWON5GtbR/te9qVx7GOY71mt4mtpj1d/vvsSgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK+b25fj++HdXvH/Q0Hn+H8wNX9X8nj+XygH43fZA5b9g/gMTbo91z+Q/8AD39Fy/b+6+//AI2oBiNYgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAl++7k928t3xfnfajy3a0nncZuXOX9O7eTe9P/AuXcs12mlw4XJSrfvx2F7Z7e5S3Wnox6yrW36Y1mlv7O/Vk5tbe6V28ve+tM7fHxae39JvMTlw0ifxVoyWy5Z7T6V+jtHdrw++S9n2OM53pbx86f0Jrq83SnTvWN8GPzT+CeCmSNDk9m1YiMWK2nj0uPrN4nzZYrEX7zFUptKFRKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhre8Od61ebdQ+P9p3Bdz6+OcAljcg6iTwr/rsbHk2bgSu6/Wznal8OePg4Wyp9Kx5xnO3ssSlayhW36EPPaC6z+reQ1+lNHN31tDy7HITS3euTZvj82PH3ie01pTJ9fWe8xkpHrHbs2Pvc/8As0R0z0fy/j91Txvl5nq2M/EdH12cXly6fB623GPb3a0yV89M21taUzr5qzWt9LYmIraLxZGQRqXdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJYXu4vdrK1kc/7TOU7Pzau2bnOunsMq96Ldj4eZCzvdRi0uSrS7k5+Vt458bVv0ypZw7taQlGFZRlT7O3Vfltv9KbWT0mJ3uPi1u0V7XiM+Knf52vfL8SIiY9K29J+agv3yvs/Rkw9Je0BwWj2yUy06W6wtgx+a+bz618vFchnmlYnHh1MHHzqWyX71nJsUjzRNoi0tZK9r9gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK+X25X7Id1e/i6Dz+T+r/AKP4f6EA/G77IHLfsH8BibdHuufyH/h7+i5f7777UCxGsQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZO9nPcLvu1zuO6XdZdHmXMSPGeTYMd5SEp0jkcZ2Vz8zOR2JRjKNJTnpMzPpZrKkqQvVhP0S9Ppr2bo/qDP0x1FxfMYLzWNbZpGftMx5tbLPwtmPT6Zw3yeXv8AKe09pYQ9ozwg4nx08GuuvDfldemxbm+E2p4ubRXvh5zSp9W8Nli0xM1rXk9fVnJFZibY4tXzR37xZm8B5rpOo/CeKc845kW8nScv4/qeRa27buRu0pi7fBsZ1q1OcKUjW7ZjfpavUpSnpuwnGtKVp4pZPobuHkdLU39e0Wwbevi2McxMW+ty0reImY+mvm7W+1MS0l+rOmuT6N6n5/pTmcN8HKdO8vyHD7uO9LY5+qOP2surkvWlu8xTJOL4mPvM96WrMTMT3cuct14AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABiT3wdzfG+0rts6k9YN7mWrOfqdFk4XFcKt6FvK2fJ9n6NfqrWFbl5lkXMPIyo7LItW41n9Ew78/MIxlOPU+tupdbpTpzkeXz3rXJiwWpq0mYi2TZy9seKKR87TS14yWiPXy0n5R6xIH2YPBHmfaB8aOi/Dri9fJk1N/lMOzz2zGO18Gjwel5tvfybN47Vw12MWC2lhyXmK/VGxirEWmYpatL59zfkPUnmvKufcrzbmx5HzDf7bke4y7kpy+Jn7nPyNhlfDpOU5QsxvZE42bfrlS3apGFK1pGit7f3djkd3a39q85Njc2MuzmvPf1yZslsl+3fv2rFrT2j6I7Q3V+k+mOI6L6Z4HpPgNamnw3TvE8fw3G69K1jyanG6mLTwefyVrW2S2PDW2W/lib5JtaY7y4i4jsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADIvtL64bvtz7ielHV/RZUsXI4jyzX5OVX4lbdq7rcys9dsYZHiUaStQw8y9e9Mq+n124Sr+pdh6U5vP071DxXL4LTW2pt47X9e0Tiv3x5It9ExFLzPafTvEMO+P/AIX8Z4yeD3X3h3yuCufD1DwG3hwR5Ivem7rxXc0rYu8TNb22dfHj7xHfy3tEfNZx8G5jpOofDOK8843kxzOP8x4/qeS6TKhKko5Gr3OFZz8G9GUflKlzHv25UrT5V8+afJZbo7mHkNPV3te0X19zXxbOG0T3i2LNSMlJ7x6T3raJaQ/VHTnJ9IdSc90rzWGdbl+nOX5DheT17RMWw73G7WXU2sUxPrE0zYr1mJ9Y7erlTlPggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK+X25X7Id1e/i6D7P6tAPxu+yBy37B/AYm3R7rn8h/4efouX++++1AsRrEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE3j3e/u7udXegG87euUbGmRy7oreu39FG9e+JmZvCNpmRyYZV71S9Xpw9ttbmtsUjGkY2Me3H64pq+AHVs8twOfp/ayebb4W02wRM9730st/NF7d5me1MuScdflHlrDWJ97v7PVPD3xa4vxf4PT+D094mY6YeUnHj8mtrdUaOtbDfXx+WPL32OP0abuWZmbWzZrz8pSIEg1PoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEL7wF3p2us/XPV9u3CN1HM4H0buUvcilhZHxcPac8v4c7eT5lal8L16SzsM7T5WPP4koZePKsq25wrbpCnx86yjmecxdPaWbzaPDz32PJbvTLvWpMWnvHp3wxkyYb1nvMXrPftMdmzx7pL2ar+G3hbv+MXU/Gzr9V+JFJx8PXZw/D2NHpTFsVvgjy5K+fy8nk1NXksGavki2vliKxatvNMeFH1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfV9QJ6vsEe5G/1u7NMfg+6zvpvKOiO3hxHMlK5WU4aHLplz4rYpblWU4RxdPr7dn1VlWM6+KxjCniKdfgR1Hbm+jq6OfJ8Ta4TLGpeZn1jXv551K9v+DhxxX7v3GqR71/wYxeGPtIZuqeM1fqXg/E/j7dRa1Yp2rbldedenPZZvEVrac/I7d8naKxNYntabT6t4bNqr4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABXy+3K/ZDur38TQef/ALgav+b5fw/h+/4pAPxu+yBy37B/AYm3R7rn8h/4e/ouX++++1AsRrEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGfXs1O6fZ9pXdp0z6hQyp2+MbTc43FOaYdbtbWJlaHkMpaieTmfOlK2tPezobePqrSlLmHGtZUpTzTvnhv1Rk6T6s43kItMa2XNXU3Kd+1LYNjvim1/o7YbXjNHf5TSJRO9tTwJ0vaB9n/rbo+2Ct+c0eNzc/0zsxji+xg5bh4ryFcOt9MZORx6tuOt27zNNm0REzPZZG6fbYG+1Gr3uqyIZer3Wuwdtrcq3WlbeTgbHGtZmHkQrStaVhex71u5GtK1pWMqVpWtFjGHLjz4sWfFaLYs2OmXHaPlbHkrF6Wj7k1mJj89picjobfFchvcXv4ba+9xu5taG7gvExfBt6ee+vsYbxMRMWx5sd6WiYiYms94fRexwwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGCPtHO7DS9n3ax1C6lZWZZtcp2Otv8AF+AYE70bN/Z8p29v6NbjiVl5lLI1mBczNzSEITlWGvnWtKRpWVOjeInVWHpDpfkOSvesbWTFbV0Mcz2tk2s0eWPJ9u2LHN83aIn0xylT7G3gFyftE+O/SHRWDWyZOC093FznVu3XHOTFpcFx1/jXnYiI7Vxb23XW43zWtWItuV9ZntWa3DknItxy7kO85TyDNu7Hecj2+x3m3zr8pTu5ey2uZezs7InKVa183sm/duVp58U9Xinyorm2djNt7Gfa2Lzkz7GXJnzZLTMzfJlvbJe09/t2tM/rtzzheH47p/iOL4LiNbHp8Xw3H6fF8dqYqxXHr6Whr49XVw1iIiO2PBipSJ7d57d59XxHpfTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAb7Pd9u4v7lXd9e6U7bO+Fx/rXx/L0WBhSufDtz5hhXcPY67Kl5rWM629RgbezGHppKtbvmk6UpWNc7eAXUP4FdXTxeXJ21+a174MdO/aJ3KTTJjv8AdmMVM0du3ee/z+iaove5eDn4ffZ4x9e8fq/E5fwz5fX5Xb2Yp5716d2sezp7mvHaItWL8htcfkm3mmv9L7TWZmJidYnE1ZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHiv3rONZu5GRchZsWbcrt67clSFu3bhSspznKvikYxjStZVrXxSlK1q/LWrWs2tMVrWJm0zPaIiPWZmftRDzx48mbJTFipbJly3rjx46RNr3veYrWtax3mbWmYiIj1mZam+6T2z3Zd2y5OXoK8zt9VOa4k7tm9xnp9l421t4WXarWk8PcbfDpn2dRk0rSla2snGrPxKNfT86MU9T+MnRvTVr4PqyOU3ad4trcfeuWKXie00zZafEjDb7lqzPy9PVP7wK92z7Snjbg1uX/AAtX6D6Z2K0yYub6v18+hfZ18kRNdnjuP2PqTJyGGfXtfDniszEx37w0Z9cfeTOuO+zMmz0E6TcO4Hq5ylbtXOdyy+Z7H4Xj0/Gt3tXlcWt2rsqeZwpPHnS3X00lSfivnCHN+0dzme9q8DxOno4p7xE7033Mvb5eaLYr6sVn6Y71nt8p7rRvC/3LvhdxWvhyeLHX/UfVe9WK3vj6VjX6a0vifP4eTFv4OdvkxxP1t/Lmr547+Wa94mNenKfbUe0R5NmXsuz1z2PGI3q1rTD4vh28HDs+a1r4s28y7sLkaU8+Keq7L6vvsf7XjN4hbN7XjnMmtE/1mtSKUj86L2yT++l9wXu0vY84TWx6+Tws0+ctj7d9jnNm+1sZO3b/AGy+vj1KW7/Oe1K/NwrD9rv7RnEyJX5d0/UTLpKXq+Bl3dZcsR+r9DGMNfblSPy+r11+uvzcOni14iUtM/ho5C/f+tvOKax+dEY4mP23Zdj3evsb7GKMUeBHR+vMR2+Lr496mWfn6za25esz6/PyxHy9HcvEfbqe0L4pdsXb/UbRcspZnCdbXLdHlbC1f9NaVrG9HB2+srKE/HiVI1jWtK1pStK/N9jU8cPEDVtWbcjg24rMT228F8kW7fRbyZsfeJ+n5d/z/VjfqH3Wfsg8/TLTF0by3T85K2rF+n+Vwal8Xm7/AF2Odrjt2ItXv9bMxbtPbvEtovQD3lSlK4Wq7jejEb07tbVvM5ZwDYz1+Hh0pWlLt+nG8vE3WZleY+ZUtQ2dqvn5eqrJ3Ae0f+IxdRcN3me0X29DJNKU+3P1Nema9/T17Rlj1QZ8Wvcr942t/wAG/EqcdafEvrcB1bpV29jYn1mmL8GtfY43XwevaJvfRvHb+tb4u2b2kHaH3Y/RcLpP1W093k2VGFYcK5Dex9Hy+UqxpWXw9Dk5Es67bjL1RpdjapGfolWlKUZ06a8RukuqvLTiuVwzs2j00tia4dvv9PbBa3xJjv8AKe3r9xVT42+xn7QvgD8fZ6/6C5HHwmCbebqXh8eblOnoiJ9PPyuDDGrS81mtpxzeZr5oiZZ0u8IsgAAAAAAAAAAAAAAK+X25X7Id1f8A4ug+z+qQD8bvsgct+wfwGJt0e65/If8Ah5+i5f7777UCxGsQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAftK1jWko1rGUa0rGVK1pWlaV80rStPnStK/OlafOlT5fJ+TETExMRMTExMTHeJifSYmJ9JiY+cJ+XsPO76vcp2marhvI9l9M6hdFLlOHbut67T6Rn6a14v6DOtWJVrc+i4epy9bqZXfM4SyMaVKSjWvopPLwS6u/DJ0pi09jJ5+Q4WfqPP5pjzZMMfXa+Stfn5KYbYsUz6x5q/P6Gpn70H2eI8FvaA3+pOG0p1+kPE2k9ScZGOnfBqclePhctq5MtYin1Rs8hg3d+MflraMWaJ7TEead0rMytQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBZ9vh3l2evfcdjdFOHbemZ0+6IVnrsyuLfpcw9nzidiVvcX7kIVrCOVpL+TstFONZSrStmdJUjKlY0g9479Yxz3UVeF083n4/hJnHfyW70y7s17ZrTEenmwWtlwT8/xM9+0+jaX90/7N+Two8Gs3iZ1Hx863V3ifFdzXjPi8uxo9L1yxbjsVLWiLTg5TFg0uVrPaImMlfLNq9rToNYIWwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO1uhfUbadI+sPTfqTp8quFn8Q5dp9tDKjWsa2seGVGzn/oqSjWlJ4F7Jt1r5pSlJea+aeaV+pwnI5eJ5fjuRw3mmTU28OWLx3iYrFork+Xb547Wj9d0LxR6N0fEHw66z6L5LBGzqdRdPcjx9sExExfNbBbLqekxMT5dvHgv27evl7R6+q0I6Yc91HVLp1wfqRoZ0npedcV0fK9XKM6XKVwd7rsfZYv6ZGkaT/SciH6KlKUr9fiizbjN/FynHaXI4J74d7VwbWKe8T/S8+OuSnrH/BtDRt646U5DoXrHqjovlqzXk+lee5TgN+s1mkxt8VuZtLP9bPea/wBMw29Jme325c6c51YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjB3Vd3nRPs66dZfUXrJyjE1GN6L8NFooX7Nd9yfYWbdJU1+lwJS+Pl3PVO1S/OxavfRoXI3ZwrH5V6z1T1bwvSHHX5HmNqmGva0YMEWr8fZyRHpjw45nzWnvNfNNYt5YmJmJZx8BvZ58TfaM6xwdHeG/B7HI54tityvK2xZI4rg9TJeazt8ntRX4WvTtW84q5L4/jWpNK3ifWIRvfl7Y/uL7vNjueKcX2uT0s6M3L92xhcU0GRes7XcYMZ1+Fd5LtY3I/S70/1cY4mLr6WoVjanG5WNZShX114wdQ9XZM2rrZbcXw02mtNTXtMZc1O/pOzliYm0z84ilcfaO0THpPfZy9lP3cng57POnxvPc5oYeu/EmmLHl2uf5fDiyaHHbU1jz4+F4+aW+p8dfxNp2M+5OS0Tes0iYrGn29evZN25fyL12/fuyrO7evXJ3btydfrlcuTrKc5V+/KVa1r+FiK1rWmbWmbWn1mbTMzM/bmZ9ZWJY8ePDSuLFjpixUiK0x46VpSlY+Va0rEVrEfREREQ8T8eYAAAD6Wp3O30ObZ2Ok2efqc/HnC5ZzNdlXsTItztypKEo3bE4T/AEMqUrSla1p5+89mLNlwXjJhy5MWSsxNb472paJie8TE1mJ9JcLf47j+V1smnyelq7+pmramXW3MGLYw3raO1otjy1tWe8eny7/dbxexf25fcT27bfScS617LJ6ydIoXbGHk2trO5Tl3H8CtY2/iabawrcsTx8Ola5M8K9rMi/leLlmGTalcjOGbeh/G7qHp7Nh1OayW5jiImtLVyzP1Xr09I74csd6zWkfXTScVrW9Yi0TMTFX/ALUnuufB3xi4/k+oPDPSweG/iHbHl2MGTQrWenuX2o81/JyWhaKZaZtj0w12cW7hxYO9MlsN4patpo3bn3LdIO6jpzq+p3RzleByXQZ8IwzLOPfsy2Oj2NLcLl/U7nEtzncwc+xG5bnKxfpC5Kzds3vRSF2KZPTvUnEdUcdi5Ph9rHs4MkRF61tE5MGTtE2xZqxMzTJXvEzW3ae0xPbtMNavxk8FPETwI6z3uh/EfgNvhOW1LWvr5c2HJXT5TTm9qY9/jdi9K029TLNL1jLim1Iy0yY/NNsdnfb7zFAAAAAAAAAAAAACvl9uV+yHdXv4ug/l/wCL+r+r/R9/5/zIB+N32QOW/YP4DE26Pdc/kP8Aw9/Rcv8AfffagWI1iAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADbR7Gvu6udq3d/xO1uc+eN0/6sXbHAOXWPiVjbrd2s62eO5FPNa27dbfIp6qt+5KEq/R4zj5j+qplbwe6tnpbq7UjNkmuhysxobde8xHmyz5de32omNicXmntP1sTCAHvHvZ7r48ezxz9+N1KZuregaZerensvkibxj0KfE5nFPaPPeL8PXfjFSLR2zTW3afWs2Flq7av2rV+zcjds3rcLtq7CtJQuWrkaTt3ISp8pRnGVJRrT5VpWlaLAYmLRFqzExMRMTHrExMd4mJ+mJj1hqE5Md8WS+LJW1MmO9seSlomLUvS01tW0T6xatomJifWJiYeR+vAAAAAAAAAAAAAAAAAAAAAAAAAAAABgV7STuv03aB2qdQ+o2Tl2rfKdtrcjinAcCd2Nm9suTbm3XGpTFlWvqrf1muuZu5pGEZSrHXy80pHzKnRPEbqrD0j0tyHI2vEbWXFbU0Mcz2nJs5o8keXv/XY8c3zdvXvGOfz0rvYw8AuS9ojx66Q6Nw6+S/A8fu4ef6t2645yY9Lg+Nv8eZ2IiPLGLd3KavGzNrVjvtx2mZ7Vmty3+92nJ95uOSbzLu5+53+0z9ztc2/Ks7uXsdnl3c3NyLkq1rWs72Tfu3JfP65VVz58+XZz5tnPecmbYy5M2W9p7zfJlvN72n7s2tM/rtzrieL0eE4vjuG4vXpqcbxOjqcboauKIrj19PRwY9bWw0iIiIriw4qUj7lXyXqfQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWBPsLesWX1X7B+B4W2yq5O56e7XdcNvxrKsq2NRq87IwuPWvFayrGlNbhRpSnnx+h/Q0pT5Unx4H8vfleg9GmW/mzaGXNp2jv3muHFe1NePt/7XSGpH70vw61+gvaw6r2ePwfB43q/Q43qTFPl8sZeQ3tXFs8xfvERE993atMz8/X1mZ9W49mBXGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAws76+9fpz2NdFNn1R5vOGw3GXTI13COJWsq3j7HlO/pbhSzi41JQuzpi493IxrmxyY2LscTGuVvXKUjT59M656047ojhcvKb0xkzX82PS1ItFcm1sdo7Ur6TPlrNqzktFZilZ809oSW9lj2Zusvaj8TNLoXpittPjtecO51P1BkwXzafBcTN7fE2M81tjr8fNTFmpp4bZaW2M9Ix0mbT6V7Xdf3b9X+8LqluepvVbkGRnXcu/O3o9BZuXYaXjWojcnPF1msxJ3btIQtfEncvXpzncvX7l256oQrC1bgB1V1Zy/V/KZuT5XYteb2mMGvEzGHWwxM+TFipMz2iO8zaZmZm0zPft2iNvHwD9n7w79nboXjeiOgeIw6uPXxVvynLZKY7cnzXIWpWufe3titKTa1/LWmPHWtKY8VMde1rxa9sX3WWcQAAAAAAAGaXZJ3w9XeyLqvq+fdP9pfyuP3snGscy4VlX71dRybSUueMvGlajcjDG2FMad76BnUjOmPk1tXb1jJt2/g17l0V1ty/RXK4t/j8tra82rXc0r2n4Ozg79r17d+1cnlmfh3iJ8tu0zFojyzGr2nPZg8Pfad6B3+kurtHFg5fHgz5em+psGLHHI8Jyc0mdfNXJNJtm1JzVx/VerM1nNhi+PHlwXv8SLDftU7n+mvdz0b431h6Y7WznavbWIY+319LsJ53Ht9atW552l2lqPiePl2PiW70IXYW53MS/j5FIUhejWtgfS3U3G9W8PrcxxmWt8WWPLmx+aJvr54iJvhyxHrW8d4tETETNLVt27TDUC8evA7rX2fPEfmvDrrfRyau/wAfltm4/c+HeurzHFZMl66vJ6OS31ubXy+S+K18dr1psYs2GbTbHbtke7GwyAAAAAAAAAAAAr5fblfsh3V75V/UaD+X/gDV/On733vv/Olf4KQD8bvsgct+wfwGJt0e65/If+Hv6Ll/vvvtQLEaxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB7OHmZWvy8XPwr9zGzMHJsZmJk2pem7j5WNdjesX7Uv+bctXYQuQl96UaV+88qXtjvTJS01vS1b0tHzrasxato+7ExEx916djXwbevn1dnFTPrbOHLr7GHJHmx5sGalseXFev00yY7WpaPprMwsXvZO92WH3Z9oPAuQ5WXavc14HhY3AecY0LnxJ42y0dquJq7t+VZVlW/sNFY12xvVl4rW5lSrSnitFhnhT1XTqvpHR2L3id3QpXQ3axPea5MEeTFNvp82TBXHkt3+mzTm9vzwA2PZ/8AaI6r4fBr5MfTPVezn6t6Wz3p5KZ9LlMnx97HiiIisYtPlcu5p44jv2pgrEz379tmLJSEwAAAAAAAAAAAAAAAAAAAAAAAAAAACCz7fLvEt9du5LH6LcR2/wBM4B0SjXX5dMW/SeHsea3cetNtkXYQlKFMrS3svY6OdPVWsa2Z0lSMqVog948dXxzvUdeG1M3n0OFj4d/JbvTJuzH9NtMRMx58FrZME/drPybS/unfZzv4VeC+bxL6h4/6n6t8TrRuYJz4prs6XTOPL/rfhpNoi04OSx4NPlKz27TGSs1maz3nQawQthAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATN/dnt9d2HQLuE0k7nqtcf6h8T+Db8/4L81dVv8AMufLzXx65Q9X1U+rz80xvZtzzk4HqDBM+mvyGp2j7XxcWxef25hrb++w4rHqeLHhDydaeXJy/R/UHxL/AE3+oN/iden0f1sWmPnPz+hJhSSUngAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOOcv5ZoOCcX5BzPlWxx9Rxvi+o2G93m0ypwt4+BqtXi3czOy71ycowjbsY9m5cnWUqUpGNfm4+3t4NHV2NzayVxa2rhyZ8+S0xFaYsVZve8zMxHatYmZ9flD7PT3Act1VzvEdN8DpZuR5rneR1OK4vRwVtfNt7+9npr6uvjrWJta+XNkpSsREzMzHaJVzvtLe9/lXex3E8n5Zd2GTb6b8bzb+h6ccf+NOeNg6TCu3aVzblP0Nu/l5+Vcysj6TC1apXFnjWqQr8L4k68fEjrXa606h2du2S0cdrXtg47B5pmtMFJmPPPyi18lptbzRWv1s1jt6d53HPYq9mHgfZl8HuD4DHqYb9Z8zrYuV605f4Va59rlNnHSY1qfO+LX1MFMGH4NsmSYz0zZPNHn8lddjHqYYADZN2d+yt7ru8qeNt+GcQv8S6fXZUrPqHy3EyMDRXrVK+Jy09ciuJb3d234r67GLmQnSvppWtPVRkbpDwu6q6wmubT1LanHz8+Q26Wx4LR9M4Zt5YzzH01reJj9eEL/aL9vDwE9m+ufjupOocXUHV+OJivR/T+xh2+Vx3mO9a8jGKM9+Mpf8Arcuxr2rMd57eiQb0O92y6H6PX2bvX3qzzLnO3+HSUrfAaYXDddbu1p5rbuWdticpuXoQr4jWUL9v1+K1p6fPyz9wns48Jgx1nnuV3N7N2iZjQ8mnjifX0mMtNqbRHp8rR3VFeKHvovFDlNvJTwm8P+m+l+O801rfq2dnqTctSPTz0ycfs8DTFa3rMRbFfy94ie/b1zAw/YIez6xMCeDLivOMuUo0jTOy+Sa25nQ8f86N23x61a9Vf37NafvO308COgKUmn1Lu3nt2899nHN4+7ExrxHf8+so77PvYPa62Nqu1Xnultetbd/qXX4Tcrq2/wCDal+Yvea/nZIn7roTqp7uN2k8h1OTXpdzbqdwfklyM6Y2RvNvqeQ6CzWtP0FZ6rE0Goy5+JV/ReNlH1RpSlPFfNa/B5T2dulNjFb8C93k9HYnv5bZ82HYwR9r+lU18N57fT/TY7+n57K/QfvlPaC4ffwx1z0x0P1Rw1JrObDxfHchw/LZIifrorv7HLcjr17x8u+lPae8+sT2jRh3b+wz7t+2rX53KuJ41nrnwfBjdv5W14Tqcu3vMHGteq5dv5nGbWXt823i41ilLl/MlfjapCNydaRpbkwh1Z4IdWdN48m1qVrzmljibXy6WG8Z6VjvM2vrRfNeKVj1m82iO3eZ7dlpPs++9G9n3xq3NXgefz5PC3qjatjxYNDqfkMF+L2s2TtTHi1+bvg4/VvsZsvemLWrjtkm1qV7zNoaXcnGyMLIv4mXZuY+Vi3rljIx70K27tm9anWF21dhKlJQuW5xrGca0pWMqVpWnmjDdq2pa1L1mtqzNbVtHaa2ie0xMT6xMT6TCyjDmw7OHFsa+SmbBnx0y4cuO0Xx5cWSsWpkpaszFq3rMWrMT2mJ7vA8XtAbz/YWd6mV279zOD0k5bvL1nph1ryMbj1cPJv1+h63mmV/vPj2Zi25VpG3f2mxua3XZM6+aVx7cKRjGtKyZv8AA/rO3T/UuPidvPMcZzVq6/ktb6zHu2+s170iZ7RbLknHjtP9jEdu301b+9M9mjB4w+CW14g9P8Xjy9c+GWHNzEbGHF/qjd6awR9U8xr571ibXxaGnTd3MFIiJ+Ne0zMxPZPIjKM4xlGtJRlSkoypXzSUa080rSv36VpWlaV/AnTE947x8p9YaqExNZmtomJiZiYn0mJie0xMfRMT6S/R+AAAAAAAAAAANWvdz7IPtJ7zeotOqfVCHULRcwuYdrD2GdwLkWp0kNtGxSUbN7ZW9lxzdyvX7dusLMZ2p2Y/DtWqVjWsayrjDqzwk6T6x5D8FOTjkMG5NIpkyaGxiwRm8veItkjLrZ+9ojtHeJr6Vj09E6vZ894d7QXs29HT0J0NbpDlenKbOTZ1NXqzhuQ5O/H2y+WcmPSvpczxcY8V7xbJat6ZJ8+S8xaImIjFL87i9g/7ZO4X8vuLf7P3Vf53boP+2eof3fqf6OZ7/oyntYflL4Qf3p89/wA7j87i9g/7ZO4X8vuLf7Pz+d26D/tnqH936n+jj+jKe1h+UvhB/enz3/O4/O4vYP8Atk7hfy+4t/s/P53boP8AtnqH936n+jj+jKe1h+UvhB/enz3/ADuPzuL2D/tk7hfy+4t/s/P53boP+2eof3fqf6OP6Mp7WH5S+EH96fPf87j87i9g/wC2TuF/L7i3+z8/ndug/wC2eof3fqf6OP6Mp7WH5S+EH96fPf8AO4/O4vYP+2TuF/L7i3+z8/ndug/7Z6h/d+p/o4/oyntYflL4Qf3p89/zuPzuL2D/ALZO4X8vuLf7Pz+d26D/ALZ6h/d+p/o4/oyntYflL4Qf3p89/wA7j87i9g/7ZO4X8vuLf7Pz+d26D/tnqH936n+jj+jKe1h+UvhB/enz3/O4/O4vYP8Atk7hfy+4t/s/P53boP8AtnqH936n+jj+jKe1h+UvhB/enz3/ADuPzuL2D/tk7hfy+4t/s/P53boP+2eof3fqf6OP6Mp7WH5S+EH96fPf87j87i9g/wC2TuF/L7i3+z8/ndug/wC2eof3fqf6OP6Mp7WH5S+EH96fPf8AO4/O4vYP+2TuF/L7i3+z8/ndug/7Z6h/d+p/o4/oyntYflL4Qf3p89/zuPzuL2D/ALZO4X8vuLf7Pz+d26D/ALZ6h/d+p/o4/oyntYflL4Qf3p89/wA7j87i9g/7ZO4X8vuLf7Pz+d26D/tnqH936n+jj+jKe1h+UvhB/enz3/O4/O4vYP8Atk7hfy+4t/s/P53boP8AtnqH936n+jj+jKe1h+UvhB/enz3/ADuPzuL2D/tk7hfy+4t/s/P53boP+2eof3fqf6OP6Mp7WH5S+EH96fPf87j87i9g/wC2TuF/L7i3+z8/ndug/wC2eof3fqf6OP6Mp7WH5S+EH96fPf8AO4/O4vYP+2TuF/L7i3+z8/ndug/7Z6h/d+p/o4/oyntYflL4Qf3p89/zuPzuL2D/ALZO4X8vuLf7Pz+d26D/ALZ6h/d+p/o4/oyntYflL4Qf3p89/wA7ken2vPs2tB2C9ROFXumOVyjb9IefauX5k7PleZi7HaYPI8SeVTN0uTsMLXazFyLv0XE/NGFYYlmULGTbhKEqwrcnH7xa8OcHQfIaVuMvtZuI38U/Cy7d65MuPYpN/Phvkx4sVLT5afEjtSsxW0R2ntMre/d6e2hy3tY9H9TYuuMHBcd4h9J78fV+jwGtn09Ha4bYprzrcng1Nrc3s+Gn1RnnTvFtjLFsuG94tWLRSunRiFYwAAAAAAAAAAAAAAAAAA3w+wT7vI9Be5+fSPk+yjjcE64Y8tNSuVf+Hh6zleNY+lavOjGVYwrlbKevxNJb8ypWv0qMY0rKtI1zn4E9WxwXU08TtZPLo83WcP11u1MW3WPNiv2mYjz5ZpXDH3bdvWfSaqvevez1bxW8Da+IPCaU5+qvC/NHJTGDF59ne4DNk+BvatpiJtGDSrt7HJ37R2j4EzPaImYnbpytVwAAAAAAAAAAAAAAAAAAAAAAAAAABhT7QTuf0faX2s9TuqWxyrdrdR0eTouH4Vb0bWTsOSbqkNbiUwo18zu3tfDKubadu3GUvgYN2VfTGNZR6Z1/1Ng6T6X5PlMl4jN8C2DTp5orfJs5u2Onk795mccWnLMRHfy0n5fNJj2RvA7lPaA8duiOhNPBe/GW5XBynUez8OcmDT4XjZtu7E7Mx9bTHuW16cfW15iPi7VI9ZmKzWscl5DtuW8i3vKd9lXM7d8j3Gy3u2zLspSnk7LbZl7Pzb8qyrKvm7k5F2fita+PV4+8rg2djLt7Gfaz3nJn2c2TPmvPzvly3tkvafz7WmW6bwvEcf0/w/FcFxWCurxnDcdpcVx+tSIiuDS4/Wx6mriiIiI+sw4qV79o79u74j0vpgAAAAAAAAAAAAAAAAAAO2+l3QXrT1tycjD6RdLucdSMrDrGmXY4bx3Zb65jVnWlI/Hhr7F6tvzWVPHqpTz5p+F9bjOC5nmrWpxHF73I3p+Krp6+TPNe/wBuMdZ7frsf9c+K3hr4ZYcOz4hdddL9GYNiLTgy9SczpcTTNFYmZ+Hbby4ov2iJ+Xf5SzL0PsjPaC7/AF9dha7c+cayFI0l9F3mp2Wpzq0rTz4piZWDG75p9VaePlX5fW7jg8Juv8+P4kdO7uKP7DPiyYcn/wDZanf/AN6N/Le8H9kXidv6kyeMnS29bvMfH4vkNPkNX0nt3+qMGzNO0/OJ+mImXDeV+zC79eH2pZGw7XurmdjW/VW9k6Xhm+2tixCNK1ldvXcfA9Nu1Tx/hJVpHzWlPPzcPa8M+u9SJtk6Y5a9Y+dsOnny1rH27TXH2iPuz9t2PgPbh9lDqLJXDp+Ofh7q5r9ox4eT6l4rQy5bWmIimKmbbib39fxMevaJ+0wj3/Ht5xXcZ/H+S6nP0W81eRcxNjqdpjXcPPwcqzOVu7Yysa9GF2zdtzjKM4TjSUZUrStHStjXz6ubJr7OLJgz4rTTJiy1mmSlqzMTW1Z7TExMTExKTnE8vxfPcdqcvwvIanKcXvYabGnv6OfHs6m1gy1i+PLgz4ptTJjvW0WraszExMTD470vogAAAAAAAAAAAAAAAAAJjPux1fPR7ulp4p8uonT35/fr549yKvz/ANCX3s0/jR1R+mHH/wAX2Gub77yP+qL4FfP16P6v+/HD/JJ/SaUcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI6HvC/dxPpb0I4/268U2s8Tl3V3I+nckpjXa2svC4Xg5FulIy9MvM8XfXLOz1t+Mo0jK3anGkq1rWlI8e0D1ZPGcFr9PauWabfLW8+z5Z7XppUtHb8+uea5cVvT5RPaVx3ug/Z9r114qcv4xc/oV2On/D3F9S8N8fHGTX2updvDeZmO8dq5+Kpl0d3FaJmYteveEJb6/rQubNQACUn7I72LeB1C1nGO5fuk12Rc4tmVs7bgvS/LxZ4c9rbx7nqsbfkcr9J3Luvv34emxr7VnEu1hYle+lzhkQjbk94TeDWPkMWr1L1PjtOrfy5tHjL18k5YrPeMuz5u8zjtaO1ccVpPasz5pi0RFFnvBveVbXSG9zfgp4FbmGnPa0ZdDqnrnBnrs10L5aeXJx/C1xTSlNzFjt3y7eTJsUi+SMfwK2w2m8vDSaLTca1eHpeP6vB02p1+PaxcLX67GtYuLjWLFuNq1bt2rUYxpSEIxj5r5lXx5lWtfNUtcGDDrYqYdfFTDix1itMeOsVrWtY7RERH2ojt9tr08nynJc1vbPJ8tvbXI8ht5cmfZ3NzNfPnzZct5ve98mSZmZta0z2jtWO/aIiPR9V7XAAAfxdtW71udq9bhdtXIyhctXYRuW7kJUrSUJwlSsZRlStaSjKlaVpWtK08PyYiYmJiJiY7TEx3iY+1MT6TDype+O9cmO9seSlotS9LTW9LRPeLVtWYmton1iYmJifkj8+1M9jHwfuP1O/609vutxOGdasHCy9nt9DgYkJajqBLDszvxsQwrPwJ4u/yoQ+h2ci3euWbtaYsKYUrkJyu4D8UPBzS6ixZ+Z4DHXT5qlL5c2DHSJw8hNIm0VikeWaZ7RHki0TMT9ZHk7xPe2/2E/eSdUeDPIcT4aeLm7sdSeGe1s6+jx3K7exaOR6RjZy1xTlts5Pi1z8TgtaNjJhvjpkxxOe07UUtWMcIrkfHtxxPfbfjPIMHI1m70WwytXtMDKtzs5GJm4d2Vm/Zu250jOMozjXxSVKVrStK+PmhVsa+bVz5tbYpbFnwZLYsuO0TFqXpMxasxPaYmJj6YbOvD8vx3P8AFcfzfEbWLd4zldTBvaO3gvXJi2NbYxxkxZKXrM1tE1tHymYiYmPofFel9J7+q2mw0ez1+51OXewNpqs3G2OuzsefoyMPNw70MjFybM6fOF2zetwuW5felGlXsxZcmDLjzYb2x5cV65MeSs9rUvSYtW1Z+ia2iJiftw4m/o6nJ6W3x3Ia+Pb0d/Wz6e5q5q+fFsauzjthz4MtZ/FY8uO9qXr9NbTCx79mD3a6ru+7TeA84pmWb3MeM4drhfUDDt3KTlgck01i16IXK1lKdZ5OnvarOuSl483MqXilKeKLE/DLqvF1b0pobvnrbc1qV09+kT3mmzhrHaJ9e/e2G2K8z9u0tNL24vZ+3/Z48f8AqzpedbJj6c5vYv1L0js3rNa7fC8llyea1I8sViuDkcW/q0iO/amCvf1bDmQUPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGuP2pnaXhd3XaR1A4fj4kLnM+J67K5twfLpbpcyrO149bjtsjAxaUp663d3h4FzUUjGta1rl/oYyr4jXHfih0nTq3pPf060idzUx23dG/bveMuvEZbY6fT5s9Mc4Y/R/KUyvYT9oDZ9nr2g+keo82xanTXP7mDpjqjXm80wZOP5e86GHb2J7+WMfF7O3TkJm3pH1P6zWO8xXI7PW5un2Ww1GxsTxdhqs7L1ufjXI1jcx83ByLmLlWLkZUpKM7N+1ctzjWlK0lGtK0pX5K7suO+HLkw5KzXJivfHkrPzrelpras/di0TE/nNyTR3NbkdLT5DTy1z6e/q6+5qZ6TE0za21ipnwZaTHeJrkxXpesxMxMTEw9F4OUAAAAAAAAAAAAAAAAA+5xjkW24hyPQ8r0OTLD3XG9xrd7qcqFZUrY2OpzLOfh3f0MoyrSGRYtylGkqeqNKxrXxV79bYy6mxg2sFvJm1s2PPivH9bkxXi9J9Jj5WrHeO/rHo+XzfD8f1Dw3K8DyuCuzxnNcdu8VyGvaImM2nyGtk1NnH9dFoibYct4ie0+WZie3ossuwXuX03df2tdLOrGvyoXtrmcexNPyvHrdjPKxuS6KktPtrmVbp4nZrsMvAvbHHhcp6q42Tal6p0rScrIOg+pcPVXS/F8rjvE5b69cO1XvE2rs4O+HLN4j1r8S+O2SsT/W2ifWPWdKv2sfBPkvAPx2676A28Fsehr8xscjwGX4c0wZuE5Wa8jx9MF/xOWNTX2senlvSe0ZsF47VmJrGZTuKN4AAAAAAAAAAAAAAAAAAAAAAAAACEr7wr3fQ6rddeP9uXEttTJ4f0etWdjySOLf8Ai4ufzfZYEpxnG5alS1Wur1+0ydXlWJ0uSt5dmfqlCUPRSFvtAdXfgrzmv07qZfNp8REZNmK271ybuXH37xMen9Kx5LYrV9Zi8T3mO0Q2bPdC+zxboLws5fxl6g0Jw9ReI2TJp8LOfF8PY1Ol9Lbis0tS9ZvEb+5o4d7BlrNK318le0WrbzI6KPK4wAAAAAAAAAAAAAAAAAABtZ9kd2J/7tjuPwsPlWHfudJenVqPJ+fTpCsLW0s2btjHwuPWsqcZWYZOZmZmJk3rNYXLtzXY+XS3GFa0vW8p+E/Q34dOoqU2qWnieOj6q357doy1rNa014vMTEWve9LTHaZnHW/aI+cQL94L7U/87L4M7WzwWxip4gdY5LcF0lWbRbJoZcmPLm2uYyYKzXJbDra2tsYceSLUpTcy682taP6Xef70+6TdNOlGiweM9OeEcc4fo9bZjj4WBpdbYxo2bMKUpCHxqxnk3KRpSlKVu3rkvl9aevH8TxvFYKa3HaOtp4McRWmPDirWKxHyjv2m09vo72lqVdX9f9a9fcrtc31l1PzPUfKbuS2bZ2+T3cua2XJaZm1vhxNcNJmZnvGPHSPuOwn0HUH8yjGcawnGM4Sp4lGVKSjKn4KxrStK0/erQmIn0mO8fal+1tasxatpraJ7xaszExP24mO0xP5zQ97aT2bvFe4vorvet/TTjOHrutXTPAnur89Th27NzmHGsS38PY6zLtY8IecnEsSjs45dKSr8HXTtztylc+LHBfjL4c6vUXC5+b4zVpj5rjMc5pnFSKzt61I7ZMV4rEfXUr/TYv6+mOYmPXvFq3u1fbO57wc8S+L8MOteb2dzwz63268birv7N8lOneb2LxfS3te+W1u2HYy1tpW1+9Y+JuUvW0RTyWglyjKMqxlSsZRrWkqVp4rStK+K0rT8NKoNtqCJiYiYnvExExMfKYn1if134P0AAAAAAAAAAAAAAAABMR92J/Wm7rfnX9cTpv4p+D/i3yP6v9PyS89mf8auqv0w43+LbLXT99//AFf+Af6j+s/v1wyUOk4ozAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAV2Hti+vOd1277OrOVXNrmcf4BlYvAuKeLnrt29PrbNNjcjTxKsPVTabTY0lWlKV+VKV+pXt4v87fneueWv5/Pr6F66Gr694jDij4kx+fGXLk/wNw73c3hTq+Ffsr9AYI1o1+X6twZ+rOfiaRW9uS3sk6dJme3mms6GjpzETM/TMfNq2YwTqAbdPY29k+H3hd0WFPl+v+ndL+lVrC5fzOxdtVnjbK5G/euaXT3q/KlcfY52D9FzIU8T+j3q+mUK1pVlnwf6Lp1f1PSdvH5+M4qKbe5WY+tyT5rThw2n+xyXp5b9vXtP0K+PeO+0zsezr4GbNentuNbrnr2+10901lpkiubSpOLHTk+Rxx6zGbT1dr4+vafrfi447xaImFgtq9ZgaXXYOo1WJZwdbrMTHwcDDxoRtWMbExbUbNizatxpSMYW7cIxpSlPvea+a1rVPvFix4cePDipWmPFSuPHSsdq1pSIrWsRHyiIiIajG9u7fJbm1yG/sZdrd3djLtbWzmtN8ufYz3tky5clp9Zte9ptP5/aO0ej3nscUAAAABD794W7GNJwvZaDu66c6SxrMDk2Za4/1RxdfjVt40d3O/Czq+R5EofpcL+0rmYerrCkYUlXBpPzKUq0RF9oDofBpZdfq3jsFcePZvGvylMdZisZ5tFcWzbt6RbL56YpjtEfWR27zMtiP3QntScn1Lpct7PXWPJ5d3b4TWycv0Ln288Xz24umK2Te4bDFvr7Y9H6n2d6Lea0/wCqZr2iKwi1owr1QEhb3enukj0r7lN70L5HtPo3Fesurn+ZMMq9S3hYXLNRj38mzct0lWkPpm5pZwNXbpWvquVjbhClZeKVkB7P/VH4F9SZ+D2Mvl1eYxT8KLW7Upt4azasxEzEefN5aYo+me0RHdUJ73vwKnrzwW4vxT4bRnNz3htvV/BC2DHN9nZ6f5HNiw5a37RNvqbjZy7W/efxNIm9rdo7ynBJsNYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+SjGcZQnGkoypWMoypSUZRlTxWMqV80rStK1pWlaVpWlfFSYiYmJjvE+kxPymPtS/YmazFqzMWiYmJiZiYmJ7xMTHrExPrEx6xKAF7bjs6udsXdjuOW8f19Mbpz1qpLmnHaY9qv0fW7O9WeLvNXfvx/Sq5mRtcHY7elqkbc442ZarWFY+JygT41dIT0z1Xm29fH5OO5r/AFZrRWPrceWe9c+O1o9PPbLTJl7domK3j5/OdtX3Y/tGU8cPAHjun+X25zdZeGcx01zE5rx8bd0cflz8XvYsU/X/AFNh0NrT4+cne9Zza1480T9bGmVh1ZEAAAAAAAAAAAAAAAAAAkue7rd29OCdW+W9r/Kdp8PRdULF/f8ACrF+96YWuX6nChfzbMKzlWEbN3R6vLlG1CMZTyZ+r1SrL01kj7PXVkaHLbfTG1l7YOTrbY0q2t6RuYqRa8R3ntEWwY7z2j1m3y+faaU/fEez7PVXh90/45cFo+flehsuLiOpsuLH3tk6d5DZti1clvLEWnLj5Te14tktNorgr5fLHbvEzxMdrZgAAAAAAAAAAAAAAAAAAAAAAAAMV+9TuL0Hax219U+sW7y7WPkce43l2eP49b0LeTm8i2krWp09vEty8yyJY2dnWM2/at0rKmLj35+YxjWcerdZ9RYOl+m+U5jPeK219a8a9e/a19jL2xYYpHztNcmSt7RHr5a2nvHzZ49mnwc5bx38auhPDnjNe+XDzHNYMnL5vh2vh1uG0a33+RvsXjtXFXNq6uXWxXvMV+PmxV7WmYras651zLedROZ8q53ybLnnb/l/INxyTb5M5Tl8TYbrYZGyy/R65TlG1S/kzpat+qtLdukYUr4pRW1vbmfkNza3tm83z7mxm2c1pmZ75M2S2S/zmZ7ea09o7+kejdi6W6c4vo/pvgeleE166vE9O8Rx3C8dgrFY8mnxmph09eLeWtYtecWGs3v5Y815m0x3lxRxX3gAAAAAAAAAAAAAAAAAHtYWHk7HNxNfhWZ5GZn5WPh4mPbjWVy/k5V2FixZtxp5rKd27OEIxpStaylSlPm8qUtkvTHSJte9q0pWPWbWtMVrER9uZmIh6NnZwaetsbezkrh1tXBl2djNeYrTFgwY7ZcuS9p9IrTHW1rTPpERMysOvZBdm1ntD7TOK4u6wrVvqP1OxsLnfNsr4VLeRD817Mtho9RfhKlbti/ptXn2ddl2pz81ycaUpW7cqeiNgnhH0fHSXSmrXNSI5Hk603t23btaPjV+JhxWj51thxXrjvE/11Z7xHyjUA94f7R2T2hvH/nc/GbOS/RnQ+bZ6V6Yweeb4bfgfljU5TkMVomMeXFyW/q5NzXyVr6YM0RF7xPnttUZSQNAAensMDE2uBnazPswyMHY4mTg5mPcpSUL+Ll2Z2Mi1OlflWNy1cnCVPv0rV4ZMdMuO+LJWLUyUtS9Z+Vq3ia2ifz4mYcjU2tjR29bd1clsO1p7GHa1s1J7WxZ9fJXLhyVn6LUyUraPuwravaadvde2jvR60dObGPTG1GRyO/zHQWLcaRsY2j5pOfI9Xg2PFKR+HgYOxx8WkafqPh0jX5q5fErp/8AC11lzPHVr5cNti25rxH4muDdmdnFSv3MdMlaRH0duzdB9iXxejxs9mvw16yy5pz8hh4bF05y+W9u+bPynTVa8Lv7WXvMz59va08ueZn8V55mPT1YEOiJXgAAAAAAAAAAAAAAAAJh/uxNf+Sfuup5+f3Q+m9fH3//ALG+RfNLz2Z/xq6q/TDjf4tstdP33/8AV94Bz9H4T+tPv1wyUSk4ozAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcU51yW1wzhfK+W3/TWzxrj+23l2k/1Fbeswr2ZOkvnT9DWNqvn50+X33F3tmNPT2tu3by62vlzz3+XbFSbz3+52h97pbhMnUnUnA9P4ptGXmuX4/i8c1/Fefe2sevXy/d75PT7qrP6qbvJ5J1N6g7/AC8i5lZG25pybOnfuS9U5xv7jMna8y+/SFqsIR/BGNKfeVgcpnts8lyGe9ptbLubN5tPzmLZrzH7Udo/Wb1/QnF4eF6J6R4nXxUwYuP6b4XVripHatZxcdr1v2j7dskWtP3ZmXAnAdrAT0/YGdBdX0u7JdJ1Drrvh7/rPuNhy2/s70Y/SL2osVsaXDwrc6QhKmHZytPlX7duVZ+L169Ok60n4pOvwH4LFxfReHkPh9tjmc2TbtltH11sNfLhpSJ7R9ZW2G1oj19bWnv2mO2qR72LxX3uuvab5Po/6s8/E+GvHanT+LSx2t8DHyGWMvJbGzes2tE7OTByGDFe9fLE48eOvl+t7zvFZtVfAAAAAAMVe9votpev3a11p6a7jAjsJ7XgnIsvSWq0jWVnkut1OZl8fyYVlCfiWPtLeNdp4pStawpSlafXTq3WnDYee6X5njctIyTl0di+GPT02ceK99e0d4n1rlilvu9uzPPsyeJXJeEvjr4ada8dtzp10Oq+G1+Tv3tFcnC7vIa+vy+C3a1e9c2jfNjnvPb671iY9FZLvNXd0m73Glv0rS/qNpsNXepX66XcDLvYlylf3/Xal5Vq58U4M2bDb8Vhy5MU/n47zSf34buPF72Pk+M47ksX+1cho6m9i/8A5e3r49in/i5IfLepznOemXP970q6hcL6j8ZyJ42+4RybS8n1d2EpR/37pNjj7HHhOsZRrW1O7jQjcj5pSUK1pX5Vc7jN/PxfIafI61prn0tnDs4piZj6/DkrkrE9u3pM1jvH0w6v1t0lxXXnSHUvRnN4q5uK6n4Tk+D36WrW0/U3J6ebTzWp5omIvXHmtNLdu9bREx8k3/iPvB/YNXiPGpcq5F1LxuVfmHrI8ixMfpvusvHs7mGHZhsaWMy3KNvItSy43Z25wjSlYypSnnx5rNbU8f8AoP6k1vqrY5Ku18DFGxSvHZrVjNFKxk8t4ntaPN3nvH0fbawnUPuifaxjqHmq8Dw/ROfgfwU3rcPsZus+N18uTjbbOS2n8XWvWb4cldeaVtS094tWfl37R9e57wp7PKP6je9T7n8PTjdQ/wBPl7p9oDw+j5Z+Tn/vdmh86vuhva/n8VxXQ1P/AOs+Nt/g7PSue8Nez+j+o2HU65/DwLbQ/wBNurwn2gegfoycnP8A3Blj/E5VPdA+1vP4vU6Hp/8A1Zx9v8Foelc94g7Co1/S59TLlPw/3GbOH8vzsVq8J9oPoT17TyU/a/1Hljv/AOK5FPc++1dP4uvRNP8A+pdK3+DLH6/+N6dz3ibsWj/g8XqVc/8A8V2EP9OJV4T7QnQ8fKvJT/3Lkj/9Dk09zx7Us/i8/RVP+/2pb/Bnj/p9t6dz3i3sij/g9R1Jufw8fzYf6cGrwn2huio+WHkZ/wC57x/7P/p9tyae509p2fxfI9F0/wC++tb/AAbMf9PtvSue8Z9l0fPw+N9R7n8OpyYef59dX/v/ADvCfaH6N+jW5Gf2K0f+zcmnub/aUn8XzXRlP++GG3+Dcj/p9t6c/eOezuP6jh3UWf8ADh3of6dVX/v+B4T7RPSEfLT5Gf8A7Ex/7Jya+5r9oufxXUfRtP8AunHb9b03oelc94/7R4/4PgPUS5/+hOH+nT1/7/feE+0V0nHy0OQn9aY/9i5NPcz+0HP4rqzo+n/2q2/wcjD07nvIvanH/B9NOoVz/wDv0h/p0lXhPtGdLR37cbyE/a+u7d//ACEuTT3MXj1P4vrbpCn7FNv8HJw9KfvJna/H9R0m6gz/AP1jbh/p0FXhPtG9M/RxXIT+yRH/ALByae5e8cZ/Fdf9I0/7jvb/AAcrD05+8pdtcf1HRrn9z96u7sQ/08cq8J9o/pyPlw2/P7PWP/2dyae5Z8aJ/F+JHSVPzuMy2/wcxD0p+8sdvEf1HQzntz+HkuLD/Txmrwn2kOnvo4Pfn/umsf8A7M5FPcq+ME/i/FLpOn/eXYt/g5uHpT95f6CR8+jt/wCeXPwf8b8GHn+fi1fDwn2kuC+jgN6f+66R/wDsrlU9yh4rz28/i30pT7f+x7at2/a52O//AE/X9O57zL0Qj+o7cudXP4ec66H+niVf+/8An8J9pPhI+XTu9P8A3djj/wDZHJp7kzxOn8X4y9LU/O6W3Lf4OoIenP3mvo5Hz6O2XnFz8H/KFq4ef5+H18PCfaV4ePl01vT/AN8MUf8A7G5FfckeI09vN43dL1+326Q37dv/AMRR3elc95x6UR/wfaxze5/D1M1EP9PC6/vf96fPwn2luKjv26X3Z/75YY7/APmbk09yH17P4vx36Yp+d0TyNv8AB1JH/T970bnvPHTaMvFvtJ5rcj4/VfdX0cPn5+rxXhFf4freE+0xxv0dJ7s/99cEf/sTlU9x91nMd7+0F0zSftR0Dylv1+8dTw9a77zzwCsafB7R+Ywl8/NbnVfSTp+94pHhMa/h+/8AyPC3tMaH9b0nuR+fyuCf2u2k91Pce9WRP9M9oPpy0fap0BydZ/bnqe3+B8657zrxSv8Agu1Hk0P3p9TtRP8A0cQi9c+0vq/R0rs/r8nh/wAWm5lPcgc/Hb4nj7wtvt+XofkK/wCHqGXo3fectLXz8LtZ3cfwevqNrJfw+fHF6f6XhPtLYfo6XzR6fTyOOfX9zOVT3IfJR/tnjvxlvt+Xo3dr+135yf33oXPebseta/C7YdjD8Hr59gS/n8cej/3r+89c+0rX6Omckfn7+Of/ANnhy6e5FzR/tnjjqW/Q9J7Vf8PMW9Ho3Pea8mvn4XbTehX73r5riz/0aWLwn2lbfR03P6+7X/M/9PtOVT3JGCP9s8a8dv0PTOev+Hk5/wAP6z0LnvM+7r5+F2424fX49fLbE/4Pq1cXrn2lM/0dOx+vt1n/AAYocqnuSuMjt8TxlyWn6fL0/kr3+3896XoXfeZOWV8/B7ecCP4PXySMq/5sKNK/zfe/f+XhPtJ7f0dP44/P2e//AOiHLp7k3p+PxfjBt2/Q8LNf8OzPb996Nz3mHn1f8F0B0sf4+8lKv+a1H+j/ADvXPtJb/wBHA4f18/8AyVcqnuT+k4/F+LXJ2/Q8XWvf9vJbt+1L0LnvLvVCvn4XQrjcfwevZ3peP5qx/wC/4PqeE+0jyfb63g9bv93Lb/lcunuUuho/2zxU5q36HRxV/wAMS9C57y11hr/guiPEY/x8vKnT/wDZyIV/B+H771z7SHMfRwupH59rT/8Aqhyqe5U8Oo/2zxO6it+h19evp+vht/gejc95W65Vr+ldGeDR/enPOl4/yc+Pn/M8J9pDm/o4bR+53nJP+DJDlU9yv4XR+L8SOqbfb8tdWv7XfVn1ehc95S7hK/4LpF08j/Hs7KX+am1p5/no9c+0f1B/W8Tx/wCvGT/Fl9f3nLp7lnwhjt8TxD6wn7flyaUd/wBvQns9G57yf3K1/wAF0q6ZQ/B6sHbS/n8byLwn2jupPo4rjI/Px5p/9vDlU9y54KR2+J171xb7fl2uPr+134uWSXZ77wD1c6y9wfTzpX1O6Y8Oscc57vsHjVvN4vazsDY4Gw2t+GHg5Mp5mw2Vu/YhlXrNb1qNm3Ktuk/FyPmkqdi6Q8e+X5jqDj+L5PjNONff2MetF9WL0yY8mWfJS0ze+SLVi9q94isT27+sfNhf2ivdJ+Hvhv4Q9Ydd9D9b9SZeZ6U4na5u+tzl9Tb09vU0MVtnaw1rr6mlfHltgxZIx3nJeIvNe9Ldu0yu0qVB7VF7YntBt92HaHy2GmwrV7qD0rsZXUDh+TKFJXKWtNajm8jwoxpSN29cztBi5+LiWYXI/wC+r8JUjcrX0SxV4v8ASMdV9JbcYaRPIcXW3Iadu3ee2GPPsU+3M3165K1iJ/FWj85Pn3c/tEX8AfaG6ftyWzkx9IdeZcHSPUeCLTWk35LJOtw21a0zOPFTV5bPqZ9jJak/0jHaJtSI80V5WTj38TIv4mTanYycW9dx8izdjWFyzfsTlau2rkJUpKM7dyMoTjKlKxlStK0pWiv21bUtatomtqzNbVmO01tE9piY+iYmJiY+22+8ObFsYcWxgyVy4c+OmbDlpaLUyYstYvjyUtHeLVvS0WraJmJiYmPR4X49gAAAAAAAAAAAAAAAADsTpJ1J3/R/qZwfqbxjKv4m54TybT8hxZ2LlbU78dbnWcnIwpzj86WM/Ht3cPIpStPVZvzj5p58vocTyWxxHJaXJ61rUzaWzh2KTWe02+Hkra1Jn+xyViaW+3W0un+IHRfE+InRPVHRHOYMWxxvU3CcjxGeuakZK4p3dXLhw7Naz6Tl1M16bOKfoy4qT2nss3e2Trdx/uM6EdM+snG8qzl4HNeL6/PyZ2JUlasbqzaph7/ChWkpfLB3WPnYnzrWX6T8/n5WWdNc1r9RcFxvMa163x7utjyWmvyrmrHk2KR6z+IzVvT7cdu0+rSM8bvDDl/BvxV638OOa18mvtdM87uamCuWJi+XjMl52eJ2bRMV/wDjXG5tXY9I7dsnp6O933GKgAAAAAAAAAAAAAAAAAAAAAAAENP3iru9jzTqbxHtX4lta3NJ05jjcn51DGveq1k8o2etnc1uLKVuVITs42p20fjWJ0nWGZZpWtYyh6aQ89oXq6N3k9TpbUy98HHRXa3orPpbay45nFWe09piuHLHeJjvF6/P6I2Qfc7ezxPTXRHUHjx1BoRTlOsrZ+D6WtnxdsmHgtHdrTdz1i8TauTNyHHz8LJXyxbWyTHaYt3mMmjUu3AAAAAAAAAAAAAAAAAAAbkvYqdl1zup7p9Rynkmurk9MejNy1y/k1b1qtcTZ7SxK3Y0ukjflStqOXTNzcXbxt1pclOxr7vi36fM45g8GejZ6p6ow7Wzj83GcNMbe13j63LlrMVw4Yt8ov571zRHrM1xz6du8q4veX+0rj8B/AjkOB4bcjD1x4k1v07wcY8kRsaOjlrky8nydsUT57a862tn46bxNa1y7lO9u/atrASEIW4Rt24xhCEaQhCFKRjCMaeIxjGlKUjGNKUpSlKUpSlPFE94iIiIiIiIjtER6RER8oiPoiGpLa1r2te9pta0za1rTNrWtae82tM95mZmZmZmZmZnvL+n6/AAAEJD3kTieJpu7Lpxyeza9GVzLpzK7mXfFKfGroZanU2PnSlK1+HajSPzrXx9VPFELPaM1K4eq+O2ojtbc46ZvP25wTixV/aj0bOHuZOf2OS8Aes+DyZPNg6c6yimtTv3+HHK15Dfyx2+jz5J8376Osj0uIAAAAAAAAAAAAAAAAATCfdipR+5d3WR8V9Vef8ATmVK+fl4pxzkNK08ePr81p8/P8iXfs0dvwM6pj6fq/jv2vqfY+hrr++/ifw9eAlvTt+FPrKPu9/wY4iY/W7RP0JR6Tqi8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB0J3UXL1rtq693cenm/b6RdQJ2afOnm5HjOyrCny+f6qlHweqZtHTfPTX8VHE7817enr9TZO377LHgRTHk8avCimX0xX8Qukq5J+1Seb0ot+93Ve+9rKW73Mp/q67XY1l/Grl3qy/wA/lWVnmZz5pn5zlyTP5/ns3kuLiteM46K/iY0NSK/oY18cR+92fKepzgFmX7PHU4uj7KO3PV4cLdvGxenmJ8OFqlKW6fH2OxyJ+mlPl853pVr9/wA1r5+aybw+xUwdF9O4scRFK8fTtEfL67JktP78y0mfbA38/Ke0z4yb2xa982fq/P57Xnvefhaenhr37/apjrEfciGZruSNoAAAAADx3bVu/auWb0I3LV2Erdy3KnmM4TpWMoSp9+Mo1rStPv0q/JiLRNbRExMTExPymJ+cPOl74r0yY7TTJjtW9L1ntat6zFq2ifomJiJj7qrL7g9da1XXTq/r7Hp+Fj9R+Y0h6P1NI3N7m3fEfnX5R+JWn1/eVf8AUGOMXOcvjjt2ryO3Edvl657z6ftt7Hwi3Mm/4W+He3l7/EzdGdOTbzfipmvFatO8/dmK9/13T75DIgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADL/ALBP8cnty/Gzwn7Q6927oL+rHpz9NtH+MY0efaxjv7OPjJ/xf9Tz+1xG3KzZWVNI14sixZyrF7FybUL+Pk2rli/ZuRpO3es3oSt3bVyNflKFyEpQnGvyrGtaV+VX5atbVtW0RatomtqzHeJrMdpiY+mJie0w9mLLkwZcefDe2LNhyUy4slJmt8eTHaL0vS0etbUtEWrMesTETCvB9sD2gZXab3dcvs6zBljdPuqN27z/AIPcpD9BHH2l2cdzjXLkaRt0uw5DZ28rVqMYVhi/C+UqU9cq+vFzpG3SnVu3XHjmvH8nNt/Rnt6eXLP9Or37RHeNiM3asdu1e357cC93d7RGDx+9nvp7Lu7UZuruhcePpLqik2+vtm0cdbcbnrS0zeaW4fJx0ZMk2tFs/wAT1ifrY1VMWp5AAAAAAAAAAAAAAAAAAJa/u43dvW/jc87TeW7b1XMet3mfTi3l3vFfgS+FXb6HXwnKnqrSddnu7sYeZUp8SXppGla0ld7O3Vneu/0pt5e8177nHRaf630+LgxxM+vafi55iPWI7z27R6a/fvlPZ9jFm6U8f+n+P7UzRj6a6zvr4vT4sfE/A/lty9Y+t71jS4ylrdomfJHmmZiEsFKpQWAAAAAAAAAAAAAAAAAAAAAAAx/7puuvH+2zoD1P6zcky7WJhcL4xmZmLK7KkaXtxl1t63R49KVrSsqXtxm4NudI18+iUq0rT63wOqOc1+m+B5Pmdm8Uppat707zH12a3bHgr27x375r0ie30T+uy34E+FnL+NHiz0P4bcLr32NnqXnNbW2IpEzOPjteL7vKZu8RPacfHa21esz6easd+/yVlPVjqTyLrB1J5t1N5Vl3sze825LueRZs71yVytiW12GRm28O1KVa1pj4Vu/HFxo1rX0WbUI+a+PKtbleS2OX5Ld5Pava+fd2c2xebT38s5clrxSP+DSLeWsfRERDdu6B6L4fw76M6Z6J4HXx6/FdM8Lx3D6tcdIp8WNDUw61tnJFYiJzbN8Vs+a0RHmy5LW7R3devnu3gAAAAAAAAAAAAAAAAAPd1uvzNvscDVa6xPK2GzzcXX4ONbpWVzIzM2/bxsaxbjSlayndv3YW4UpStaylSlKVq88eO+XJjxY6zbJlvXHSses2ve0VrWPuzaYiPz3G3dzX4/T29/cy1wamjrZ9zazXmIph19bFfNny3me0RXHipa9pme0REzKxS9k32c43Z72ncQ0G0woWuofPcXE5vzzJnZpay4525sy2Gv0+TGVPiW72hws6OqvQlWla3MatZQhKnppYT4U9H16Q6U1NfLSI5DfrTe37THa3nzV+Jjw2iY7xOCl4xWifpr8oad/t++0Zm9orx+6i5bQ2bZOkOk8+x0x0phrknJr21eNyRp7fI4LRPktj5XZ1Z38doie1M8RFrRPednLJiEAAAACGd7zPKtevfblGtKeI9MuWePFPnX1ch1dfn+H5/wCb5Id+0pP+v3Tsfa4zb/f2MX/I2RPcl17eFHjJPefrut+A9J+UduI3o9Ptd/p+6jMI1rtAAAAAAAAAAAAAAAAAEwP3YuX/ACbd1UPw856dy/m4/v6f0pc+zR+N3VP/AG7x38BsNdz331e/WngNb7XS/WEft8txKUqk+oqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdedXON3OY9LuofFLNuV27yThvItJbtxp6pXJ7PV5OJGEafPzKUrtKUp4+t8/ltadzi+Q1YjvOxp7GGIiO8zOTFakR2+n1l2/w/wCap05110hz+S8Ux8N1Jw3J3vae1a10t/BsWtM/RERj7zP2lWpzvBlrOb8y1so1jLX8q5DhSjWnisa4u3zLFaVp96tK2/HhWDvUnFu7mOfSce1sUmPtTTNes/4G9X0ttRvdMdObtZi1dvgeI2omPWJjY4/XyxMT9qYv3hxVxX3gFkJ7KDqBg9RuwTt22+NkQvZmBxC/p9tajL1SxM/C3W0pSxc+da0n9EljXfFfFfTcp8vHhYt4V8hj5HoPp7LW0TfHqWw5Yj+syUzZY8s/d8nln9dpme310js9He1n4xcfmw2x6+11Di5Hj72iYjY1NrjdGZy09PWv1RXPj7x3jzUn17xMNijISHQAAAAADi3OOUYfCeGcr5jsJwtYHFuPbjkGZcuypG3bxdRgX8+/O5KtaUpCNuxKsq1rTxGlfnT63F3dqmlp7W5kmIx6uvm2LzPpEVw47ZLTP3O1X3emOD2ep+pOB6c063vt87zHHcRrUxxNr3z8jt4tTFWlYiZm03y1isdp7zMKs3qpuKch6ndRN7S78aG35xyrY2rvmlaTs5m8zr9mtK0+VY/CnCka/fjSnzqrA5TN9UcnyOfv3jNvbWSJ79+8Xz5LR6/nTHZvYdCcdPEdEdH8VNPh247pfgdK9O3aa5Nbi9XFkiY+ifiVt3+73cCcB2sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABl92DVrTvI7c60/dZ4R9otc7b0H/Vh07+m2l/GMaPPtYfkcfGT/i/6n+8+4s2llbSNAaWvbhdns+5jtP2fMuM636X1D6J/H5lqZWbVJZGXx7Fj8Tk2NenSlZ1x8HSfmpsbVulaU+kR9Va1p5Ya8bOkJ6l6Vy7mtj8/IcL5tzFMR3tfXpHfZraY9fLTD8XJER/XR6+iyv3YHtFV8E/H3R6c5vd+p+j/ABN+F03yEZckxi1+Yzz5OEz46TPljNtcnOjp3vMTPwrdo7du6AbKMoSlCVKxlGVYyjWnisZRr4rStK/OlaVpWlafeqgZ8vm2zImLRFqzE1tETExPeJiY7xMT9MTHrEvwfoAAAAAAAAAAAAAAAADITtV678h7auv/AEx6ycczLuHkcQ5Rr8nY1teqtcjj+Vdpg8hxPRGVKTllaXJz7Fv1UlSE7kZ+iVY+K/f6X53Y6b57jOY1rzS2ps47ZO3efNr2nybNO0THfz4LZKx8/WYntLEXjx4VcR41eEvXHhvzOtTZw9RcHuYNKL+WIw8vgxztcPsea0T5Ywcnh1ct+3lm1KWr5oie8WbHS/qDouq3TvhnUfjWTZytLzPjen5Dgzs3YXo24bTBsZc8WdyH6Gt/EuXZY2RHxSsL1qcJRjKNY0sr4zkMHK8fp8jrWi+Hc1sOxSYmLdoy0reazMenmpMzW0fRaJiYiY7NI7rnpHlegusOpOjebw5MHJ9Nc1yPD7VcmO2Kb30drLr1z1pb1+FsUx1z4besWxZKWrM1mJnnjnOqgAAAAAAAAAAAAAAAAAAAAAIifvGnd9PP33C+0fiO3rGxo/ovMepdrFveJyzMzAuXdJo86Ea1pPGuYGxwNxGE40lG/ZtSpWtKIl+0P1d8TPpdJ6mbtXB5dzkopb1m96TOHBkj6aWpkx5o/wCFWJbCfubvZ5rq8T1L7QfUPHxbJynx+m+icmfH3rXW1tuuPlOU1bzETXNTa09rjpmszE4suSJjvKKmi2vlAAAAAAAAAAAAAAAAAAAbsfYe9lk+53uew+ofJ9dLJ6ZdEJ2+Sbj49ms8HbcjlS3Y02iuXK09EL8K5tN3bpWspSjra09HprWVM0eCfRk9TdTU5DaxzbjOEmNnN3r3x5dj0rhwTPbtFu9/jRHf5Y59FZnvP/aWr4IeB2z0fwe5GHrfxPpfheN+Fkim1x/DRNsvJcrWkT5rYbRrTxl57REW3Y+uie1bT5oxjGNIxjSMY0pSMY0pSMaU+VKUpTxSlKU+VKU+VE8Pl8mp3MzMzMzMzMzMzM95mZ9ZmZn1mZn1mZ+b9H4AAAAhme8zfr+9un4suV/aDVode0p+P3T36WbX8YxtkX3Jf2JvGP8AVvwP3o3UZpGxdmAAAAAAAAAAAAAAAAAl++7GS/5Pu6eP4eadP6/zaLdpcezR+N/VH3dzQ/gM8/4mvB772P8AZf4ET9rprq6P2+V4uf8AElNpQKJgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFap7S3o1k9C+9frxwiWLLH1tOYX9xpLtYVhDM124xcbOlk2qeKUrCubey7VaxrWlZ25fPz5pSuDxJ4e3Cdac7peSa4/quc2Ge3pfHmrXJNo+555vHp6d4bqHsVeI+HxS9mbwp6ojPGXdnp3Fx3J4/N57625x2fPqxhyT37+eNXHr5O09p8t6+nbswSdGSoAS4Pdwe63Ev6zqD2ncj2NKbK1mZHPuCWsi7StzLx54FixutXh261p+lazG08tjOkaSrSuXKsvFPFUsfZ16ppbHyHSuxk/psXtv6MWmO96zjrXNipHp6Yq4fiT27/i5me3za+vvmPATPi3ekfH7htOZ0smti6T6qvhxzFNfNTby5eM3tm8d/wCmbubkY06+aYifqesV9fRK4SnUIgAAAAANOPtuO63C7cuzrlHGNfsI2Oc9arOdwHQ4cLkY3ruo2FiGHym9WlK+uMbemz78rc6eKVnCtPPyrRh/xq6px9O9H7WtjyRG7zUZOPwUiYi04clYptW7fPtGDJbtKxv3Y/gJs+MntGcHzm5pzl6X8M8mr1Zy2zakzjpyOnltscDiie3lm1+S1cVb1nv2raJmPVX7SlWUqylWtZSrWUq1+da1rXzWta/hrX51QH+fzbbkREREREREREREfKIj0iI+5EPwfrnvTXpf1A6w8u1fBOmfE93zPlm5vRs4Gk0GvydjnXa1r+ju1sYtu7djYsx83L930VjatRnOXiMa1c7jeM3+X28Wjxupn3NvNaK48ODHbJeftz5axM+WI9bT29IiZ+UOqdadcdJeHfT2/wBVdbc/xnTfAcbjnJt8ny23g0tXH2j63H8XPfHScuS3amLH5vNe9q1j1mG4niHu/Hf3yXS4m42Om4JxmWbahftazacu11NlZtzpTxHNxZXLF3DyI180nj3YeuPila/qqMvangF17s4aZsmHQ1vPEWrjy7eP4kRP9nWZrNLR8praO8K6eofe4eybwvJ7HHafJ9Vc3Grktiybuj09uTpZL1ntM62etMtNnFMdprlx28tu8xHyco/O7PfT/wBZ6a/lVrv625X8731z/Zcb+68f+U+F/RhvZZ/3HrT+4O5/Jz87s99P/Wemv5Va7+tn8731z/Zcb+68f+Uf0Yb2Wf8AcetP7g7n8nPzuz30/wDWemv5Va7+tn8731z/AGXG/uvH/lH9GG9ln/cetP7g7n8nPzuz30/9Z6a/lVrv62fzvfXP9lxv7rx/5R/RhvZZ/wBx60/uDufyc/O7PfT/ANZ6a/lVrv62fzvfXP8AZcb+68f+Uf0Yb2Wf9x60/uDufyc/O7PfT/1npr+VWu/rZ/O99c/2XG/uvH/lH9GG9ln/AHHrT+4O5/Jz87s99P8A1npr+VWu/rZ/O99c/wBlxv7rx/5R/RhvZZ/3HrT+4O5/Jz87s99P/Wemv5Va7+tn8731z/Zcb+68f+Uf0Yb2Wf8AcetP7g7n8nPzuz30/wDWemv5Va7+tn8731z/AGXG/uvH/lH9GG9ln/cetP7g7n8nPzuz30/9Z6a/lVrv62fzvfXP9lxv7rx/5R/RhvZZ/wBx60/uDufyc/O7PfT/ANZ6a/lVrv62fzvfXP8AZcb+68f+Uf0Yb2Wf9x60/uDufydqV7n+2zn/AGn9XeQdGOpctXPlnG6Ylc+Wny7ebg1pmYljMtfCyLU7kJ/pV+FJeJV8SpWlfqYo6m6c3+leW2OG5L4U7Wt5PiThvF6fX1reO1omYn0tCwHwP8aOkvH3w94jxK6JjejgOZnYjUjkde+rtROtsZdbJ8TDkrS1f6Ziv271jvHafpY9vgMugAAAAAAAAAAAAAAAAMvOwj/HH7c/xtcH+0etdt6E/qw6e/TXS/jGNHr2r/yOXjJ/xfdU/ebcWbiytpGAPR2etwdzrdhqNnjWszW7XCy9dsMO9H1WcrBzrFzGy8a7Gv6q3fsXblqcfvxlWjwy46ZseTDlrF8eWl8eSk+sWpes1vWfuWrMxP3JcrS3NrjtzU5DRzX1t3Q2sG5p7GKfLk19rVy0z6+bHb6L4stKZKT9FqxKuI9qH2nbPtF7tuoPC6Yl61w/lWwyObcCzLlqtq1naHeXa5OTHGj6Yx+Brdzc2Opt+jzSkcKnmvq8q6/E3pTL0l1ZyGl5JjT2slt3QvMdovgzz5rRX0iPLizTkxR27/iPm3LPYZ8ftL2hPZ96Q6l+qMeTqLgdPD0x1ZrUv576vLcXT4GGc0+abTl3eNpp795t2+u2Z7R27NdjHyYQAAAAAAAAAAAAAAAAACaj7u73cXepHRnlXbTyrafSORdJb13c8St3rta37nC9rmwvX4yrOUpXJ2N5tMm3apH0xt41uEPR4j6ky/Z86snkeG2um9rL5tjiZnNqRa3106WW8Tb5/Oa58tojt8qxEdmtL74T2fcfRniTwPjZwWjOHh/EHHj43qC+LHEYqdS6GtbHitHkrFaVy8Xo4b3m3eb5r2t5vXskjpGqYQAAAAAAAAAAAAAAAAAAAAHT/X/rBx3oH0Z6i9X+U5ljC0/BeMbDcTu5M4ws3c6kKY2ow5SlKNKfT9tkYWFH5+fVkRpSla+KV+Rz/L6/A8NyPL7V60w6OtkzTNvlOTt5cNJ//mZrUp/9pkTwl8O+Y8WPEjo7w84HXy7XI9U83qcdTHhrN8lNWbTm5DYrWImZjU4/Fs7NvTt5cU9+0eqsl69dYOS9e+sHUHq3yvMyMvbc25Pt91SmTcrdnhYGVm3rms1cJ18VrY1evrj4FilaeaWceFK/UrU53l9nnuX5Dltu9r5d3ay5vrp7zTHa9pxYomfXy4sflx1+5WG7l4U+HfC+FHh30j4fcBr4dfj+mOD4/jO+GkY67O3g1sdN7evWPT4u9txm28vb0nJms6hfJZCAAAAAAAAAAAAAAAAAAfQ1Gqzt5tdZpNZYnlbLcbDD1evxoUrWeRm5+TbxMWzClKVrWV2/dtwpSlK18y+p7MOK+fLiwYqzbJmyUxY6x87XyWilKx92bTEfruJyG9q8XobvJ72WuDS47U2d7bz2mIrh1dTDfY2MtpmYiK48WO9p7zHpCxq9lr2f4XZz2ocI4bl4kbfOuWYWLzLn+Vcs0tZtd1u7NdlDU5fypKsuP28+eoj6vTWscWlZRjL5UsP8MOkadIdK6WnekRvbdK7m/ea+W/xs8fFjFf6e+vGScMd/opDTd9ur2idn2jfH3qjqTX2Jv0rwG1sdN9JYKZPia0cZxeSNK3Ia/aZr5eYvqV5G3bvHmzz2mY9Wx5kVDQAAAABDM95m/X97dPxZcr+0GrQ69pT8funv0s2v4xjbIvuS/sTeMf6t+B+9G6jNI2LswAAAAAAAAAAAAAAAAEvf3Y2VKcG7pIffry/gUv5tJuafX/LVLb2aZ/1F1PH0fVmhP/kM7Xl997WZ6p8CbfRHT3Vsft8nxn/u/bSoUolEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACJT7yH2tZEMrpv3Wcf13qw/olrp9zi/j2qxt4lbeffydFsMu5GlaSvbHM3U8GEp1p5pixpStfHhFD2i+l7RbjuqdfH9Z5Y0N61Y7RTtktbBkvP02yXzTSJnt6ViPobAnuZPHXDbB1p4C8vudtn6ov1f0vizZO99iL6mLByupr0mYmMenr8bXatFe/ac9pnt3RPUVl+gDt7oR1s5z28dVuGdXuneyua3k3DN1g7XGrSU6Y+fYxsm1eydVnwtztzva/Y2rcsXNsxuW5XMe5OMbkK19VPrcFzW90/yuny/H5Jx7Onmplr6z5cla2ibYskRMTOPJETS9YmJmszETHzY98VPDPpfxg6C6k8POsNKm7wnUnG7Whn7xWc2plzYcmPBv6lrVvXHuaeS8Z9bJal60zUra1LxHlmxs7G+9Dpr3sdFdF1J4RscaO9sYtjB5xxiuRbnsOOchtWbX0uxkWaem7DHyPiW8nFuXLcKVt342/M5W5TlYj0R1lxvWnC4OS0clfj1rXHvavmicmtsRWPPW1fSYrbvFqzMR6W7evbu02/ai9mzrX2ZfEvlei+p9PNbi8ufLtdMc5GG9dPmeIyZL/U+XDknvjtlxeS+DPSt7TF8U3mKxaKxmc7ijaAAAA646t9WOC9D+nnJ+qHUje4nHeH8S1mTs9rscu7bt09Fi1O7DFxo3JR+kZ2XKHwMLFt1rdycicLNuNZypR87luV0eE4/a5Pkc9NfT1MVsuXJeYj0rEzFKxMx5r3mPLSketrTEREzLufh90B1V4n9X8H0N0XxWxzHUXUG7h0dDT16XvPmy5K0tnz2pW3wdXXrb4uzntEY8OKtsl5itZlXae0g74+U983X/cc7zJ3cHgXH63NB054/W5clDA0GNfv3I5eRSUqQuZ2fk5GVkTuwtWfTj3bFisZVs1nKvfxF632ut+fzb15mmhr99fjtfvMxTXra0+e3ee03yWta0zEV7VmtZj0bhnsZ+y7wXsueEnHdKa9ce11Xy3l5brLl4pSLbfL58WKk6+GYjz01dTDhwYaY7ZMnfLTLli0RkitdfLoCXICbz7vj2manpx225vcHyTj+LPmfV/bZF/je4ycWEsixwfWxs4GNYxpXozlblXd4m6nO/ZlD4kLlLdY/ofnNXwB6Uxcd05fqDZ16zu8vltbWzWpHmro4+2Ota9+8xPxqZu8x27xMR29GsT73bx/3+s/GjW8IeF5fPXpvw74/Di5rjsGxaMOXqndnLtZ8uauOa1vX8C9jja1x5It5LUm0T9ckPpBqfQAAAAAAAAAAFfN7cv8AZDur370NB/L/AMAauv8A8kA/G77IHLfsH8BibdHuufyH/h7+i5f7777UAxGsQAAAAAAAAAAAAAAAAAZd9hNfHeN251r+61wb7R612zoX+q/p39NtH+M4ke/aujv7OXjJEf733VP3m3Vm6ssaRYADQr7fDs9u9ee2ix1k4nqq5nPuiFz81L9MWxW5mbLhl6/WG3xbk4xlKOJprOZsN7crSlaU+BOsq0j5rTBPjv0hPO9N15jUxeff4Sfi28le98mnNu2WkzETPkw1vkzz9ryzPotc90/7RWPwp8bMvhx1Bvxr9J+KFPqHFOxlimtpdSY8Xm4/PStpittjksmvqcXSO8TPxaxHeZ7TBRQdbTgAAAAAAAAAAAAAAAAADNv2enc9tu0zur6X9UsXKla0VN7jaDmGLK7W1iZXG9/Wenz7+ZSlaeu3qrefLa2qVrSlL+HblX5U8O6eH/U2XpTqnjOUraYwfHrg269+1ba+fvhvN/l3jFF5yxHf8VSJ+hGT2vvA/j/H/wABuuehc+vXJys8Vm5bp3PGOL7ODmuJ8vI6mPWmYny3376ldDJMRMzi2L1j1lZS8e3ut5RoNJyXTZEcvUch1Gt3mqyoVpWGTrtth2c/CvwrStaVjexsi1cjWla0rSVPFVj2vnxbWvg2cNovh2MOPPivHytjy0rkpaPz62iWlny/FbvB8tynCclhtr8jw/I7vF7+C0TFsO7x+zl1NrFaJ7TE48+G9J7/AEw+w9z5wAAAAAAAAAAAAAAAAAAACKh7xp3f3tZquE9pPD9tW1kbatjl/UqOLf8A0X5nQt3J6jj+fajXzGORdu6vd2vX6a1pZt1pGsa+UWvaH6unFi0uk9PL2tl8u3yUVn/rcRM4cF4+ceabYs0d/orHb7a+j3N3s8Y97e6n9oHqLj/Pi0Iy9O9FW2MX1v1Za9achy+peY7WnFjpvcZfy94icl4mYtHZEWRMbCAAAAAAAAAAAAAAAAAAADef7Cnsrr3H9ysOrXK9b9K6bdDJw3WVTIs/FwNxy3Itxx9RpL9a0pSk7VjOu7u3WkqSpPWRr4rSla0zf4HdGfhi6kjldrFNuN4OYzW7174823aPLiwW9O0TWuSc8evfvihVv7072lv5jPgrbw/4HcjB1p4pVtxmCcWXybfHdP4r2zcjyeKInzTXJl1acZeJr5Zpu29YnsnkUpSlKUpSlKUpSlKUp4pSlPlSlKU+VKUp9VE6WqfMzMzMz3mfWZn5zP25foAAAAAIZnvM36/vbp+LLlf2g1aHXtKfj909+lm1/GMbZF9yX9ibxj/VvwP3o3UZpGxdmAAAAAAAAAAAAAAAAAl4e7HS/wCJ3dFH/wDGrgkvH/6m29P6f8/8KWns0/8AxTqf/trR/gczXp993H+yPwMt/wBgeqo/9JcdKVQlIodAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdFdynQLh3c30W530X5xjWrum5lpM3X2sqdql25qNpcxrsNZusWNfqy9Xlzt5mPX50+Laj5pWnyfD6k4HT6l4Xf4bdrE4dzBfHF5jzThyzWYx5qxP9fivMXr92IZT8FvFjqPwR8S+lfErpfPkx8l03ymtt5MFLzSnI6NM2O29xmeY/wD4ff1631s30/DyW7TE+qta7ne3vnHa91r5x0b57rcnA2vFttfs4eRdtThj7bUXZVua7Z4N6saW8rGv2JRhO9ZrK3TJtZFnzSVqUaVw9TdP73THNbvD7+O2PLq5bVpaYmK5cMz3x5aTMRFq2r6TMd4i0Wj5w3TPBDxe6X8cvDPpfxI6T3cO1x/Pcfiy7GLHkrbNx/I0rFNzR2scTN8GbFlibRjyxW84b4snby3rM9AvgssgMpu07vC61dm3UfD6i9HuRT19+k7UN1oM342Rx/kWDCVfiYW1wbd/HrchO3K5b+JZvWL1KT/wnyj47R0r1dzXR/I05HiNicdu8Rm1797a+xSPnTLSLV7xMTMd6zWfX5sFePvs7eGftH9GbHR3iLw9dvDNcluM5bW+Hi5fh9q0fWbOhtXxZYpat4raaZMeXHM1/Ees95pXZT7bjtf7ncTU8Y5/tsTot1Ru2bFjJ1PLNljY3HdpnSjGHnT73Lhg4sruXkeqGPrKVyMmFZW4Vu3JXKJldF+NXTHU1cWrv5acNyk1rFsW1krXXy3n0/pOe8UpM2t3iuLva0ekd57w1qfaY92N45eB+fkOc6S4/Y8TOhaZMuXByHT+lmz8xoa0Wm3bkuKwW2titNfF5bZd6Yw4bRF7RSkVlufw8zE2GLj52DkWcvDyrUL+Nk49yN2xfs3KeqF21chWsZwnSvmMo1rStPnSrMlL0yVrelovS0RatqzE1tE/KYmPSYn6JhWxsa+fUz5dbaw5NfYwXtizYM1LY8uLJSe1qZKWiLVtWfSazETE/N7LyekBrm7vPaj9p/Z5r86xzTnOBynnWPau0xenXEs7F2XI7mVGlaWbOzs41cq9pbF+7T4f0zLxJWrfic6xrSEqMd9W+J/SvSGO9d3ex7W9WJ8vHamSuTZm8fKuStfPbDWZ9PPekxHrM/JMf2evYX8ffaK3NXL010tt8F0rlvT4/WPUGpn0uGpgmYnJk0smeNfHyeXFTvf6m19iuS8+WkTE3iULf2gntQOt3fZyS7g7bJnw7pHq8y5c4z091d+9SzS36qSjm7/Jpc8bTZTlGNK3IWcXGjZtWIRxYzhcnchr194m831zszTNadPicV5nW4/Fae0R6T589u/bLlmY9ZiKV7RWIrE9++yr7I/sOeGHsr8Lj2ePw16j8Qd7XrXnOr9/FjnJNu0xOtxODyd9HSrEz2pbJnzTkvltOeaWpSmshjVNwB3H2/8ARrk3cD1j6fdIOJ4t/J2/OOTanSUuWLM7/wBAws3Ox8fO2t+MPnHF1uNduZmVdlWMLVm1Oc5xjStafY4Dhtnn+Y4/iNStrZt7ZxYO9azb4dL3rXJltEf1uOsze0z2iKxMzPZjnxb8SOE8I/Dnq7xE6gz4sPHdL8JyHKTTLkri+q9nW1cubV0cVrfPPu56U18FIi1r5Mla1ra0xE2c/RfprqOjvSjp/wBMNFjWsTWcK4vq9Has2aRpa+Pj2KTz7sKRpSPjI2FzKyPl9+7X51r862W8NxuHh+K0OMwVimLS1cWGKx27eate+SY7en12SbW9PttITxK615HxG6+6u645XNfY3upuc3uUyZcnecnwsuWa6tLeaZnvh1KYMPr9FPlHydnPpukAAAAAAAAAAAK+b25f7Id1d+fn9BoP5P8AgDWfL+n+VAPxu+yBy37B/AYm3R7rn8h/4e/ouW/X/wBd9/8A/d+s1AMRrEAAAAAAAAAAAAAAAAAGXfYV/ji9ufz8f8rfBvnX73/GTWu2dC/1X9O/pto/xnEj37V35HPxk9O//U96q9P+8u6s3VljSLAAfE5Lx7U8u47veLb7FhnaTken2Wi22HcpSsMnW7bDvYGbYrSVJUp8TGyLkKV8V9Na+afOj0bOvi29fPq56xfDsYcmDLSY7xbHlpbHePX7dbTD6fC8vv8AT/McVzvFZ7avJ8NyOlynH7FJmLYN3j9nHt6uWO0xP1mbFS3bvHft2+lWse0F7Yt12m90/U/pbn4l2zpYb7K3nEMutmVvFz+Obv0bTD+hTr5hes66uZLVXJ25SjS/hXYV9Mo1jSuHr7pnP0p1RyfF5KTGGM9s+nfyzFcmtm7ZaeSflaMfnnFMx3jzUmPm3TvZH8b+M8f/AAI6G671NimTk78Vg4vqLXjJF8+pzXGebR2fqmv4rHk3PqeN+lbxEzi2aWjvW0WnCl0xJcAAAAAAAAAAAAAAAAApWtK0rStaVpXzStPlWlafVWlfvVoHz+aeZ7B/u7l3Bdq9rpjyXZ1zOe9D8iXHsmWTepPO2PGr136Vp86luVfifRNdi52FpIXKUlD1YtI+v1eY0nT4F9Wzz/S0cZs5fPv8Jade3mt3vk1rW8+G/afXyY65KYYn1jvXt37+jVO96r7PVfCPx4ydb8Jo/U3SfifhrzGCMGOa6ulzePH8DktWbxHl+qNzPq7PJ2pMxaYzzbt29W8xm9VwAAAAAAAAAAAAAAAAAAA4F1S6haHpP065p1I5NlWMTScL45tN/nXci9CxbnHAxbl6zjUu3K+ml3MyKWsSxT51nevW4RpKUqUrwOU5DBxXHbvJbN60waWtl2Lza0Vifh1ma17z6d727Ur9u1oh2zoXpDlev+semujOEwZdjlOpeZ0eJ1ceHHbLes7eemPJnmlfWcethnJsZZ9IrixXtMxETMVlfdZ195H3N9fupfWbkuZfy7/LuTbHI1Mb9ZevC41jZFzF41r6xlX9DLB0lnAxZ1pGHrnZrKsI1r6aVrdU89sdS89yXMbN7Xnb2clsMW796a1bTTWx9p+U0wVx1n5d5jv2btvgL4TcN4I+EvRPhtwmti18XT3CaeHkLYvLNdnms2GufmtyLVj1rtcpk2s9YmbeWuSKxaYjux4dfZfAAAAAAAAAAAAAAAAAAfV0Wl2HJN3qOPamxPK2m82eDqNdjQpWU7+dscq1iYtqNKUrWtbl69CNPFK1+b24MOTYzYdfFWb5c+WmLHWPWbXyWilYj8+0xDgcryWnw3Gchy/IZq6+hxeltchu57zEVxaungvsZ8lpmYiIpix2t6zHyWP/ALM7tE1vZx2q8C6ezxI2+Z7vXY3K+f5lyzS3m3OR7y1XaZGsyq0pGs6aC5nXtTYrWlK/Bx4+rzWixTw26Sx9H9LaHHzWI3c2Ou1v3mva87OePiWxX+39Tze2Ks/2NYaZ/ts+0Lu+0d489V9X1zzbpvjNzPwHSWtTJN9anDcXeNHDu68d5iv4LU1cfIZYiZj4maZj0bBHf0RgAAAAAEMz3mb9f3t0/Flyv7QatDr2lPx+6e/Sza/jGNsi+5L+xN4x/q34H70bqM0jYuzAAAAAAAAAAAAAAAAAS6vdkJf8Ve5+P4eTcHr/ADafa0/pSz9mn/4r1N/2zpfwOVr2++7j/X7wNt/2F6pj/wBIaE/P9ZKuSlUMgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANKXtkvZx4feH0eyOovTrT2o9dummtys7UXMOxSeXy/Q4dLmblcavWYUpdzMysfpdNNG1Kl76bmemsciPotUwx4w+HdOr+ItyPHYYjneNx2vhmle9tzBTve+tNY9b37ef4MV+u+JftMW9IWY+7i9srY9nXxFxdHdY8lknwq613cGryFNjLNdfp7ltia62Dm8eS8zTX14t9T/glN4+H9S68zFsVvNkmBLt9TsdDtNhpdvh39ftNVl38DYYOVblZyMXLxrkrV+xetTpGcLlu5GsZRlSlaVp86UQSzYsmDLkw5qWx5cV7Y8lLRMWpeszFqzE+sTEx2mJbXfH7+nyujqclx+xi29Hf18W3qbOC9cmHPr56RkxZcd6zNbUvS0TExMxPf5vnPW5gDyWr13HuQvWLtyzetypO3dtTlbuW5xr5jKE4VjKMqVpStJRrStK080r5fsTNZi1ZmtonvExMxMT9uJj1ifznhkx48tLY8tKZcd4mt8eStb0vWY7TW1bRNbRMekxMTEx82UfS7vc7sei9vHs9M+vHP+LWMXx8CxjbSGbahGlfV6KR2ljO8R81r8qV8UpXxTw7PxnWvVXDxWvG87v6tafiYrli8R69+39Nrf0YM659mPwB8Sb5snW3hV0lzuTP3+LkzaNta95mO3mm2jl1frvu/TPrPdlRa9tB7RS3bhbr1/wB5drCMY1uXcTArcn4p49U6xsRjWVfrrWkaUrX7ztNfGTxCiIj8Hs9u0du80x95+7P1rBGT3bHsd3va8eEnF44taZilNjbile8/iaxbLae0fKO9pn7ro/qX7SLve6twyMfnHcVz/Z4GRCVr8zrWXh4OJZsypWkrNn6Fh2MiMK1rKX6K/OdKyr4n9Xj4fJeI3W3LRau91Dv5cdomPh1vTHSIn+tjyUrbt+faZ+6yf0V7GPsw+H18Wbpfwd6S0dvFeMn1Zk19jb2MmSs965Mn1Ts5cNrRERHpirXtWO9fn3wv2W12e5y7uft9jm7TOvSlK7l7DKv5mTclKtZVrO9kTuXJea1rX5y8fP5OnZMuXNecmbJfLe0zNr5LWvaZn1nva0zKSeloaXG69NTj9PW0dXHERj19TBi18NIiIiPLjxVpSPSIjv27+nq9B63LAf1GMpyjCEaynOVIxjGlaylKVfFKUpT51rWtfFKU+upETM9ojvM+kRHzmftPy1orWbWmK1rE2taZ7RERHeZmZ9IiI9ZmflCZ97B/2bu16Ncfu91vWTQS1/OuZa6eL030W0xq287j/GcqxKzf3d/HvwpdxM7cxv5liFm9CM6YVvEyrX6G/GVZj+Bnhzl4fBPVXMYJpvbmOa8bgy17X19a1ZrbNato71vm816xExExSKXj8U1sveq+2doeI/LU8A/Djlq7fSvTe5XP1pyujmi+rzHN4MsZMXGYs2OZx7Grxs4tbLbJjtNfqq+xgv647ViSwkipVAAAAAAAAAAAAV83ty/2Q7q7/E0Hj5f/AGg1f8/z+/8AyfeQD8bvsgct+wfwGJt0e65/If8Ah7+i5f7777UAxGsQAAAAAAAAAAAAAAAAAZc9hla07xO3OtP3XOCU/n5LrKf0u2dC/wBV/Tv6baP8ZxI++1ZHf2dPGSP/AKveqvvJvSs31ljSJAAARyveGO0GXVLofx7uR4lqq5HLekF2xrOTyxbHxcvP4Ts8+Vq3CNu1H4sq63Z7S5scm/L4lLeFYn6qQhD10jv7QPSM8pwmv1HqYvNt8RMYtny172yaWTJMRHaPWfh5Ms5LWnv2pWe/aIXI+6C9oeOhfFDl/BfqDfjD0/4iY8u9wcZ8vw8Gr1NpakZL2te8zSv1bpaGPTwYo8k5NnLWIm1rRWYTiF7ZnAAAAAAAAAAAAAAAAAAbRfZF922V2n94HB9nn51zH4J1Hy8fgHNsWk6xt38bd3K42lvylWtbdqGHyC7rMvIvSty8Y9i5StYU8yjk7wm6st0r1do5cl5ro8jeuhu17zEWrmny4bT9ERTPbHe0zE/W1mPT5oM+8I9n7B4++zv1Ro6mrTL1V0bgy9W9MZ5rFr4s/GUjPyeKsR2vkts8Rj3dfFjraO+bLWYi0/WzYmY2TYzMbHzMW9byMXKsWsnGv2pUnavWL9uN2zetzjWsZ27luUZwlStaSjKlaV8VWEVtW9a3pMWresWraJ7xato7xMT9MTExMT9pp5Z8OXWzZtfPjviz4MuTDmxZKzXJiy4rzTJjvWYia3pes1tWYiYtExMd4ed5PUAAAAAAAAAAAAAAAAAAjS+8R94V7p90p4t2ucQ2lbG/6pTt7vnUce7WsrXDNbfnexsG58KsZY+VkbvE1eVGlydfiYXrpS1WM/XSN3tCdXzocVq9L6mXtn5SYz70Vn1jTxWma457THlvbNXFeO/zp39PXvF1nuevZ1x9Xde89469Q6HxeI6Frfi+lrZscRW/Uu7hrizbdPPFq5sGLjNjewT5ax5NiInzxNfLMMFDhsmAAAAAAAAAAAAAAAAAAAN9nsF+yuPcF3FXut3Ltb9J6edDJw2FmGRZpdwdvzTMtRxtZqsikqeKxsYWbl7e3KMqSjka6196laM7eBXRn4P9RTzW3j83H8HMZKxaO9M27eIrixWiY9YrS98sTE+lscfalVF71v2lreEfg5j8MentyMPWHilW2nkthy+Tb47pnXyTm3t/DMW7xOXZ1tfj7xasxbDuZPtxKdZ9X1JxNWQAAAAAABDM95m/X97dPxZcr+0GrQ69pT8funv0s2v4xjbIvuS/sTeMf6t+B+9G6jNI2LswAAAAAAAAAAAAAAAAEuX3ZCv/ABc7nY+fr5Dwmvj+DVbOnn/Olj7NM/6n6mj7expT+1iy/wDK18ffdV/158D7fa4jqeP297SSs0p1CoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8rSlaVpWlK0r8q0rTzStPwVpX6w+XyRv/a6+xut9fq7HuD7ZdLha7qvYsX8vmvCsW3bsYvOrWNCtymfq7UPRKzyOln12pWbdMiOyjZxMexi2sis7t2Oni14Pxz05Of6awUx8rWtr7ulSIrXeisTPnxRHby7EV7x2jzRk7UrWtbd5m5r3e3vHcnhLGn4Q+N3JbO50DlzYtfpnqbPe+XY6VvmtFJ1d+9vPGThpyeW8ZL/CnSnJsZsue+KK46QxuUcX5BwrkO34pyvUZ+h5Foc27rtvp9njXcPPwMyzWnrsZONfhC7an4rGdKThGtYSjKlPEqIc7WrsaWxm1drDkwbGC8482HLWaZMd4+dbVmImJ+U+sfKYlsk8FznEdTcRx/P8DyGryvD8rrY9zj+R0s2PY1dvXyd/Llw5sVrY717xNZmtpiLVtX5xL4L0PqgAAAAAOyulXR/qZ1v5dgcF6U8L3/OeU7C5bhZ1PHtbl7PJt25y9MsrJt4lq9Oxh2Y0lcyMmcaWrNqE7k60jGtX0uL4jkub26aPFaWxvbWSYiuLXxXy2iJn8VaKRM1pHrNrT6ViJmfSJdL698ROifDDp7b6p696l4npfgtOl7ZeQ5jd19LBe9a964MN9jJjrl2MszWmHDW03y5LVpWJm0JfHsx/YZaLo3laTrT3X42t5b1BsVx9pxzp3Glu/oeK5dusbuLkbm5Sd781tljXaQybUbc8Ozj3o27WTjX6W7lLktvDTwQwcPbBzPVVce3yFfLl1uOjtbBq3j1rbNMd5y5Kz2tHaaVrPaLVntPfXj9t33pHK+I+Dk/DTwCz7nT/AEhljNocz1jab4uW5/XvE48+HjaTXH+B+lnpNsGS1q7GTNjtfJhzY5vSayUMfHsYlizi4tm1j42PbhZsWLMI27Vm1bjSMLdu3ClIwhCNKUjGNKUpSiR9a1pWK1iK1rERWtYiIiI+UREekRClvNmy7GXJnz5L5s2a9smXLktN8mTJeZta972mbWtaZmZmZmZl5n69YAAAAAAAAAAACvm9uX5/vh3V3+JoPH8H5g6z6/5fP8iAfjd9kDlv2D+AxNuj3XP5D/w9/Rct9999qAYjWIAAAAAAAAAAAAAAAAAMt+w3/HE7c/xu8E+0usds6F/qv6d/TbR/jOJH72q/yOnjL/xedVfeXdWcKyxpEAAAOI8/4ToupHCeWcB5NiW83Qcw49uON7XHuRhL1YW51+Rr8iUPXGcY3oWsiU7M/TWsLkYypStaOJv6WDkdLb0NmkXwbmvm1stZiJ+szY7Y7THeJ7WiLTMT9E9pdh6T6m5XozqfgOrOE2La3LdO8xx3NaGatrV8u1xu3h3MMW8s1m2O18Na5Kd4i9JtWfSVZt3mdu+/7W+5Dql0b3mJPHt8b5Llz0d2tuUbOVx3Z0t7XR3LFyvmN+lrWZ2Lj37luvp+k2r0fEaxrCNbHWPT2fpfqPlOHz0msa2zecE9u1ba+XtlwTWflbtiyUraY9PNE+kfJuy+zf4wcT46+DHQniRxexXNbm+F168pj89bZcHMaM20OUrlpHrinJu6ufNipaO/wcmOe9omLTi86yzkAAAAAAAAAAAAAAAAA8ti/exb9nJx7s7ORjXbd+xetyrG5avWZxuWrsJU+cZ25xjKMqfOkqUrR+1tatq2rM1tWYtW0T2mLRPeJifomJjvEvXlxY8+LJgzUrkw5sd8WXHePNTJjyVml6WifSa3rM1tE/OJmFh/7Hzu2sd1nZ/w3J2edDK550ws2On/ADOzSdJXLdzU262tDdnStazrLI47b1d67OVa+q9cnX5efCwXwi6sr1T0jp2y3i2/xla8fux39YnDHlwT6zM97a8YpmZ+czLT994n7PuTwE9onqPDo6tsHSnXOTL1d01kmnlpenIXjJyuOsxEViMPMX3seOsRHlx0r8/m2qMpIGgAAAAAAAAAAAAAAAAOO8v5RqeE8V5HzDe34Yum4vo9pv8AZ35zjCNvB1OFezsmvql8qSrasSjClfrnWNKUrWvhx9vaxaWrs7me0Vw6uDLsZbTPbtTFS17es/T2rMR919jp7g+Q6n57huneKw2z8lznJ6PE6OKlZvN9rf2cerhjy19ZiL5Ym3b5ViZ+hWj99fcxvO7Luc6odX9rmSydds+Q5ms4rbjOVbFjimlufmTx6tmEpSpCWTqMLCyMj0eI3L85z9MfV6aVudcdSZ+q+puT5fLfzY8uxfFqxEz5a6mGfha/aJme02xUpa3b52mZ7R37Ruteyz4KcX4A+CHQ3h3oa8YdzR4jX3eevNaxly8/ydPwQ5iMlorWb1w8hs7OHD5u80xUrXvPbvOILqSQwAAAAAAAAAAAAAAAAAD7fGuP7PlnIdHxfS488vb8h22v02txoUrKV7N2WVaxMa3SlPn87t2Pn8FPNfvPdra+Xb2MGrhrN82xlx4cVY9ZtfJaKVj9uYfM5rl9HgOI5TnOTzV1+P4jj9vkt3NeYiuLV0sGTYz3mZ7R6Y8du3257R9KyR9nN2l6js57Wun3TCzixt8py9Xjck55lztxjl3+Vby3+amywsicYx+JDTZebk6zErWnqjj2IRlKVfMq2M+HfSmLo/pfj+MrTttXxU2d68x9fbaz1+LlpafTvGG9746f8GI+lphe2R7QHIe0b47dXdc5c834LX3s3C9Ka9bzbXxcDxd/qHS2cNZm3kvyWDVw72xET2nNltMRWO0RnY7yiuAAAAAAAhme8zfr+9un4suV/aDVode0p+P3T36WbX8YxtkX3Jf2JvGP9W/A/ejdRmkbF2YAAAAAAAAAAAAAAAACW/7sjL/gLubj96u84ZX+Wmt2FP6UsfZq/wBo6lj/AOX0/wB7Hk/5Wvt77qP9dPBGf+xnUsft7unP+JK5SnUIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANX/fZ7Kjt072tNnbLY6exwHqzTFuR1PUjj2NatZU78aSni2t/h/Cnb2eut5EqyvWrH0PMu2rl23TNhWVuVvGXXPhZ071phvkyYa6HKxWYxcjr1itpt6zWM9O0xlxxae9or5LzEzHnj0mJx+yv7enjH7MnJaulp8jl6s8P5z0tyHRnMZsmTXritNa7GTidn4lb6O5fFEVxXy/VGtjvTHada0RaLREe6j2Mfed20X87Y4vB8zq1wmzcuyx+TdPMDK3GRTDt1rWuVtNHgV2OXqbUIUrO5PKvemkYynWtKUqiX1R4OdZdN2vkrpX5bSrMzXZ4+ls1vJH9flwY/iXwxEeszae0R3nu2FfAj3kns2eNmLV08/VGt4fdTZK0rm4TrDbwcbhnYtEdsGhym3Gng5C97T5aVwYu82mK9pmWqLZa3YafOytZtcLJ12xwrsrGZhZlmePlY16Pj1Wr9m5SNy3cj5p5jKNK08/UxXkx5MN7YstLY8lJmt6Xia2raPnFqz2mJj7Up76e7qcjq4N7Q2cG5p7OOMuvta2SmbBnx2/E5MWWk2pek9p7WrMw9J4OSAAyE6I9qfcJ3GbKzrujfSnmPN6XL0LN7ZafR7HK02BWdaUpPY7THxruLhWqefMrl+cYxpSta18Uff4TpbqDqLLGPh+K3N3vPa2XDgyWw4/u5MtazWlftzM9mIvE7x58IfBzSybviP17050vNMdsuPS5HlNPX5LbisTM009HLmx59rJPbtWmKtrTPaIj1SGOz33c7lW3vYXKe77l9OOa2vwr0en3BczByNvOsa0uR+ncjnHZ4EbN3zG3ew6au3fhSFyNb0azpWMgekfZ42s002urtz6nx/W2jj9C9LZp+n6/ZmMmOIn0iafCi0dpjv6+lQftFe+P4Hj8ezwXs8dO/gzux8TFPV/VWts4eOr370tGrw1Z0tq2TH2m+LZnevitM0n4cxWYmTL279oHbx2saC1oOivTXQ8Up8OEM3b2semRu9pdjGkK5OdsL/rn8e5GMY3Po0ca1KlP8FTzXzJTp7pHp/pfXjX4bjcGr6R580V82bLaP66+S3efNP0+Xyx9xSX4w+0P4weO/L35bxL605Xn589ra3H3y/B4zRx2mbRg1dTF5axipMzNPjWzZI7/wC2T2jtku7IwoAAAAAAAAAAAAAAr5vbl/sh3V3+JoP/AHDrPq/7/X5QD8bvsgct+wfwGJt0e65/If8Ah7+i5f7777UAxGsQAAAAAAAAAAAAAAAAAZbdh/8AjiduX43uBfV//U2s/wC9f3nbOhf6r+nf020f4ziR/wDaq/I6eM3/ABd9V/eTdWcSyxpDgAAAIv8A7xf2if3UcA4b3XcT1VJbTgs8bifUC7jWaeq7x/ZbCdrU7C/6I+q5fjt9pjYkrkpVpHFtRj6aUjSqMvtD9JfVOhp9U6mLvl0Zrq781j56+TJMYslu3rNoy5a07/2MR9ruvG9zl7Qv4B9W9SeAfP78xo9U1z8/0jjzZJ7U5fS1K35DUxRafLTFbj9HNsRSsRNs97T3mbdkOdEFsZAAAAAAAAAAAAAAAAAAN3XsLO72Pbn3W4fT7kuypidP+t9mPFM/6Te9GHruRVpTI0ewt26yjCubsNhh6/SRlKtfNvL9MaVl4Zq8D+rfwvdVU4/Zy+Tj+brGrk809qY9j8VgyRHeI8+TJTHh79/lb0Vje9L9nifGTwD2eruF0pz9W+GGSef1PgY/NsbnDRM4eU1L3iJtGtqamzt8nMRH4vB3mYjunvJ3NUAAAAAAAAAAAAAAAAABH79v93hz6I9uuv6EcV2NMbm/XK5GxsfgXvh52t4Rr8meVmbCxWMvPpy9lrLOovUrGtJWM27T5VrStMB+PfV88J09j4LVyeXe5uYrk8tu18eljtN75I9e/wBdkxVxW9PxN5+2tu90p7OtPE7xj3PFXntP43THhdS2XT+Lj+Jq7vVG5gjX1tPLEx276+lvZeQxzExNcutjn1j0mDWhG2igAAAAAAAAAAAAAAAAAAEgr2BHZVDrl18ze4HmWsrkcC6JS+Np45Fmk8Lbc4zbNMXDw70ZxrS7ZxdbmbDPjKFY1t5mFZ8y+VY1z74DdGRzfPX5/cxebQ4WfNh81YmmXevEVpSe/wA60x3yZPT5XpX19FRvvZfaXt4W+E+t4R9ObsYerPE6Ph8jbDk8uzx/S+rknPs7OOa2iceXPu62pqTF4mL6+zk7R6xMTjk22ryAAAAAAAAhme8zfr+9un4suV/aDVode0p+P3T36WbX8YxtkX3Jf2JvGP8AVvwP3o3UZpGxdmAAAAAAAAAAAAAAAAAls+7JS/4L7mI//bfh8v8A1fnU/wC//wAkr/Zqn+ldSx/8rpz/AOTu1+vfcx/q7wSn/wCYdRx3/P29af8AElfpUqDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHju2bV+3OzftW71q5GsZ2rsI3Lc41p4rGcJ0rGUa0+VaVpWlafW/JiLRMWiLRPziYiYn8+J9HnjyZMV65MV748lJi1L47WpetonvFq2rMWrMT6xMTExLGbqx2X9rHXGk6dU+hvAuWznblbrdytVXCvemVZV81uaq9gSlPzKtfVOspfhrWnyda5Xo3pfm+/4KcJo7czHbvfFNJ7T93FbH3/X7s29Ae0p47+F0xPQfij1Z0/Wt4vFMG/G1j7x2jtFN/Ht1rXtWI8tYrHb5dpnuwI5H7CL2fW/y8jJx+B8g45G/OUo4vH93j4+Nj0l9UMeObrc65GEfvUncnX8NauibHgZ0Bnva1dDY14tPfya+eta1+5WL48kxH3Jmfu90r+G96n7XPE6+HBm6r4jmbYqxWdjluLy5s+bt/XZba27q0m0/TNaUiftQ4VH3fPsHpOk62OqEqUl6qwrybSeitPPn01pTjFK+mv1fKvnx99w48Aeg4nv5eTn7k7ODt/FO/wC+7Nb3uvtYTWa/F6GrMx280cHyfmj0+cf6+du/0/Lt9xkj0x9j72AdL8rD2Ov6E6PkW2wJQuYu15TkZewy7V2HitLtI413BxZT8xpWvrxpQ8+f0LsXGeEXQXGWpkpweDYzY5iaZdq18l4mJ79+1ZpTv8vnXt9xhfrf3iXtbdc4NnT2/FTk+H4/bramxocDh19PXyY794nH3z02s9a9p7R5c0WiPpbE+N8N4lw7Cs67inGtHx3Cx7UbFrH0+sxMCEbUKeIwlXHtQnOlKfLzclKVfv1qyFraepp0rj1dbBr0rEViuHFTHHaPlH1sRM/rzKHnNdSdQdR7OTc5/muU5jZzZLZcmbkd3Y27TktPe1ojNktWsz9qkVj7UOSuS+KAAAAAAAAAAAAAAAAr5fblV/8ApDur370NBT/1Bq6/0oB+N32QOW/YP4DE26Pdc/kP/D39Fy/3332oFiNYgAAAAAAAAAAAAAAAAAy17EPl3h9uX43+A/5+T6ujtfQ3p1f07+m+h+/tYoYA9qmO/s6eM3/F11ZP7XB70rONZa0hgAAAHWnWPpdxzrT0u510t5Xh4+ZpObcZ3GgyI5Fql6OLd2ODfxsTY24V+X0jXZNy1m40q0r6b9i3LxXx4fN5ji9bmeM3uL26Vvg3dbNr280d4rOTHatckR/ZY7TF6/atWJd18OeueZ8NOueluuuB2MuvyfTHN8dy2GcN5x2z49PaxZs+ne0evwdzBTJq5oiY82LLeO8d1ZL3LdE+Q9uvXTqX0b5NiXsPZcI5Pna61bvxrG5d1N6Uc7R5cqVpT/xzTZWDlfVSn6d8vkrU6k4XY6e5zkuH2azTJpbN8cRb0mcVvr8F/wD7eG1L/a9W7l4K+JvEeMXhb0T4kcJsY9jS6o4PV3L2xTE0x7+OJ1eU14mJn01uRwbWD5/9bdGPiMogAAAAAAAAAAAAAAAAPq6LdbLje61HIdNlXMLbaPZ4O31mXalWNzGz9blWszDvwrT50layLNudP34/N7cGbJr5sWxhtNMuDLjzYrx865MdovS0fdi1Yn9ZweU43S5njeQ4jkcFNnj+U0trjt7XyR3pn1N3Bk1tjFaJ+dcmHJek/clZNezk7oNX3Zdp3S/qVj5Vu9yDF0WJxnmONW7S5l43IePRlp8q/mw8+u1d2v0Cu1hGcY1lay4Sj6o1pKtjfh31Pi6r6U4zkq3i2xTBTW3K9+967Gv3w2tePnE5fh/Fjv8AOLxLS79snwN3vADx+656Ky4L4+Iz8pn5vpzP8OaYM3D8vMcjgxa1u3lvj0Pqr6gtNZtFcmvas9piYjOl3hFkAAAAAAAAAAAAAAB87cbbA0Oo2m82uRDE1mm12btdjlXK0jbxsDXY13Ly7861rSlIWcezcuSrWtKUpGvmr15suPBiy58toriw475clp+VceOs3vafuRWJmfznM47Q2+V5DR4vQxWz73JbmroaeCsTNs23uZ6a+virERMzbJmyUpEREz3tHaFb57TTuv2Hd33Z9RuoEcqdziWk2uTxDhGJC7W7h2NDx6cdRDOw/Na0jb3lzA/Ni54lKMrmXKsa+Kq6fErqrJ1b1XyPIebvqYcttTSpE96Vwa8/Bi9PuZ5x/Gnt6d7tzT2JPAPT9nn2f+jekZwVp1Byehh6h6o2LY4ps5eV5is8jbV2e0R5r8XTb/A6szET5NeO8d2vt0FLgAAAAAAAAAAAAAAAAAByPh/FdxzjlXHeHcfxrmZuuT7nXaPWY1qErk7mZssq3i2f0EP0VYQlc+JcrT9TbhOVa0pStacjU1c27ta+ngrN82zmx4MVYiZmb5LxSPSPojv3n7URMvjdRc7x3S/A8x1Hy+emtxnB8bucpvZslopWmtpYL58n11vTzWinkpHzte1axEzMQsoPZ/8Aano+zzti6edJdfjQt761qcbd82y6xh8fL5dubf5p7y1cuwjGl2xgbLMzMPC8+qUMW3bhWc/HqrY70D0tg6Q6Z4/icdYjPGGufdv6ea+3mj4uaJmPnWmS96U+1WI7zLS39rbx75T2i/HDrDxB281rcVfkM/GdM68TaMWDp7jb/UXF5KY7TPky7elr6+xs9u0Wz3taK17+WM1Xc0aAAAAAAAAEMz3mb9f3t0/Flyv7QatDr2lPx+6e/Sza/jGNsi+5L+xN4x/q34H70bqM0jYuzAAAAAAAAAAAAAAAAAS0vdlK/wC8+5WPn69lxKvj+DBzKef86V3s1fiOpY/+U1P/AFLtf/33Ef6p8Fbf/M+oY/b2taf8X/TsljJVKBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFfL7cr9kO6v/xdB9n9UgH43fZA5b9g/gMTbo91z+Q/8PP0XL/fffagWI1iAAAAAAAAAAAAAAAAADLPsSrWneF25Vp9f3X+AfajVu19Df1XdO/pvx/8axMA+1P+R28Zf+Lvq37x7yzlWWtIUAAAABE39427QYfA4T3ccQ1EbdLNMfh3U27iWa0jWt3JuW9LyDY3aUr5vXruVrNHarWsY+i1ajSlZfXFT2iOko8ul1ZqYe0R5dPk5pH02tMYdjJP27TbFgjv29IiIX8+5t9oe3xep/Z86i5GbfEnN1H0RTYyd7R5MNb8nxGnSZjtjx48G9yuTtFp817zPaES9FJf+AAAAAAAAAAAAAAAAAAka+7zd3UOl3XPkXbhyrZ/A4t1isXs/jFvIvfDxsTm2qwo5M7k7lyVbcIZWm1d/Es2aUt1uZd+HiUpT9NZD+z91ZHF85sdO7WXy6vL1nJrRa3atN3FSLTMzPpEWw4ppEene9o7esqb/e++z3brrwt4fxm4HR+Lzvhzlx6nOXw4/Pm2OmN/ZnBWlaUiL2vr8lvYtjJknzxTXxW71rFfNE2NNFrLgAAAAAAAAAAAAAANJ3ty+8Gnbd2pbDgPHNlXE6h9brlOJ6mWNepHO1mi9Uszc7Stqnmf0TLw9dmaWdytIwpczaR9Xq8Rrhfxu6u/C50rk0NfJ5OQ5qfqXDNZ+vxYO83zZe3z8tqY74e/pHe/bv39FmfuufZ1nxn8fNPqzmdKNjo/wwpPP8hGfHM6u9yvlrrcZoxee1fqjX2dzX5KtO82mmrMzXy95iAzWtZVrKVa1lWta1rWta1rWtfNa1rX51rWvzrWvzrVA/5/NtiRERERERERERERHaIiPSIiI9IiI+UPwfoAAAAAAAAAAAAAAAAACRX7vv2WW+sHWvbdyvM9XW/wzo3WVjiscmzSuPsec7C1TGtz8XYyhk4uHqcnbVlW3Snws6zZ83KSjWEpC+AXRkcvzWXqTcxebT4afLqxav1uTeyR5In1iYtWmK2afSPrcla+vp2mnX3uPtLZPDvwy4/wW6b3oxdSeJERl52cOSfjafS2pknNevfHatsGfZ5DDoREXmfiauTJ2pMW80TbU02siAAAAAAAAAhme8zfr+9un4suV/aDVode0p+P3T36WbX8YxtkX3Jf2JvGP9W/A/ejdRmkbF2YAAAAAAAAAAAAAAAACWb7spX9J7lI/hzeKV/mw8mn9KVns1T9b1H93Jq/+pZQH77eP6Z4LW/+bc/H/nGGf8SWWlYoDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAV8vtyv2Q7q//F0H2f1SAfjd9kDlv2D+AxNuj3XP5D/w8/Rcv9999qBYjWIAAAAAAAAAAAAAAAAAMsexX/HB7cfxw9P/ALUat2vob+q7p39N+P8A41iYC9qb8jt4y/8AF11d94t9ZzrLWkIAAAAA6Q7kOifHO4jol1H6P8owsfMwOZ8X2usxa5MYyhhbmWJdno9lHz9U9bto4edCvmn6KxSla+HxOo+F1uoeF5HiNqlb49zWy46eb5UzTSZwZPz8eWKXj7tWT/BnxN5rwe8TujfEXgtnNrbfTXOaG7n+DMxbZ42NjHXlNGe3zru8fbY1bfP63LPaO6sk6z9LuQdFuqvPOlnJ8TIw9zwjku00eRbybcrV67YxcmdMDMrblSlaW8/ArjZtmv6mVrIhKNaxlSta1eZ4zY4blN/i9qlqZtLZy4LRaO0zFLT5L9p+jJTy3j7cWiY9G7l4bdc8R4ldB9Kdd8HsYdnjep+E0eVw3wXjJjx5c+Gs7Wt56zMTfU2oza2SPnXJitW0RaJiOsXzHdwAAAAAAAAAAAAAAAAHNum/O950w59w/qFxzJu4m64dyPUciwLtmcrcpXtVn2MyliUo1pX4WRGzWxej5pSVq5ONflVzeO3s/Gb+pyGtaaZ9PYw7GOYmY72xXrfyzMfRbt5Z+5Mus9Z9K8Z1v0p1F0jzODHscZ1Hw3I8Pt48lIvWMe/q5db4sVmJj4mGckZcc9u9b0rMesLNPtI6+6Dub7eOl3Wbj+ZazLPLeMYNzaStSjKlnkWBD8zeRY9aUrX00sbvEz7UKV+fohTzWv1rKek+ewdS9P8AGcxr3i8betScsxPftsY4+HsV/Wz0yRH3IaSXtBeE3LeCPjB1z4bcvr318nT/ADm1TRi8TE5OH27fVvDZu8/OcvGbGpktMenmtPpDI92JhoAAAAAAAAAAAAB4MrJx8LGyMzLvW8fFxLF7Jyb92VIWrGPYtyu3r1ycq0jC3btwlOcpVpSMY1rWtKUeN7VpW17TFa0rNrWme0RWsTMzMz8oiImZl7cGDNs58Otr475s+xlx4MGLHWbZMubLeMePHSsd5te97VrWsRMzaYiPWVd77X3u7vd2Xd7zPN1WZdvcB6Z5WV0/4ZjVnWdqEdJdpg77NtTpWlq9Z2W9xM7Oxb0IUpXFyIUjOca0lWvnxb6tnqvq7dvivM6HG3tx+nXvMx/SJ+HnvE/Ka5M9Ml6WiPxNo7TMercG93j7PWPwA9njpvU39amPq3rbBg6u6lzxSK5LW5Sk7fE62Ss9748mlxWxq6ufHa3f4+G0zWkx5a6sGL07QAAAAAAAAAAAAAAAAAHK+C8N3fUPmXF+Dccxb2bvOWbzXaLWY9i1O9cnlbHJt48Z/Dh+ilbsxnK/erTxSFm3Ocq0jGtacrR08/Ibmto61Jvn2s+PBirWJmZtktFYntH0V7za32oiZfB6p6j4zpDpvnOqeZ2MetxfAcXucrvZsuSuKlcGngvmtXz3+ti+WaxixRPfzZL0rETMxE2WHYx2vcf7Q+2rpx0c02LatbHV6TF2PLsmFLdZ5vL9vajseR3a3YRjW5YhuMrOhh0lWdbeN6LfxJ0p6q2Q9EdMa/SXTfHcPhpFcmLBTJt2jt3vt5Y+Jsz37etYzXyRTv3mK9o7y0q/al8c+X9obxq6z8R+Sz3yae9yefT6ewWm8V1enePvOnw2OKWmYpltx2DVtsTWKxfN5reWvfyxl67ajyAAAAAAAAAhme8zfr+9un4suV/aDVode0p+P3T36WbX8YxtkX3Jf2JvGP8AVvwP3o3UZpGxdmAAAAAAAAAAAAAAAAAlj+7Ky/RdyMfw5HF6/wA2Ne/7/wAyVXs1/PqP9Fq/+pdQN77es9vBe30Ri52P/LYv+n7aWilcoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAV8vtyv2Q7q/wDxdB9n9UgH43fZA5b9g/gMTbo91z+Q/wDDz9Fy/wB999qBYjWIAAAAAAAAAAAAAAAAAMsOxb/HB7cPxxdPvtVqna+hv6runf034/8AjWJgL2pfyO/jL/xddXfeLfWdCy1pCAAAAAAIdnvF3aBb4tzjhvddw/U/C1XNoWuL9RJ4tn1UhyTBtzt67cZdbUaRxse9q7Oq1cJXI+LmVGlPi1nP0UiF7Q3SMau9p9VamLti3Yrq8hNa/LZpE1x5rzEfW1tjjFijv87fT6ti/wBzn7RF+e6X6k8A+ouQ8+/0xbJzvR1c+XtNuF2b0vucdrxeZtmzYt7Jv714pPemvPrSK18yL0jIvJAAAAAAAAAAAAAAAAAASsPdx+7imBuOddpnLNr+k7ml3mPTe1lXvMqZ2Paty2+h11qtaem3XFtbPd3aRpOVblLkq1jH6pS+zv1ZGPNvdKbeX0zebc46L2/r6xE5tfHHf5eWMuefTv37z8lC/vk/Z9nb47pbx/4DQ/pnHfD6c6zvgxzFZ1c2S8cfy25eInveM+TR4zHNprHlmlY9fnLoSza94AAAAAAAAAAAADVD7Ynu9x+1LtD5b+ZWfHG6g9Vbd3gHDLcZ0+Lbns7Up7vKuWo1pdpZpx6zt7Vq7GVukMqVr9HWtPRLFfi91dXpXpLb+FeK8hykToaUd/WJyR3z3mI9fL9TxlrE947Xmvr6J8+7o9njN49+0N0/9X6s5ukeg74+repb2r9ZemjeK8Xgpe3ek5J5fJx+S+Oa3m2CL+kR9dFeTevXci9dyL9yd2/fuTvXrtyVZXLt27Ks7lycq+aynOcqylKta1rKta1+dVfkzNpm1pmbWmZmZnvMzM95mZ+mZn1mW35jx48OPHixUrjxYqVx48dIitKY6VitKVrHpWtaxFaxHpEREQ8b8eYAAAAAAAAAAAAAAAAACST7vX2W2eqHVred0XNdVW/xbpPKeu4PTJs+LWZzbPt/RZ5tv4sZQy8TB1N7cY9z4Uf0nO+F6rsZQpCUjPZ/6Njk+Wz9T7uKZ1eK749LzR9bfdyR5ZvHeJi9KYrZqz2+WTt3nvHaaYPe9e0rk6H8P+L8C+mt+MXO9fxTd6onBk75NbpjUvOeutf4dotr7G1yGLjs1PPP9M1ZydqTW3miaemY1pgAAAAAAAAAEMz3mb9f3t0/Flyv7QatDr2lPx+6e/Sza/jGNsi+5L+xN4x/q34H70bqM0jYuzAAAAAAAAAAAAAAAAASwvdlpf747joeafO5xqXj79fGPcp/m81/70Sp9mv8X1F+frf+rZQX77aP6T4NW/4PNx+3lpP+L95LWSva/YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACvl9uV+yHdX/wCLoPs/qkA/G77IHLfsH8BibdHuufyH/h5+i5f7777UCxGsQAAAAAAAAAAAAAAAAAZX9i9fHd/241p+7F09+1Wqdq6H9Orunf044/8Af28MMB+1J+R38Zf+Lnq/7w76zpWXNIMAAAAABjF3jdu3H+6btz6ndGd/h2sqXJeOZ09FO5SFK4vKNbarseNZNLkoyrC3a3eLgTv0jWFblmM7dZxpLzTrPWHT2v1R07yfDbFIv9U615wTP9btY4+JrW7/ADiIz1pNu3bvXvDN/s5+MPL+BPjH0P4k8TsXwRwnNateVrTzT8fgty8afNYPJWY818nGZ9quLvForlmtorMx2ms26h8H3nTTnXLeAckxbuHvOH8g2vH9jZvWp2JVyNXm3sSt6Nu5+ipZyY2o5FiVfNJ2btucZSjKla1s8ho5+N3tvQ2aTTPp7GXXyVtExPmxXmveIn6LREWrP01mJhuzdIdT8X1r0t0/1bwufHscX1FxGhy+nkx5K5axh3tbHsRitevpOTDN5w5Y9JrkpesxExMOGuG7GAAAAAAAAAAAAAAAAA7t7cetHIO3vrd036v8by7+Hn8L5RrNnkSx5SpcyNT8eNjd4XiP6r6bqL2bieK0r4+N5pStfk+107zOx0/zfG8vrXtS+ltYstvL372w+aK56enz8+Gb0/8AtMZeMvhrxHi94Y9Z+HfNa+LY1OpuC3tHDGWKzTDyHwrZeM2u9vSPqXkMetsfOP8Aa+3eIWcHRvqfoOs/S3gnVHjGVYy9PzbjGo39iWPdjehYu5+FZv5eDKcK1p8bAyp3sPIhXxK3esThOMZRrSllnD8nr8zxejymtat8O7rYdis1mJis5KRa9JmP67HebUtHzi1ZifVpFeI/Q/LeG3XXVXQvOYMuvyPTHN8jxOWubHbFbLj1NnJi19qtbRE/C28FcezitHetseWtqzMTEuy30nSQAAAAAAAAAAH5KVIxrKVaRjGlZSlWvilKUp5rWta/KlKU+da1+qh8vm/YiZmIiJmZmIiI+czPpER92ZQD/bi93tvuU7s9nw3jOz+mdPuikbvDdTSxdrLGyuQY/iPJcm7bpWsK5ODuq7TWwuU8V+DCsfn581gZ429XR1J1Xl09bL5+P4XzaeHyz3rbYr6bNpj5eamb4uOJ/sYbZfuvfZ4v4Lez/o9Sc3o/U3V/ibanUnITlp2zYOIzd54XDjvMRaMO1xsaO5ak94+Jbv8AcaWGGllgAAAAAAAAAAAAAAAAADmvTjgm+6n884j094xiXs3fcw3+u0Otx7Fqd+5W9n5ELUr3wrf6KVvGs1uZN6tPFIWbNycqxjGtac3jtHPye9qcfrUtfPuZ8eDHWtZtPe9oiZ7R6zFY72t9qImXWusuquK6H6V6g6v5zYx63FdO8Vucru5cuSuKkYtXDbJGPz3mKxfPkimDFE+tsmSlYiZmImy67Lu2jjfaX259N+jHH8WzYv6DRYeRybJteiX5ocu2VqOfybM+JClKzs3t3k59zGpKU627E4QpOVKeqtkXRvTWt0n07x3Da9IrbBgpbZtHb+mbeSIybN+8fOJzWyTXvM9qzEd5aUftKeNnNe0B4ydZ+JXL7GTLi5bldjDweHJ5o+pOntLJbU4PWmlp7UyY+Mw6tc81ivny1taa1me0ZUu0sEAAAAAAAAAAIZnvM36/vbp+LLlf2g1aHXtKfj909+lm1/GMbZF9yX9ibxj/AFb8D96N1GaRsXZgAAAAAAAAAAAAAAAAJXXuy9f+Ee4yn4Y8cr/NalT+lKj2a/8AbOoY/wC1/wB+J/5FB/vtY/1H4Nz/AMLmY+763j/kS3ksGvuAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr5fblfsh3V/8Ai6D7P6pAPxu+yBy37B/AYm3R7rn8h/4efouX++++1AsRrEAAAAAAAAAAAAAAAAAGVvYz/jfduP44+nn+flepdp6I/qu6c+7zPHfxrEwL7UcRPs7+M33PDfrCf1/wB31nWsvaQIAAAAAACFL7wx2e2+mHWnj3cvxLV/A4v1et29dy2Vi1SlnG5trMWWPCfi3GMbNnJ0uuwZyrP1VuZl25X11lP00hj7QPSEcZzOv1JqYvLrcvEY9ua1+tru46zWJ9IiIi2HHSZmY9bzPr6tmH3QXtFX658NOY8FOoN74vOeHl77vT9cuSZy5+mN7PGa1Zm9ptly4OT3NqtYr28mvSkeXtXzTHBR1XLgAAAAAAAAAAAAAAAAAJlXu6XdvPmXTPmXa1yva0u7jpzcvcm4Lbyb3plPi2zzbdzYYNqt2UpZGRb3WyzMmMLcqVtYkPHwqQt+tML2eerJ3ON3Ol9rLE5uOm21oxae0zq5ckTkpHeZm1ozZb27R8qx8vRrg++M9n2vTfW3TfjtwGhNOO6ypj4Pqq+HH3rXntHWtTT2rxjiK4cN+M0tfDNrx/TNi/4vzW8qTckspFAAAAAAAAAAAa/vaZd1Wr7SO0rqRz25l2bXKt7qsnh/BcK5dpavZ/IN7CmDcriV9UZSyNZrMjN3EaQ81pTBrWtPTStadB8SuqcXSfSfJb83rXaz4ramjSZ7WybGePJPk9YmbYsdr5YiO/4hLb2JfAbe9oL2gei+k66+XJwPF7+HqLqnZpjnJi1OI4q07VI2I8s1jDvbuHW46027RP1V2ie8wreNttM/ebXZbra5NzN2m3z8zabHMvS9V7Kzs/IuZWXk3Zf865fyLty5Ov35SrVXTly5M+XJmy2m+XNkvlyXn1m+TJab3tM/TNrTMz92W5voaOpxejpcboYaa2jx2pr6Onr447Y8GrqYaYNfDSPopiw46UrH0RWHz3rcsAAAAAAAAAAAAAAAAABJo93i7LrHPuo3Ie6/m2p+Px/pvW9penf0mz4t5HMMulMXL21it6MreVjYWrlutddpbjX4Wbct1ldjOHorJT2feja7/I7HVW7i82vx3mw8d56+ltu/1t81e8TFqUxTmx2iPleY9fTtNJfvgPaVy9JdG8P4BdMchGLl+tPh8l1j8HJ3vh6c15+Pr8flikxbBn2t6vG7lJvP8ATNaloik1t5omYJiNbsAAAAAAAAAABDM95m/X97dPxZcr+0GrQ69pT8funv0s2v4xjbIvuS/sTeMf6t+B+9G6jNI2LswAAAAAAAAAAAAAAAAErX3ZiX/DHcVH8Njj8v5o0p9X73n/ADpTezX/ALd1D+h1/wDAoU99pH+t3g7P2svLx+3b/wByXGlk18gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFfL7cr9kO6v/xdB9n9UgH43fZA5b9g/gMTbo91z+Q/8PP0XL/fffagWI1iAAAAAAAAAAAAAAAAADK3sa/xvu3H8cfTz7Wal2noj+q7pv8ATnjv41iYF9qL19nfxn7f72/WH3h31nWsvaQIAAAAAADCz2gXa9qO7jtb6m9KM3Fje3d7R5W84fkQtxnlY/KNFGm31FjFlKkvh12ebg4+uv1pTzXHyLkaVjWtK06Z1/0xi6s6X5Pir1ic84L59O3bvau1gj42KtZ9e3xb0rjt/wAG0wkt7JHjlyPs++OvRHX2tnnHxmPlMHF9RYbXmmDLwXK2njuQy54iY88aOttZd3FEz2jLhpMxPymtX5Rxza8P5Jv+KbzGnh7nje52Wi2mNcjWM7Gfqsy9g5dutK/P9DfsXKUr9VaUpWla0qrh2tfLqbOxq56zTNrZsuDLWfSa5MV7Y7x+tast07g+Y0OoeG4nnuLzV2ON5rjdLldDPSYtXLqb+tj2te8THp9diy0mftT6PhPQ+oAAAAAAAAAAAAAAAAAy97Fe5Lc9qnc90s6ua3Lnj6/V8ixNdya1W5KGPkcb3Xr1G4lkxpWlLkcPBz8jNtRl8o37FuXivh23ofqPN0t1NxfLYrzXHi2KY9qO/attbN3w5vN8u8UpktePtTWJR69qbwY43x68Duu/D3d165tzf4bPucJkikWzYea4zy8jx1cNpiZpOztamHVyTHrOLLePTv3WXfE+TanmnF+Ocw0ORDL0nKdHquQ6nJhKko3tduMGxsMO5SsfNPMsfIt1rT71a1osj1NrDu6uvuYLRfDtYMWxitHrFsebHXJSf162iWlHz/Cch01zvM9O8rhtr8nwXKb/ABHIYbRNbYtzjdrLp7NJie0/W5sN4j7cerkDkPkAAAAAAAAAAIPXvBXdzb6w9xGo6CcV2tMrh3RbGtS2/wBFv0vYWw5nscP6ReyKTt1rare1eLssjUZFvzOVu/YuRn6ZxrGkJvH7qyOY6hw8Fq5fPp8NWvxvLbvTJuZKeabenp5sVctsNo9Zi1Z79vk2f/dGez3fw68HuQ8WOe0ZwdR+JebJHHTnxfD2tTprS2Zw4sM1vEXjFv59LDyOG/aIviy0tXzVmJR7GAFvIAAAAAAAAAAAAAAAAADn/Svp1yDq31H4X004tiX87fc15DrtDr7GPanfu0lmXqUv5HwrdKylbw8WN/LvVp4pGzYuTlKMY1lTn8Xx2xy3I6XG6tLXz7uxjwY61ibT3vb663aO8zFKea9vtVrMz6Q6n131jxHh90b1L1rz2xi1eJ6a4jc5Xcy5slcVJrr45nFh895isX2M84tfF39bZMtKxEzMRNmJ2idufGO1Xt96b9FuMYlnHhxfj+DTe37NIVpseVZliGXybZeuNPMoZ28vZ2TZjKU/h2rsbdJVpGlVkvSXTur0twHHcNq0rWNXXp8e0dv6ZtXrF9nJ3j5xfPOS0d5ntE9u8/NpOe0J4x8548+LvWfiXzmxlzW53l9r8CsWXzROlwOtltr8HpeWZ7Vvq8Xj1cGSYrXz3xzaaxM9oyVdkYWAAAAAAAAAAAQzPeZv1/e3T8WXK/tBq0OvaU/H7p79LNr+MY2yL7kv7E3jH+rfgfvRuozSNi7MAAAAAAAAAAAAAAAABKv92Zl43/cPH8OHoq/v/L0JS+zX/t/UH6DB/iUMe+0j/Wnwen7Wzysft+afn+sl0pZte4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABXy+3K/ZDur/wDF0H2f1SAfjd9kDlv2D+AxNuj3XP5D/wAPP0XL/fffagWI1iAAAAAAAAAAAAAAAAADKzsb+Xd724/jk6df5+W6ijtPRH9V3Tf6c8d/GsTA/tQfkefGb/i36x+8HILOxZe0fwAAAAAAAEFr2+nZ3HoR3JYvW3i2t+i8C65QpnZH0ez8LA1fNMLHri7DWWq0j4rdzcXW/m3frKdZVu5tytKUjWlKQe8eOkI4LqOvNauPy6HORGS3ljtjxbtKzTJjr2j53pi+Pbv6+a8/OG0v7pz2i7eKngvn8Mud3fj9V+F1p1cPxsnn297prZzRn1N7JE27xj1djd/AzHFaxWKa1Yn1+egxghbCAAAAAAAAAAAAAAAAAAnS+wG7u7nXHtoy+i3KNn9M5x0Pv3MHHlk3viZ+y4dm5VMnX51yMpeqmPrLmyxtHY9MKQpbxbcayrKlfM4PAbq2eb6bvw21k827wlppXzT3vl08l/PjyT6+lcc5K4K+nbtWPp7tWr3s/s9U8L/GzX8S+D0vqfpfxQxU2c0YcXk1NLqPV1/g7erSYjtObepp5uUy95802z3ntEdm/NnhU4AAAAAAAAAxT72O4rR9rPbR1U6w7jLt4+RoONZePoLNbsIZGVyLbVt6jTRxrVfM78sfYZ+PmXrduNZUxrF6dawjGs49W606hwdL9N8py+a8Vtg1r1147xFrbGXtiw+WPnby5Mlb2iI9K1mZ7REyz17Mvg7ynjt42dB+HXHa982Hlua183L5Ipa2LBw3HxfkOSnNePrcUZtTVza+K95is5suOsRa1orNZ1zXl2659y/k/N+R5U83e8t3+35Htsmcpyrd2G62GRscusfXKco26X8m5S3Csq0hCkYUr4pRWzu7ebf29rd2LTfPt7GbZzWmZnvkzZLZL9u/r281p7R9EdobsXTPT3GdJ9O8H0xw2CutxXT/ABPH8Nx+Gta1imnxuph09eLeWKxN/hYaze3aJteZtPrLjDjPuAAAAAAAAAAAAAAAAAAJQvu7XZdj8u5jyXu45vp6X9PwuuTx3plXKs1pbu8nvTpibLe4krlKwyLWDgx3Onu0jGtLeRf81nGcKRrJv2e+ja7e5s9WbuHzYdLza/GzevpOzafJkz0mfS0Y6Rmw27RPa1vnEwo298N7SmXp7pzhPZ86Y5H4XI9S/B5nreMGWJvTg8VZz6XF7FaT5sN9ratxvI0m0xN8OKYis1tNkxNL1roAAAAAAAAAAAAIZnvM36/vbp+LLlf2g1aHXtKfj909+lm1/GMbZF9yX9ibxj/VvwP3o3UZpGxdmAAAAAAAAAAAAAAAAAlU+7NSp/dN3Cx+/XX6Wv8ANKzT+lKP2a5n6q6gj6PhYJ/X7woc99nH+snhBb7W5ycft1yf+5LvS1a9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACvl9uV+yHdX/AOLoPs/qkA/G77IHLfsH8BibdHuufyH/AIefouX++++1AsRrEAAAAAAAAAAAAAAAAAGVfY5/je9uH45enP2u07tPRH9V3Tf6c8d/GsTBHtP/AJHnxm/4tusv3un+QlZ2rL2j8AAAAAAAA14+0+7TsDu77SuofBrWJC5zDj2syOY8HzI2qXcvH3XH4R2s8LDp9fxd3i4NzT+I0rKscytIUrKtGPvEzpSnVvSnIaMUidzXxW3NK8R3vXNrx8WaU+7nrScP51/T1S/9h3x+2/Z69oHo/qm+xanTnMbuHpvqnXnJ8PXy8Zy9p0KbWzPeI+HxefapyPrMRE6/e09olXC7bV52j2uz0m0x54mz0+wzdXscW7SsbmNna/JuYmXj3I1pSsZ2cizctzpWlK0lGtK0pVXZlxZMGXLhy1mmXDkviyUn0muTHaaXrMfRNbRMT92G5dx+9q8poaXJ6Oamxpcjqa29p7GOYmmfV28NNjXzUmO8TTLhyUvWYmYmLRMPnvW5YAAAAAAAAAAAAAAAADZF7Kzuvze0zu96ecpyMu7a4ZzDZY/B+b4cbkoWcrWb6dcDX3r8vnCFrW7jJwNjduTj6Y28WXqlGNKypkXwu6qv0p1dx21a8109zLXR3aRMxFsWxPw8drfRFcea2PJaZj5U+cQhl7ePgHreP/s8dYcDh18eTqTp3Sy9UdMbE1i2TBvcTWNvbxYo9LWybvHYdvSx0rPeb547RafrZsbMDOxNng4eywL9vKwdhiY+dhZNmcblnIxMuzC/j37U41rGdu9ZuQuQnGtYyjKlaVrStKrEMd6ZaUyY7RamSlb0tE94tS8Raton6YmJiYn7UtNva1djS2tnS28V8G1qZ82rs4MlZpkw7GvktizYslbRE1vjyUtS9ZiJi0TEx3h7TzegAAAAAAABDl94y7to8p6hcK7VuKbas9XwOFjlnPbONer6Zci2WBcnqsC/SEvRcsx0+0xsqtuVJVjkW4yrWlY+mkQPaH6s+quQ0+ltXL3xaMV2t+Kz89nJjmcWO3ae01+DlrbtPytET3+hsae5w9n6eC6Q6m8eee0PLvdV2y8B0pkzY4714bS26V39rF5q+amW3I6ObBF6zHmw3tHaYt3mMCjMvEAAAAAAAAAAAAAAAAAAdmdGul3IutXVTgfSrieHfzt9znkeBo8KxjW5Xb0YX51u52TG3Glayjg6+zl5t371LWPOVa0pStafS4fjNjmuU0eK1aWvn3tjHgpWsTM9rT3vaIj5+THF7z9ysuk+JHXPDeGfQnVXXvP7OLV4npbhtvlNnLnvGPHNsVYpq4JvaYiLbW5k19Wnr3nJmrEd5mIWZPa12/8AFe2HoR066McSw7GLh8R49r8bZ3rEaUpsuRXca3e5Dtp1p86y2e4nmZtaVlKkPj1jGvppRZP0vwGr0zwXHcNqUrSmpr465JrHpk2JrFtjL+yZpvft9Hm7R6NJrx28W+e8cfFTrHxK6g2cufZ6h5jbz6WPLaZnS4fHmvi4fj6xPpEaXG11tXvER5vheaY7zLIN99iIAAAAAAAAAAABDM95m/X97dPxZcr+0GrQ69pT8funv0s2v4xjbIvuS/sTeMf6t+B+9G6jNI2LswAAAAAAAAAAAAAAAAEqP3ZuX/G7uCh+HVaeX81yxT+n+X+RKL2bP/jfUEf/ACOH961f+VRD77KP9j3hFb/shyMft0yz/iS9UtmvKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr5fblfsh3V/+LoPs/qkA/G77IHLfsH8BibdHuufyH/h5+i5f7777UCxGsQAAAAAAAAAAAAAAAAAZU9jta07ve2/x9/rP04p/J/ddqHaOif6rum/06439/bxMEe0/wDkefGb/i26y/8Ay/yCzvWYNH4AAAAAAAB+VpSVKxlSkoypWko1pStK0rTxWlaV+VaVp8q0r8q0Pn837EzExMTMTExMTE9piY9YmJj1iYn1iY+SAj7cPs8n20912z5vx3X/AEbp11sjXl2k+j2a0xdbup0ljbzW3b0f0uuXlbHC2G3+FX0TpYy419FYeJVgb42dIT031Vl3tfH5eP5vvt4fLH1mPNP1ufHNvl575KZM0V9Jito9PpnbK91/7RdfGvwD0el+Y2/jdY+GNo6e5P42SJz7vGVmM/F7uPHP1/1Pg09rU474n11Zy68xNvN3rGlZhlZaAAAAAAAAAAAAAAAAA/u3cnauQu2pyt3bc43LdyEqxnCcJUlCcJUrSsZRlSkoypWlaVpStK+aP2JmJiYmYmJiYmJ7TEx6xMTHrExPyl43pXJW1L1rel62peloi1bVtExatqz3ia2iZiYmJiYmYlYNexb7u490XaFxvWbzYRyuoHR+lrgXKIznSl27h6+FY8cybdqVa3ZW4cf/ADLsX79ZTjPKpP8ARRlX00n54NdW/hn6R1sefJ5+Q4jy6G13n1mmOO2taIn66YjX+HW1pme9u89479o1FveVez1PgX7Q/NbvF6k4OkfEScnVnB2rT+l49nctE8zhvesRSL25f6vy4sURW1cE19JiPNO3tltXkAAAAAAA6V7iusvH+33ol1J6w8ny7GHq+D8Y2G0jcyZ0hZu7OVv6JpcOUqyj4+nbjIwcKniVK+q/TxXz4fF6h5jX4DheS5favWmLS1cmXvb0icsx5MFJn0/2zNalI+7Zkvwd8N+X8XfE7ovw64PXy7O91RzmpoTTDE2yY9Gt/qjk9msRE9/qXjsO1sz6du2Ke/orIutfVTkPW3qtz3qrynKv5e45vyjcb+7XIuVuzxcfPz7+Rha6E6/OtjW4c7ODj0r5rGzYhGta+PNa1Oa5TY5rld/lNq9r5t3azZ58095rXJe1qY4n+xx0mtK/8GsN3Tw06D4fwx6C6T6D4LBi1+O6X4PjuJx/BpFK7GbU1cWHa3b1j0+Lu7Fcm1mmIjvky2ntHydXPmO8gAAAAAAAAAAAAAAAAAJU3u6nZjZ3e45T3fc209L2BpfpXFelssyx5tz29MmmLueRYNyUaUlPBt4+20dz0+qlJZMq1rGVKJR+z10bGfNtdXbuHvjwefV4ubx6Tm83lzbFJn6ccVy4J+15p+lQ/wC+K9pLJxnHcF7PHTPIzj2+T+Bz3XUa+WPPXjvgzn43h9qkT3rXavm0OUpM+WZjBXt3rMpeSWrXnAAAAAAAAAAAAAQzPeZv1/e3T8WXK/tBq0OvaU/H7p79LNr+MY2yL7kv7E3jH+rfgfvRuozSNi7MAAAAAAAAAAAAAAAABKc92dl/x36/x/8AtLqpfv8A+GxaJQezbP8Aq3no/wDkcU/v17f41Evvso/2M+Elv+ym/H/ks8/4kvxLhrwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK+X25X7Id1f8A4ug+z+qQD8bvsgct+wfwGJt0e65/If8Ah5+i5f7777UCxGsQAAAAAAAAAAAAAAAAAZT9kNfHd324fjn6b0/n5fp6f0uz9F/1W9Ofpzx38bxME+09+R68Z/8Ai16z/wDy7yKzxWYtH0AAAAAAAABqv9r52hWe7PtE5jh6nCs3uf8ATLGyef8ADMqUKSuwlpbVMzfYcKU9N29cz9Dj7DExbEZ/PKv26xhOVfTXF3i50jXqvpLcpipWd/jK239K0xEzHwY8+xSPpmcmCuStIifxcx6T8k7/AHePtDZPAD2hunNnf2cmPpLrfNg6S6lwRea0tHJ5J1uJ2bTPemOmpyubU2M+W1fTBivE2rX1iu+ysXIwsnIw8uzcx8rEv3sXJx7sJW7tjIsXJWr1m7CVKShctXIShOEqUlGUa0rSlaK+rVtS1qXia2paa2rMdpraszExMfRMTExMfbbgmDPh2cGHZ18lM2DYxY8+DLjtFseXDlpGTHkpaO8Wpelq2raJmJrMTHpLwPF7QAAAAAAAAAAAAAAAAG5T2JPd7Xtl7t9JxnkGx+idPus0YcI39L92scbE2mVKl3QZluFZUj9Kytzj6zW+utJfpN+sfFPrZh8FurvwtdWYNbYyeTj+Z7aWfvPatMtp82C8R8vNbNXFj7/2M9lcPvN/Z5/m3ez5ynN8Rp/VHV3htNuqOJ+FTvn2NHBE4+X1r3iJt8DBxubd3fJHb+mYomZ+cTYB0rSVKSjWlYypStK0r5pWlaeaVpX79K0+dKp7/P5NSaYmJmJiYmJmJifnEx6TE/diX6PwAAAAABFP9437ubmu1XBe03iW1rbyNrK1zHqPDEv09VdfbjdrqdBsLca19FLt6Wr3dqM6RlKNu3KlKwr5rFr2iOrJx4tHpTUy9rZe25yMUt6/Djv8LXyRHy7zOLNET2me0T8l9HubfZ7pub/VPj/1BoebFoRk6c6MtsYu0Rt3nHHIctp3tEeaceKN7jMk171ib3jv3RF0TGwgAAAAAAAAAAAAAAAAAA7Z6E9JOR9d+r/T3pFxPDv52853yXB0uNZxoVuXoY0qyydnlRjSkvNMHV4+bmz80rT0Y8vPy8vq8HxOzzvL8fxGpS18+9s0w1rWJmYrPe2W8don/a8Vb3n07dq+vo6B4p+IPDeFXh31f4hc/sYtXiuleF2uTz5M1opjtmiK4NHXtaZjtO1vZtbWr69/Nmjt6rNDtw6HcV7ceinT3o5xDCxsTWcL43q9Zk3Ma38OOy3NvDs03e4u081/T9ttKZWwvfe+JkS9NKU+Syjp3hNXp3heP4fTpWmLT1sWO01jt8XNFI+Nmn/hZsvmyW+7aezSV8ZvFHnvGXxM6v8AEbqLZzbG91LzW9u4aZreedLjb7GT8DOOpP8AuXH6PwNTH9Pkw17zM+ru99tjAAAAAAAAAAAAABDM95m/X97dPxZcr+0GrQ69pT8funv0s2v4xjbIvuS/sTeMf6t+B+9G6jNI2LswAAAAAAAAAAAAAAAAEpf3Z6X/AB96+x+/XQa2X82RhU/p/wA6T3s2z/q/no+3r4p/atX/AJVFPvsa/wCxPwmt9rl92P28Oz/7/wDpCYCl013QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFfL7cr9kO6v8A8XQfZ/VIB+N32QOW/YP4DE26Pdc/kP8Aw8/Rcv8AfffagWI1iAAAAAAAAAAAAAAAAADKbsi/xu+2/wDHR02+2Gmdn6L/AKrenP0547+N4mCfae/I9eM//Fr1p/8Al3kVnksxaPoAAAAAAAADx3rNrIs3ce/bhesX7dyzetXI0nbu2rsawuW5xr5pKE4SrGUa0rSsa1pX5Vflqxas1tETW0TW0T6xMTHaYmPtTHpLzx5MmHJjzYr2x5cV6ZMeSkzW+PJS0Wpelo7TW1bRFqzHrExEwrz/AGxvZ/kdqPdzym5qMCuN086r3L3PuG3IQ82rX5pXZU3uHcuwpS3C9HkFvbXbNj0wlDErarSNY+Jyr98X+kbdK9W7U4cfl4/lZtv6cxHpHxZ/p9JmPSJ+qIyzWvpMU7ekx6zt8+7l9onD4+ez3wNeQ2ozdX9A0x9JdSUtbtfJOljj8C9jHjt3vbFPEX0MeTL5r1tsRkjzRP1sam2Kk/AAAAAAAAAAAAAAAAAHv6vZ52l2eu3GsyLmHstTnYmy1+XZr6buNm4ORbysXIty+9cs37Vu5Cv3pRo88WS+HJjzYrTTJivTJjvHzrelotS0fdraImPuw4u9pavJaW5x29hpsaW/q7Glt6+SO+PPq7WK+DYw3j6aZcV70tH0xaVj97MLus1/dv2j9OOcyybVzlnHdVi8L5tiRu/Fycbd8dty1VrKza+qso5G5wsGzuJeqkfNMz1Rj6a0WK+GfVOPqzpPjt3zRO3rYqaW7Tv3tXNr1+FFr/8ACzUpGae/9n9ppn+3D4C7ns++0H1n0vGDJTgOZ38/UvTGxOP4eHPxnMXjfvg1o7RE4eN2drJx0TE27Tr9rT5omGwtkBEEAAAABwfqXz3R9Lun/MeonJMmziaXhvHdtyHPuX70LEJ29ZhXsqOPG5crSPxsq5bhjWI/OVy9dtwhGUpUjXhclv4OL0NzkNm0Vwaevl2Mk2mKxMY6TaKxM9o73mIrWPptMRDtHRXSnKdddW9OdH8LgybHJ9R8zx/EatMWO2W1b72zjwTmmlPWceCl7Zss+kVx472tMViZisr7s+v3Ie5zuC6m9ZeRZl3Lucr5NsbuopdrOlcTjWHfnhcbw/ROtfRLF0mPgWLvpjD13Lcp1jGtfFK1eq+e2Opef5PmNi83nb2ck4e/f63Wpaaa1O0/Ka4K46z6R3mJmY7t23wB8JeH8EPCLojw34fWpr06f4TTx8jNPLP1RzWxirtc1s+asfXVz8pm28tO828tLxWLTEd2ObrzMYAAAAAAAAAAAAAAAAACWJ7uj2aWcqvLe8Dmunjet2/pnEOlksyx5hHKs5scfecjwJ1pStMjFnhbPRSr6pR+Hl3f0NK+KpVezz0dW/1X1du4YtEefU4ubx3iLVyeXPsY5/sqzjy4J+5eVBPvjfaQy4Pwv+zt0zyM48l/qbqLruNbL2tbBl1pzcXw23WJmJw7FNnS5SvpW3xNenrMd4mWolc1/QAAAAAAAAAAAAAEMz3man/L526V/D0y5X/m5Bq0OvaU/H7p79LNr+MY/wDlbIvuS5/6k/jHH2ut+A/f4jeRmkbF2YAAAAAAAAAAAAAAAACUj7s9L/lE6+R/DxvX1/l+l4P9CT3s2/jjzsf/ADfH+9bH/wAqi332Ef7DvCeftc1uR+3r7U/4kwdLprsgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK+X25X7Id1f8A4ug+z+qQD8bvsgct+wfwGJt0e65/If8Ah5+i5f7777UCxGsQAAAAAAAAAAAAAAAAAZS9kXy7uu3Cv4Os/Tb7YaZ2fov+q3pz9OeO/jeJgr2nI7+z34zRP0+GvWn/AOXeRWeazFo+AAAAAAAAAANNfttez+vc72l7rk3HddHK6hdGPjc30U7dqksjJ02HD1ckxLk6U9crGPpJbPOt26SjT6RCkv0X6muHfGnpH8M3SmbZ18cW5Dhu+7gmI72thp67NJnt38tcHxbxEdvroj5/JZB7sj2iI8EPaA43hOZ3JwdIeJXwumOVre8xiwcls28vC7FKzPlrlzcpGjq3yTE/0m0x6R6xX+zhK3OVucZQnCUoThKlYyjKNaxlGVK/Oko1pWlaV+dK08VQJmJiZiY7THpMT84n7Uttetq2rW1Zi1bRFq2iYmLVmO8TEx6TExPeJj0mH8j9AAAAAAAAAAAAAAAAASDvd+O7u30b7itp0F5Ts/o/DutmNdt6iOTepaw9fzTW4tMyxl3Llyvw4Vzddqp6uxb8wrcycq1GNZTlGEs/eAfVscP1Dl4LayeXT5qsxhi09qY93HWL1tMz6R58eKcVY9O97xEd5nsqJ97j7PV/Efwd0fFfgtL4vUfhjmpfkZw4vibO501u551sutSlI89o1tzervZL/XRTDgvNoisTaJxSbTV9AAAAARwveHu7m90y6JcZ7bOLbL6PyPrBet7LlcLN2sb9rhOqyrmRCMa25RlauXt7rcCE6SrWlzGuTj6K0l6qR19oLq23GcLrdN6uTy7HL2jLteWfro0sN5tER29azbPipE/brMx29Vy/ufvZ8xdb+J3N+NPPaU5uG8OsV9HgL5MffFk6n5DXrhtMxes1yUxcXu7V6zWImmelZ80TXshSIYtmEAAAAAAAAAAAAAAAAAB3P28dGeSdwfWrpz0d4piX8zcc65LhamEMeNZ3LWDGlzN22VSlKS/8T1WJm5XzpWn6T4r9b7HT/D7PP8zx3EatLXzb2zTDEViZmKet8t/T+wxUvf8A+yxv4v8AiRw3hF4adZeI3P7GLW47pXhNnkLWzWitMm1aaa3H68+sTP1TyGfV1/Se/wDTO8LNHoH0a4r2/dH+AdIuHYONhafhPGtTpqyxrVLUdhscXCsWtpuL0KfL6Vt8+GRsMmtPFK38i5WkaUr4WU8Dw+rwHEaHE6dK0w6WtiwzNY7fEyVpWMua3/Cy5Itkt8vrrTPZpJ+LHiRz3i34idW+IfUezm2eS6n5vkOS7ZrzknT08+1lyaPHY7T6/A4/Uth08ETMzGLDWJmZ9XcD67HYAAAAAAAAAAAAACGZ7zN+v526fiy5X9oNWh17Sn4/dPfpZtfxjG2Rfcl/Yn8Y/wBW/A/ejeRmkbF2YAAAAAAAAAAAAAAAACUX7s/L/lM68w/DxbCl/Nm66n9P+lJz2bZ/1y52P/mtJ/8AHxxP+JRj77CP9hPhTP2ue2o7/n6u5P8AiTDUvGuqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr5fblfsh3V/+LoPs/qkA/G77IHLfsH8BibdHuufyH/h5+i5f7777UCxGsQAAAAAAAAAAAAAAAAAZR9ktfHdz23/jp6a0/n5hp3Z+i/6renP0547+N4mDPaajv7PfjP8A8WnWk/8A4d5H/Es9VmLR6AAAAAAAAAAensNfhbbAztXsce1ma/ZYeTr8/EvR9VnKwsyzPHyse7H5eq1fsXLlq5Hz84yrR4ZMdMuO+LJWL48tLY8lLetb0vWa2rMfatWZifuS5Gnt7Oht6u9p5r6+5pbGDb1djHPlyYNnWy1zYM2Ofoviy0rek/RasSrk/aodpew7Ru7jn3E7WJetcL5jnZPOOB5k7XwrWXpt3e+lZtrGjSMY0sazc3dhq7VKUr4t4cfNa181V3+KPSmTpLqzf1IpMae5ktu6N5jtF8OefPeKx/Y481smKI+1RuSewj7QGp7Qns+dJ9QZNjHfqXpzVw9LdV69b+fJr8lxeP4GtkzTNrW+Lvcbj1N+8z/X7M9oiJiGt9jpMwAAAAAAAAAAAAAAAABynhHL9zwDmHF+b8eyZ4m74nvtTyDWX7c5QrHM1GdYzrFJVhKMq253LEYXYUlSk7cpQr8pVcrS282huau7r2mmfUz4tjFaJmO18V63r8pie0zXtMd/WO8Ph9T9Pcd1Z07znTHL4abHGc/xPIcPvYr1raLa3IauXVyzEWi0RetMs2pbtM1vFbR6wsxeyruM0fdR21dLesemyoZGRv8AjeFi8hh641u2OUaiNdTyKly3TxKzC7uMHNu48J081sStypKdK0lWyXovqLB1T03xfMYbRa2fWpXYjvHeNnDHwtjvH9bE5qXmsT/WzHrPzaTntL+DnKeBHjV134c8lgthw8TzWzm4i01mKZeD5C0chw80vP1uS1OO2tbHltWe0Za3iYrMeWMqnaWBgAAHyd/u9dxrRbnke3vxxdToNVsN1s8mdaUhj6/V4l7NzL8q18UpG1j2Lk6+fvRerYz49bBm2M1opiwYsmbLafSK48VJve09/tVrMvocTxm5zXKcbw3HYrZ9/lt/T43RwVjvbNt72xj1dbFWI+nJmy0rH56th9or3RbXu27rep3U/Iy53uP2t5lcb4bjRvVu4ePxvj0o6bAysOlaypCG3sa+1tb1IyrSV/KnKnilaUpXF4hdT5erOquT5O1pnXjPbW06xPeldbX/AKTjvT7UZoxxlt/wrzPp8m6P7HfgZoez94CdD9D4cFcfL34vBzPUmeccU2M3NcvWeS28GzMRXz24/Lt30MczETGLBWJ79u7Bt0lKEAAAAAAAAAAAAAAAAABLh93R7NLWPquWd3/NNRG5d2X03iHS+uZY8xtW8TYRsbzkOFOtKShlWsnXZunpPzWEsXLveI1rL1Ulj7PPR0VxbfV27h7zl8+nxfnr6RFMkVz7FJ+cXi+O+H7XltP0tfT3xvtIXzb/AAHs7dNcjNMelOt1F11Gtl9cl8+pbLxfEbURM1vgyYdzW5Ga9vNXPr4/ro7dplbpTqEgAAAAAAAAAAAAAAEMz3mb9f3t0/Flyv7QatDr2lPx+6e/Sza/jGNsi+5L+xN4x/q34H70bqM0jYuzAAAAAAAAAAAAAAAAAShfdoZf8qnXWP4eI4sv5s/WU/pSb9m38dOc/wC1KfwmL/lUbe+uj/YH4V2/+kOxH7epvT/iTE0vWugAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr5fblfsh3V/8Ai6D7P6pAPxu+yBy37B/AYm3R7rn8h/4efouX++++1AsRrEAAAAAAAAAAAAAAAAAGUXZP/jc9t/46umn2x0zs/Rfp1Z05+nPG/v7eGGDfaZ/I+eM//Fn1r/8AlzkVnssxaPIAAAAAAAAAADRH7ebs8udwHbHHq1xTV1y+f9D7ld34xLFbmbtOI3btbe4wrk4xlKOJqbGZn72filPFcaVZS9PmjBnjr0hPP9M/gtqYvPyHCT8f6yve+XUme2bHPb+sxVvkzz+hlal7qX2iqeEnjfPh9z29Gv0l4oVjjO+fL5NbR6hpj8/HbNKzNYnZ5DNr6nFV7zPeM0REd+yCGg02pgAAAAAAAAAAAAAAAAAEon3c3u4hxvm/Nu1Plm19Ov5pC7yrp5ayb3nxv8GxbubPUYUJSpSFqerxdntbkaRrWV6M5er5+EnPZ46sjW3d3pbay9qbsTtcfFrR/t+OsTlxUifonFXJlmP7Lv8AbUZe+Q9n23M9L9M+PfAaEW2+mr4+A6wyYcfb/Wjby3po8js2iJm2Sm9n0tCkzPpjmsdvTumHpeNdQAABo/8Absd3le3jtSyunPHNl9E591wyI8YwJY16kM/Wcet3K5232VLdK+r6Lm42uy9JcuSj6PObWFJeutKMJ+OXVv4X+lr8drZfJv8AN2jWp5Z+vx68T582Tt8/JeuO+CZn0nzzHfus+91h7PP82Dx7wdZczpfVHSfhfitzm1GfF5tTe5i9PqXjtLzzEV+qNbNua/J0pWfP21ot28vdAnrWta1rWta1rXzWtfnWta/XWtfv1qgm2uvl8gAAAAAAAAAAAAAAAAAHe/bL0M5L3IddOm3RriuHfy9jzXkmHr79bEa1rjauzG5n7jLlLxWNumPqsPNuwlP9DW5CEfEqypGv3OmuE2eo+c43h9Wlr5N3Zpjt5Y7+XFXvkzXmflHlxUvMTPp3iIYr8bfFHhfBnws608SOe2cWvpdM8Ls7mL4toiM+/lmmpx2vWO8Tec2/sa2O0V9Ypa1vSImYsz+inSbi/QzpVwTpRw7CsYWi4RxrT6GxTHt0tUzMjX4GPjZm0vRjSlPpW0yrV3Py5UpGk8jIuSpGPnwso4XitXg+L0eK06Vpg0tbDgr5Y7ee2PHWt8to/s8tonJefTva0z2hpK+JnX/OeKXXvVXX3Uezl2eU6n5vkeVy/FvN51sO3tZc2to4pmZmNfRwXx6uCszPlxYqR3nt3ntJ9R0UAAAAAAAAAAAAAABDM95m/X97dPxZcr+0GrQ69pT8funv0s2v4xjbIvuS/sTeMf6t+B+9G6jNI2LswAAAAAAAAAAAAAAAAEn/AN2hr/yt9dI/h4Zj1/m2Wpp9X/6VUmvZt/HbnP8AtOv8JhUde+uj/qfeFtv/AKS5o/8AMuQn5/rfvJjKXzXMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAV8vtyv2Q7q//ABdB9n9UgH43fZA5b9g/gMTbo91z+Q/8PP0XL/fffagWI1iAAAAAAAAAAAAAAAAADKDsor47t+3D8dXTSn8/MdNR2boz+qzpz9OuM/jmFg72mI7+z54z/wDFl1tP7XTnJSs+FmTR4AAAAAAAAAAAfH5DodXynQ7rjW7xbebp+QarYaXa4d2NJW8nXbTEvYWZYnStK08Xce/chX79PV5p83p2MGLawZ9bPWL4djFkw5aTHeLY8tJpes/cmtph9HiOV3uC5XjOa4zPfV5HiN/T5PQ2MczF8G5o7GPa1stZjtPfHmxUtH2+3ZWw+0S7Xdv2ld1fU3pjl4l21oLu7yuRcNzK2a28XN45vZR2mNDCl4pC7Z1c82WpnO3WVKXsKcJVpOMqUrj8QumM3SnVPJ8ZesxgnPbY079u1b6+ftlrFJ7dpjFN5xTMf11Jj5+jdH9j3xz472gfAbojrjXz478tj4vBw/UmvGSL59bmeKi2hnts17zbHk3q61d+tbxWZx7NbViazEzg66SlAAAAAAAAAAAAAAAAAA7Z6FdWeQdDOr3T7qvxjMyMLa8J5Rqt1SeNOtu7fwsfKt/mng+qlK1pb2GtllYN3xTzW1kTpTxWtK0+rwfK7HB8vx/K6t7Uy6W1izRNZ7TalbR8XH6fRkx+ak/cs6B4pdAcR4o+HvV/QPN6+HZ0Op+D3+MmuesWpi2c2C/1Dtdp/r9Pdrg2qfavhr37x6LODoH1f49166O9POrfGMrHytXzfjGq3Na41yl21i7C/iWvzW13rpKXmet2VMrBu0rX1RuY8qSpStKrLOB5fX53iOP5bWtW+Ld1sWb62e8UyWpHxcff7eLL5sc/drLSJ8WPDzl/CjxG6w8PucwZsG90xzm/xsRnrNMmfTxbGT6g3PLMR9bu6U4NqkxHaaZYmszExLt99djwB4cjIsYmPfysm7bsY2NZu5GRfuypC1ZsWYSuXbtycq0jC3btxlOcpVpSMaVrWtKUflrVpW1rTFa1ibWtM9orWI7zMz9ERETMz9p7MOHLsZsWDBjvlzZ8lMOHFjrNr5MuW0Ux46ViJm173tFa1iJmZmIiO8q7/wBsB3b3u67vA5pl6rNu3uB9MsnI6f8ADsaU6yt26aS5HD3+VCtPTbvW87f42xy8W9GHiuNfhSM5xr6pV8+LnVs9VdXbt8V5tocba2hp1mZmI+BPk2LR8omL565L0mI/E2j1luC+7v8AZ9x+Afs7dNa2/rUx9V9b4cPV3UmaKxW955Ok7HE4LRPe+O+rxObT18+K1u8ZsVptWtvrY1WsXJ3gAAAAAAAAAAAAAAAAAJgPu6vZpHR8V5X3c810/wDwjyemXxLprTNsUpLH1eHsYWtxu8ak40uWsmWbrL+DZvUrSFzBy7lYxlSdJ0lx7PPR/wAHV2+rd3D/AEza82pxvnr+JxUyds2esTHeLTfFbHFvlNLz279+7Xe98V7SE8pz3Aez30zyXfT4OdfqDrX6ly94zb+zp2ycdxeea2mmTBXW3cO1kxzE2x7WvTvas1mqUulAooAAAAAAAAAAAAAAAAQzPeZv1/e3T8WXK/tBq0OvaU/H7p79LNr+MY2yL7kv7E3jH+rfgfvRuozSNi7MAAAAAAAAAAAAAAAABJ592il/yxdcofh4Par/ADbTT0+f9H/zSY9m38eOc/7Rr/C4VH3vra/9Tnwut9rqjJH7ehyKY+mA1yAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFfL7cr9kO6vfvx0Hj8n9XT/SgH43fZA5b9g/gMTbo91z+Q/wDD39Fy/wB999qBYjWIAAAAAAAAAAAAAAAAAMn+yqvju37b/wB/rX0zp/PzLS/0OzdGf1WdOfp1xn8cwsHe0x+R98aP+LLrf/8ALfJLPlZk0eAAAAAAAAAAAAEdj3hDs+n1a6D6TuL4lqvpHMOjd2zicili2Pi5mw4Vss6tj4UbVqnxJ012y2ktlkX60uUtYli5WfotwrKkevH/AKRnluCwdRamLzbnDzWmx5K975NLJeazWIj1n4eTLOW1u0+WlZ7zEQuH90R7RFfD/wAVuU8HOoN/4PTviPjybHDxny/D1tPqfT1Yy/EtfJPkr9WaejXSw4oms5NjNWK+a9orMI5Cxs4gAAAAAAAAAAAAAAAAAJgvu5fdvXfcP5z2o8s21J5/E5XuX9PbeVfpDzpM3LtV2uoxKXZerIyfzTz87ZVt261nbxYTl6KW7fqpLn2d+rJz6m70rt5e99TzbfHxae39IvePi4q9/W1vi5L5O0fKsTPbt6tdv3yPs+xxPUPS3j50/wAfNdXqCMfTvV98GKbf66auveNDkdiaR2w4fqHU1dLz3iK3z3rHnm9orMpNJ9RWA1b+147tcbtR7P8Am2w1+dbxuddSce9wDhNms/TcuZW3tVhubsYxrGdK4/HvzVvWpxlH03rcK+a1p6a4w8W+q69K9I7uTHeK73I1nQ0o79pm+aO2aft/W6/xZiftxCdPu9PZ/wA3j37RPTGnuat83S3RebH1b1NkinelMHHX83G45mYmkxl5j6gx5KTFvNivaO0RPeK7XIyL+XkX8rJuzv5OTeu5GRfuyrO5ev3pyuXbtyVfnKdy5KU5yr86yrWtfrV72ta9rWtM2taZta0z3m1pnvMzP0zMzMzP224XhxYtfFiwYaVxYcOOmLFipEVpjxY6xTHSlY9K1pSsVrEekRERDwvx7AAAAAAAAAAAAAAAAAGRXah0A5J3OdwHTPoxxnEvZORy/kmLjbG7C3KVrC0uHC7stxk37lP0FiNNZhZULNy7KMK5E7UP0UpRjLsPSvAbPU3P8bw2tSbW29itckxHpTBSJyZrWn5V/pVLxEz6eaYj1+TD3j54tcL4IeEnW3iVzexjw4eneFz5tPHe9Yvs8nsWx6XG4MVJ+uyzO7s4LZK0ibRhrkvPaKzaLMvpN00410d6bcK6Y8RwrODoOE8a03HcG3ZtwtfGjqtfj4U829GEYxllZs7EsrKuUjH4l+7cnWlKy8LJ+K43W4fjdLjNSlcevpa2HXxxWIjvGLHWk3ntEd7Xms2tPb1tMy0mOv8ArXmvEbrTqbrfqHZybXLdTc1yPMbd8l7X+Hbf282zXWxzabTGDVrljBgp3nyYsdK957Ow30HTwAAAAAAAAAAAAAAAEMz3mb9f3t0/Flyv7QatDr2lPx+6e/Sza/jGNsi+5L+xN4x/q34H70bqM0jYuzAAAAAAAAAAAAAAAAASc/do5f8ALT1vj+HgUK/zbbS0/pqkv7N34883/wBoR/DYFIXvrI/6mnhhP/0rtH/o/k5j/BKZKmC1xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH5WtI0rKVaUjSla1rWvilKU+uta/epQ+XzfsRMzEREzMz2iI9ZmZ+URH0zLjmTzHieFdrYy+SaPFvR/VWr+zw7Vyn8MJ3oyp/M41tzVpPlts4K2j5xbLSJj9aZiX2MPTvPbNIy6/C8pmxz8smLR2clJ9O/pauOYn0mPpe/rt7pdv5/Mvba7Y+PPn6FmWMnx4p5r5+DOf3vn/AAfN7MefBl9MWXHk/QXrb/BMuLucXyXH9vq7Q3NPv8vqnXy4e/f5f7ZSvzfVe1wAAAAAAAAAAAAAAAAAFfP7cv8AZDurn/5vQeP/ALg6z+nygH43fZA5b9g/gMTbn91z+RA8Pf0fLd/7rb3+Ls0/sRrEQAAAAAAAAAAAAAAAAHK+B8w23Tzm/Due6GUIbvhPKeP8t1FbtJVs/mnxzbYm4waXowlCU7NcrDtUuwpONZQ9UfVTz5crR3MvH7unv4JiM+lta+3h7+sfF18tM1O8RMTMeakd47x3jvHd8Hqrp3j+r+mOo+k+Vre3GdT8Fy/T/IxjmIyfUPM6Gxx218O1q2rXJGDZyTS01tFb9p7T27LBP2fntWOgPebxHj+ky+Ta3hXWzHwMbC5FwbkGbY12Rs9vYtRjfyeMzzZY/wCbVjLjSOZ8LApkyxaXZ2Ls6zsXK0n30D4p8D1jqa+G+zj0uarjrTY0ti9cdsuaI7WtrTfy/GreO1+2PzzXvNZnvWZajXtb+wX4tezd1Dy/J6/CbvU3hll2s+zw/VPEa2Xcw6PH5MlrYsHN11q5fwNy68zOtN9ucNc80rlx1iuWkNrTKaBQAAAAAAAAAADinOuG6PqHw3lPBeSYtvN0XLtBt+O7XHuQhOk8HcYF/X5FYUnGUY3YWsiU7U/TWtu5GM6fONHF3tPByGntaOzSL4NvXza+WsxE96Zsdsdvn39Yi0zE/RPaX3uluo+U6Q6k4Lqnhc99blenuW4/mNDNS1q+Xa47axbeGLeW1ZtjtfFWuSneIvSbVn0lWfd6/bjve1buV6o9HdziXMfG0HI8vI49e+HKmPlcb2vo22jlj3q+YZH0fWZ2Li5Fy3KUaZNq7CtIyjWEa2utOnc/S3UnKcPmpNa4Nm9tee0xW2tl7ZcHlmfS3lxXrW0xM/XRMekx2jdh9mfxl4rx58FehfEfjdimXNy/Da+HmMfnrObBzWh5tDlIzY47Ww/G3dXPsYaXiJnBkx2jzVmLTim6szyAAAAAAAAAAAAAAAAAyg7Ne4Te9r3cj0s6x6TMniw41ybDhu40lP4eRx3aevVb63dtxlGlz06nOzLlmkvVSN+FufprWNKOzdHdQZ+mOo+L5jBeaxrbNIzR9FtfL3xZ4mPp/pV7zH2rRE/OGDvaP8IeK8cvBjrzw45PXrntzfB7NuMtMV8+HmdHy7/E3x3mJnH35DV1qZJrMTbFa9O8RaZWZnA+ZaXqJwvinO+O5NvK0fL+PafkervW7kbtK4W51+PsceE5Q+XxbdrIjbux8UlC5GUZRjKlaUsn0dzDyOlqb2vaL4NzXw7OK0TE/WZsdclYmY+mIt2mPomJiYhpL9VdN8n0f1Lz/SvMYb4OU6d5jkeG3sd6WpMbPG7ebTzWrW3r8O98NrY7d5i1JrMTMTEzyxy3wEDD273d5b7he6m9004xs6ZnAeh9mvGseuNe9eHseUyh8Xe5d23SUoxzdVn5Ox0lZU9Pi3YlGsfPmqCnjn1bHUHVNuN1snn0OEidavlnvTJszHfPeYiZ+vxXtkwzP2q/ntrT3Vns838IPAbH1rzujOt1b4oZY5rNGfH5dnT4KLfD4rXpea1mdbf1MOnycRPmjzZYmJ7dmjZhJaIAAAAAAAAAAAAAAAAAAmRe7tdm39x/T3lHdjzTT1t73n1Mri/T+mbj+i9h8b1+yhDZ7GFq9D4tq/l7HVVpi5Mawje12VWsKThdpOswPZ76P+pOP2uqt3D2z7/m1dDz17WprY8sRlyREx3i18mL620du+O30xPdrje+G9o/8MXV/BeAPTXI+fi+k/qfnerp1c3mxbPNbmla2lpWvjt8PJi19Lfic+GfPOPcwx5prenliTskwpAAAAAAAAAAAAAAAAAAQzPeZv1/e3T8WXK/tBq0OvaU/H7p79LNr+MY2yL7kv7E3jH+rfgfvRuozSNi7MAAAAAAAAAAAAAAAABJt92lr/y49bKfh6fef5txo6f0pK+zfP8Ar3zMf/MO/wD5XB2/xqRvfWR/1L/DGf8A6X9v2+N5Wf8AEmVphtcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB0T137mOiHbTxm7yzrR1C49wrWxtzuY2Psthi29ts/R59VvUaqd6GZs71K/L4WJauz9VaU8ea0fC53qThOm9adrmeQ19LH2ma1yZKRly9voxYptF8k/cpEyyp4VeCfif4185TgPDXpDmOpt2b1pnzaWnsX0NHzdu1+Q364ra2ljnv38+xele3ee/aJR/+473kTpZx2mw03bb002fOdjbrdhhcu5jTL1Wgrcj5jGt3j87Ws29y366Vr6refGk4VpWNafXXAnUXtF8Xr/Ew9Ocbl3ckd4pt7nmxa/f1+evNceWYiftZI7wtr8Gvcx9d8xOnyXjR1rpdLad/Jba6e6cnX3+Xilu0zFOXrfd4+l/LPby31LTW0TFon5NHvWn203f11iyMmNnq1d6caXKrOl7j/AsDFwtdO3KtfTCV3b29xsI0hTx4rbzYV8/XWtPkwnzPjL15y9reXlp47DaZ76+hjpTHMT8o75ozZI7fcutA8NPdqeyd4c4cM5PD+nWXJYIrOPl+rNvPs7lLxEea0U463Hak+aY9YvrWiI9IhgRyDuO698pv3snfdYeomfevzrcuz/uq22L651r5rX0YeTjwjStf+bGNI/e8ePk6JsdRc9tWm2fl+QvaZ7zP1Vmp3n86lqx+8lfxHg34UcFix4eK8Ouj9XFirFMdfwB4/P5axHaI82zgzWme30zM2+64bc6mdSLsqzu9Qeb3J1+uVzle+nKv8MpZ9a1/ncOeS5GfWd/dmftztZ5/w5HY69E9GUiK06R6YpWPlWvAcVWI/OiNSIe5gdXOquryLOVrupXPcO/j3YXrU7PLt9H03bcqShKsPp9YS8SpSvpnGUa/VKlafJ54+W5TFaLY+S36WrMTE1288dpj1ie3xO3p92HH2/D7oPexZMG50V0psYstLY8lcvT/ABNvNS8TW0eb6k81e8TMd62iY+cTEs0elntW+/PpJLFs8e7gOVZ+oxfRT8wt7a1ey19+Fuvmlu9cua+OwlGv1V9GbCVaf853Li/FPrriZpGvz+1kw0/6xnjFkx2iJ79rTOP4nb868SjX137BPspeINdjJzHhHwOryOfzf668Vk39LcxWt87Y6U251ImPnHm1rRH2uzdV2w+8jZ1q/rdB3TdMcS5iS+Hj5HNun1M6xXDtxrSks3YaXLv7vM2N2tK1rK3g1xqVrTxGNPv5n6Z9oy8Wx4OqOMrNJ7Vtu8f56+SPpvkw3tmvkn6Zik1+592tDxw9zFq3xbvLeBPXGxTYr582Hpjq6dXLGxee811tTk9fFxmvp0j0it9uM/aJ9ZlJb7eu5/oj3ScNxucdFed6bl+qu2oXM3ExMux+bOluT8UpjbvUfElnarI+dKxs5tmzclCUJ0j6Zx8yQ6f6m4TqjTrvcLvYdvFMRN6UvX42GZ/rc+LvN8VvX5XiJmO09u0qU/F7wO8TvAvqPN0x4l9K8l07v0yWprbGxgyzxvJUr375uM5DyRq7+H0mJya2TJStq2rM96y7/ffYlAAAAAAAAAAAAAAV8/ty/wBkN6uf/m9B/wC4tagH43fZA5b9g/gMTbn91z+RA8Pv0fLffbeaf2I1iIAAAAAAAAAAAAAAAAAD6em3e449scXb6HaZ+n2mDehfxNhrcq9h5ePetypKE7V/HnC5GtK0p8qS8Vp5pKlaVrSvtw5s2vkrmwZcmHLSYtTJjval6zHymLVmJhweR4zjuY08/H8ro6nI6Ozjti2NTd18Wzr5sd4mtq5MWat6WiYn6Y7xPrExMRKTx7ML26m14XPR9Eu8TbZW843cuY2p4x1YuwlLZaT4k42sPH5V8KMrOTrYTlHGrsI2cKmFYrHLzsi5CxelOS/hn445dKcHC9X5bZ9aZri1uVt3+Jg7z2pXa7RMXx9/rfiRWnkrMWvaYiZUge3D7rPQ6lrynid7OfH4OL5qlM3Ic50BS0Rpcp5K2vsZuBnJaMmDdvWJzfUk5NmdnLE4NbDS2XHWsvHjXJdBzHQ6rlHF9tgb3j+7w7Ow1W31mVZzcDOxL8aSt38bJx53LN2FafKsoTlSkqSjWvmlaJa62zg3MGLa1cuPPr56RkxZcVovS9LR3i1bVmYmJ+5LXo5rheW6c5bf4PneP2+K5fi9nJqb/H72DJrbWrsYp7XxZsOWtMmO0ekxFqxMxMTHpMPuPe+WAAAAAAAAAAjIe8Vdof8Adj004j3UcT1VJ7rp5cxuNc8u41qlZ3+L7LOnZ12ZdjClLlzItbjZ4lid6VZ0t4lukaxjGHqpGn2hekvqzjdTqjUxd83HzXW3prXvNtXJeYx3mI9ZtGbJSvf17Uj6Ihd37nX2hvwuda9Q+A/P7814zrCmbm+lKZskxXFzulq1ybutjm8+SmLJx2lny1x1is32LzPeZt2mGsh62PQAAAAAAAAAAAAAAAAAE3/3fHu4udX+3vddAOUbOuVzHotkXr2npk3viZufwrZZsb9rKn5lWtLOuz9pa1NikYxpGzYtx+daeazX8AOrJ5fgM/AbWXz7fDWm2HzW73yaWW/mi0+v4nHkyxhr6R2rWPz2sJ73b2fKeHni9xni3wejGv054l4seLkfg4/JravU2jqziyYK9o/2zd1NDJyGWZme+TLefTv2jZ97Qzua1Pah2p9U+qGZl2rO7px/K0HEsWt6lvLzOQ7/ANGnxJ4MPPxL1/WfT67WUbcZVjZwrk50pCMpUyZ4g9S4uleleU5O94rn+p76+pXv2vfYz9sNJpHfvNsXn+LMR37VpMz6IO+yD4I8h4+ePfQfQ2vr3ycZ+C+Dluoc/wAOb6+vw/E+bkdiu1btNMePd+pY0K2vNYtk2a1rM2mImtZ3+92fJ97ueSbrKuZ243+12G52mZdlWVzK2G0y72bm351r/wA69k37lyv3vMvlTwrh2M+TZz5tnNab5tjLkzZbz87ZMt5ve0/dta0z+u3TeJ4vS4Ti+N4bjcFNbjuJ0NTjdHXxx2pg09HXx6utirH9jjw4qUj7kPkPU+gAAAAAAAAAAAAAAAAAyd7Ou3XkfdP3FdMujPHsS7kU5NyLG/NvIjanLHwOP4ELuy3GRl3o+IY0LmDhX8WxduyjCuXfsW6eqc4wl2bpDp7Y6o6h43htek2+qdivx7dpmuPXxxOTNa0x6ViaUtSszMR57Vj5zEThH2i/GLhvAnwd638SeY2MeKeD4fN+BmGcla5tvl9u2PS47Fr4573zWptbOLPlpjra0YMWW8+WtbWrZh9NOn/HelXAOH9OeJ4VrA49wvjmm43q7FqEIecXT6/H19u9dpCMYzyMiOPS9kXfTSt29OdyXzlVZLxuhr8XoafHalIx6+lr4dbFWIiPrcOOuOLT2+drRXzWn6bTMz82k71r1dzHXnVvUXWXP7OTb5fqXmeR5rey5L2v2z8jt5tu+Ok2m01w4pzTjw07zFMda0j0iHOHNdXAAAAAAAAAAAAAAAAAQzPeZv1/e3T8WXK/tBq0OvaU/H7p79LNr+MY2yL7kv7E3jH+rfgfvRuozSNi7MAAAAAAAAAAAAAAAABJn92lr/y89ao/h6cTr/Nu+P0r/pokn7N/4+8z+l0/w2BSX76uP+pT4aT9rrOsf+jOWTMUxWt2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0B+1F9tDxPtWlsejnQK9o+cdbZWrmPutlcuTz9BwSl6lYU+kywMizG/vYw9V6zh1zIzxJSxr+VjXbN2MZ4F8TvGTV6W+Jw/Azg3eamJrmyTM5NfR7+n180tXzZ+311aef63vW1qzEwtp9hj3a/P8AjxGn4jeLOPlOl/DGuSmXjNKlK6nLdVTjmLT8CNvDkti4qbdseTZjXmuxEZ8WDPTLjm1YYnWbr51d7geXbLm3VvnW+5lvdnkzybtzZ5k5YmPWUq1jaw8C1S1hY1u1HxCHwrEZ1jGlZynLzKsOOZ57l+f28m7y29n3M+W02mct58le8+kUxx2pWI+Udq9+3zmWyX4b+E/h74R9P6XTPh90rxXTfFaOGuGlNHWrGxl8sdrZNjbyefZz3yW73t8TLasTMxWta9ojp58hkQAAAAABkD26dz/WftY59quofR3mOx45ttbl2r+TgRvXLml3WNGUaZGv22urKlrIxc2xSeNflb+FlRs3JVsZFm7GFyP3+nepuZ6X38XIcPuZNfLjvFrY/NM4c1Y/FY82Pv5bVvX620x2t5Zny2ie0xiTxj8D/Dbx36S5Do/xH6c0+Z4/d18mLDt2x0pyXGZpiZw7nH7kVnJhz62Xy58Vb/EwWyUj42HLSbUtPq9mx7Rjp9369LYZ+NPF0PVniuPYxuoHDK3vTdx8msY+jb6yzelW/f1GbSVKW78ZX7cci3k2a3qzszjGePhx4h8f13xnxKTXByurWtd/T79prbtHbLji0za2K/f0tE2jzRavfvHZqce2j7HHV3so9dW1M9djlegOfzZc3SPUvw/NjzYYtbzcfvZMdYxYuR1prM3xTGK9sNsOWMcVyVm2y1khCkAAAAAAAAAAAABCP9tZ2Td0fM+9Hl3Urp/0T6i9RuIc0wdVlavacD4nu+V2rFcPX4+vvY+w/MTCzPoV+l3DuTjbyK25ytztzpH0zjWsLPGfovqfc6y2+R4/heQ5HU3KYr4sujqZ9qK+XHXHNcnwaX8lu9JmIt2mYmJiO3q2cPdne0z4F9N+zV0/0X1b4m9HdHdQ9Nbe/r72j1Xz/GcBky/VG5m28eXU/BPZ1vqrFOPZpWb4fPWL1vWZ70tEahf9wl3qf+Sf3Df+iLnP9iMSfhG6z/Mr1B/cne/zKw3+eo9mn/f88IP/ALwulv8ASZ/uEu9T/wAk/uG/9EXOf7EPwjdZ/mV6g/uTvf5k/nqPZp/3/PCD/wC8Lpb/AEmf7hLvU/8AJP7hv/RFzn+xD8I3Wf5leoP7k73+ZP56j2af9/zwg/8AvC6W/wBJn+4S71P/ACT+4b/0Rc5/sQ/CN1n+ZXqD+5O9/mT+eo9mn/f88IP/ALwulv8ASZ/uEu9T/wAk/uG/9EXOf7EPwjdZ/mV6g/uTvf5k/nqPZp/3/PCD/wC8Lpb/AEmf7hLvU/8AJP7hv/RFzn+xD8I3Wf5leoP7k73+ZP56j2af9/zwg/8AvC6W/wBJn+4S71P/ACT+4b/0Rc5/sQ/CN1n+ZXqD+5O9/mT+eo9mn/f88IP/ALwulv8ASZ/uEu9T/wAk/uG/9EXOf7EPwjdZ/mV6g/uTvf5k/nqPZp/3/PCD/wC8Lpb/AEm8d3sX7z7Fq7fv9qfcHas2bc7t67c6Sc4hbtWrcazuXJzlpaRjCEI1lKVa0pGNK1rXxR+T0P1lWJtbpbn4iImZmeJ3YiIiO8zM/B9IiPWXnj9qT2bMuSmLF49eEWTJkvXHjx08Qel7Xve9orSlaxycza1rTFaxEd5mYiPVi7mYeVr8vKwM7Gv4edg5N/DzMTJtTs5OLlY12VnIxsizcpG5av2L0J2rtqcYzt3IyhKlJUrR1i9LY72x3ral6WtS9LRNbVtWZraton1i1ZiYmJ9YmO0s5a+xg29fBt6ubFsa21hxbGtsYb1y4c+DNSuTDmxZKTNMmLLjtW+O9Zmt6Wi1ZmJiXrvF7gAAAAAAAAAG6/2WXtZufdnXMdV066nbXY8v7f8Af59nDz9bm3ruTm8LuZco2IbnSZFazuQxcW7K3fzsO7bybdzEjk28eOPdnC7DM/hf4rb/AEhuYuO5PLk2+Az5K0yY72m19KbT5YzYbes+SszFslJ80TSLRXyzMTFZvt2+wB0n7RnTm/1j0RoafT3i5xOpl2dTd1sWPBq9TU162y243lMURWls+ekXxauzS2G9Ni2G+a2XHS1LTv8AhHNuMdRuJcf5zwzcYW/4vyfWY2202219+1k4uXh5UKTjWN2zOcKXLUvVZyLXq9djIt3bNykbluUaTn0t3W5HU197TzUz6u1irmw5cdotS9Lx3jtMTMd4nvW0fOtomsxExMNVfqfpnnOjeoOX6X6l47Z4nnOD3s/H8lx+3ivhz6+xgt5bRNMla2mmSvly4cnby5cN6ZaTNL1meVOU+CAAAAAAAAA656udNOPdYumfN+mPKcSxmaTmvGtvx/KhkW6XYWJ7HBv42PnQhKlafHwMi5azMeVaV9N+xbl4r48Pnctxuvy/G7vGbVK3w7utm17xaO8VnJS1a3iP7LHaYvX7VqxLuXh71tzHhz1t0x1xwWxl1uT6Z5rjuXwWw3nHbLXT2sWfNq2tExPwtvDS+tmiJjzYst47x37qynuh6F8i7bevPUzo1yfDv4efwzk2dh4kb8fTO/pcmdM/QZlflSlfpmlysDJrWlKUpW7WninjwrW6n4PY6c53kuG2aWpfS2b0p5omJthtPnwX9fn58NqW7/dbt3gb4pcP4z+FPRPiRwmxi2dXqXhNXZzzinvTFyeGs6nLa3zmY+puSwbWCIn17Y/nLoN8FlgAAAAAAAAAAAAAAAABn/7M7un2faX3bdM+fRy7tri243GPxLmuDS5W3i52j5BWerhczPH/AOB1WdmY238+Y0pPCjWVfRStK998NuqMvSnVnGb8XmNXNmrqbuPv2rfBsd8Xe/3MV71zfn0jv6QiX7bHgTo+0B7PvW/SdtfHfnuO47N1B0xtTSL59XlOIiu9amt3if6bv6uvn475TM12piI7zDZv7wZ3l67rF1V4L0D4FvLey4P091Gs5busjByKXsHack5Lp47LV5Fm/YlWzesWuP7uxauWqyufDyoS9VYzj6Y5K8fuscfMcro8DoZ4yaXH4cW3ntS3emXY2cMZcVoms+Waxr54iY9e1o+iYmEIfdF+zfueHPQXVXix1Zxd9LqjrDkN7p/jMO1hnHtaHC8JyNtLew5MWWvxMWXJy/GZb0v2pN8F47RNbd5jko8LkgAAAAAAAAAAAAAAAAAEz/3eHs2l0+6Vck7puZ6atjk/U6mTx/hNM7GraysDiGv2cY5eVSzfj8W1PZbDVWsnDyoUtUva7IpWHxLd2k6zH9n3o78D+K2eqN3D5dnk/Nr6Xnr2tj1MeSPPbtMd4nJkxRalo7d8dvTvE951svfA+0fXq7rzhfAnprkoy8H0P8Hl+qJ1c3nwbfUW5pWtr4JyYp8l6aWnv3wbOC03nHuYe14pek1iSykipUAAAAAAAAAAAAAAAAAAQzPeZv1/e3T8WXK/tBq0OvaU/H7p79LNr+MY2yL7kv7E3jH+rfgfvRuozSNi7MAAAAAAAAAAAAAAAABJh92ml47gOtEfw9M71fH8G94786f0pJezf+P/ADEf9jbfvZ9f/lUn++qj/qSeGtv/AKbY4/8ARXMT/iTN0xmtuAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0i+2T9pRj9nXS+vS7pvscefXbqVqcq1rZwuxnf4Zx7L+Ngz5NPHjL1Uy7k4ZsNRO9+kQzcKsrtrIhStquFPGHxHr0hxc8XxuSs87yWG8YpiYm2nr37452ZrHyvMxeMM2+ti9O81tHos693D7Fmb2jOuY6660081PCrorkMF92t8c0xdS8xrzj2qcLTNavadelba1uRrj/AKbbV2e2PJhvNciBru91teR7fZb7eZ+VtNxt8y/n7LY5t6d/KzMvJuVuXr167OtZTnKUq/f8Rp4jGlI0pSkF82bLsZcmfPktlzZr2yZMl5m173tPe1rTPrMzP/JHo2sOM43Q4bj9PiuL1MGhx3H62LU0tPWx1xYNbXw0imPFjx1iIrWtYj7tp72tM2mZn5b1OcAA/qEJ3Zwt24SuXLkqQhCFKynOUq+IxjGnmtZVrWlKUpTzWpETMxERMzM9oiPWZmflER9My8bWrStr3tFaVibWtaYitaxHeZtM+kREeszPpEOd4fSzqVsMWWbgcC5fmYcI0lPKxePbS/jxjX6pSvW8aUKUr+GsnOpxfJZKzfHobl6R87V18tqx+vFZh1fZ666L089dXb6s6d1tm0+WuDPzGhizWmPSYjHfPW0z3+js4jsNVs9Terj7TX5mvv0r4rZzce7jXaV/ft3YwlT6q/XRxcmLLit5cuO+O39jes1n9qYiX39Tf0t/HGbR29fcxT8sutmx5sc9/l2vjtas9/z3oPW5YADKrs17rOednXXbiHWPhGXfpDVZ+PY5NpYXJRx+Q8Zv3aWtxqr8PNLcrmRr7mVZxbs6S+j3rtL0aeYu0dH9U73SHOanMaV7dsWStdnDE9q7GtM9suK30d7Y5vFJnv5bT3YH9o/wF6U9o3wr6i8OOqNfF5t/UzZeE5K1Itm4fm8VJycdv4rdpvFMO3TBkz46TX42PHOO09pWQvb1114P3IdIeFdYen+zx9lx/mGosZ8Y2bsZ3cDM/RWs7XZdulfXYv4uVau2/RdjCc7dLd2kfRcjWti/T/OaPUfE6XL8flrk19vDW8dpiZpf1rfHePnW1bxMesR3jtPbtLTK8XvC3qjwZ8Q+pvDrq7SzaXL9O8jl1LTkpNabet6ZNXcwX7eXLiz4L47+bHNq1vN8cz5qWiO6X2WNAAAAAAAAAAAAAAAAAAAAAHw+T09XG+Qx+9XR7an8+BkUejZ9dbYj7eDL/B2fU4Se3NcRP2uU0J/a28UqsrrHTx1d6qU/B1I5xT+bk+0oq/5j8duU/THd/jOVvY+HM9/D3oOft9GdLz+3wmi64fOdzAAAAAdg8e6TdUOW27d3i3T3mfIrV7x8K5peObbZQuefq9EsTFu0n5/82tXP1+K5PbiJ1eP3NiJ+U4dfLkifzvJWf/3+nzdR5jr7ofp+98fO9X9N8Pkx/wC2U5LmeP0rU/RxsbGOa/r9n3Nx0A648ehW5vukPUjTQpGkqz2fDd/hR9NaeqkvVkYFunp8V8+fPjx8/qe/NwPN68d8/Ecjhj598unsUj7f9djh8zjvFnwv5e3k4rxD6M5K8z5Yro9ScRtW83ft27Ydu89+/p2+fd1PfsXsW9cx8m1csX7M5W7tm7CVu5bnGviUJwlSkoyjWnitK0pWlflV8q1bVtNbRNbVmYmsxMTEx84mJ9Yl37Hlx5sdMuHJTLiyVi+PJjtF6XraO8WraszW1Zj1iYmYl4n48wAEij2I/tO9h0J53ru2nrTyG7kdI+cbG3hcM22yvTnXhPJc6UbWJhUvTlWNNNtc74WPS3OlK42Xn3ciV+liNLcZCeCviZk4Pfx9N8zsTbid7JFNPLkt/wDEtnJPalPNM9vg5b9q9p9a3yTbzeWO0U8e859h/U8Veldzxq8NeHx4fELpfTvtdScfpY61jqbhNWJybOzOOtfNPJaGt583nrMxn19WmGMXxZm9ptlm9ZybNrIx7tu9Yv2rd6xetTjO1ds3Y0nbu25xrWM7dyEozhONaxlGtK0rWlU062i1YtWYtW0RatonvExMd4mJj0mJj1iY+cNZHLjyYcmTDmpfFlxXvjy48lZrfHkx2mt6XraImt6Wia2rMRMTExMd4eR+vAAAAAAAAABFH9417QaZWu4T3b8Q1Pi5rqY/DupdzEseIysXr9y3puQbG5SlayvSyMjWaO1WtYxpat2o+msvnWK/tEdIxbHpdWamLtOPy6fJTSPnWbTGHYyT9vzWxYI9e3aI9F93ubfaGnBudT+z51FyHem58bqTommxk72jNjxUvyXEadO8RXHXFh3uVydomZvfJMz29ER9E9sFAAAAAAAAAAAAAAAAAP2MpQlGcJShOMqSjKNaxlGUa+YyjKnitJUrSlaVpWlaVp5p8yJmJ7xPaY9YmPnE/bfkxFomtoi1bRMWrMRMTEx2mJifSYmPSYn0mHu7HZ7Hb5Vc3aZuVsMutrHsVycy9O/frZxbNvGx7dblysp1hZsWrdq3Sta+mEIxp8qPPJlyZr+fLe2S8xWs2vabW7UrFax3nvPatYiI+1EQ42no6fH4I1tHWwamvGTLljBr464sUZM+W+bNeKUiKxbJlvfJeYj1taZn5vReDlAAAAAAAAAAAAAAAAAMseyTtr5D3X9yfTPo9o8S7exN1v8AGyuS5dLU54uu43rKXNltb2Zej4hjW8nGxLmBYu3ZxhXLyse3T1TnGEu1dFdN7HVXUfG8RgpNqZtittm8RM1x62Pvky2vMfiYtWk46zMxHmtWPnMROAvac8auH8AvBbrfxF5XYpi2OM4nNg4XXm9a59zmt6aaWhj1sc97Zr4M+xTby46Vtb6nwZbz5a1m0WXPAuE8f6bcK4rwHiuFa1/HuH8f1HHNRi2oQhSGBpsDH1+NW5S3GMZ3p2ceEr1zxSty7WU5fOVVkehpa/HaWroatIx6+nr4tbDSIiO2PDjrjr37fO0xWJtPzme8z6y0perOp+X606m57qzndm+3zHUXL8hzPIZ72tbzbXJbebczxTzTaa4q5M1q4qd5ilIrWPSIcuct14AAAAAAAAAAAAAAAAABDM95m/X87dPxZcr+0Gr/APgh17Sn4/dPfpZtfxjH/wAjZF9yX9ifxj/VvwH3o3v+VGaRsXZgAAAAAAAAAAAAAAAAJLfu1EvHcP1lj+HpfkV/lpv+N/8Ax/zfwJIezfP+yHmI+j8C7T/5xrKU/fVV/wCo/wCG9vtddYo/b4jmkz1MhrZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOqeuHV7ivQbpRzrq3zPKt43H+Dcc2m/zIzvQs3Myuuwr+Xa1+LWfn4mZnSs/R8WzCM7l29OMIQnKtI1+VzfL6vA8Vvctu2iuvo6+XPfvMRN/h0teMde/zvfy+WtYiZmZiIiXffDDw857xW6+6W8PumsF8/L9U8zocRrTXHbJTW+rNnFr33M8V7eXW1a5PjZ8lprSmOtrWtWsTMVoXdP3Ccy7oOufPesfNdlez8/k+6yrmvtXJT+DrdLZuVtazAxLU5Srj2LePCN2dqlaU+kXr8/FKzrSlbnVHUG51Nze/wAxu5LZMmzmtOOJme2PDE9seOkT+JrFYie39lMz9Ldd8CfCHpzwN8Luk/DjpnSx6mpwfG4Kbl6RX4u7yeSkZN7b2MlYr8XLfNa1K3mO/wALHjr3ny95x6dfZeAfe4xxfkPNN9q+L8U02x5ByHd5ljX6rT6nDv5+xz8zJuws2MfFxMa3dv37t27OEIQt25SlKVKUpWtXv1tXY3M+LV1cOTY2M9648WHFS2TJkvaYrWtaVibTMzMREREz3fK5vnOI6b4rf5znuS0+I4jjNbNub/I8hsYtTT1NbBjtly5s+xnvTFjpSlbWta9qxERMzPZKO7Hfd49husXSdQu7/kORqcPLs42wx+l3GbuLHZRjKkb9uzyHa3IZ9mlq/SsbeTg49rBzbFKXYSuwnWPpk70T7PuTNXByHV2xbFS9a5K8ZrTT4kfTFdjLMZI7W9ItSsUvXtMTMSov9qD3wGpxmfk+kPZ34fDyGzgyZtPN11zmPPOlMxM4r5OH0KX1MnxMUxa+HazX2tXLM0tFLViYmRt0d7Eu0joPhWsPpp0K4JpawsxtXMrL1kt5k5EqRpGV65Pe3tlGN2fj1SrZhapSvzhSKRHEdDdJ8FSKcbwejh7R2m18U57Wnt2mZnPOTtM/8GIj7UQpu8Rvap9oLxW2b7PW3ip1XyUWyTfHg196OLwYYm3mrjpXiselM46/KIyWvMxHa0yyItdP+B2LdbNjhPEbNqtPFbVrjemt260/BWEMKka0/e8OwxoaNY8tdLUrX7Ua2GI/ainZh7J1b1XlvGTL1N1DkyRPeL5Oa5K94n7cWtszaJ+73cF5r259BuoupyNHzPpFwDeazKjKORj3eNa3FncjOniVPpWvsYmZHzT78MiNfwV8uDu9O8FyOK2Dc4nQz47x2tWdbFWZ7/8ADx1peP1rQ7T0z4yeK3R3IYeU6b8QureL3teYnDmx83u560ms94/pG3l2Ne3b7VsVoaV+733fvtw6r6nP3XbpKXRLm9uF/Iw9VZuXtlwzYX60lc+DlYubK/tLVy/OtYRvQ29qzalKMpQrCNaVwz1b4B9O8riyZunZ/AXdiJtTFE2y6d59Z7WpebZYm0+nf4sVj09IiFlvs8+9v8ZugeQ1ON8Y618TumL2xYtnfyUx6XUupiiYp8XBsa0YtHJTFXta2O3H5MmSImtbRaYlEO7o+0rrX2g9RM7pz1l4tl6TYWpylqtvbtzu6LkOF5l8PO02zhSeHnWZUjKlymPfvVsXYXLNytLluVKRK6n6U5rpHkL8dzOrbBkie+LLETODYp9F8OWO9Lx9vy2nyzExPaYlsLeBftAeGftD9HavWfhvz2vyenkpWN/j73rj5XiNntHn1eS0bTXZ1clZmPLObFjjLS1MlI8t6zONDrbNYDf97DP2hk+3Lq7DoB1M3l2HSTqvs8XD0t/Nvyrh8U5pm1tYODkW5Tr4x8Tb3467ByqyrTGxYRuZMqQrK5OuevBHxBnp3lvwB5PPMcTyuStMNr2+s1d2/amO0d/xNc1vh47esUpETae3rKpb3o3sg18ZPD23i10TxeO3iD0Bo59jk8WriiNjn+mdb4m1tYbRWO+bY47Fbc2sEVic+e00wVm0RSictZvWsi1av2LkL1i/bhes3bcqTt3bVyNJ27luca1jOE4SpKMo1rSUa0rStaVTdiYtEWrMTW0RMTE94mJjvExP0xMesS1c8mO+LJfFlpbHlx3tjyY71mt6Xpaa3pesxE1tW0TW1ZiJiYmJjvDyP14AAAAAAAAAAAAAAAAAAAAPh8nl6ONchnWvikdHtpefwenAyK+f8z0bM9tbYn7WDLP7WOz6nCV83NcRWPXzcpx9f29vFCrK6x19XV7qpL6/PUjnFf5+T7Sqr/mPXl+U/THe/jOVvY+HMeXw96Dj7XRnS8ftcJow64fOdzAAAbTfZ/eyl68d9OdTf4FqfT7pLg5VuOw5/v8AX36Y2zhbuQ+k4vG7NyeNXa3609WN9JxK5VjFyKXK34Spj3bbKHQXhZzvXF/j44nj+KpaIyb+fHby5YiY81daszX4tv63z189a27+aJ8swgn7W3t7eFXss6v4E7d69X+IG1gvbT6S4ncxTm0r3pb4OfmsuOuaNDFE+XNODY+Blz4Zr8K0TlpZL57ZfY79lPblqdVL7m2H1J5tgwtzyObc5uXNhsbuTTxO5SzhYlcDURxY3ay+BC9rbt2Nv0xuXbkqVlWW/TXhB0X07ixT+BtOS3ccRNt3emcmSbfT2x08mHy9+/li2OZiPSZn5tePxt94v7THjLyG/X8Omx0X0ztWvXD0x0tSmnp48H4mnxNrYja5C2eaRX4t8e5THN+9qUrExEbJNd0/4Hp7VqxquFcT1tqzCNu1DB47qMWkIQpSMaU+DiQr8qUpTzWta1+uta1ZGx8fo4YiuLS1MVaxERFNfFXtEfL5UhDDc6t6q5G98m/1Lz+7ky2tbJba5jkM83taZm0z8TYt85n876Pk93K4lxTOp6c3jPHsyNaeK0ytLrcilaePHjxdxp08ePl4/A876mrf0vra94+1fDjt/hrLi4OoOe1Z763N8vrz3798HJbuGe/z798eas9+/wBLFDrn7Pbs/wC4jCy7HUnohw7N2GRYuWrG71WFPR7LAuzhWEMvFrqb2HiSyLNa0nCuVi5Fuso09dudPNK9V5zw/wCkeoaXryXCad8lqzFc+Kk4MuOZjtF6/BmlZtHzjzVtHf5xLPvhb7XntE+D2zr5Oi/E/qPV1MWWmTLxm/s15TS28dbRa2vnjkMeznrhydvLeMGfDbyzMVtWfWIsftAPYLdRug+r5B1U7b9nsup/TvWxvbHY8QyMeGTzXQ4FJVuX7tmmFaxqbjEw4VlOsMLW1u4+HCt3Iu1pauXKxe6+8CeR4LFscp05ly8nx2KLZcmpasW3cGP52mvw61+NSkd5+tx960jvafSZXteyT71vo3xW3+I6D8ZtHS6G6x3Zx6en1DhzXw9M8tt+WK4seWdrJmnjtjYtEVi2zuxjzbFophpE5KUiOxkY9/Fv38XJs3MfJxr1zHyLF6Erd6xfszlbu2btudKSt3LdyMoThKlJRlGsa0pWlaI92ratrVtE1tWZrasxMTW0T2mJifWJiY7TE+sSuGxZcWfFjz4clMuHNjplxZcdovjy4slYvjyY71ma3pekxatqzMWrMTEzEvE/HseWxfvY16zk4925YyMe7bv2L1qcrd2zetTpctXbdyNaShctzjGcJxrSUZUpWlaVpR+1tNbRaszW1Zi1bRPaYmJ7xMTHrExPrEx8peGXFjzY8mHNjplxZaXxZcWSsXx5MeSs1vjvS0TW1L1ma2raJi1ZmJiYlPG9hx337Dun6CZXS3n2xt5fVHopYxdVeybtylc/f8P8Y8NTuciHq+vEllW9J66Qj8T6BS5P1TlKVZ0eCXXOTqjgb8Xv5IvynC1ritaZ/pmfT+tjDmtHf+tm8YO/aO/w+8+szM6qPvQ/ZV0/AjxXwdddJadtfoXxMy59/Hgx0mNTieou+W3Icbht2/8A4iuvflO1rT5Z25pTtWsVjeazeq4AAAAAAAAAdMdwvRnjncD0Y6idIuUYeNma3mvGNpqrX0qFJ28Pa3MW5LTbKNK+PFzW7SOJnW6/V68ePmlaeaPjdQcPr8/w3IcTtUrfHu62XFHmjvFMs1mcOT8/HlimSPo71jv3j0ZJ8IPEjmfCPxJ6P8Q+C2c2tu9M85o8hk+Bby32NCmeleS0pn1+s3dG2xq39O/lyz27T2mKyTrj0n5D0M6t8/6T8pxcjE3HCOTbPSXI5NuVq7kYmPkz/M3P9EoxrSGx10sXOtVpT0yt5EJRrWNaVVqc3xWxwfLb/FbVbUzaOzlwT5omJtWtp+Hk7T29MmOa3j7lo7ejdy8L+v8Ah/FHw+6S6/4LYw7HHdUcJo8nS2C8ZMeLYzYa/Vur5om0TbT3Iz6uSO/eL4rRPaYmHVL5bvoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACa97vb2Zz6V9GN73Mc001cbmPVul3WcTpm4/wsvXcJwdhH1XPhXo/Eh+a2brMbY4mTGlul3BvxrCs7VykqzP8AADo6eL4bP1Lu4fLuct3xakXr2tj0qZI7z2mO8fFvirkpaO3elvTvE951nPe8+0hXrvxJ4rwS6a5GM/Tnh9OPe5+dbN59fd6n2tS3lp58c+S34H627n09nBabzj2sU+aK3p5YkdJEqagAAAAAAAAAAAAAAAAAAEMz3mb9f3t0/Flyv7QatDr2lPx+6e/Sza/jGNsi+5L+xN4x/q34H70bqM0jYuzAAAAAAAAAAAAAAAAASVfdqZf+Ef1ij+HpVly/m5Dxmn9KR/s3/wBUXMR/2Kv/ABjV/wCVSx76mP8AqM+HNv8A6e68f+h+bn/Emhpkta4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABF+94/wC6CvHOnfTvte0GwnY2fNci3zfmeNauyhclxzAzaR4/T9LlCVLd7a6vZW70ZVnC7bp6JRpTz5jL7RXU31Nx/H9Ma+Sa5d20bu7WLTEzrY7/AOp/lMek5cWSLRPeJj07Lx/cz+Bscz1h1j458tp1y6XTOG/THTWbJji9K8xt6025efr4tXz49De07Y7Vitsd580W79u0OhEFsYgPq6PR7bku51fHtDr8vbbrdZ+Lq9VrMGxdyc3P2GdfhjYmJi49mM7t6/kX7kLVq1bhKc5yjGMa1rSj24MGXZzYtfBjvlz5slMWLFjrNr5Ml7RWlKVjvNrWtMRERHeZntDgcpyfH8Lx29y/Lbmvx/GcZqZ97f3tvLTBrampq4rZtjYz5sk1x4sWHFS18mS9orStZtaYiJlPP9k37LPg/aX010PUrqbxvVb/AK/8oxbe2ytln41MifDMHMx7f0bSYFq5KePDKtQ9eTeyqwnkWr2VK3Gdq5Yp6Z1eFPhfpdKcbg5Lk9fFn5/arGa2TJXzTpUvWPLgxxMzWLxHe1rdptE2mImJj01TPb99uzqj2gOtOV6K6I5nf4jwk4LPfj8OlqZpw16l2tbNf4/J7eSkUzWwZLeXDjwRauLJjwRea3plnzbtPq+pmlWSAAAAxj7qO0vo53d9NNz056scX1+1hl4OTb0m9rZjHccc2U7cq4ey1ubClLsZ4eT8PJjYufFxrk7fi7YuRlOMutdU9KcP1bxubjuV1seWL0tGHP5e2bXyTH1mTHePXvS3a0VnzVmY9azEzE5v8B/aA8RvZ66243rLoDndzj76+1hvyfFxlm3HczpVvH1TpbutaZx2ps4PPhtlp8PPSt+9MtLVrMV2feb2l9QuzbrjynpHzvByI2cHLuZfF97XHuWsHkfHci5OuDscC9Lzavwj6bmJfnZnONMrFvxr6JRrbjXt1j0pyHR/N7XE79LdqWm+rn8sxj2de0z5MmOflaI9aWmszHnraPT5RuG+zd4/9Ie0d4X8F4hdK7WGcm1r01+c4qM1L7XDcxhpWNrT2scdsmG1u9NjDXJWtpwZ8U97RMXtie6qz48ti/fxb9nJxr13HyMe5C9Yv2ZytXrN23Kk7d21chWM7dyEqUlCca0lGVKVpWlaP2trUtFqzNbVmLVtWZiazE94mJj1iYn1iYevLixZ8WTDmx0y4ctLY8uLJWt8eTHes1vS9LRNbUtWZratomJiZiY7J7XsUvaAWe7HoTZ6Yc32MJ9YujuBi6rayv3KfSuScap4jqd9Sla0pKdukrmsuW7dPVGGt+Ncp+jrKs7fBjr2vVfBxxm7kieY4fHXFl80/XbGt8sWf7XeO84piPWIxxafm1RPeY+yTk8AfFTJ1z0xp2r4c+I23n39CMWOfgcLzc955DiZmI71pea03cd7zFZtuzipM+Tyxu5ZqVjAAAAAAAAAAAAAAAAAAAAOIdQs61rOA842V+cYWNfw/kudenOVIwhaxNLm37k5Sl4pGMYW5VlKtfFKUrWvycTkLxi0N3Jae1ceps3tM/KIphvaZn86Idi6Q1cm91Z0vpYqzfLudRcJq4q1ibWtk2OS1sVK1iPWZta8RER6zM9o9VWh1Rybeb1N6i5lmVJ2svnfLsm1OlaVpK3f5BsLsJUrT5VpKM6VpWnyrSvlWBydovyXIXj5X3tu0dvl2tsZJj/C3rehsF9bono7WyRNcmv0t09gvWY7TW+LidTHaJifWJi1ZiYn5fJwVwXaQAG5z2Qfs1M7vY6n151z/Ey8ToR0422Le5FdpCtqnLdxixsZ9ji+NfuRlT6Ne+Lh120rMZXpa+/ft2L2Ne9N+GY/CTw3ydacn9Xb9b04PjstLbE9pr9V5qeXJXVraY/E270+L29fh2tFZrPa0Vt+8O9tXV9mXob8K3SefX2fFXrPj8+Ph8c3jJPT/G57ZdTLzubFS0T8bF5NmNCuWYpXbxYr5MebH3xXnqcN4XxTp7xvVcR4VodbxvjekxLODrNRqsaGLiYuNYhSFuEYQp5nLxTzO5clO5OVaynOUq1rWdenpanH62LU0sGPW1sFK48WLFWK1rWsdojtHzn7cz3mZ9Zlqj9SdS891fzW/wBQ9S8ru81zPJ7GTa3uQ381s+xnzZbTa1ptae1a9/StKRXHSIita1iIhyhynwwAAH8XbVu/buWb1uF6zehO1dtXYRuW7tu5GsLlu5bnSsZwnGtYzhKlYyjWtK0rStaPyYiYmJiJiYmJiY7xMT6TExPpMTHpMT83lS98V6ZMd7Y8mO1b48lLTS9L0mLUvS1Zi1bVtEWrasxNZiJiYmEWD23HspNPsePbbuw7deKW9duNJZlndVuH6HErWxtdfblWmRyrCwbNKzs5GBjShe2dceP0aGBg3sm5Zty+JkIveNXhXhya+Xqvp7VjHmw1m/K6eCszGXHEz5tqmOI7xbHXtOXy/Wxjpa01j1svd92N7e3I6fMcf4A+MXP33OO5PJGr0D1FyuxEZNDctWJw8DtbWTtXJh280Wx6MZrRnvt7WPDTLePJiRCq0rStaVp4rStaVpX66Vp8q0r/AAIkthmJiY7xPeJ9YmPlMfbfgNnvshO4rK7de+DpRtb2wuY3Guc7SnT/AJHg/ErDG2X91Vq9pNHHKp5p6o4W72WHm2vnTxdsxrX5eaMmeEnUNunutuKy2yTXW3ssaGzTv2rk+qothwef9BmyUvH3YQe94b4O4PGL2YOvuPxadM/N9LaP4buG2vJ58+l+AOTHyfKTg9J7Ts8Zp7Gtk7R3nHktEevZYtRlSUaSjWkoypSUZUr5pWlaeaVpWnyrStPnStProsM+fyadMxMTMTExMTMTEx2mJj0mJifWJifSYn5P0fgAAAAAAAACH37xj2gx4/yzhXdjxDU1hruVxtcT6izxLFZUhvMS1chrN1myt09OPYu6+xrNVCdykYXMn0x9dbk6RrEX2h+kY19vS6q1MXbHtdtTkZpX5Z6RMYs+SY9K1nHXFhiZ7d7do7zMtiT3OPtDTy/T/U3gD1DyEW3OAtk6g6OrsZYrNuL2MlLb3GasXnvmy03Mu7v2rSZtTD3maxSvdFrRhXqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMxuw3tg5B3b9zfTXpJqMS7e1WZu8fa8uzqWp3MXWcY1Pr2GwuZtyNPRj2s6OLTV2rtyUY/Sc2zGlZSlGMu39C9M7HVnUvG8ThpM4r565dy/aZri1cXfJkm8x+JjJ5YxRMzH12SsfNHP2q/HHiPZ98EetPEHkdjHj39bjM2h07qzkrTPu85yHl1NOmtSfrsuTVnPO/kpStp+Bq5bTEVra0WVvDOI6LgPEuNcJ4zhWtfx/iei1PHdNh2oRhGxrdNg2Ndhwr6KRpK5THx7fxLlaeq5P1TlWsq1qsg09TBoamtpa1Ix6+pgxa+GkREeXHhx1x0j0+c+Wsd5+cz6y0rupOoOU6s6g5vqbm9m+5y/P8AK7/Mcls5LWtbLu8ltZdzZtHmmZrSc2a/kpE+Wle1axEREOSuS+IAAAAAAAAAAAAAAAAAAAhme8zfr+9un4suV/aDVode0p+P3T36WbX8YxtkX3Jf2JvGP9W/A/ejdRmkbF2YAAAAAAAAAAAAAAAACSf7tVL/AMJbq/H8PSbOl/NyPi9P+/8AAkd7N8/7JOXj6fwJvP8A5zqwpc99RH/UU8Op/wDrB1o/b4XnZ/xJpKZTWqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAV2XtkusmV1i7+Osd6uRLI1HBc7D4Px6dZ1nGmrwMS1spRjTzWkaU2G0zqVpSlPn5r99Xt4w8xfl+vOYmbebFo3po689+8Rix1jJMR+yZb9/l6tw33cPhxg8OfZO8OccYow8h1TrbPVHMVisVmd7b2L6VbW9O8zOno6vrMzMx2/OatGME6wEhD3fjtExOsvcNuOunMdPb2HDejOPau6a3mWvXhZ3M8yFyuFOFfl5ytDcrrtnbj5rHzchW5CUa+K5+8A+kqcz1Bm5zcwxk0+GrE4YvHel9y8TNJj/hYJ+Hljv8ATMd4mFRPvcPaF2PDfwf47ws6c5G+n1J4lZsmPkr62Ty7Or01r2pG1S0evbBy1I3NG89ontS3ktFoTh6UpSlKUpSlKUpSlKU8UpSnypSlKfKlKU+VKU+pNpq/TMzMzMzMzPeZn1mZn5zM/TMv0fgAAAADRf7eDtBxuvfatndV+N6a3kdROifxORQy7FrzlZXD7VYX+RWci5T5yxtZrLOfn2o+Y+m7cnKvqpXwwh459I157pfJyuthi3I8L32IvWPr7acTFtitp+muLFGTJEfRMytK91V7Q+bwo8eNXoHmuSvh6P8AE7ycPbXy5P8AU+DqK8WxcNlw0n0rm3t3JqamS0d/NSla9o+aBvWlaVrStPFafKtK/XSv4KoLNq75/IBlz2Qd1nK+znuI4L1k45lZEcDWbPHweX6y1WdYbniOddjjb7ClZjX03MiWrvZlMKc4XPgZM43IwlWnivbOiuqdvo/qHR5jWtaMeLLWm5jjv2zal5iuenaPnacU38kzE+W09+yPntP+AvA+0b4PdU+G/M4cU7e9o5trp3evFYtxvUOrSc/E7UZLR3phrvY9edmtbV+Lhrak2iJ7p0+n9r92E7LU6vY5HXDQ6/Iz9fh5l/AyK0jfwr2Tj2713EvUrONfiY9ycrU/MY+ZQrXxTz4Thw+LnQeTFiyW5zXx2vjpe2O3fzUtasTNJ+7WZmJ/Oas/I+7w9q/S5De08Xhfyu3i1dvY18W3h9cWzjw5r48exjmKzHkzUrGSvrPpaPV9L++49gf7vnG/8qP+tez+az0D+X+t++4f9D59rP8A3p+Z/an/ACD++49gf7vnG/8AKj/rT+az0D+X+t++f0Pn2s/96fmf2p/yD++49gf7vnG/8qP+tP5rPQP5f6375/Q+faz/AN6fmf2p/wAg/vuPYH+75xv/ACo/60/ms9A/l/rfvn9D59rP/en5n9qf8g/vuPYH+75xv/Kj/rT+az0D+X+t++f0Pn2s/wDen5n9qf8AIP77j2B/u+cb/wAqP+tP5rPQP5f6375/Q+faz/3p+Z/an/IP77j2B/u+cb/yo/60/ms9A/l/rfvn9D59rP8A3p+Z/an/ACD++49gf7vnG/8AKj/rT+az0D+X+t++f0Pn2s/96fmf2p/yD++49gf7vnG/8qP+tP5rPQP5f6375/Q+faz/AN6fmf2p/wAg/vuPYH+75xv/ACo/60/ms9A/l/rfvn9D59rP/en5n9qf8g/vuPYH+75xv/Kj/rT+az0D+X+t++f0Pn2s/wDen5n9qf8AIP77j2B/u+cb/wAqP+tP5rPQP5f6375/Q+faz/3p+Z/an/IP77j2B/u+cb/yo/60/ms9A/l/rfvn9D59rP8A3p+Z/an/ACD++49gf7vnG/8AKj/rT+az0D+X+t++f0Pn2s/96fmf2p/yD++49gf7vnG/8qP+tP5rPQP5f6375/Q+faz/AN6fmf2p/wAg/vuPYH+75xv/ACo/60/ms9A/l/rfvn9D59rP/en5n9qf8g/vuPYH+75xv/Kj/rT+az0D+X+t++f0Pn2s/wDen5n9qf8AIP77j2B/u+cb/wAqP+tP5rPQP5f6375/Q+faz/3p+Z/an/IP77j2B/u+cb/yo/60/ms9A/l/rfvn9D59rP8A3p+Z/an/ACCvtcewOlK1+75xv5fglHz/AP8AU/ms9Bfl/rf9P1z+h8+1nP8A/ifmf2p/yGsb2jntx+3u90H5x0s7ZOR7DmvUXnum2HE8rcV02ywNJodDu7FzWbvJhm5Fm3Yzsq/qsnMs4ccbJpKxkSs35wuW6VhLGniL429P24Le4vpnYybvI7+HJqXyzhyY8GvgzROLPbz2iK3tbFa9aeS31tpi0949Jm97GvuvPF7H4q9LdeeN3DanTXR3SnI6nP6/HRyWnt8ny3LcZlpu8XgtrYclsurr4t/DrZNmc+Dy5sNcmKl6XmLRDJu3bl67cvXZyuXbs53blyVfMp3LkqynOVfvylKtZVr9+taodTMzMzMzMzMzMz85mfWZn7sy2R6UpjpTHjrFKY61pSlY7VrSsRWtax9EViIiI+iIfw/HkA5Nwvie255zDi3CdDZlkbvl/ItLxnU2YxrOtzY73ZY2rwoemPitaSycq1Svzp8q/XT63J0tTLvberpYKzbNt7GHWxViO/fJnyVxUjt+ivD4nUvP8f0r07zvU3LZa4eM6e4fk+b5DLa0VimlxWlm3tm3efSJjDgvMfP1+iVmX2Xdu3G+1ztv6YdI+P63HwL+k43hZHIbtuzS3kZ3ItlGWx21/Mn+ru3rOXl3cSEp1rWNjHtW/NaQosn6N6e1umOnOM4nXxVx2w62O2xMR2tfYyR8TLa8/OZi95pEz3mK1iO/aIaTHtKeMXNeOnjN1x4g8vu5tvFyfNbWHh8d8k3w6nDaU10+Pxa1fxOPHk19fHsXrWIi2XLe8x3tLKd2hgkAAAAB8/barXb3V7HS7fDsbDVbfBy9bssHJh68fMwM6xcxcvFvQ+XqtX8e7ctXKeaVrGVfFaV+b15cWPPiyYc1K5MWbHfFlx2jvW+PJWa3paPpi1ZmJ+5Ll6G/ucXvafJ8fsZdTf4/a193S2sNvLl19rVy0z6+fHb6L4suOmSs9pjzVjvEq4H2n3azldpvd51J4JYxJY/Et7srnL+D3/h1tWcnRbykMy9DGjWlKfA1+1vZ+st+PPiOHSla1r8611+JnS9+lOreS0a08upnyTt6M9u0WwZu17RWP7HHlnJij9A3MPYd8dsHj/7PPRfVWXYrl6g4rSp071Ri88XyYOU4vza+K2e3ee+Xc0Meru3me3edjv2jv2a9WP0vXKeDb+fFOa8P5TblKFzjXKeP7+3OHn1QnpttibGEo+Pn6oyxqVp4+fmlPHzcrSzzq7uptRPadba188THzicOWmSJ/wDFfC6o4mvP9M9RcFesXpzXBcvxN627TW1eR4/Y07Vt39O0xmmJ7+naVpV0f3n903SbphyP4nxa77p7wvcTuer1VnPZcc1uZOsq/fl670vV5+fq8+fms94jP9U8Vxmx37/H4/TzTPfv3nJrY7z6/b7z6/daKviJxf4Cdf8AXHDRT4ccT1f1Lxtadu0Vrpczu61YiP7Hy448vb07dpj0divounAAAAAAAAAMbO7rt8493QdvPU3ozyDDtZUeVcazoaaV30Rri8kwbddhxzKpdlTzbhZ3eLgXL9YyhWdmM4VlSkq1db6t4DX6n6f5PhtikW+qta/wZnt9bs44+Jr2iZ+URmpjm3bt3iJjv2lmj2e/F3l/A3xg6H8SeI2MmC3A81q25KuObT9UcLtX+o+ZwTSvpe2TjM+1XFExby5ZraKzMdlZj1K4DvulvP8AmHTvk2Lew95w3kW249sLV61OxKV7V5t7EpkQt3KUl8DKhajk48/nG5Yu27kJShKkq1scjoZ+M39vj9ms0z6exl18kTE172xXtTzRE/1tu3mrPymsxMTMN2novqziuuuk+nesOEz49ji+pOH4/mNPJiyVy1rj3tbHsfBtekzX4uC15w5q+lqZcd6WitomI4Q4Ts4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACb57v52Y3ujHQra9w/NdNXD5z1lhW1x+Obj1tZus4Lj5kJ41IwuxpONrd3dfg7jGvxjGtzFvw9EpW5+azW8A+jrcNweXqHdwzTe5iO2vF6zF8WjW/evaJ9e2ecePNW3aO9LR27xPdrD+9u9pPH4k+Keh4P8ATPJRsdLeG9oycvOtmjJrb3VWbWtXNM2xzNZycZj29rjs2K1reTPit5orevaJDiQSn8AAAAAAAAAAAAAAAAAAABDM95m/X97dPxZcr+0GrQ69pT8funv0s2v4xjbIvuS/sTeMf6t+B+9G6jNI2LswAAAAAAAAAAAAAAAAEkn3auX/AITvV2P/AOSDYy/m5NxOn9KRns4T/sm5eP8AsPkn9ra1P+VTD76eP+od4ez9rxE04/XnhOe/xJp6ZjWlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfzOcbcJXJ1pGEI1lKVfqpGNPNa1/epSnkme0TM/KPWXlWtr2rWsTNrTFaxHzmZntEftqsruD5Fm8s659XOQbGdbmZsOoXK63Z1rWtZUxtxl4dqvmta1r+k49un1/eVfdQbF9vnOW2Mk975OQ2+8/oc16R/4tYb2PhFw+twHhb4fcRp1imvqdIcBGOsR2iJzcdr7OT0jt/wBczXl08+QyKAsBPYT9KMTpz2BdPuQWsaNrK6p7Lbc7yr1YRpdu1uXoaCNKzpSk626U0NKxjKtaUlWVafX5T38DuKpx3QXH54rEW5TJl3rz27TMzMa8d57d+3bBHb9v6WpN70/r7Y6y9rTq7iL57ZMHQejx3SuDHF7Tjx+THbl7TFe81i8zysxa1YjvERE/JuUZhVwAAAAAAOLc54rgc64Zyvhe0hC5reV8e3HHs6FyFLluWJuMC/gZEZwlStJRravzpWNaVpWlfHhxd7Vpvae1pZYice3r5te8THePJmx2x27x9PpaX3el+e2+lupOB6l0bWpu8BzHHcxqWpaa2rscdt4tvDNbR2msxfFXtMesfNVudZ+K3+D9W+pXEciz9HuaDm/JddGzSnppCxZ2uVXFpSP3qVxpWa0p96laKw+Z1baPLclqWr5Z193ZxxH2qxlt5P8AxZhvS+G3PYuqPD/ovqDDk+LTlumOF3LZO/ebZcmhg+PMz9MxnjJEz9Mx3dZvmu7AAAAAAAAAAAAAAAAAAAAAAAAAANsPsU+k+F1Z9oH0hwNtiwydPxmHIuX5VZxjONnN47x/Z7jS3PTKkqeqO1wMasJePMZUpKlaVp5ZV8GOKpyvX3EY8tYth1o2Nu/eImIvr6+XNgntPf8A67jr8vWO3dAX3l/X+z0B7I/iHt8fntg5Hm7cN07g8lprOTW5nl9LjuTp5omJ7TobWeLR37WiZie8T2mw3WBtQEAAAAAABE/95n6Y40cDt46w2saNMy7l7bp7k5ELdKS+jY9ra8ht0uyjHzWlb2ZSNJTr48+mNPvURW9pTjKxj6e5eKx55vm4+1oiPxNYy7Ed/Tv+Kv8AbX6e5L64z22/GDw6yZ5+p8evx/WGDDa8zHxs2TR4e846zPaO2PX7zFY+XeZ+lEnRQbAgC0C7Ns29sO1foDk36Vjdl0s4darSv10jj6bFsQ/k9FuPj97wsz6OvOTpbgbW+f4F6cfrVw0rH+Du0cvaP1sep48eLWDFMTSvXnUd4mPl3y8lny2/X897d/u92SzsrCgAAAAAAAAACFn7w92f2+nHWHjPc5xLV1s8b6r27On5lLGs/pONzLWYc7Fi/KNqNIY+Pk6bXYfqncp4vZt2VfiVnP0oae0F0jHHcvrdTamLtrcrFcO55a+ldzFSa1tPb0rW2HHT1mPrrzPr3lsr+5+9oi/Wfh1zfgh1Bvxl5noG+TkenK5sn9MzdNb2xXLlxROSZtmy4OS3Nny1pP1mtjr9ZFaeZGzRyXQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM3/Z59qu+7ve6Pp10v1+Jfu8esbbH5FzjPt2pXMfV8X0865mRPMrSlY2rGxyrONp6TnWNPjbC3SNfVWNHdfD/pbP1b1Px3GY6WnXrlrsb2SI71xauGfPabz8orktWuGJnt9dkj6UYfa+8eeK9nnwL6y653NjHTl8vH5uH6X1LZIpm3ud5Gsa2GutEzE3y6eHLm5Ga1iZ+HqXmY8sTKyc4vxvT8O43oeJ8ew7Wv0fGtPrNDqMKzGkbeLrdThWMDCsRpSlPPwsbHtQrKvmUqx8yrWta1WOauth09bBqa9Ix4NbDjwYaVjtFceKlcdK/rVrEfdaXXOczyPUfM8tz/L7F9vlOa5Ld5XkdnJMzfPu8hs5dvayzM/Lz5st7do9I79oiIh9173ygAAAAAAAAAAAAAAAAAAAEMz3mb9f3t0/Flyv7QatDr2lPx+6e/Sza/jGNsi+5L+xN4x/q34H70bqM0jYuzAAAAAAAAAAAAAAAAASQ/drJeO6Xq3H8PRvZ18fwco4l8/5P6Ui/Zwn/ZPy0fb4fL+9taimX308f9Qnw+t/9ZGjH7fBdQT/AIv+nZNVTNa0IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD0tlYlk6/Nx4VrSd/Fv2oVj9dJTtyjGtPr+fmtPvPDLWb471j52raI/PmPRydPLXBt62a8RNcWfFktE+sTWl4tMT+fEKrLqtCtvqj1Jt1rWtYc+5jCta/XWseRbGNa1/f80+arnlY7cnyUT8439yP2tjI3w+grRfoXou8ekW6T6ctEfai3D6cx/hcBcB2wBZH+ykuYV32ePaxc1//icunuT8H50r9XKeQxufOny/wtJ/wfV95Yx4WTSfD7pecf4j8D7eX9ba2In9/u0xPb3ps4/bA8d6bf8A8Yr1fh+J6THz4LiJp6T6/wC1zX8/5thLICIQAAAAAACsR74ZY0+7fr9LElSWPXqJt/hyj48V8RsUn48fL5XKSp/DRWf1tNZ6s56aetfwRzdv/F7/AL/dvAezBXNX2ffCauxE1zR0dx3nifn88s1+f26eWf12Krq7PAAAAAAAAAAAAAAAAAAAAAAAAAADfH7vJexLffZZtX60pk3+CcojhU80p5nb0W5nfp4rStZfpNJV/Q1pWn1180Z09n6aR1xEW/FW0dmKfrYc02/ehVT73/FsX9lfJkxR3wYuquCnZntM9q35bja4vWJ7R/TZr84/an5ztU5Gq6AAAAAAAjfe8qXsSHbB0XtX/T9JvdVthTD8ypSXrhoKTvemNa+ZfpFJ0rSlK+KfP6qVR09pCaR0zw0W7ea3K5Ip+fGCJt2+39bE/wCFc17lfHsW8cfEq+LzfBx9Bak7PaszHltys1x+aY9K9ss1+fpM+nz7IVCGTZeeWxZuZN+zj2Y1nev3bdm1Cn1zuXZ0hCNP35SlSlP4X7Ws2tWtY72tMViPtzM9oj9eZeGXJTDiyZslorjxY75Mlp+VaUrNrWn7kViZ/WWj3bBp66Dty6F6qtPEsbpNwCtynj01jdv8X1mRdjWlfqrG5dlGv4a08/fWd9MYfqfp3g8X014rQmfn87auK0/P7s9mi7448j+C3jJ4p78fic/iB1bFZ794mmLnd7DS0T9q1MdZj7ku9X3GLAAAAAAAAAAGHPfp2zabuy7X+qHSTYYkL+1z9BlbXil+luEsnG5PpKR2+nt405xl8KufnYOPgX5UpT1Y+Rcj5p5806f1301h6r6Y5PiclItlya98urbt9dXZwx8XDFZ7T2+JkpXHb/g2lIz2UvG3kfAHxy6G8QdTYti0NTlsGhz+Lz2jDm4PlPNx3I3zVrMeeNTV2s23iie/bLhpbtPbtNabyzjO34XyjkXEN9jTw91xjd7TQbXGuRrGVnYajNv4GXDxL5+KX7E/TX50lHxWla0rSqt/b1sultbGpnrNM2rny6+Wsx2muTDe2O8f/wB1Z7fbj1bqvAc3x/UvB8P1DxOeuzxnOcZo8toZ6Wi1cupyGti2te3ePpnFlr5o9Jie8TETEw4+4764AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACc97AzsyvdCO3fL648z030PqD1tpHM130yxWGdquDW78Z6uxarKMa/Rd7bxNdvbc/TWVYXrfpn6K+Kze8B+jZ4Lp6/N7uHychzX1+Pz17XxaMWicVY79vrc8UxZ4nt/XR2ns1bvexe0lj8VfGHX8Lum+R+qOkfDGba259T5Ytrb/VN8U138uSKzMfH4u+xucVevftFsdu9fNHeN/TPSpgAAAAAAAAAAAAAAAAAAAABDM95m/X97dPxZcr+0GrQ69pT8funv0s2v4xjbIvuS/sTeMf6t+B+9G6jNI2LswAAAAAAAAAAAAAAAAEj33a2X/hWdWYf/kW20v5uVcPp/D99In2cZ/2VcrH/YbLP/nWp3/xKaffTR/1BPD+3/1maEf+gOop/wASa2me1nQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFYj3w8DyOmXdv194RlY1cS/pOoe19ePKPorb/ADShj7ePmNaU8euOfGf7/q8+a+fKtDrbQtxnVnPaNq+S2DkMvesx27fEiuWPT7sZO/6/dvAezB1Xi639n7wm6nwZo2MXJ9H8f5c0W80X+orZeOt6957+W2pNPn6eXtPyYqurM8AJ8HsDusuB1K7E+OcOhk2/zR6Q8h23Cb2HW7SuRHErHF31nK+DWXrjj3bu8u2oXKRpblctXI0lWUZUpO7wH5jHyXQ2tpxaPicTsZdK1O/10V+tzxfy/OKzOeaxPymaz6+ktT/3sPhvtdFe1PzHUVsN/qPxD4fQ6nxbEUn4U54tn4nLgnJEeWc1KcXjvakz560vSZiItEzu4ZqVjgAAAAAOC9Tuca7pn065z1C29y1a1vCeKb/lOdO9Olu3TG0WsytlepKda0pSlbeNKn10r+CvlweT3sfG8dvchlmIx6Wpn2rzae0eXBitkt3nvH0Vl2nojpfc626x6X6Q4+mTJu9Tc/xPBatcdZvf43K72DSxzWsRPeYvmiftfbVb/VXk9zmvUzn/AC25erkV5FzHkW3t3q19XrsZu1yr2N4l9+MceVqMa/8ARpRWJymzO7yW/tzbzfVG5sZot9ut8t7V/W8sxEfcb0nQnB06Z6K6S6fpj+DHDdO8Px18fbt5curoYMWfvH0TOauS0x9EzLgLgO1gAAAAAAAAAAAAAAAAAAAAAAAAANknslOtWH0I78uhvLtleja1u23WXwXJpcn6LNbvPdfk8Qwrl2vmNPFjL3Nq7Gsq0jGUaSl8qVZG8KOapwXXXB7eSe2PNmvo27z2r338dtSk2/Q2zRMT9ExHeeyGHvAvDPY8VfZS8UuntLHN93j+M1+qsE0r5ssU6T28PUOzXHHrMzl1+NyY5iImZi3aPVY5QnG5GM4SjOE4xnCca0lGUZUpWMoyp5pWMqVpWlaVrStK+aLEomJjvE94n1iY+Ux9tpr2ralrUtE1tWZratomLVtWe0xMT6xMTExMT6xPo/ofgAAAAACIR7y71j1+y5X0I6HYWXbyMnQ67O5/tLVm5SdMPKz7u20drGyaRrWlrIli27GRG3c9Nytm7buen0SjWsSfaR5jHk2uC4Sl4tbBjyb+WsT38lsk5cEVt9EWmsVt2n17TE/KYbDXuUfDnc0uA8VfFDZ174cPK7mr0lo5MlZrOzg1MfH8pfNgmYib4a575cNr171jJS1JnzVtERXkXV7zsrozoLvKur/SrjNi1K/d5D1H4PpLdqMayrclteTavBpDxSlfPqrf8fyvpcPgna5fi9asTadjkdLBERHeZnLs4qdu3/2nS/EjlcfBeHnXnN5ckYsfEdG9T8nfJMxWKV0OE3tqbd5+XaMXePurSTguonx/hHDtDch8O5pOK8e1E7fjx6J63UYeFKHj73plZrHx+8s80cM6+lp4JjtOHV18Mx9qceGlO363laLPVPIV5bqfqPlaW89OT57l+Qrf+yru8hsbNbf/AGoyxP67lTlPggAAAAAAAAAAINPt/OzyHRDuLweu3FNZ9F4N1vhC/nxxrNLeBrOaYOJXHzcG36Y0/Tdhi62e5v1lOVZXsydaVpStI0hF499IRwnUWPndXF5NHm4ib+WvbHi3cdPLfHHaPxWSmOc1u8zMzeZ+5G0Z7pb2i7+J/g5t+FfP7vx+qfC+98WpObJ59ve6Z2tiM2tt372/2vT2N2vG4orWsVxa9ImJmJmY/rAi2wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnv7NrtN3feB3U9PunmLh3rvFdPssflfPs+Fr4tjXca012mTWmXSsZRpY2ewt4WnlWtY187CnprSXirvfhz0pm6u6p4/j60mdTDlrtchkiO9cethnzfXek/W5ckY8M//AMxFH2z/AB+4z2d/Afq/rDPs46c9yOlm4DpLUtfyZdzm+SpOCPqee8TOXR077PJV7RMf6knvEx3hZF6DR6rjGj0/HNHh2ddptDq8DTanAx4+mzh67WYtrCwsa1H51pCxjWLVqPmta+I081rX5rF9fBi1cGHWwUrjw4MWPDipWO1aY8VIpSsR9qtaxEfchpi8tym/znKcjzPKbOTc5Llt7b5Lf2ss+bJs7m9nybOznvP02y5st727do729IiH1nufPAAAAAAAAAAAAAAAAAAAAAQzPeZv1/e3T8WXK/tBq0OvaU/H7p79LNr+MY2yL7kv7E3jH+rfgfvRuozSNi7MAAAAAAAAAAAAAAAABI392ul/4WfVWP4eiW5l/NyzhtP6f86RHs4/1V8p+kub+Naam330sf8Awf8AoK3/ANZ3HR/+H+o5TYU0GsyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgue8I9v9/pp3e4nVbAw5x0PWTjeHt8vPparC1c5Xg387A2GJ8TxSM7tnVYWquy+da0jej5Qf8f8AgLcb1dXlcdJjBzOvTNfJ2mKzt47Xx5Kd/lNoxUxWnt9FobSvuiPFvF1r7PGx0FtbFZ5Xw45rZ47X1ZvFslOA28WrtamxNe8zWmTf2d/HX6Jtjt2aCmB1sYDeL7C3vOxO2vucj035ntKYfTvrdXA4zeu5Fz0Ymq5VK9csaHL9Va0hYjnZ+Vh4ubkXf0q3jWaSnK3GNZs2eB/WVOm+po47cy+Tj+b+Hq2m09qYtqZmuC/f5Vi97UrktPeIrXvPbt3Vfe9L9m3Y8afBC3WfTej9U9Y+GEbfOY6YaebY3+Brjpl5bX7RE2yzq6mDZz62Gn1982Wa1i8zFU9C3ct3rdu7anC5auwjct3LcqThctzjSUJwlGtYyhONaSjKla0rStK0rWlU64mJiJiYmJiJiY+UxPrEx9yYapV6Xx3vjyVtTJS1qXpeJrel6zNbVtWYia2raJi0TETExMTHd/b9eIAAAACPJ7f7vTwOkHQXH7cOIbq3DqL1fhC5vbGLep9M0/BbeVW1lTvwjKtKWN/TH2mplG5GkqRhKUa080qj7499Z4+I4KvTmpmiOR5eInPWsx58WjF/LebRE+ldjy5cU94ifSey3/3Sns1bXiH4r5vGbqLjL36O8O7XpxWXPjn6m5Hqq+D4mCmK0xEzl4icujyFbVnt3tWJ7/JCCQpbPID6+g0O35Ru9Txzj+vyttvN7scPU6jWYVm5kZefsdhkW8XDxMaxajO5dv5GRdt2rVuEZSnOcYxpWtaUe3BgzbWfFra+O2XPnyUxYcVIm18mTJaK0pWsd5m1rTERER3mZfP5bleO4PjOQ5nltzBx/F8Vp7PIchvbWSmHX1NPUw3z7Oxny5JrTHiw4cd8l72tFa1rMzMRDeTwT3ezvd5bxnV8g3NzhHD8naYtnMhpdju9bm5uPYyLcLtmmVXH2luli/WE6fFxrtuF6zOlYXI0lStGbtHwA6229bFsZZ0tS2WsXjDkz4r3rW0RMeby5Y8tu0+tZiLVnvEx3Vd9Ve959mLp/m97iONr1P1Fh0c+XWvyenxm7raubLhvbHk+BGbRvOXF5qz8PNS1seWva1JmJhzH87kd437benn/AG7F/thy/wCd36x/trj/APwlP8865/RkvZy/KDq/9y7H+jj87kd437benn/bsX+2D+d36x/trj//AAlP88f0ZL2cvyg6v/cux/o4/O5HeN+23p5/27F/tg/nd+sf7a4//wAJT/PH9GS9nL8oOr/3Lsf6OPzuR3jftt6ef9uxf7YP53frH+2uP/8ACU/zx/RkvZy/KDq/9y7H+jj87kd437benn/bsX+2D+d36x/trj//AAlP88f0ZL2cvyg6v/cux/o4/O5HeN+23p5/27F/tg/nd+sf7a4//wAJT/PH9GS9nL8oOr/3Lsf6OPzuR3jftt6ef9uxf7YP53frH+2uP/8ACU/zx/RkvZy/KDq/9y7H+jj87kd437benn/bsX+2D+d36x/trj//AAlP88f0ZL2cvyg6v/cux/o4/O5HeN+23p5/27F/tg/nd+sf7a4//wAJT/PH9GS9nL8oOr/3Lsf6OPzuR3jftt6ef9uxf7YP53frH+2uP/8ACU/zx/RkvZy/KDq/9y7H+jj87kd437benn/bsX+2D+d36x/trj//AAlP88f0ZL2cvyg6v/cux/o5p87qu2fmvaT1j5F0U5/ma3P5NxqmJXNyNVONzCnTMxLGZb+FOF7IjXxbyIxl4uV/RUqxH1T03u9J8xscNv3x32dbyee2KYmn19K3jtMWtE+lo+n5rE/Afxs6Z9oHw44bxM6S193V4Xmp2I1sO/S1Nms62xl1r+etseKY73w2mO9I9JiWOLrrMgAAAAAAAAAAD6Go2ufotrrN3qsm5h7TT7DC2uty7VfTdxc/X5NrLw8m1WtK+LljIs27sK+K+JRpXxV7MWXJgy4s+K00y4clMuO8fOmTHaL0tH3a2iJj7sOJyGhqcpob3Gb+Gmzo8jp7Ohu6+SO+PPqbmG+vsYbxExM0y4cl6WjvHetp9Vjl7MTvI4z3j9sHDOUYmdY/u44frcLiHULT/FpXKwd5qca1Ys5M4SrW5O3stb+Z+wlfjStr4+XO1Ssaw9EbEfDPrDW6w6Z09ml6/Vunjpp8hi797Uz4axWLTE+sxkx/DyTPy815j6O0aa/twezjzfs5eOXUvBbGrl/Cv1FubPUXSHI+Ttg2uL5DNfLkw0tWIpS2lu/VenXFMxk+Fr1vMTFvNOxZkNDoAAAABwbqZ1E4v0m4Dy3qPzPZY2q41w7Q7Pf7TKyb1uxGuPrMO9l1xrMrlaUuZeXWz9Hw7EaSuZGTctWbUJ3JxjXg8lyGrxOht8ju5K4tbTwZc+W9piv1uOlr+Wvf53v28tKx62tMViJmYh2nono7nfEDqzp/ozprSzb/ADXUfK6PE6GDBivlmM29s49eM2StImaa+v8AE+NsZbdqYcNL5Mlq0ra0Vpnev3Jbvuv7k+p3WfbXrlcTke+vWuPYkqzpawePay1Z1ept2bc61la+kYeFZy78Pl/vi/dr6Y+fTSt7rPqPP1V1HyfMZbTNNjPMa9J+VNfHFcWKKxPy81KVvaPpta0+nfs3VfZn8F+M8AvBbojw14/HSNjhuJx35jYiKzfa5jdyZN7kL5L19MnwtnZya+K0f9ZxY47z27zim6sz025exR7eL/Xvvk4DkZeBLM4r0vt5PPeSXqW/XDCu63Fy7vGr061pWkPXyPH19uNa0r+ir4pWlfFWWfBjp63Pdb6Fr45vq8XFt/Znt3ik463nWmfojvsVxx+ur595j4wY/Cf2XercWvtxr891zbB0nw2KbeW2zj3c+CnN469pibeXhsu3eYiflE94mFhMn+1DQAAAAAAAAAAAGv8A9pj2pa3u67Teo3T/AOiQucs02qyeW8HzI2qXczF32gjHafRcKlaS8Xt1jYVzTV/QyrWGbKkaUlWladB8SelcfVvSnI8f5Inbw4rbeleI81659ePi+SkfbzVpOH5TPa8xHaZ7pbexN497vs9eP/RvV31RanAclv4en+qNa1/JrZ+K5abaPx9qe8f0rjM21Tko9Y7W1ome9e8TW87nUbDQbfa6LbY1zD2ul2WdqdliXaVjdxc/XZV3DzMe5GtKVjOzkWbludK0pWko1pVXTmxZNfNlwZazTLhyXxZaT865Mdppes/drasxP5zc143kNTluO0OV4/NXY0OT0tXkNLYpMTTPqbuDHs62akxMxNcuHJS9ZiZiYtExL5r1uaAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/aUrWtKUpWta1pSlKfXWtflSlP361CZiImZntEeszPyiPtync+wd7Mbvbz22T6vcx1H0TqN1vja3NuuVZ9ObquFVnG5pMSzOsYy+ibrEsaze1pL1V9d2PplSP6FOXwL6Nnp7pyeX3MXk5Hm4jNHmj6/Fpd++CkT2j6zNSuLP+fMfnNVv3q/tJ4/F/xpr4edOch9UdG+F85ONv8DJ5tbf6mik05TYyV7zH1Rxuxl3uL7x5Y8tJ7xM/XN7zOaqsAAAAAAAAAAAAAAAAAAAAABDM95m/X97dPxZcr+0GrQ69pT8funv0s2v4xjbIvuS/sTeMf6t+B+9G6jNI2LswAAAAAAAAAAAAAAAAEjL3a+X/AIXfVSP4ehm7l/Ny/hVP6apDezj/AFW8pH/YPP8Av7en/wAinH30kf8Aweug7f8A1pcZH7fTvU0/4k2ZNJrKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANPPtse0zI7m+z3kG245r45fPOjlczn2grC38TIu6rBsWsvlGFYtw8XcjJy9Vra2cSxCs5VvzpSFucpeK4h8aOlLdS9IbGXWxxff4fz7+D072tipFbbNIiPrrWvix9qRHf675RPdYr7svx/w+CPtF8Rx/M7dtfpTxHjW6T5aJv5MNN/ay5NfgtrLe3fHhw6+/uRk2Mt4rWMVZm961r3V+N21dsXbti9bnavWbk7V21cjWFy3dtyrC5bnCVKSjOEqVjKMqUrGtK0rSlaIDTE1ma2iYmJmJifSYmJ7TEx9ExPpLbgx5KZaUy471yY8lK5Md6TFq3peItS9bR3i1bVmJrMekxMTDxvx5vPjZOThZFjLw797Fysa7bv42Tj3J2b9i9alSdu9Zu26xnbuW50pKE4SpKMqUlGtK0pV+1talq3paa2rMWraszFq2ie8TEx6xMT6xMesS9WfBh2cOXX2MWPPgz474s2HNSuTFlxZKzW+PJjvE1vS9Zmtq2iYtEzEx2TWvY4+1u471p4rx/tu7geR4Wn6t8exrOq4fyjb5FvBxOda21CkcPBycrInDEpyKzKk8SzbhOzXPt0wrNnFllSncvTO8H/FjX5nV1+nOf2KYeW16xi09rLaKU3sUR2pS1rdqfVEfiYiJr548la0m0zM6z/vG/d98x4ac9y/jP4R8Ntcl4fcvmvv9R8Fx+G2zsdK7uS8zs7WHBhrbYnh8kTXYy5L1yRq3nZy5c9cEVpjkbRlSUaSjWkoypSUZUr5pWlaeaVpWnyrStPnStProkT8/kptmJiZiYmJiZiYmO0xMekxMT6xMT84fo/AAAGCXfh37dI+xjpZseX802mFsOa52FkQ4RwOxlQnuN9tZwlawZ3cGzKWZa1McusKZebW3bsws28ivx7dbU5R6N1z13xPRHF5Nvcy0ybt6WjS0YtE5s+WYmKTNKz564vP281+0ViIt9dHaZSo9lX2UPEH2pOu9Pp3prS2tPprV2cNup+q8uC1eO4nQrauTZrTayVjWychbXi06+r57ZbZL4u2K8XrFq8TuL6/8/7murvLusHUfa5Gz5BynZXcmNu7clKxq8ClfRhazBt1lKNjFxbMY0pbt+Iyu1uXa+Z3JVrX31Dz2/1Ly23y/I5bZdjayTaIme9cWP5UxUj5VpWv0R6d+8/OZluA+DnhL0l4JeHvT3h10ZoYdHiOC0seCb0pEZd7bmPNs721eIi2XPnyzaZvf66McUxx2rSsR0e+IyeAlk+wl9mLkQv6vvH64aD02PTcudIeL7XH9M7koxlZry7Nx70aXYUtZNblNVblSzOGTgQypVu2bsIpV+BvhnaLYusObwfW9pniNXLXtM+k1+q71mO/paZ+FH1va2PzfXVmFA3vUfbfw2xb3s4+F/LebN5qV8ROd0M3mrSJmuSOntbNjnyWm+GKzv3rOSt8O1bBHw8lJsln0pSlKUpSlKUp4pSnypSlPqpSn3qUStUATMzMzM95n1mZ+cz9uQAAAAAAAAAAFfN7cuv/ANId1d+X1Q0FP4f+AdZXzT+fx/DRAPxu+yBy37B/AYm3P7rn8iB4e/o+W/W/123v/wB7UAxGsRAAAAAAAAAAAAZ9+zz77+fdiXWvXc50N29s+Dbq9j63qHxC5O5XD3WkuypZv5Vq3Cca29prrU65mDft/OWRjY9u/byLFJWJ988Puud/obmse9gmcujmmuLkNSZmaZsEz2teIiY7ZccT56Wj52rWLRaseWYm+197KvSftUeGe50ty1Mej1TxmPLu9H9RUrSNnjeTx1nJiwZL2rMX0Ny9Y19rFeO1cObNfFbDlmMtbCHty7lekndN010nU/pFynXch0u1xbdzMw7GVZntdBn+PGTqt3gUlTK1+Zj3KVpS3l2bEr9iVnKtQrYyLUpT+6d6k4nqjjcHJ8TtY9jDlrE3pW8TlwZP67Fmp+Kx3rP0XrWbV8t4jy2iZ1EfGTwV8QfAnrXk+h/EPgdzh+T0M96a2zlwZK6HLasT3w7/ABm3MTg3NbLTt3vr5MtcWWMmC9vi4r1jvx95icAAB8bkPItFxPS7LkXJdtr9FotRiXs7Z7ba5djBwMLFx7crt6/k5WTctWLNuEIyrWVycafL63p2NjBqYcmxs5seDBhpN8uXLeuPHSlY7za17TFYiI+mZfS4jh+U5/ktLh+F4/c5TlOQ2MerpaGhr5drb2tjLeKY8WHBgpfLkva1oiK0rMzM/JCT9sr7WCPc/t7/AG/dB9rmYvRnjefW3yjf487tifP9zg5PxKfBl+l1px7Ev27H0eMI1rm38WWTTJu4WRC1WFnjD4q/hmzW4Dgst6cPrZO21sVmazv5qW7/AFvymMFLRXy9o+vtWbea1LRDZu93B7AtvA3j8Xi54q6Gvn8Sea1IvwXEZq48tekeN2sEU/ptfr4nl9jFfL8WbWiNbFnjDOHHsYpvEexgBbw8+NjZGbk4+Hh2L2Vl5d+1jYuNj253r+RkX7kbVixZtW6SndvXrs427duEaznOUYxpWtaUeVa2vatKVm172ita1iZta1p7VrWI9ZmZmIiI9Zme0PVnz4dbDm2djLjwa+viyZ8+fNeuPFhw4qTky5cuS8xTHjx0ra972mK1rE2tMREyn3exU7ErnaR27W+a8zwIWerHWWzi8i3kb0IfTNDx+9bsV0/H6ThSni1dx8bF3F61P1XrOXm3rVyUawrbhPHwY6GnpPp6N3dxxXleYrXYzxaPr9fXmK/B1+/aPrbVrTNMT61ve0T2mJiNTX3l/tUU9oLxiv0z01tWydAeG2TPw3F2x2t9T8ty+O+WOR5eaWmf6ZjzZ8/HY8le2PJr62PJSLRaLzujZlVrAAAAAAAAAAAAPytKSpWMqUrGtK0rStKVpWlaeK0rSvyrStPlWlflWh8/m/YmYmJiZiYmJiYntMTHrExMesTE/KUCL26HZ7Ttw7qszqFxrW1xOnvW63XlGtpj2q0wtbyH0Vx93rpXaU9FMvOzsLP3MrUpeulvKrOkfh+mqCPjh0j+F3qm/Ia2PycfzUfVWPyx9Zj2O01z4+/y8970vm7TPftbv8m197rb2iv5svgNrdIc1uxsdX+GFo4LdnNkidnd4fzRm4zcjHM+adfV1dnV42Mla+Tz4PLNpv3hpFYVWcgAAAAAAAAAAAAAAAAAAAAAAAAAAAANh/sw+0Xb94PdbwThUcS9c4ZxfPx+ZdQM6Nuk7OFx/TXo37Nu/wCqMo1tbPbU12quR8er0Z1axrGtKSpkHwz6TzdXdVaOlFLTp6uSu5v3iO8U18NomInvExMZM3w8Ux9q/fvCH/twe0Jx/s6+AnVXU87GOnUnOaubpvpHVtfyZNnmOSxWx5L4e1q2jJpcfO5v0t37efViJifxM2PGn1Ou0Gp1mj0+JZwNTptfharWYOPH0WMPX6/Gt4mHi2Y+a+m1j41m3at081rSEKU81WJ4cWPBixYMNIx4sOOmLFjrHatMeOsUpWI+1WsREfchpp8hyG5y2/vcpyOxk2+Q5Lb2d/e2s0+bLs7m5mvsbOxlt6d8mbNkvkvPaO9rT6PovY4YAAAAAAAAAAAAAAAAAAAAACGZ7zN+v726fiy5X9oNWh17Sn4/dPfpZtfxjG2Rfcl/Ym8Y/wBW/A/ejdRmkbF2YAAAAAAAAAAAAAAAACRX7thLx3h9UYfh6D76v83MeEf96/yJC+zj/Vfyn6RZ/wCOaSnb30kd/Z06Ft9rxW4qPl9vpzqf07ptqabWQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeDKxcbOxsjDzLFrKxMqzcx8nGvwjcs37F2NYXbV23KlYzt3ISrGcZUrSUa1pWnh43pXJW1L1i9LxNbVtETW1ZjtMTE+kxMekxL24M+bVzYtnWy5MGxgyUy4c2K00yYsuO0Wpkx3rMWreloi1bRMTExExPdAA9sd7P3cdoPXzac24nqMiXRLqpn5G74xn2bU54uh3GRdnXaccyr0aVjC7C9SOfZnOsIzhsbdm3StbdUCvF/oHN0jz2Xd1MNvwF5S9s2tkiJmuDNaZ+Lr2n6Jie16zPaJjJFY9Yba3u5fa3472h/CfR6Z5/kMMeJvQmph4znNTJetc/K8dhpWNHmcGOZibY7Y/NqZK1i1q3075bzEXhptYeWOgPc1+xz9TmY+x1ebl67PxLsL+Lm4ORdxcvGvW5Unbu2MixOF21chKlJRnCcZRlSlaVpWjzx5MmK9cmK98eSkxal6Wml62ie8TW1ZiYmJ+UxPdx9vU1N/Xzae9ra+5qbGO2LPrbWHHnwZsd4mt8eXDlrbHkpaszFq2rMTEzEwkA9jvt8Ot/QbF1HA+4DX3Os3T3C+Bh4+6lcpic302HSkbUYW863WODm4eJGnxq27+tyc+95uwpkVrK36c99E+O/NcFXDoc/jnmOPp5aVzd4pu4aRER2i8dsd6V/FTFsdslu8x5vkqT9qH3T/hj4r5+R6r8JNynht1fs/F2c3GxSdjpfktmZtkta+raLbWtsbEz8Pz4t3Dq4+1LThiIv5pKPRf2v/Yd1pwdde1/WnR8Mz8yFumRruoNyPDqYF+VfErN3N5BXW41yEK1p5yIVpalTzWlflVI7hvFzoXmaY5x8zg08l+3mx8hMacY7fTW19icVZ7f2Uen2lLXiX7u/2q/DTa28e34acp1Lqa9rTh3OkKT1HO1ir6xkpq8RG7mpNoj/AGq0TePSJ9ZZfWu6rtlv24XrPcH0Yu2rkaTt3bfUvh87c41+qUJx29YyjX71aVrSrt9eqOmrRFq8/wANasx3iY5LTmJj7cT8b1hHjJ4D+NuK9seXwi8SceSkzW9L9FdRVvW0fOLVtx0TEx9MTES6j6le0Y7KelWNdyeTdxPTHKlZhKd3C4zyzR8o2UKRp6vTLX6XPy8uk60+cYVteqVK0rSnzp5+RyXiH0ZxdZts9Q8beaxM2prbeDayR2+iceHJe/f7nZkHov2OfaY68z0wcJ4O9cYK5LVrTa5vp/lOD0reae3mrucnqa+vNIn0taL9omJiZ9Gi/vE94v41ia/acS7Q+J39vtL0L+JTqPzLCz8PAxaTpKzXI1WhufmXnRzcevqvY1/LllYc5/CrKxchScZYQ6v9ofWpjy6nSOpbNltFqfgjuUyUx17+nmw68xiyRevzra/mpM9u9ZjvE2lezp7nLms+5o9Qe0P1Bi4/Rx2xZ7dGdN7OpsbeaaTXJGHf5ak72rbVzemPNi14wbFa+eK5aWmsxFm6xdcOqnX3mWz571a5puuacl2mRO/ezNrk+u3YpL5RsYeJajaxMOxbhSkI28axapWlKyn6pynKUX+Y5vlOe3Mm/wAtu5t3Zy2m03y27xX7VaUiIpSsR6RFax9ue8zMzex4deGHQfhP03pdKeH/AE1xvTXCaOKuLHraGHy3yzHrbLs7GS2TZ2ct7d7Wvmy3mJny18tYrWOqHynfQG/b2Pnsnt13Scq1fXXrbpNhqeg3GNnZytXrs2xcwr/UbZ4MreTDFxKX4Ru3OOwv/Bs5+fjw+FlRpmYeLmWsqxOtvPHhF4VZ+p9vFznNYMmHgtXLFsWPJWaTyOXHMWitYtEWnXi3aMl6x2vEXpS9b1ma1N+8T9vrjPArgd7ws8MuT1OQ8Vuc0cuDe3NXLTZxdG6W1W+C2fYnDa2PHzNsU5Mupq5rfEwWnW2c+tk18tYvOP0ul1XHNRrdDo8DF1en1GFj6/W67CtRsYuHh4tuNqxYs2oUpSMIQjSn35Sr5lOUpSlKs28OHFrYceDBjriw4aVx48dIitaUrHatYiPlER+3859WrzyXJb/Mchucrym3n3+R5DZy7e7ubOS2XPs7Oe83y5ct7d5m1rTM/RFY7VrEViIj6b2uCAAAAAAAAAAAr5vbl18+0O6u/vQ0FP4P+ANXX+nygH43fZA5b9g/gMTbo91z+Q/8Pfu25f7778NQDEaxAAAAAAAAAAAAABkx20d3nXztL5hj8x6K882vGr9L1qWy0/xI5Wi3WNCUfjYWy12TC7ZrayrVJWL17Gpj5lLUv0rJtzjCUeydN9W890puV3OF38utbvHxcPeL4M9Y+dMmO0THa0fWzavlvET6WhhPxq9nrwn9oDp3N054mdKaHN4px3rpcj5Jwcrxma1Z+Hs6W7hmmSL4Mkxlx4s/xtabx/TMN6zaJlS9rHvGPRLlWr12k7oeK7TpvyW1atY+Vyni+u2m/wCObLJ8UhC7a1OHa2ezwI3ZVj8e5lZkrVufxLv6C14pGUfS/tD8LtYseDqfVy8dsxEVvtauPLsa2S3yiYw0jLlx9/TzTa/aJ7z6R2UP+O/ucfE3gd7c5PwM57R604W975tfged3NHieZ0sMTNr0vyGxfR0tuaR5vhUwa0ZLx5Mf11+8zt54D7SXse6jYH5oafuT6VamzWEbnwuX8x0HEcvxLx4p9E32xwr9JU8/OFYeqnivmnyZb0PEbonkcfxMPUfF4qzHftt7mvqX/O8mfJS3f7cdu8K9OrPYv9qDo7a+o+R8Fuvd/J5pp5+nunOW6h1+9fnMbHE6e1imv2rRbtP23Kd7379l3Htdf2eZ3Q9C8qxjxrKdnU9T+GbbNnSlPPi1hYO5vZN2VfvRt25Vr9VKeXKz9d9G6+O2W/U3B2rWJmYxcnp5bz2+1THmte360S+DxXsoe0ry+5i0dfwM8U9fLmtFa5OQ6G6k4/WrM/Tk2dvjcWHHH25teIj6WufuA9v32W9KtZnY/TrN5B1g5dat3oY2q02sz9VqaX6xrGzeub7NwrmsyLELlYzu2rGRG5ct0rGE4ylSVMd8/wCPXRnFY8leOvscxuViYriw4smHF5u0+WZ2L45x2r39Zis95j5T694mP4S+6W9pbrzd1cvWOtxHhz09e+O2bf5Le1d/kJxRMWyY6cTrbNN3FltTvWl8uGaVvMTasxExMW7vZ9qv3Od6Wfl6zkPIZcG6aVvVrhdPOIXMjA1c7UJ+bV3aZVzIytlm5U4UhTJh9Pjg3K0r6cWMZVjWMPWnin1N1ne+LY2PqHje/wBZx+pNqYpiJ+ttlvNrZL2mI+uj4kUn1+s7T2XpezJ7Bngh7NOpr7vEcPHVPW0Y4+qesOoqYdvfre1e2THo4KYsGlrYK2m04bfUk7VImO+ebREtZNa1rWta1rWta+a1r861rX661r9+tWNU3Pl8n9W4TuzhatwlcuXJxhbhClZTnOdaRjCMaeaylKVaUjSlK1rWtKU+ZETMxERMzM9oiPWZmflER9My8bWrStr3tFaUrNrWtMRWtaxM2taZ9IiIiZmZ9IiO8pU3sXvZE7XY7fQd1fczxa7h6TBrb23S3gG6sVsX9plQp5wuUb3Bu0jl2MXHv+cvU4d6ONLIuY2Jmz+kYGRG3clH4N+EuXJmwdU9S6s0wUmMvF6Gava2W0R9ZtZ8doi1a1t9fipaK+by1vPmpaImh73lPvCdDT47lvAXwS52mxymzF9Drrq7jMsZcOjgtPba4Litqk2182xmxdtff2cVs9cNM+xrV+Dt4ZvSXbbt27VuFq1CFq1ahG3bt24xhbt24RpGEIQjSkYQhGlIxjGlIxjSlKUpSiWkRERERERERERER2iIj0iIiPSIiPlDXsve+S9smS1r3va173vabXve0za1rWtMza1pmZtaZmZmZmZ7y/t+vEAAAAAAAAAAAABq+9rf2iYvdr2i811WvwrV7nnTrDyue8JyqxjW9bydLZpl7nEt+PE709horGxwsexSVayyci3WEJTrSlcY+LPSVerOkt3FjpE7/HUtv6V+3rFsEefNWO3rab4K5KVrE+trR2iZTl9317Quf2fvaF6Z39zZyY+lOstjB0n1Pgi0xjvh5PJ9T8bsX+dMddTlcuns5ssxEVw4b+a1axMxXYZeJk4GXlYOZZuY2XhZF7Eyse9CVu7Yyce5Kzfs3bcqUlC5auwlCcJUpKMo1jWlK0rRXvelsd7Y71mt6WtS9ZiYmtqzMWrMT6xMTExMT6xLcN19jDt6+Da1stM2vs4cWxgzY7RfHlw5qVyYsuO9ZmtqZKWretqzMWrMTEzEvXeL3AAAAAAAAAAAAAAAAAAAAAAAAAAAP2MZTlGEI1lKcqRjGNK1lKUq+IxjSnzrWta0pSlPnWvyoREzPaI7zPpER85n7T8mYrE2tMRWImZmZiIiIjvMzM+kREeszPpEJ63sL+zGfbZ2w2OpXLtVTF6k9b4Y/JcqWRbpTL1vEL9Y3+PYNmdKUrTF2mut6rc3bc6zlTInT5wpT0UnZ4H9Gz030zXktvF5eS5uK7N5tH1+LUt2tr44+XauXHGLNMT3mLT9DVH96V7SdfGnxwy9FdP705+i/C+2XhcEYbzOvu9Q4u+LmNrJSZmJz6O7bf42l6xWJw1n0t38zeCzYrAAAAAAAAAAAAAAAAAAAAAAAAQzPeZv1/e3T8WXK/tBq0OvaU/H7p79LNr+MY2yL7kv7E3jH+rfgfvRuozSNi7MAAAAAAAAAAAAAAAABIl92xl/4ZXU+Pn6+gXIa+P4OZ8Fp/m+aQns4/1Y8n+kOx/HdH/3qevfRx/8G/oef/rZ4iP2+muqZ/xJuaajWMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdB9yvbh007qeknJuj/VPT2tnoOQYd63j5cYQpsdHs/hy+hbnU5MoTrj52BkfCybXqjcsXblm3DJsX7VK26/B6k6d43qnidniOUwxl19ikxW8REZMGXt9Zmw2mJ8uTHbtaveJrMxEWravoyx4K+MvW3gP4gcJ4idCcjfR5fiNnHfNr2tadLlNLzx9U8byGGtq/G1drD8TDk8tqZaVyWthy4sna8V63fx2EdV+xbqvncR5hr8vZcH2uRfyuCc6sY1yuo32rlcn8OxcyrdJY2Pt8Ska28zX3LkMmMKWsqti3YybNa1/9edCcr0Pyt9Tcx3yaOW1raO9Ws/B2MXee1ZtH1tcte3a2OZi3btbyxW1e+3p7J/tX9A+1L0Dq9Q9O7mvpdT6GHFg6q6Vy56xyPE70Up58tMF5rmzcfsTaL6+3SlsFrfEwRltkwZe2BjoqVgAAD6Mdxt4RpCG02MIxpSkYxzsmMY0p9VKRpdpSlKfepSnh7IzZojtGXLER8ojJaIj9bu4duO4+0za2jp2tM95tbWwzMzPzmZmneZ+7L0rt69kXJXb925euy+crl25K5clXx48ynOspV+VKU+da/KjwmZtPe0zM/bmZmf25cnHjx4qRjxY6YqV/E0x1rSlfzq1iIj9aHjfjzAASFfZE+yB3HcpuNV157hNJstL0Q1OZay9Bx7MtTwM3qJl4ko34R+HkW6ZNON1vUtWcvLsQtRy7cczGxM23kW6ytyA8JfCPN1Jmxc71Bgy4eExXi+vr3icd+QvTtaPS0eaNfzdq2vWI88RetbxaO8VC+8J94fx3grx2/4U+EPJ6XJ+KHIa2TX5bl9fJXb1ujtfPFsVrebFecM818Ob5NfXy2vOva2vnz618N4i82XjPGOP8M0Or4xxbUYGh0Glw7OBq9Vrce3i4eHi48KQt2rVq3SlKUpSnmUq+ZzlWs5ylKVa1mjrauvp4MWrq4ceDXw0rjxYsdYrSlKx2iIiP/3zPeZ9Zay3N85y/UnK73Oc9yO3yvLclsZNve393NbPs7OxltNr5MmS8zMzMz6VjtWsRFaxFYiI+8975QAAAAAAAAAAACvm9uX+yHdXfq/UaD6v/wCQav6/wV/o8VQD8bvsgct+wfwGJt0e65/If+Hv6Ll/vvvtQDEaxAAAAAAAAAAAAAAAAAAAB7ut1uw3GwwtTqcHL2e02WVYwdfrsDHu5ebnZmVdjYxsTExbELl7IyMi9OFqzZtQncu3JxhCMpSpSvnjx5M2SmLFS+TLkvWmPHSs3ve95itaUrWJm1rTMREREzMz2hxtzd0+O1Nnf5Da19LR0sGXa29zbzY9fW1dbBS2XNsbGfLamLDhxY62yZMmS1aUpWbWmIiZS9fZM+xPxeIU473E92mix9jvrtrH3PCelewhSuNppSjG7gbTk9mMvjXM+zPxmWdfcnj0s3I49vMxbsKXrdyW3hT4L11PqfqHqzBXJnmtc2lxeT8ThmY70ybVYnvOSs9rxjma+WYrW9ZjzROvN7f3vM8/UP4M+Dvs/crl0+Jpkzcb1P15p2/p3JVi0029Hg8sx8Ompkr318u5SuaclLZb62fHacdqSkMbGx8PHs4mJYs42LjWoWMfHsW4WrNizajSFu1atW6Rhbt24RpGEI0pGMaUpSlKUSdrWtK1pSsVrWIrWtYiK1rEdoiIj0iIj0iI9IUW5s2bYy5M+xlyZ8+a9subNlvbJly5L2m18mTJeZte97TNrWtMzMzMzMy8zyesAAAAAAAAAAAAAB47tq1ftXLF63C7ZvW52rtq5Gk7dy1cjWFy3OMqVjKE4VrGUa0rSUa1pWnir8mItE1tETExMTE+sTEx2mJj6YmPSXnjvfFemXHe2PJjvW+O9Jmt6XpMWreto7TW1bRE1mJiYmImPVXu+2Z7Prvar3cckztJr5Y3Tzq7K/z3idy3CsrFi/sb0vzfwrl6FPhW71d/Da37GNWlucMStuVLdYUpOsAPGLpG3S3VmzfDj8vH8tNt7UmImYrbJP8Aqik2+UW+PGW1a+kxTtPbt6tu/wB277ROPx59nzhdbk9uM3V/h7XF0n1BS9orly4tOkfgTs0x2+vvj/Am2hiy54m9bbEXibRfvWNRrE6wYAAAAAAAAAAAAAAAAAAAAAAAAAABsp9lX2fbTvB7r+FcavYd65wPhGZj836gZtIUlZx9Np78LmHjTrOMoTpn7qWrwb1nxKdcbKuypSNKeuOR/C3pHL1d1Vpa1qTOho3ru8hft9bXDitHkrPeJifiZpxUmPWfLaZ9I9Yhb7ePtFaPs7eAXU3N49nHTqvqfXy9MdI6s3mMmbkuRxWps56xWa3r9ScZG9tY8netYzYMdZme/lmxi1uuwdRrsDU6zFs4Ot1eFi67X4WPH0WMTBwrEMbExrMPn6bVixat2rcfP6GEKU+8sOx46YcePFirFMeKlceOlY7VpSlYrStY+iK1iIiPtQ04t3c2uR3NvkN7Pk2d3e2c+5ubOWfNl2NrZy3zbGfJb+uyZct75Lz9NrTL3Xm4wAAAAAAAAAAAAAAAAAAAAAACGZ7zN+v726fiy5X9oNWh17Sn4/dPfpZtfxjG2Rfcl/Ym8Y/1b8D96N1GaRsXZgAAAAAAAAAAAAAAAAJD/u2Uv/DR6mR/D2/cjl/NzXglP6apBezj/Vnyf6n9j+O6P/Kp+99FH/wauiJ+j+a7w0f/AIY6rn/Em8prNYgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB0D3I9tPSbup6Y7zpZ1c43i7zR7fFv28XMrbhHa6LPnbrHG22nzPTWeNm4d74eRapKlzGu3LUI5WPfteq3X4PUfTfFdU8Zn4vltaufBlpaKX7RGXBkmPrcuG/zrek9rR371mYiLVtHeGWfBjxr8QPAfrfi+u/D3ms/F8px2fFfPrRe1tDldSt4nNx/I63eK5tbYx+fFkms0z0pkvODNiyTF4hD9+vsXe4ftNzNpzHgmuz+r3SCWTdu4e341r72w5DosWs61+DvtNgRvZvw8W3WNy9tYYWNgUtVlWtY/Au1pCnrvwa6h6Uvl3NHHk5fiJtM0za2O2TYwV7/ic+HHE37Vj1nLFK4/L3+Xlls7+yj7ynwf8f8AX0enOqtzU8PPESuHHj2OO5rbx6nD8rn8sR8TiuS27Y9bz57xamPQts5tv4kRERMZKQ0wXLdyzcuWbsJ2rtqc7d23cjWFy3chKsZwnCVKSjOEqVjKMqUrGVK0rSlaMOTExMxMTExMxMTHaYmPSYmJ9YmJ9JifksmpemSlMmO1b471rel6TFqXpaItW1bRMxatqzE1mJmJiYmJ7P4fjyAAAAeS1au37tuzZtzvXrs427Vq3GU7ly5OtIwhCEaVlKcpVpSMY0rWta0pSnl+xE2mK1iZmZ7RERMzMz8oiI9ZmftQ8cmSmKl8mS9cePHWb3ve0VpSlY72ta1piK1rETMzMxER6yk9+yY9iptOe5PHO4ruu0N/XcIjKxtuFdMNjbnibDkFbUviY+15LjT9Obh6+V6MZY2BcjhZF63ZrflO7jZNmiTHhT4MZd+2v1D1Vgtj0u9culxmSJpk2JrPeuXZrPa9MczETXHPktaImZma2hR57f3vMNHpTDzPg74B8ri3Op5rl4/qbrjTvXY0+HjJWaZtDhM9Ztq7O5GK0xm2622cOK2T4Va482DJKYNpdLqOOarA0eh1uHqNPq8W1ha7W6+xbxsPDxbEaQtWbFm1GMIQjSn3qeZSrWcqylKUqy6w4cOtix4MGOmHDirFMePHWK0pWsdoitY7REf4fnPq12uS5LkOY39vlOV3NnkOR38+TZ3N3by3z7Ozny2818uXLeZta0z9ue1YiK1iKxER9N7XBAAAAAAAAAAAAAV83ty/2Q7q78vH6DQfy/8AAOs+f9H8iAfjd9kDlv2D+AxNuj3XP5D/AMPf0XLfrf677/8A+/8AXagGI1iAAAAAAAAAAAAAAAAAADlfCOD8s6kcq0nCeD6HZcl5RyLOsa7UabU4l/NzcrJv3Iwp6bGNbu3KWrVJVu5F6sPh49iFy9dlG3CUqcrS0tvkdrBpaWDLs7Wxkrjw4cVLXve1p7elaxM9o+dp7dq1iZn0h8HqfqjgOjOB5PqfqjldLhOC4fVy7nIclyGxi1dbXw4qTafNlzXpScl5jyYccW8+XLauOkWvasTNu9lR7G7iva/r9T1q6+6/W8u627HDtZun0eVas5en6eQyLVPRS3bp8S1l76tmcq3ci7dv2cT40YW8exm49bsZp+Fvg9q9MUxczz2PFt81kpF8OC8Vvi4+LR6do9Yvn7T3m0zaKd4iK1vWZayHt6e8d57xy2+Q8NPCbb3enfDHT2L63I8rgyZNfkesLYb/AF03vPkya/FfErWMeKlMWTY+Ha1suXWzRSd/1KUjSkY0pGMaUpGNKUpSlKU8UpSlPlSlKfKlKfKlGe/l8lSszMzMzMzMzMzMz3mZn1mZmfWZmfWZn5v0fgAAAAAAAAAAAAAAADT17ans/j3R9pO/3eh18cnqH0cpe51xu5bt0rfv67At1ryLDnKlPXcs29FLaZVqzSVPOTGMo0lKtI1xD4zdIR1P0nnz4McW5Dh4tva8xH11sdI/1RSZ+c1jBOW8Vj52iPSe6xX3aPtEz4Ge0FxPGctt2w9IeI84uleape0/Cw7m3eI4fZrWfraZL8rXRwZMsxPbBa0TMR6xX3XITtTnauQlbuW5yhchOlYzhOFaxlCUa+KxlGVK0lStKVpWlaV+aAsxMTMTExMT2mJ9JiY+cTH0TDbhrat61vS1b0vWLUvWYtW1bRE1tW0d4mtomJiYntMT3h/I8gAAAAAAAAAAAAAAAAAAAAAAAAH927dy9ct2rUJ3Lt2cbdu3bjWc7lycqRhCEY0rKU5yrSMY0pWta1pSlK1q/YiZmIiJmZmIiIjvMzPpEREeszM/KHje9MdLZMlq0pStr3vaYrWlKxNrWtae0VrWImZmZiIiJmfRPz9iN2Xy7XO1rXcz5TroWOpXWu1i8v3Fy5CH0jX8czYRyON661OlPXbtZOorq8/Lx7kpShm0l6qW6xrbjPLwV6NnpjpfHubWPy8lzUV3M0zEebHr3jza2OJ+cRbD8LJes95i/eJ7THZqZe869pSPHTx13OmuC3LZeivDLJsdO8dSlrfB2+Z1rTh5ndvWZ8t74eQje1dfNSK1trdu03ifPO6JmVWsAAAAAAAAAAAAAAAAAAAAAAAAhme8zfr+9un4suV/aDVode0p+P3T36WbX8YxtkX3Jf2JvGP9W/A/ejdRmkbF2YAAAAAAAAAAAAAAAACQ17tnXx3r9SqeflXt65L/AD/3b8CSB9nKf9mnJR9vp/Z/e3tBUF76GP8A4M3RU/a8X+E/f6Y6rTfk12sIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8GVi4ubYu4ubjWMvFvwlbvY2VZt5Fi9blSsZQu2bsZ27kJRrWkozjWNaVrStK0q8bVres0vWt62iYtW0RasxPpMTExMTEx84mHtwZ8+tlx59bNl18+K0XxZsGS+LLjvWe9b48mOa3paJ9YtW0TE+sS1l903sjezPunhlZ+96f2+AcxyviVuc16eVs6fbzrKn6GM8LJtZ2g9MJ+qfqjqI3ZSnL1zl8vGNeqPCbo7qiL5M+hGhuX7993j+2HNPePTvS0X1+0T6+mGJ9fmm34Fe8H9pLwItg1OK6tv1b05g8kU6Z6wjJyXH18s/XTXaw5Nblu9q9q9rchNKxWPLWvr30PdYvdq+q+s2WTldFOsvHeSaSUp1w9TyvCrhby1Gla+imTs439brLspU8UrW1i26UrSta/KtKMGcv7OHK4slr8NzOvs4fXyYtqnkzxH0ebJ5sWKZ/OrC1Xw599P0DvaeHX8TPDfmOF5OsV+qOQ4HZjZ4vJMxEW+Bozj3d6kVnvP9Mz2mY7RHqwa5r7Bv2iHEfjX8bpzxnkmut+r0Zen53xa9kXfT5rX06y3s72bTzGlK08wr58+Kea0q6Ru+BfiFqd7V47W2ccfK+He1ZtPb/wCSjLa/53olF0z71j2Puofh4s3WXN8LuX7ebX5HpXnceHH37R67ttLHrT2mZie1vSI7z6TDGjc+y577NHdrZyu3jnuRKk/h+rW6bP2VusvPjzS5h4t2FY/f9VK+nx8/LrWbwx64wTMW6f3rdpiO+LDkyx6/dpSWbON9uf2V+UxxkweMPSeGs183bd5LV0rxHbv2mmzmx2i30RXt3mfSIcn4v7I7v85Zet2Nf0E5BhTu1jSkt7ctaK3Gsvq9dzaUxoQ/f9VaePv+HK1vCbr3bmK4+B2KTP055jBEfnzl8vb7v2vpfD5z3g3smdP475dzxX4jZrjiZmOKpflbzEd/xNNGc1rfL07RPf6GcHST3dTvI5jexrnU3e8E6UYM5W53pXdrr+X5FbFa0rOkLfH9rOtu7WPmkaXIV9MvHqjXxWju3E+zz1huWrPJ59Hisc9pnvlx7l/L9MRGDLPa3b5d4mIn5oweIPvivZw6cx5q9EcV1V1/tVreuOMeht9O4PixExWbX5bRrF8cW7ebyWjvHfyz8m/Ds09iJ2sdrG11vNuR2c7rJ1EwfhZGPtOZRxL2j02wh483tJqMTD18JWq1jGVLe4psq0l5r5pTxSmd+jvBXpfpfLj3dmt+Y5Gna1cu5FLYMOSP67BhrSkdp+fbN8T1VP8AtIe878d/HfQ3emeGyanhv0dtefDm0em52MfK8lqW79sXJ8jsbO3at47zE346dLvXtHb6W5yzZs41m3j49m1YsWYRt2bNm3C1ZtW4UpGFu3bhSMIQjGlKRhGNIxpSlKUpRmOIisRWsRWsRERERERER8oiI9IiPoiFbWTLkzZL5c2S+XLkta+TLkvbJkyXtPe173tM2ta0zM2taZmZnvM93lfrwAAAAAAAAAAAAAAV83ty/wBkO6u/On6jQfyf8A6z5V/f+/8AwVogH43fZA5b9g/gMTbo91z+Q/8AD39Hy36/+u+9/wDuagGI1iAAAAAAAAAAAAAAAAAD7fGuP7PlvI+P8V0tiuTueTbvVcf1ONStKVyNnuc/H1uBYpWVaUpW7lZNq35rWlKerzWtKPdra+Xb2NfVwV82bZzYtfDX+yy5slceOv697RH675nNcvo9P8Ny3Pcnl+BxvCcZv8vyGbtM/B0eN1cu5t5e0d5n4eDDkv2iJme3aE/b2XvssOmXZbwfVc45NiYnMeuvKdViZ+75Hsca1ds8Xjm49u7TRcdsSt0piwxrUowysm7XIy7mZLKlbyYY8rVm3PTwy8LuN6M0sW7s0puc5s4q5M+zkrExq/ErE/A169vrYrHaLWnzXm83mLRXyxGph7cvt39b+0t1Rv8AS/CbGfpvws4Lf2NTjOF0816ZOdtrZr0nleYzVvM57Z71m2DBjjDgprV14vhtmrky33DsvK6QAAAAAAAAAAAAAAAAAHq5+DibPBzNbsMe3l4GwxMjBzcW9H1WcnEy7M8fJx7sf+dbvWbk7c4/fjKtPvvDJSmWl8eSsXx5KWpes+sWpeJrasx9q1ZmJ+5L36u1saO1rbupmvr7ennw7Wtnxz5cmDY18lcuHNjt9F8eSlb0n6LViVc/7V3tJzu0ju653xzGw7lnhHOc3I53wXKrb+HYyNZvLv0vY4+PSkYxpZ1m6v5+ttR+ulvEj85ePVWvPxU6Tv0n1bva9KTGlvXtvaN+3atseefPkrX0j0xZrZMcR9qjcb9gf2gdb2gvZ76V5rPsUydT9La2HpXqnBF/Plxb3F4/qfTzZpmZmcm9xuLU3clu/ab57fL5NaLGyawAAAAAAAAAAAAAAAAAAAAAAAADaN7JHs42Hd53Y8S1+dhXLvTzptkY/O+e5UoeLNcLV37dNXgwuXIytXL2TvbuqjfxqUnclhSvz9FIUrcjk7wn6PydXdV6mO9Jnj+NtXf37TH1s0xWj4WPvPpM2zzii1fWZp5p7dvVBj3gntG6ns8+APUO3q7NKdYdaYc3SnSmCLd8kbW/iv8AV+1alZjJTHg4rHv2xZu9aV2a4q+abTFbWJOHh4uvxMXAwbFrFwsHGsYeJi2Y0hZxsXGtRs49i1Cnyhas2oQt240+UYRpSnyosIpSuOlMdKxSlK1pStY7VrWsRWtYj6IiIiIj6Ihp6bOxn29jPt7WW+fZ2s2XY2M+W03y5s+e9smbLktPra+TJa172n1m1pmfm9l5PSAAAAAAAAAAAAAAAAAAAAAAAAhme8zfr+9un4suV/aDVode0p+P3T36WbX8YxtkX3Jf2JvGP9W/A/ejdRmkbF2YAAAAAAAAAAAAAAAACQp7tvLx3tdRaf8AS7fuS0/9teCVoz/7Oc9uteQ+7wGzH7e7oKhffP17+zJ0dP8AY+LvCT/+Geq4/wAKcImy1gQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFfN7cv9kO6vfxNB/7g1aAfjd9kDlv2D+AxNuj3XP5D/wAPP0XL/fffagGI1iAAAAAAAAAAAAAAAAADLXsR1+Ds+8LtzxdhZpfx6dXeB5FLdaeaVv43JdZkY8q0r5pWkL9u3KtK/Kvh2vobHTL1f07TJXzV/BfQt2n7ddnHas/rWiJR/wDap3NrR9nXxkz6eScWafDzqvDN4ntMYs/CbuHNET3jtNsV7Vifo791nFSlKUpSlKUpSlKUpSnilKU+VKUpT5UpSnypSn1LLWkRMzMzMzMzM95mfWZmfnMz9My/R+AAAAAAAAAAAAAAAAAAANGft3OzuXcR2u3OqHFtZ9K6g9DrkuQ2Potn4mdtOKSnKzutdOfplWmHrMbNzd7KlPTWk8Wtay8eaMIeOfSE9Q9MTyerj83IcJM7FfLXvfLq9+2bHM+vamOt7557ev1k+v0LR/dWe0XHg/46U6G53ejB0h4oUjh8vx8nl1dDn60jJxm5WveInZ3c+vq8VWZ7/W54iK9/VAz+r60Fm1iAAAAAAAAAAAAAAAAAAAAAAAA8tmzdyb1nHx7c71+/dt2bNm1CVy5du3Z0hbt24RpWU53JyjGEI0rKUq0pSla1pR+1rNrRWsTa1pitaxHeZmZ7RERHrMzPpER85eGTJjw48mbLemLFipfJlyZLRSmPHSs2ve97TFa0pWJta1piKxEzMxELA72LfZn/ALlPtS0m75Jr7VjqT1js4nOOSXpQh8fF1OytUyuN62lfFbtj0aS7rZ5uLcl6oZ1u5Wdu3ONYRnz4NdHfhV6VwZ9jHEcjzFab2zMxHmriyV82tj+3X+kzjm9ZnvF4nvETHaNR73lXtI/ze/HvlOM4Xbvl6L8OMmx0vwuKt7fCz7+lknBzW7MR2x5fNyePdrrZ617W1b18tr1t5rbhWXldYAAAAAAAAAAAAAAAAAAAAAAAACGZ7zN+v726fiy5X9oNWh17Sn4/dPfpZtfxjG2Rfcl/Ym8Y/wBW/A/ejdRmkbF2YAAAAAAAAAAAAAAAACQb7t7L097nPqf9LoHySlPyz4NX/wCf8jP3s6f1a7/6Q7P8d0VRXvm47+zH0n9zxZ4Sf/w31TH+NOLTaavgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACvl9uV+yHdX/4ug+z+qQD8bvsgct+wfwGJt0e65/If+Hn6Ll/vvvtQLEaxAAAAAAAAAAAAAAAAABl/wBgn+OT25fjZ4T9ode7d0F/Vj05+m2j/GMaPHtY/kcfGT9QHU33p21mysqaRwAAAAAAAAAAAAAAAAAAAD5W90ut5JpNvx7c4tvN1O91mfp9nh3o+q1k4GyxbuHmWJ0+XmN3HvXIV8VpXxL5VpX5vVnwY9nBm181Yvhz4smHLSfWLY8lZpes/cmszDn8Vye7wvJ8fzHG5763IcXvavI6OxjntfBt6WfHs6+Ws/2WPNjpePo7x6q2z2kPavte0fuv6ldN72NdhxvP3OVyjhWZW1W1i5fHt/KO1s2MKvikbljUXc2enrKNZVpcwpxnWs6SVy+IvS+XpPqrkuOtWY1sma21pX7dq3188xlitPomMM3nF6fTT19e7c/9jLx30PaD8A+ius8Welua1OOw8F1NrRki+fX5jiazoZMuzHmm1MnI49avIxFojvTZrMR5Zhge6MlUAAAAAAAAAAAAAAAAAAAAAAA2w+x67Ncvu27sOM3NtgTvdOOlN2xzvmt+5CsbGRHXX7UNNrbN+dPhTyp7zI1V+9i0pcuTwYZEq26W/VOOVPCLo6/VnVWtObHNuO4qa727aY+tt8O0RhxxafrZt8e2K1qeszSLT27d5iAvvFPaQ1/Z98Aubrx+1XH1n17jy9K9MYqXicuG25ivbkd3JirPxKYK8Xh38OPYny0ptWxV803mtLWGOPj2MTHsYmLZt4+Ni2bWPj2LMKW7VixZhG3Zs2oRpSMLdu3GMIQjSlIxjSlKUpRYFWtaVrSsRWtaxWtYjtFa1jtEREekRERERH0Q1Bc2bLsZsuxnyXy58+S+bNlyWm2TLly2m+TJe095te97Ta1pmZm0zM+svM8nrAAAAAAAAAAAAAAAAAAAAAAAAAQzPeZv1/e3T8WXK/tBq0OvaU/H7p79LNr+MY2yL7kv7E3jH+rfgfvRuozSNi7MAAAAAAAAAAAAAAAABII93Cl6e97nH/ndB+SR/n5hwj/4f96M++zr/VtvfpFs/wAc0lR3vl47+zF0v9zxV4Wf/wAO9Tx/j/xJyCbbV4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAV8vtyv2Q7q/wDxdB9n9UgH43fZA5b9g/gMTbo91z+Q/wDDz9Fy/wB999qBYjWIAAAAAAAAAAAAAAAAAMv+wT/HJ7cvxs8J+0Ovdu6C/qx6c/TbR/jGNHj2sfyOPjJ+oDqb707azZWVNI4AAAAAAAAAAAAAAAAAAAABHn94I7Pp9Ye37U9wPE9XXI5l0Wu2o7z6JY+Lm7HhexzK413HhatRrduUwM/Z/mnkXfTP4WLi3JTrC1brKkfvH3pGeX4DF1BqYvNucLMRnile98mnkv5ZrER6z8PJl+Lae09q0nv2iO8W+e6N9omnh14uch4R8/vRh6c8S8d54v6oy/D1tLqXT14z0zWvefJSdvU0fqHFj71+JnzUisWvaImD+hQ2fAAAAAAAAAAAAAAAAAAAAAAHnxcbIzcnHw8SzcyMrLv2cbGx7MJXLt/Iv3I2rNm1bjSsp3LtycYQhGlZSlKlKUrWtH7Wtr2rSsTa1rRWtYjvNrWntEREeszMzERH0y9WfPh1sObZ2MlMODXxZM+bLktFMeLDipOTJkva0xFaUpW1rWmYitYmZntCwp9jl2aWu0ntO43f3uDatdSOrOPh885fk1hD49rF21n6Zx3WV8+buPLD0eRr7OdiylGsc6zclctwuUrGlgPhB0dHSfSmtOekRyPK1pv7du310Vy18+vj9fWs0wWx1vT0+vrMzHf0jUM9417SF/aB8fuaxcVtZMnRnh/l2OlOncPmtOLJn4/L9T8xux2mMeauzymHcyauesT31ctIre1J7ztoZWV/gAAAAAAAAAAAAAAAAAAAAAAAAAIZnvM36/vbp+LLlf2g1aHXtKfj909+lm1/GMbZF9yX9ibxj/VvwP3o3UZpGxdmAAAAAAAAAAAAAAAAAkB+7jSpTvf5l/53Qzkcafw/3W8Mr/Qz37O/9W25+kmx+/t6UKkvfKR39mDpz7ninws//h7qaP8AGnKputXQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABXy+3K/ZDur/8XQfZ/VIB+N32QOW/YP4DE26Pdc/kP/Dz9Fy/3332oFiNYgAAAAAAAAAAAAAAAAAy/wCwT/HJ7cvxs8J+0Ovdu6C/qx6c/TbR/jGNHj2sfyOPjJ+oDqb707azZWVNI4AAAAAAAAAAAAAAAAAAAABxnmnEtNz3iPJeFcixbeZo+VaLa8f2uNcjGdLmDt8G/gZHppOMo0uRtX5StT8VrbuUjOPiUaVcbd1MO/qbOlsUi+DawZdfLWY7xNMtLUt8+/ae1p7T9E+r7fTXUHJdKdQcJ1Nw+e+tynA8rocvoZqWtWabXH7WLaw+aazEzScmKtb179rUm1Z9JlWid8nbZve1Hua6o9H9vi3LGFp+Q5Wfxq/8OdMbK4zufRt9J9Gv1828muLrc/FxMmdqcqRyrN63OkJxlCNbnW3TefpXqXk+HzVmtMOxa+tbtPltrZu2bB5bfK3kx5KUtMd+14mJ9YmG657L3jTxXj54I9C+IvHZ6ZdnkuHwavNYvPWc2Dm+N83H8p8fFHa+H4+7q59jDW9Ym2DJjvWbVmLTiQ6mkCAAAAAAAAAAAAAAAAAAAAA2++xj7ML/AHX91mi3O+18sjpn0euWebctndhKOPnZeHct29Hq7N+VPhSy47jK1mfcxvM7lzCx78q2/h0lKmXPBzo23VXVODNnxzbjeHmu7tzMfW5L0mIwYotPpN4zWxZJr6zNKzPbsrx95J7SeHwC8BeV43ituuLrbxFpl6Y6epS0WzauDZpe/Kb+XFHfJXXnjsG7qUz9q0ps5sURfz9qzYL2bNrHtWrFi3CzYs24WbNm1GMLdq1bjSFu3bhGlIwhCEaRhGNKRjGlKUpSlE+4iKxFaxEVrERERHaIiI7RER9ERHpENRjJkvlyXy5b2yZcl7ZMmS9pte972m173tMzNrWtM2taZmZmZmZ7y8j9eAAAAAAAAAAAAAAAAAAAAAAAAAACGZ7zN+v726fiy5X9oNWh17Sn4/dPfpZtfxjG2Rfcl/Ym8Y/1b8D96N1GaRsXZgAAAAAAAAAAAAAAAAN/vu5da074eWU8/quiPI6f+1fDq/0M9ezx/Vtt/pLsfxrTVLe+Qjv7L/Afc8T+Gn9rgepP+VObTeauAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACvl9uV+yHdX/AOLoPs/qkA/G77IHLfsH8BibdHuufyH/AIefouX++++1AsRrEAAAAAAAAAAAAAAAAAGX/YJ/jk9uX42eE/aHXu3dBf1Y9Ofpto/xjGjx7WP5HHxk/UB1N96dtZsrKmkcAAAAAAAAAAAAAAAAAAAAAAjQe8S9n8+edKuLd0nEdV8Xf9MZ4+g5xLFs+q7k8S2ebOxh5U7dqPxb+Rj7jZYcJ3q+v4WFal6qRhCsoxt9oTpGd/i9XqfUxd8/GeXBvTWve1tTJea0t2iO9rVzZaRM+vakTMxERMrr/c8+0RXpXrznvArqDf8AJxPW9MvLdL1z5fLjwdQaOtGXZwVvknyYsObjdPYtTHHk+JtXjtNr2iswxkOWySAAAAAAAAAAAAAAAAAAAA9rCwsrY5uJr8Gxcyc3PysfCw8azGs7uRlZV2FjHsWoRpWU7l27chbhGNK1lKVKUpWtXlSlsl6Y6Vm18lq0pWI7za1pitaxEeszMzEREfOXo2dnBp62xubWWmDW1cGXZ2M2S0Ux4cGDHbLmy5LWmK1pjx1te1pmIrWJmZiIWIHsiezfH7Qu03imFt8O1b6idTMXD55zbL+HSORSe5sfTtJrLtJUrdsXNXpsrCwcvGlWPpy8a5WduNylaRsF8Jejq9I9KatM1IjkeTrTf3b9u1onNHxMOKe/rWcWG9KXr6fX1nvHeGn37wr2js3tDeP/AD+1x+zkv0d0Tn2OlOmMHnmcM043JGrye9SYnyZab3Ja+zta+aInvr56xS80nvO05lFBIAAAAAAAAAAAAAAAAAAAAAAAAAABDM95m/X97dPxZcr+0GrQ69pT8funv0s2v4xjbIvuS/sTeMf6t+B+9G6jNI2LswAAAAAAAAAAAAAAAAG/X3dGXp75OS0/6XRbkUf/AGo4hX/v/P8AeZ59nme3W2z+k2xH/nOp/jVN++Mr39l3hZ/sfEvhp/8AQXUX+PsnRpvtWsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABXy+3K/ZDur/wDF0H2f1SAfjd9kDlv2D+AxNuj3XP5D/wAPP0XL/fffagWI1iAAAAAAAAAAAAAAAAADL/sE/wAcnty/Gzwn7Q6927oL+rHpz9NtH+MY0ePax/I4+Mn6gOpvvTtrNlZU0jgAAAAAAAAAAAAAAAAAAAAAHAeqfTzQ9WenXNem/JsWxmaXmnG9xx7Mt5FuN2Fqmzwb+Jby4wlSVPjYd27DKsS8V9F6zCdKVrGjgcpx+DleO3eO2aVvh3dbNr3i0RMR8XHakW7TEx3pMxes9p7WiJ+h2zoTrDlugOsemus+Ez5dfk+mua47l9a+G847XnR2sWe+va1Zifh7OOlsGWO8ebHktWZ9VZV3V9BuRdtHX7qb0a5Jh3sTJ4hybPx9d8aNaVydBlXPp/H8ukvHpnXJ02Vg3p1j8qTuSjWkZUrGla3VPBbHTfP8nw+zSaW1NnJXH3/rsF5+Jgv3+U+bDalp7fTP0T6N27wG8VuH8bPCXojxI4XYx7GDqLhNXNufDmJjBy2Cv1Ly+vNe/evwOSwbWKsT860iYmYmJnHp19l4AAAAAAAAAAAAAAAAAABuZ9id2W3O6bum1fL+Sa6uT0y6LXLXL+R1v25UxNnt7ErdrR6i3er4t1y7OyzNft5WPVKc8bDu1rbrb9VWYvBfo23VHVGLc2Mfm4zhprt7E2j6zLmrMRgwxb5eeuS+PN5fppSfTt3Vu+8z9pWngT4E7/T3C7kYet/EuuTp3hoxXj6o0eOyxbJyvIXxR3v9T5dLX2+PjL2itc+xSItF/LCf7CELUIW7cI27duMYW7cI0hCEIUpGEIRjSkYxjGlIxjGlKRpSlKUpSiesRERERERERERER2iIj0iIiPSIiPlDUrta17Wve1r3vabXvaZta1rTM2ta0zM2taZmZmZmZmZmZ7v6frxAAAAAAAAAAAAAAAAAAAAAAAAAAAQzPeZv1/e3T8WXK/tBq0OvaU/H7p79LNr+MY2yL7kv7E3jH+rfgfvRuozSNi7MAAAAAAAAAAAAAAAABvw93Wl475t/T/pdG+RU/wDabiVf/gzv7PU/7N9iPt8PsftRs6n/ALlT/viY7+y5xP3PEjhp/wDQnUEf4/8AEnUJwtWcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABXy+3K/ZDur/8XQfZ/VIB+N32QOW/YP4DE26Pdc/kP/Dz9Fy/3332oFiNYgAAAAAAAAAAAAAAAAAy/wCwT/HJ7cvxs8J+0Ovdu6C/qx6c/TbR/jGNHj2sfyOPjJ+oDqb707azZWVNI4AAAAAAAAAAAAAAAAAAAAAABFV9407Qa7PScK7teIajzkaT4HEOpU8Oz4pLAyL1y3qOQbG54rKd2mXf1ektVpKkaWqW6VhWtPUi37Q/SPxMOl1Zp4frsPl1OSmkfPHa0xh2Mk9u82i9sWCPXt5e0dvRfJ7m/wBoeNLlOpvZ+6i5D+k8p8XqLomuxk7zXbw4635HiNOveIrjnBj3uUvExMzfzzFu3aqIiiW2FAAAAAAAAAAAAAAAAAAHvazXZu42Wv1Gtx7mXsdrnYmuwMW1Gs7uTm51+3i4uPahGlZSuXr923bhGNK1lKVKUpWtXnix3zZMeHHWb5Mt6Y8dIjvNr3tFa1iI+c2tMREfblxt3c1uO09vkN3NTX09HV2Nzbz5JiuPDrauK+fPmvaZiK0x4qXvaZmIitZmZ7LFj2UfZ1hdnnahw3judh24c/53h4nOOeZsrVLeXPYbqx9P1+syKV/RWrmk1uXj6q9a8R/TcOUrkfiearC/Cvo+nSHSunr5KRG/vUpvb1+3a/xM8fEx4rfTE4cd64rR6fXU9Y7tOr2+PaM2vaL8fOo+Y1di9ukuldjY6X6U1ov59eunxmT6k297DMTMZKcnu6+bfx5O9v6XsRFLeTtDZkyUhKAAAAAAAAAAAAAAAAAAAAAAAAAAAAhme8zfr+9un4suV/aDVode0p+P3T36WbX8YxtkX3Jf2JvGP9W/A/ejdRmkbF2YAAAAAAAAAAAAAAAADfV7u3Xx30bmn/S6P8ip/wC0nFK/0M6+z3PbrjN93h9mP/OdSf8AEqj98LHf2W+N+54icPP/AKG56P8AGnXJxtWMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABXy+3K/ZDur/8XQfZ/VIB+N32QOW/YP4DE26Pdc/kP/Dz9Fy/3332oFiNYgAAAAAAAAAAAAAAAAAy/wCwT/HJ7cvxs8J+0Ovdu6C/qx6c/TbR/jGNHj2sfyOPjJ+oDqb707azZWVNI4AAAAAAAAAAAAAAAAAAAAAAB1B196P8c699HeoXSTlOHjZuq5txjaaekcqHrt4uwvY1yWp2NKeafpmt2cMTOtVr5j8THj6oyp5pX5HPcRrc9xHIcTtUrfFu62XD9fHeKZLVmcWT8/HlimSPu1j0lkTwn8ROY8KPEbpDxB4LZza2/wBMc5o8jM4LeW+fTx56RyGnM/2G7o22NXJ8p8ma3aYntMVknXvo/wAj6CdYeoXSPlWJk4e34RybZ6escu3W1eytfZybktTsawrGNKW9nrJYmfarGNIytZEJR+VaK1Od4jY4Ll+Q4napambS2cuHteO1rY62n4WTt2j0y4ppkjt6drR2buXhR4icN4r+HXSHiFwOxh2OO6o4TS5KJwXi+PBt5MNY5DTi0Tb67R3q7GpkiZmYvhtE+sS6hfJZCAAAAAAAAAAAAAAAAAbufYb9lku5nudxepHKNfXI6adD5w5Js6ZFmssDccl9ELOl00rnilKZOLfz8XexhGcZShr6+qkoeqlc1eCXRn4ZepqcltY5txvCTGzl80fWZtntEYcMz9Fq2vXP2iYmYp9rurH96H7SseCXgfn6M4PcjD1r4oVtw2jOHJFdrjuF81svJclFO/ecGfFq5+LtaazEX247TFu0xPejGMIxhCNIxjSkYxjSkYxjGnikY0p4pSlKUpSlKUpSlKeKJ3RERHaI7RHpER8oj7TVAmZtM2tMzaZmZmZmZmZnvMzM+szM+szPrMv0fgAAAAAAAAAAAAAAAAAAAAAAAAAAACGZ7zN+v726fiy5X9oNWh17Sn4/dPfpZtfxjG2Rfcl/Ym8Y/wBW/A/ejdRmkbF2YAAAAAAAAAAAAAAAADfJ7vBXx307T9/pLyCn/tDxev8AQzp7Ps9uuMv3eJ2I/b2NVVR74KO/ss6U/a8QeHn/ANEc7H+NO0TkarwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACvl9uV+yHdX/4ug+z+qQD8bvsgct+wfwGJt0e65/If+Hn6Ll/vvvtQLEaxAAAAAAAAAAAAAAAAABl/2Cf45Pbl+NnhP2h17t3QX9WPTn6baP8AGMaPHtY/kcfGT9QHU33p21mysqaRwAAAAAAAAAAAAAAAAAAAAAAACIb7xp2hU1W/4T3acQ1HoxN7GzxDqPcw7NZU/NPHtXY6re58oUlSzbrh2Nbp7dyXw7c70oR81uS+cSvaI6R+FsaXVepi7Uz+XT5HyV7/ANNrExiz5O34mPJXHhifSJntHz+ewv7m72hp3+J6n9n/AKh5DzbHFTl6i6MrsZIifqHNkpbkOL1ItMTlvGzl3eRvSPNeuOLWiIpHaIrKLi+EAAAAAAAAAAAAAAAB9LTanP3+31Wi1WPcy9putjharXYlqNZXcnO2GTaxMSxbjTzWs71+9btxpT66yo9mHFkz5cWDFWb5c2SmLHSPWbXyWilKx92bTEOHyPIanE8fvcpv5qa+jxuns7+5sZJitMGrp4b7GxlvM+kVx4sd72n7USscPZedoWu7O+1HgnCr2JbjzflGBjcy57nytfDzb+63tuWzta7M+UfFzQYubb0tKUjGtaYVKz9U/Mq2I+GPSOPo/pXR0rUj6t2sddzfyTHa9s2ePixjv8vXBW8Ye3aPxHr3n1abPtze0Pue0Z4+dVdTY9i9umOC283TfSepGSb62LjOKvGlk3dbvM/Wctn1rclMza3rszFe1e1Y2LMhocgAAAAAAAAAAAAAAAAAAAAAAAAAAAAIZnvM36/vbp+LLlf2g1aHXtKfj909+lm1/GMbZF9yX9ibxj/VvwP3o3UZpGxdmAAAAAAAAAAAAAAAAA3v+7yy9PfXm08+PV0p5BT+H/h7jXyZy9n6e3XN/u8VsR/5fWn/ABKrPe/R39ljW+517xE/+iubj/H/AIk7lOZqtAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK+X25X7Id1f/i6D7P6pAPxu+yBy37B/AYm3R7rn8h/4efouX++++1AsRrEAAAAAAAAAAAAAAAAAGX/YJ/jk9uX42eE/aHXu3dBf1Y9Ofpto/wAYxo8e1j+Rx8ZP1AdTfenbWbKyppHAAAAAAAAAAAAAAAAAAAAAAAAMdu6/oHx7ua7fupvRnkWHZyrPLuM51jVyu0hT6LyDEhTP4/lRuy8VtRsbnFwbl2UZR9VqE4Sr6JSo691VwOv1LwHJcNsUrau3rXrj839bsUj4mvbv6dormrSZ9fWImJ9GYvAPxZ5jwR8XOiPEnh9nJr5Onub1cu/GPzT8fiNi06nL680r3jJOXjc+1THE1t5clq2rHmiFZZ1R6eb/AKT9ROZ9N+T4t7E3nC+Sbfjufbv2Z2JXLmrzr+JHKtwuUjWuPmW7UcrGuU8wu2Ltu5blKEoyrWtyfH5+K5Hd43ZramfS2c2vki0TWZnFe1ItET/W3iItWflNZiYmY9W7Z0N1fxPX3R/TXWfB58WxxfUvC8dzOpfFkrlilN/VxbE4L2pMxGbXtktgzUntamXHeloi1ZiOBuC7UAAAAAAAAAAAAAAA3rewj7LadxfcpTq9yzW/SunHQycdzdhlWfXr91y69Zjj6nU3Jen1Uv4NNha31n0Th+j10fXWUfVCWcfA3oz8MXUkcvt4vPxvBz8aYvHfHm27RFcWKfTv5scZI2K9pj1x+vePSasvepe0rPg54Kz4e9P7vwOs/FKJ43HbBk8u5xnT2PJbLyHIUjv2nFtTqX4nJ5q2+t257RFu1ong0pSlKUpSlKUpSlKUp4pSlPlSlKU+VKUp8qUp9Sc7VVmZmZmZmZme8zPrMzPzmZ+mZfo/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEMz3mb9f3t0/Flyv7QatDr2lPx+6e/Sza/jGNsi+5L+xN4x/q34H70bqM0jYuzAAAAAAAAAAAAAAAAAb2Pd6peO+2/T/pdLt/T+becbr4/zf5mcfZ/nt1zb7vGbEf8AltdVj73qvf2Vsc/2PXXET8v+xnM/tfa/XTwE52qqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr5fblfsh3V/+LoPs/qkA/G77IHLfsH8BibdHuufyH/h5+i5f7777UCxGsQAAAAAAAAAAAAAAAAAZf9gn+OT25fjZ4T9ode7d0F/Vj05+m2j/ABjGjx7WP5HHxk/UB1N96dtZsrKmkcAAAAAAAAAAAAAAAAAAAAAAAAAhh+8Sdn8eA9VuK90fEtV8Hj3U+Njj/Nq4tn9LxuX6zBnaw8uduzGkcXGyNNrcWFy9cjGF7Pu1p8St25SNYb+0H0jGhyur1PqYu2vycRg3fJX0rt46TFLzEfia2w46xNpjtN5+feezZM9z17RFuregee8C+od/4nMdDTl5fpmNjL9fm6d3tut9jXrfLM2z58PI7ue1MdLTbHq4/SkY6eaI0aN66wAAAAAAAAAAAAAB9fQaPZcn3um45psa5mbffbTX6bWYlqNZXMjP2eVaw8SzGlPNfNy/etw/BTz5r8ntwYMmznw6+Gs3y58uPDipHrNsmW8UpWPz7WiHz+W5TS4Ti+S5nks1Nbj+K0dvkt7YyTFaYdTSwZNnYy2mflFMWO9v1u0eqyD9mp2kars67Ven/TuOLbpy/ca3H5XzzYStUt5uVyHexltLuDmVjSMZS0MM78xbVYxj+k4cPVWc/M5WLeG/SeLpDpbQ4/yx9V5sddreyTHa9tjPE5Zx39I7zgi/wI7R8qR859WmX7avtBb/ALRnjz1b1jOe89O8du5uA6U1IvN9bBw/FWjRpta0TNprXlrav4J5Im0x8TZt5YrHasZ/O+olgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIZnvM36/vbp+LLlf2g1aHXtKfj909+lm1/GMbZF9yX9ibxj/VvwP3o3UZpGxdmAAAAAAAAAAAAAAAAA3pe73y8d9/8bpnv4/8Arnj1f6P52cPAH+rn8/jc/wDDa8/4lWvvd47+yr+d1txE/wDo3mP+VPGToaqIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACvl9uV+yHdX/4ug+z+qQD8bvsgct+wfwGJt0e65/If+Hn6Ll/vvvtQLEaxAAAAAAAAAAAAAAAAABl/wBgn+OT25fjZ4T9ode7d0F/Vj05+m2j/GMaPHtY/kcfGT9QHU33p21mysqaRwAAAAAAAAAAAAAAAAAAAAAAAADEbvm7a9J3XdsnVDpDtcS3fz9tx7Kz+M3/AEQrkYvJdP6Ntpvo9yUZVtVy8/Bx8O/KPisse/chWVKSrWnUuuOnMHVXTXJ8RlrFsmXXvfWt2+ups4f6bh8s/R5slK0t9utpjvHzSE9lzxp5TwD8buhvEPQ2LYtXj+XwanN4vNaMOfhOR83H8l8alZiMka+ptZtnFW3eIzYqW7TMRCtF5lxTccF5byXhnIMa5h7viu923Htrj3YStyt52nzr+vyqUjP5+it7HnW3L5xnCsZRrWNaVrW7uaubR29nT2KzTNq58uvlrMTExfDktjt6T9Hes9vtx6t1rpznuO6p4DhepOIzU2OM57itDmNDNS1bxfU5HVxbeCZmvp5ox5qxePSa2iazETExHGnGfaAAAAAAAAAAAAAb8/YJ9lsOvvcRf648v1n0rp70Pn9OxbWVZpc1+65plY8cfXa676o+ZVwMfY13dqVucKRyNfbpKUvFbcs8eBPRkc91Dbm9vH5uP4T6+sXjvjzbt6xXHjmJ9e+OuT49Zj5Xxx3+1NTvvXvaVt4TeD2Lwv6d3fgdX+KFY1c98GTybfGdNYM05dzdp2ntFdvNp/gZkretpnDt3mKx3i8Tpfq+pOBq0gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIZnvM36/vbp+LLlf2g1aHXtKfj909+lm1/GMbZF9yX9ibxj/AFb8D96N1GaRsXZgAAAAAAAAAAAAAAAAN5nu+kvT34Wv/O6c76P8+20Vf6Gb/AH+rqP0uz/wuCVXPvc47+ypk+51lxM/+j+Vj/GnmJ0tU0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABXy+3K/ZDur/wDF0H2f1SAfjd9kDlv2D+AxNuj3XP5D/wAPP0XL/fffagWI1iAAAAAAAAAAAAAAAAADL/sE/wAcnty/Gzwn7Q6927oL+rHpz9NtH+MY0ePax/I4+Mn6gOpvvTtrNlZU0jgAAAAAAAAAAAAAAAAAAAAAAAAAEHf3gXs9h0Y7hNZ1+4pq6YvCetcLf5qxxbNLeDrOa6/CrYycWFIwp4u7LD1lzcZE5yn68jKuVpKPqpFCbx86RjhuoMXPauLyaXNRHxYrXtjx7uOnltSPT55KYpzW7zPe15bQPukPaJt4k+EO94S8/vfH6m8Mr5PqCc+Wb7e90zt7MZcGe3e098elsb1OOw1rWvlw4KRMW7TaY97AC3cAAAAAAAAAAAB93i/G9tzDkmh4pocW7m7rke412k1eLZhKdy/nbTLtYWLbpGPz8VvXoeqVfFIx8ylWlKVrT36utl3NnBq4KzfNs5seDFSI7zbJlvFKx+3Md5+iPWfR8rnOZ4/p3huV57lc9NbjeG47c5Te2MlorTFqaOvk2c95mfTvGPHbtHztbtWImZiFkp7OvtO03Z32t9POl+LjW48myNVj8j5zn1txjmZnJ95GW1zsXLnCMI3fzFu513T406R/8WxLdKynX9HWxnw86Uw9IdL8fxdaxGzbFXY3snaPPfaz98t6XmO3m+BN5w1nt+JpHrPznTA9sTx95L2i/HXrDrrPnvPCYd/Nw3S2pF7W1tbg+LtGjq59atptakcnTVpyOasz/t2xeYrWPrYznd4RbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQzPeZv1/e3T8WXK/tBq0OvaU/H7p79LNr+MY2yL7kv7E3jH+rfgfvRuozSNi7MAAAAAAAAAAAAAAAABvH935l4788Sn/AEunu+p/600fhm7wC/q6r+l+f9/LhhV773CO/spbE/a6w4mf/MeU/wDcnop1NUkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABXy+3K/ZDur/8AF0H2f1SAfjd9kDlv2D+AxNuj3XP5D/w8/Rcv9999qBYjWIAAAAAAAAAAAAAAAAAMv+wT/HJ7cvxs8J+0Ovdu6C/qx6c/TbR/jGNHj2sfyOPjJ+oDqb707azZWVNI4AAAAAAAAAAAAAAAAAAAAAAAAABgZ7SPtV1Xd12odSunF3Ftz5PrtPkcp4Rn0s/FzMLkOgpDa27GDSsZ0pe3NjCuaWVawlX4WfP0+mXiVOi+I3S2Lq3pXkuOmsTtY8NtrRydu96bGDtlitPn65q0nDPpP1t57eqVnsYePO/7Pfj70V1njz3rwe3yOHgup9Scnw9ba4flpto3y7c96zOLjcuzTkoiLV+v1a9+9e9Zrbt5ptjxzdbfj24xrmHttFtM/T7TDu0rG7i7HWZd3Czce5GvzpOxk2LluVK/VKNVc2fDk182bXzVmmXBlyYctJ+dMmK80vWfu1tWYn85ufcXyWnzPG8dy/HZ6bPH8ro6nI6OxjmJpn097Bj2dbNSY9Jrlw5aXrMfOLQ+W9TnAAAAAAAAAAAJCPsA+yyHW3r1n9wnMtZXI4J0UnKWlt5dmksLcc2zcWmPjY04zjWt2Gvwdhe2dq7arGNvNwrVJXPVGtuuf/AXo2Ob52/UG5j82jws98MWr3pm3b08taT3j1jHTJOSJjt2vSI7+kwqI97R7S1vDHwo1PCHpzejD1V4mViOSvr5Zrtcd0xrZ5zZ81ZpPbHfb2tTFpXpkibX1tq81p2mLxOHTZavwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACGZ7zN+v726fiy5X9oNWh17Sn4/dPfpZtfxjG2Rfcl/Ym8Y/1b8D96N1GaRsXZgAAAAAAAAAAAAAAAAN4Hu/8vT3662n/S4Fvaf+stNX+jz/ACM1+Ak/7O8Ufb0c/wC9kwqwfe2R39lHd/4PVnFT/wCZclH+NPYTtaooAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACvl9uV+yHdX/4ug+z+qQD8bvsgct+wfwGJt0e65/If+Hn6Ll/vvvtQLEaxAAAAAAAAAAAAAAAAABl/wBgn+OT25fjZ4T9ode7d0F/Vj05+m2j/GMaPHtY/kcfGT9QHU33p21mysqaRwAAAAAAAAAAAAAAAAAAAAAAAAAD8rSlaVpWlK0rStK0rTzStK/KtK0r8q0rT5VpX6x+xMxMTEzExPeJj0mJj5TE/RMIGXt3Oz2Hbv3SXep3F9b9D6fdcbdeRYsMazWODq+UQt1sbrArd8VpXL2WXhZ+8nblOsvTlVlGMYeKUgr45dIfhe6nnk9bH5OP5uPqikVj+l4tqI8ubH3/ALPLemTPMTMz2t9EdobWXurvaKt4w+BWPofnN36o6u8L7/gPntmyRO1vcHa/xeM24x9+8a+lr7Opxdb1rFfNgiJmbd5nRqwitFAAAAAAAAAAcl4bxPc875ZxvhnHcS7m7zlO71mh1eNZtzuzuZu1zLOFY8xhStaW4TvUndnXxG3ajO5OUYRrKnJ09TNvbetp69Jvn2s+LBirWJmZvlvWlfSPoibd5n5RHeZmIh8XqPn+N6V4DmepOY2MerxfBcZvctv58l64601tDWybOXta0xE3tTHNcdY72vktWlYm1oibKbsG7WdH2g9sfTnpHrca1Dc4unx9xzHNpG3XIzeU7mNdpuIX71uNKX4a/OzcnAw5VrP04li1Ck50pSVbHug+l8HSPTXHcTipEZq4a5ty/aPNfazR8XNFpj8VGPJe2Ok+valYjvPzaWXtY+O3Ke0P439ZeIO7nvbjc/I5uO6c1ptf4OtwPGzGhx1sWO8zOK23q62Hb2KxFe+xlyWmte/ljM13FG4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDM95m/X97dPxZcr+0GrQ69pT8funv0s2v4xjbIvuS/sTeMf6t+B+9G6jNI2LswAAAAAAAAAAAAAAAAG7r2AkvT376f/zuD72P8PnP1H/wZq8Bf6vMP/aOx/6+FWN72ivf2UOSn+x6o4qf/NeQ/wDenvJ3NUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABXy+3K/ZDur/8AF0H2f1SAfjd9kDlv2D+AxNuj3XP5D/w8/Rcv9999qBYjWIAAAAAAAAAAAAAAAAAMv+wT/HJ7cvxs8J+0Ovdu6C/qx6c/TbR/jGNHj2sfyOPjJ+oDqb707azZWVNI4AAAAAAAAAAAAAAAAAAAAAAAAAABrM9rF2jYXdv2jc60OHhWrvOuBYOTzvg2ZWMa3rGdo7P0va41r/nXZ7DR2djg2bFPVWd/Jh8OFblYsa+KvSdOrOkt7BSkTvaFLb+lftHmrfBHny1j6ZnJgrkx1r9NrR2jv2Ta9gP2g9n2ffaE6W5XZ2cmPpXqzawdKdU68WmMWXU5TJ8DQz5P63HXT5TJp7WXLPby4sNvNaKd1dHm4eVrszL1+dYu4ubg5N/DzMa/CVq9j5WLdnYyLF63OkZ27tm7Cdu5CcaShONYypStK0V53pbHe+O9ZrelrUvW0TFq2rM1tWYn1iYmJiYn1iY7S3GNbYwbmvr7erlpn1trDi2NfPitF8ebBnpXLhy471ma3pkx2relqzMWrMTEzEvWeL3AAAAAAAAAJGfu+fZdb6t9Z9x3L8z1Vb/D+j054fFYZdmlcbZ812GJTHpOlu9CtMrGwdZn5l6F61T02NjjWqVuUuQ9CQ/gD0bHLczm6k3MXm0+ImaasXr9Zl3clPL37WjtetMWS9omI+tyUj17x2U4e909pS/h94a8d4J9N7/wuo/EatNnnra+Sfj6PTGnsfGmnnx2idfPt72rrY7Y8kxbLp5rzFJpfzJsqaLWWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQzPeZv1/e3T8WXK/tBq0OvaU/H7p79LNr+MY2yL7kv7E3jH+rfgfvRuozSNi7MAAAAAAAAAAAAAAAABu19gRLx38aH/wA7hm8j/wDfmsr/AEM0eA/9Xmv/ANp5/wD18Ssr3ssd/ZO5b7nUvFT+1rb/AO180+NPBqeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK+X25X7Id1f8A4ug+z+qQD8bvsgct+wfwGJt0e65/If8Ah5+i5f7777UCxGsQAAAAAAAAAAAAAAAAAZf9gn+OT25fjZ4T9ode7d0F/Vj05+m2j/GMaPHtY/kcfGT9QHU33p21mysqaRwAAAAAAAAAAAAAAAAAAAAAAAAAAD+Llu3et3LN2ELtq7Cdu7buRpOFy3ONYzhOEqVjKE41rGUZUrSVK1pWlaVfkxFomtoiYmJiYn1iYmO0xMfTEx6S8qXvjvTJjtamSlq3pekzW9L1mLVtW0TE1tW0RNZiYmJiJie6vr9tN2fS7We7ff7fQa+eN076xfH53xicIVnYxs7Pu1ryLCuXYUras3rm+jtcrHxK1hOOHWEoW/hUpJATxl6Q/Cv1ZsZdfHNeP5jzb+rMR3rW+Sf9UUmY9K2nP8W1aT2nydpiOzbl92p7RMeO3s+8Tx/Lblc/WHhz8LpTnK3tFcubV1af6zbNMdp8+THTiZ0MGbPHmrOzFq2tF5msafmI1iIAAAAAAADlvAuF7zqNzXivBONYl7O3vLt9q+P6zHsWbl+dcraZlnEt3JW7VKypZsfFrfyLlfELVi3cu3JRhCUqcvR08/I7mro61Jvn28+LXxVrE2nz5bxSJmI/ra9/NaflFYmZmIju+B1X1LxfR3TXO9Vc1sYtXiun+J3+X3s2XJTFWMGhrZNi9K2vMROXL8P4WGkd7ZMt6UpW1rRWbLTse7Y+P9pHbZ036OaXFs2c7UaTGzuU5UKW5Xc7lW2jXZ76d2/bp+n2rG0zMzHw5SlP0YkLVuMqxjStbIeiemdfpPpzjuHwUiL4sFcm1aO0zfayx8XPM2/rorlvetJnv2pER3aVHtQeN/L+0H409aeI/JZ8mTU5HlM2rwOC03jHq8Dx8xo8TWmK/pivl0dfXzbFYrXzZ7XtasWmWW7tiPoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACGZ7zN+v726fiy5X9oNWh17Sn4/dPfpZtfxjG2Rfcl/Ym8Y/1b8D96N1GaRsXZgAAAAAAAAAAAAAAAAN1/sDa+O/rjdP+lxDeU/8AvrW1/oZn8CP6vNb7upn/APWxqzvewx39k3mvudQ8XP8A5Ddj/Gn0p4tTgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABXy+3K/ZDur/APF0H2f1SAfjd9kDlv2D+AxNuj3XP5D/AMPP0XL/AH332oFiNYgAAAAAAAAAAAAAAAAAy/7BP8cnty/Gzwn7Q6927oL+rHpz9NtH+MY0ePax/I4+Mn6gOpvvTtrNlZU0jgAAAAAAAAAAAAAAAAAAAAAAAAAAAGor2zfZ9Z7qe0fkuw0mvjk9ROkVu/zzid2EYUvX8bXW5V3+Fcn4pcu2fzBntb9jHjOnqzI2qxjOdaRriXxj6QjqnpPZyYMcW5DiItv6kxEea1ccf6opM/OY+BOW1a/Tft29Z7TYT7tv2ir+A/tBcLqcpt2w9H+IdsXSnP47WtOPFm3Lx+BG1SvrSmT8FaaGLLmmv1uvbJFrVr3tFe/ct3LNy5ZvW52rtqc7d21chKFy3chKsZ27kJUpKE4SpWM4SpSUZUrStKVpWiAUxMTMTExMTMTEx2mJj0mJifWJifSYn5Nu2l6ZKUyY71yY8la3pelotS9LRFq3paszW1bVmJraJmJiYmJmJfw/HkAAAAAAAko+70dl1vqV1V3/AHS811PxuMdK53dTweOZZ/SM7mOfi0x7+Zbt3o1t5mJh6rN2Nv4tuM4Y+xtW6VnG9bpGkjvZ/wCjY5Llc/U+7i76vFzOLS88fW5NzJXy2vET6XpTFfJHeO8VyRH9dEQpb9757Sl+iuguJ8CemuQjHznXlcfI9UTr5e+XV6b1M85sWte+OfNrbGzv62necd7Vtl08l58k4795mjplNasAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDM95m/X97dPxZcr+0GrQ69pT8funv0s2v4xjbIvuS/sTeMf6t+B+9G6jNI2LswAAAAAAAAAAAAAAAAG6j2CUvT3+cVp8v0XFd3T/wDf6/6mZvAie3Xur93Vzx/42P8Axq0vevV7+yZz0/2PPcXP/ktv/wByfgnk1NAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFfL7cr9kO6v/xdB9n9UgH43fZA5b9g/gMTbo91z+Q/8PP0XL/fffagWI1iAAAAAAAAAAAAAAAAADL/ALBP8cnty/Gzwn7Q6927oL+rHpz9NtH+MY0ePax/I4+Mn6gOpvvTtrNlZU0jgAAAAAAAAAAAAAAAAAAAAAAAAAAAHrZmHi7DDy8DNsW8rCzsa/h5eNdj6rWRi5NqdnIsXY/863dtTnbnH78ZVo8b0rkpfHesWpetqXrPytW0TW1Z+5MTMT9x7tbYz6exg29XLfBs6ubFsa+bHPlyYc+C9cuLLS30Xx5K1vWfotESrrPa19o2V2k93fN9Lg4d21wbqDl5XPeEZVbfpsXcLeXqZu1xbHilIxt63dZOdr7NutKSpZxY1p6qfoq16+K/SV+k+rd3DjpaNHkL239K0x2rNM8+fLSvpERXHmtfHWPtV+mPVuJe7+9oPB7QPs9dMcntbFL9U9Ia+DpPqfBFvNlx7PF451uP2MveZta+7xmHV28l+8xOTPb5T3rGsNjNOAAAAAABzfprwHf9UufcQ6d8XxL2bvuY8g1fH9dYsWbl+dL2yy7WNXInbt0lL4GLbuTycifikbVi1cu3JRhCUqc3jdDPym/p8dq0tfPubGLXx1rWbT5sl4r5piO8+WkTNrT8orEzMxEd3WOtOrOJ6F6T6h6w53YxavE9OcRvcvu5cuSmKs49LXyZoxVveYr8XPelcGGvfvfLkpSsTa0RNl92adtnG+1Dt16b9GOPYlmxd47ocS7yLIt+ic8/lOxh+aPIsmd+FPN+3Lc5WdTFrKU/RjfDtxl6Y0WR9HdN63SnT3HcNr0is6+Ck7Fo7d8m1kj4mxaZj5xOa1/L3me1e0RPZpRe0h40c14++MXWniTzGxky05jls+Ph8NvPWurwWnb6j4fDXFb0xXjjtfV+PFa18+bz3tHmmWUbtDBYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACGZ7zN+v726fiy5X9oNWh17Sn4/dPfpZtfxjG2Rfcl/Ym8Y/wBW/A/ejdRmkbF2YAAAAAAAAAAAAAAAADdF7Bifp7/uHU/6XGt3H/8Ae4Vf6GZPAr+r3T+7r5v8NJ/xK1/etR39krqP079ua4yf/E2o7/vp+yejUvAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAV8vtyv2Q7q/wDxdB9n9UgH43fZA5b9g/gMTbo91z+Q/wDDz9Fy/wB999qBYjWIAAAAAAAAAAAAAAAAAMv+wT/HJ7cvxs8J+0Ovdu6C/qx6c/TbR/jGNHj2sfyOPjJ+oDqb707azZWVNI4AAAAAAAAAAAAAAAAAAAAAAAAAAAABpB9un2d17ju1jK6jcY1v0rqH0PuS5Pg/RrNJ5+141Wssfd6udysZeMLX4mbm72UY+iXxMPz6q08xrhTxw6Q/DF0vfkdbF5+Q4SfqnH5Y75Mut3mubFM/RTHS+TPPb170/PhZ57rT2i48GvHfB0bzm78Do/xQpHB7Xx8k11dDm+1cvGb9axMd9nbz6utxdZtFo8mx2iIn66IEtaVpWtK08Vp8q0r9dK/gqgk2vPn8gAAAAAEm/wB3g7L7XOeoXJO6/m2o+Noensr+h6eUzLPi1lcqzcemPnbWxC9H0ZmJi6zK2eFW5CNyFjPhH9FG9bpSklvZ86Nje5DZ6q3cPfBx/mwcf56+ltq9fLfLWJ9L1rivlp3iJiLx9uPSkX3wXtKZOl+kOF8AumOQjHyvWEYuW6wnXyd8mDgNXN8bV0Mtsc+bX2NjewaOz5LTS2XUtP1tsd57zKUwmuCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhme8zfr+9un4suV/aDVode0p+P3T36WbX8YxtkX3Jf2JvGP9W/A/ejdRmkbF2YAAAAAAAAAAAAAAAADc57B2vj2gHCKefHq4/uqfw/osSvj/MzH4Fz/s90vu6+aP8A1Z/xK2/erR39knqef7Hl+Mn97Yj/AKSn+J6tSsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABXy+3K/ZDur/wDF0H2f1SAfjd9kDlv2D+AxNuj3XP5D/wAPP0XL/fffagWI1iAAAAAAAAAAAAAAAAADL/sE/wAcnty/Gzwn7Q6927oL+rHpz9NtH+MY0ePax/I4+Mn6gOpvvTtrNlZU0jgAAAAAAAAAAAAAAAAAAAAAAAAAAAAHzd1p9dyDT7XQ7fFtZuq3WuzdVssO9T1WsrA2ONdxMzHuUpWlawvY965bl4rSviVfFaV+b15sOPYw5cGWsXxZsd8WSlvWL48lZpes/ctWZifz3N43kNziOR0OV47PfV3+M3Nbf0tnHPbJr7enmpsa+ak+va2LNjpeveJjvWO8TCt29pd2pbPtF7suo/T6WNdhxXc7fK5dwjMra+Hi5Og5BcjtY4mDWkYxnY0l/Onpa1p6q0nhSpOUpUrWtdHiT0tl6S6r5Lj5rMaubLbb0r9u1LYNifi+TH6R3rgtknD3/wCB85lucexT496PtC+AHRnV9c2O3O8bx+Dp7qjW+J59jBy3D0nQtsbX10zXLymLVryfafLE12YmtYr2hgE6ElmAAAA7C6T9NuRdYOpHCumXFMS/m77mvItZoMG1j2p352652VbtX8uVu3GUvgYOPW7mZE/Hpt2LFy5OtIRlWn0OK47Y5fkdLjdWlr593Yxa9IrE2mPiXitrzEd58uOsze0/RWszPpDqPX3WfD+HfRnU3W/P7GLW4npnh97ltrJmyVxVvGpgvkxa9b2mI+LtZox62GvfvfLlpSsTa0RNmN2ldvHGe1rt/wCnHRjjGHYxrfFePYUNzes0jKufyTMt/TuRZ0rtPMrsMndZOdeseqUqW7NyFu36YRjGlkvSfT2t0vwHHcNrUrWNXXpGa1e39M2bx59i8z85i2a2Sa+vpWYiO0NJv2gfGDm/Hbxb6z8Suc2cufJz3L7NuNx5JtEanC6151uH1Yxz2jHbDxuHVx5e1azfJW17d7TMskHY2GQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEMz3mb9f3t0/Flyv7QatDr2lPx+6e/Sza/jGNsi+5L+xN4x/q34H70bqM0jYuzAAAAAAAAAAAAAAAAAblvYRSrT2gPAqU/52k3Ma/weMev9DMXgZPbr3R+7hyx/6v8AiVv+9Tjv7I/Vn3OU4yf4aP8AGsAk9mpOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr5fblfsh3V/+LoPs/qkA/G77IHLfsH8BibdHuufyH/h5+i5f7777UCxGsQAAAAAAAAAAAAAAAAAZf9gn+OT25fjZ4T9ode7d0F/Vj05+m2j/ABjGjx7WP5HHxk/UB1N96dtZsrKmkcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAj8+8Adn0+tXbnr+u/FdX9I5r0Rv28jaSxLFbuw2fC9hkyw8nBjbhSU7lvBztnHbXpxhWVqxiTnKdLUJUYD8e+kZ5rp3Hzurj827wlotlmte+TLp5LeS1IiO8zGO+T4tp7elaT3ntC3D3SftE18NPGTb8Kue3vg9M+J+K+HRjYyxj1NLqXUwRs4Nm17zFaX2tXRnj8dZtFcmXYrEVm9olBtQjbRAAAACUb7u12XQ5Py3k3dzzfT1uaniX0njfTP6ZYlS3f3+RCmNtN7ieulLeVYxsK7tdTOVKXIWsvz49N2FKxk77PfRsbO3s9W7uHvi1PNrcZ56+ls9o8uXPTv6WitJy4pn1itvtTCjD3w3tKX4Pp/g/Z86Y5Lyb/UPwea63+pstZvi4nDb4+jxWz5Z8+DLn2aaHIViZpbJr/wBljvMTMLS7a6wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACGZ7zN+v726fiy5X9oNWh17Sn4/dPfpZtfxjG2Rfcl/Ym8Y/1b8D96N1GaRsXZgAAAAAAAAAAAAAAAANyHsJ5en2gnTz6/0Wp3NPl9/wDQWfr/AM7MHgdP+z/j/u4c3/6VcfvT47+yN1h9zkONn/xsn/KsCE+GpGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAr5fblfsh3V/wDi6D7P6pAPxu+yBy37B/AYm3R7rn8h/wCHn6Ll/vvvtQLEaxAAAAAAAAAAAAAAAAABl/2Cf45Pbl+NnhP2h17t3QX9WPTn6baP8Yxo8e1j+Rx8ZP1AdTfenbWbKyppHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOO8v4tp+b8V5Hw7f4tvM0vKNJtNDtMa7CM43cHbYV7ByaUpKlaUnS1flK3Px6oTpGca0lGlacfb1cO7q7GnsVi+HawZcGWsxExNMtLY7ek/T2tPafon1h9jp7neR6Y53huouJz31uT4Pk9HltDNS1qzTa4/ZxbWCZmsxM1nJirF6/K1JtW0TEzCtL78O2bd9pvc/1Q6RbTFuWddruQZW14tkUtz+jZXF95WO40kcbIrStvJrha7PxcLKnanP4eVYu27npuRlGlbvXXTWfpTqbk+Iy1mMePYtl1bdp8ttXP/TsMVt8rTTHetLTEz2tWYn1iW6v7KvjZxfj/wCB3Q3iHoZ6Zdzd4jBo87i89fj4Od4vzcdyk5sUdr4Y2dzUz7WCt618+vlx3p3paJnD11FIkAB2h0W6Vck639VeCdKeJYeRm73nHI9bo8W3i2pXrtmxk34/T870RjLzb12BHJz71axrGNnHuSl8qVfT4bitnm+V0OK1KWvn3tnHgrFY801i1v6Zft9rHji2S32orMz6Oj+JXXnC+GPQfVXXvUGxh1uK6Y4bc5TPfPeMePJlw4rfUmr5pmva+5t2w6uKImJtkzVrHrMLMvtg6DcY7aOhfTno1xXDsYuFw7jmBh59yxHxTP3tyzHI32ylKv6KVdht7ubl/OviNL3phSMKUjSyfpngtXpvg+O4fVpWtNPXx0yTX/rmeY82fJ+yZpvf7nm9O0ejSY8cfFbnPGzxT6y8SOe2MufZ6j5nb2dWmWZmdTiqZJw8TpVr8qxqcdj1tee3racXmtNrTMz36+8xMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhme8zfr+9un4suV/aDVode0p+P3T36WbX8YxtkX3Jf2JvGP9W/A/ejdRmkbF2YAAAAAAAAAAAAAAAADcV7CyXj2g3Tan/S124p9f4LVuv8AL9TL/gfPbr/jfu4s8fvQro96XXv7IvWk/wBju8bPy/8AlL/tfa/XWByfLUeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAV8vtyv2Q7q/8AxdB9n9UgH43fZA5b9g/gMTbo91z+Q/8ADz9Fy/3332oFiNYgAAAAAAAAAAAAAAAAAy/7BP8AHJ7cvxs8J+0Ovdu6C/qx6c/TbR/jGNHj2sfyOPjJ+oDqb707azZWVNI4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGv94g7P7nUXpBxnuf4lq6XuRdKJ2dNzOWLZ9WRlcO2mZPHx79bVmPxcm/i7nY4PxLtaXK2MG1OsvRZtylGOPtB9IzyPEa3U2pi77PFTXDueWO9r6eS81rby1jva1c2WnefXy0j17VjvF0nufPaIp0d4ic34HdQb3w+H6+rl5HpqufL5cWDqTR1ozZsUZMk/Dw4c/G6e15ccTSMm1krEea94iYW6GrZUAASr/d1OzKGz2vK+7zm+m+JiaumTxXpbXNs19EthKUcfb8j18q0pS58C1TbaK56qzhGc5+IUnGM6Sl9nno6MuXb6t3cPemLzanF+evpOSe1c2zjn6YrHxcE/OO8z6d4UM++K9pG2jocB7PPTHJeTY35w8911GtkjzRp1icvHcLuViZmnxMn1BytO0Vtata97TSZiZdKWbXtAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQy/eZf1/e3X8WfK/8A3/qkOvaU/H7p79LNr+MY2yN7kz7E3jF+rbgfvTvIzaNi7IAAAAAAAAAAAAAAAABuE9hjXx7Qjpf+/h7in/3vSv8AQy74IfZA4v7tM3/q9/8AErs96RHf2Q+ufubPHT/5aY/x/wCJYKJ9tRoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABA09uT0X6sXe/Dn3KcLp3zTacd5Rg6XO0u61PGdzs9ZmWbGrxMC7G3nYOFfxvjW8jDvxnYrdpejGNJ1hSEoyrBbxu4blZ6539qnH7mXX2qYcmHNi1s2TFeIxUpMRelLV80WpaPL379o79u0w2sfddeJXQOP2Vek+C2esemtHmOD2+T1eT4zf5vjdHe1smXe2NvHa+rtbOLP8K+HZxTXLFJx2mZrFvNWYjTn9yXqr+5n1B/Izkf9msP/gVyn5W7/wC49j/NrGf5oHQf5tukf75OG/lp9yXqr+5n1B/Izkf9mn4Fcp+Vu/8AuPY/zZ/NA6D/ADbdI/3ycN/LT7kvVX9zPqD+RnI/7NPwK5T8rd/9x7H+bP5oHQf5tukf75OG/lp9yXqr+5n1B/Izkf8AZp+BXKflbv8A7j2P82fzQOg/zbdI/wB8nDfy0+5L1V/cz6g/kZyP+zT8CuU/K3f/AHHsf5s/mgdB/m26R/vk4b+Wn3Jeqv7mfUH8jOR/2afgVyn5W7/7j2P82fzQOg/zbdI/3ycN/LT7kvVX9zPqD+RnI/7NPwK5T8rd/wDcex/mz+aB0H+bbpH++Thv5afcl6q/uZ9QfyM5H/Zp+BXKflbv/uPY/wA2fzQOg/zbdI/3ycN/LT7kvVX9zPqD+RnI/wCzT8CuU/K3f/cex/mz+aB0H+bbpH++Thv5afcl6q/uZ9QfyM5H/Zp+BXKflbv/ALj2P82fzQOg/wA23SP98nDfy0+5L1V/cz6g/kZyP+zT8CuU/K3f/cex/mz+aB0H+bbpH++Thv5afcl6q/uZ9QfyM5H/AGafgVyn5W7/AO49j/Nn80DoP823SP8AfJw38tPuS9Vf3M+oP5Gcj/s0/ArlPyt3/wBx7H+bP5oHQf5tukf75OG/lp9yXqr+5n1B/Izkf9mn4Fcp+Vu/+49j/Nn80DoP823SP98nDfy0+5L1V/cz6g/kZyP+zT8CuU/K3f8A3Hsf5s/mgdB/m26R/vk4b+Wn3Jeqv7mfUH8jOR/2afgVyn5W7/7j2P8ANn80DoP823SP98nDfy0+5L1V/cz6g/kZyP8As0/ArlPyt3/3Hsf5s/mgdB/m26R/vk4b+Wn3Jeqv7mfUH8jOR/2afgVyn5W7/wC49j/Nn80DoP8ANt0j/fJw38tZrezu6E9ZN13k9A5YfTDnsbGp6h8b3ezzMriW+xMHX6zU7TG2GblZubkYFvGxbVvGxrsoyv3YUnOlLcPVOVI17p4e8HzGbrHgZpxm95cPI62fLe2pnpjx4sOWuS973tjitYitZ9bTHefSPX0Rn9sLxU8OOM9nDxYjY646Utl5Do/meM0dbB1BxWfa293f0s2prYNbWw7d82fJfNmxxNcVLTWsze3asTKyBWKtM0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwfqZwHRdUun/MenfJcWzmaTmXHdtx7PtX7cbsIW9nhXsWORGE6Sj8bFuXYZNifitbd61bnH9FGjg8noYOU4/c47ZpW+Dc182veLRExEZaWpFu0/TSZi1Z+i0RPzh2jorqzleherunOsOFz5Nfk+m+Z4/l9TJivbHa19Hax7E4bWrMT8PYpS2DLXvEWx5L1n0mVZh3cdv3IO2DuF6m9GeQ4l7FnxXkmdDUSuxrT6VxzOuV2HHcqNz9Rdle0uVg3LtYV8RuylGVIypWNK2OrOA2OmeoOT4fYpas6uzkjDMxP12vefia9on5T5sNsczMfTPae0+jdq9n3xc4jxx8IOiPEniNjHnpz/AAurbka45j+kczq1+pOYwTT8VSMXJYNqlItHrStbRNqzFpxudcZmdt9B+kHJevfV/p90i4jh5Gbu+c8k1+mtW8aNJ3rGFcu0u7XPpGtJUrDW6u3mbC55jKnw8afmlfqfW4PiNnneX0OI1KWvn3tnHhiK+s1pM98uT6Y7Y8UXyT6T6VY/8VPEPhfCjw86u8QuoNjDrcX0twu3yWS+e01x5dmlJx6GpMxMTFt3eya+pTtMT581fWPms0u3Xolxft26L9Pej3EcLGw9Xwvjet1l6WLD0QzttHGtz3W1nSvzrd2m1ll59z6o0nkSpCMI0pGllHT3C6vT3DcfxGpStMWnrY8VvLHaMmaKxObLP3cuWb5J+jvae0RHo0k/GLxN53xh8S+sPEXqHaz7O91NzW7vY4z2i1tXj7ZrV43Qr29Ph6OhXX1KfOZphrNrWt3tPdb7TGYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACIZ7yT0p6kco6s9vnLuL8H5VyXj2JwTk+pzdpx/QbXc4uDsb26wb9nEzbuuxMmGLdvWce7dtRvyt1nCFaxpWnzRJ9o3iuR2uW6f29bR2tnXpobOG+XX18uamPJOalq0vbHW0Um1a2mIt27xHdsMe5g696M4Pw/wDF3p/nOqOB4XmM/VXB7+ro8vy2hxuxt6ePjNrHl2NbHuZ8Ns+PFky0x5LYovFbWiJmJRm/uS9Vf3M+oP5Gcj/s1Gz8CuU/K3f/AHHsf5tdl/NA6D/Nt0j/AHycN/LT7kvVX9zPqD+RnI/7NPwK5T8rd/8Acex/mz+aB0H+bbpH++Thv5afcl6q/uZ9QfyM5H/Zp+BXKflbv/uPY/zZ/NA6D/Nt0j/fJw38tPuS9Vf3M+oP5Gcj/s0/ArlPyt3/ANx7H+bP5oHQf5tukf75OG/lp9yXqr+5n1B/Izkf9mn4Fcp+Vu/+49j/ADZ/NA6D/Nt0j/fJw38tPuS9Vf3M+oP5Gcj/ALNPwK5T8rd/9x7H+bP5oHQf5tukf75OG/lp9yXqr+5n1B/Izkf9mn4Fcp+Vu/8AuPY/zZ/NA6D/ADbdI/3ycN/LT7kvVX9zPqD+RnI/7NPwK5T8rd/9x7H+bP5oHQf5tukf75OG/lp9yXqr+5n1B/Izkf8AZp+BXKflbv8A7j2P82fzQOg/zbdI/wB8nDfy0+5L1V/cz6g/kZyP+zT8CuU/K3f/AHHsf5s/mgdB/m26R/vk4b+Wn3Jeqv7mfUH8jOR/2afgVyn5W7/7j2P82fzQOg/zbdI/3ycN/LT7kvVX9zPqD+RnI/7NPwK5T8rd/wDcex/mz+aB0H+bbpH++Thv5afcl6q/uZ9QfyM5H/Zp+BXKflbv/uPY/wA2fzQOg/zbdI/3ycN/LT7kvVX9zPqD+RnI/wCzT8CuU/K3f/cex/mz+aB0H+bbpH++Thv5afcl6q/uZ9QfyM5H/Zp+BXKflbv/ALj2P82fzQOg/wA23SP98nDfy0+5L1V/cz6g/kZyP+zT8CuU/K3f/cex/mz+aB0H+bbpH++Thv5afcl6q/uZ9QfyM5H/AGafgVyn5W7/AO49j/Nn80DoP823SP8AfJw38tPuS9Vf3M+oP5Gcj/s0/ArlPyt3/wBx7H+bP5oHQf5tukf75OG/lrcX7Dboz1Ys99vB+S5nTvmmr4/xvV7XN3O523Gd1q9Zh2ZwtY0IXM7OwrGL8e5dyLfox6XfjThSdyMKwtzrTL/gjw/Kx1zo7N+P3MevrYst82bLrZsWKlZiKx3vela+aZtHavfzTHeYjtE9q5/eieJHQOT2VuqOF1+semt7l+Z3+P1eN43Q5vjd7e2ctbZM1rU1dXZy5/hUx4r+fNOP4VbTStrRa9YmeYnU1TQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHx9px3j+8rbrutFp9xWzStLNdprMLYVtUr5rWluuXYvVhSta1rWkfH11/C9OXXwZ+3xsGHN5fl8XHTJ2/O89Z7frPo6PMctxcXjjOU5HjoyzE5I0d3Z1IyTHbtN418uPzzHaO3m79u0Pkfc+4F+0jiH5Nab+pPV9QaP9pan7mw/wCQ+h+G7qv80/UP92uS/lJ9z7gX7SOIfk1pv6kfUGj/AGlqfubD/kH4buq/zT9Q/wB2uS/lJ9z7gX7SOIfk1pv6kfUGj/aWp+5sP+Qfhu6r/NP1D/drkv5Sfc+4F+0jiH5Nab+pH1Bo/wBpan7mw/5B+G7qv80/UP8Adrkv5Sfc+4F+0jiH5Nab+pH1Bo/2lqfubD/kH4buq/zT9Q/3a5L+Un3PuBftI4h+TWm/qR9QaP8AaWp+5sP+Qfhu6r/NP1D/AHa5L+Un3PuBftI4h+TWm/qR9QaP9pan7mw/5B+G7qv80/UP92uS/lJ9z7gX7SOIfk1pv6kfUGj/AGlqfubD/kH4buq/zT9Q/wB2uS/lJ9z7gX7SOIfk1pv6kfUGj/aWp+5sP+Qfhu6r/NP1D/drkv5Sfc+4F+0jiH5Nab+pH1Bo/wBpan7mw/5B+G7qv80/UP8Adrkv5Sfc+4F+0jiH5Nab+pH1Bo/2lqfubD/kH4buq/zT9Q/3a5L+Un3PuBftI4h+TWm/qR9QaP8AaWp+5sP+Qfhu6r/NP1D/AHa5L+Un3PuBftI4h+TWm/qR9QaP9pan7mw/5B+G7qv80/UP92uS/lJ9z7gX7SOIfk1pv6kfUGj/AGlqfubD/kH4buq/zT9Q/wB2uS/lJ9z7gX7SOIfk1pv6kfUGj/aWp+5sP+Qfhu6r/NP1D/drkv5Sfc+4F+0jiH5Nab+pH1Bo/wBpan7mw/5B+G7qv80/UP8Adrkv5Sfc+4F+0jiH5Nab+pH1Bo/2lqfubD/kH4buq/zT9Q/3a5L+Un3PuBftI4h+TWm/qR9QaP8AaWp+5sP+Qfhu6r/NP1D/AHa5L+Uvo63ivF9Nfrlafjeh1WTWNYVyNbp9fg36wr5pWNbuLj2rlY1pWtKxrLxXzX5fN7MerrYbebDr4MVu3bzY8OOlu32u9axPZw93nec5LFGDkeZ5XfwxaLRh3eR29rFFo+Vox582SkWjtHae3eO3zfee98oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABFk94y7QLm84zwvu04fqazy+MfB4l1Jnh2fr1GTduW9Vv9hOkfVO5bzbuq0tuVJeI2awpWHiPqRf8AaH6RnPraXVeni731vLqclNI/6zaZjFsZJ+czF5xYY9fSO0dvpXte5w9oinF831L7P/UXIRXW5z4vUHRddjJ8uRwY633+J1KzMRSmTWx7/J3jt3tli0+bvPZECRHbDyWZ7un2YwlHlfd/zfTUnStMrifSyudYpWkJwu0x91yXXT8UlS7Gtra6G5WUpQrC5c8W/V4nSVns9dGxP1V1dvYe/wCK1OL89flMT5c2zjnt6THbLgn17dpn079pigT3xftJWieA9nfpjkpr2nB1B139S5fW9bY5zcbwm5XvMTS0ZNDlaRWIt5qU727d6zLMSsUBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPnbLT6nc2aY241eu2uPGXrjY2WDjZ1mM6UrSk6Wsq1dhSXitaeqkfPitaefFavXkw4s0eXNix5a/Py5KVvHf7fa0TDmaXI8hxuWc3Hb25oZprNZy6Wzn1cs1mYmazkwXx3mszETMTPbvET29HwfufcC/aRxD8mtN/Uno+oNH+0tT9zYf8AIfV/Dd1X+afqH+7XJfyk+59wL9pHEPya039SPqDR/tLU/c2H/IPw3dV/mn6h/u1yX8pPufcC/aRxD8mtN/Uj6g0f7S1P3Nh/yD8N3Vf5p+of7tcl/KT7n3Av2kcQ/JrTf1I+oNH+0tT9zYf8g/Dd1X+afqH+7XJfyk+59wL9pHEPya039SPqDR/tLU/c2H/IPw3dV/mn6h/u1yX8pPufcC/aRxD8mtN/Uj6g0f7S1P3Nh/yD8N3Vf5p+of7tcl/KT7n3Av2kcQ/JrTf1I+oNH+0tT9zYf8g/Dd1X+afqH+7XJfyk+59wL9pHEPya039SPqDR/tLU/c2H/IPw3dV/mn6h/u1yX8pPufcC/aRxD8mtN/Uj6g0f7S1P3Nh/yD8N3Vf5p+of7tcl/KT7n3Av2kcQ/JrTf1I+oNH+0tT9zYf8g/Dd1X+afqH+7XJfyk+59wL9pHEPya039SPqDR/tLU/c2H/IPw3dV/mn6h/u1yX8pPufcC/aRxD8mtN/Uj6g0f7S1P3Nh/yD8N3Vf5p+of7tcl/KT7n3Av2kcQ/JrTf1I+oNH+0tT9zYf8g/Dd1X+afqH+7XJfyk+59wL9pHEPya039SPqDR/tLU/c2H/IPw3dV/mn6h/u1yX8pPufcC/aRxD8mtN/Uj6g0f7S1P3Nh/yD8N3Vf5p+of7tcl/KT7n3Av2kcQ/JrTf1I+oNH+0tT9zYf8g/Dd1X+afqH+7XJfyk+59wL9pHEPya039SPqDR/tLU/c2H/IPw3dV/mn6h/u1yX8pPufcC/aRxD8mtN/Uj6g0f7S1P3Nh/yD8N3Vf5p+of7tcl/KX19Xx3j+jrclpdFp9PW9SlL1dXrMLX1u0p9VLlcSxZrOlPvUl58Pbi19fB3nDgw4Zn5zixUx9/z/ACVjv+u+fvcxy3KRSOT5TkeRjH3nHG9vbO3GOZ+c0jYy5PJ37z38vZ9h7nzgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHU/XPpNx7rn0i6g9J+UYePm6jnHGNppJwyoeu1j5mRjTrrM/0/fua7ZQxM+15pWlLuPCsoypSsa/K5zidfnOI5Ditqlb4d3Wy4Zi0d4re1Z+Fk7d49ceSKZI+jvWPSXfvC3r/mPC3xC6R6/4LYza3I9L85o8nW2C3lyZtbFmrG9qd/7Dd0rZ9TJ27T5M1u0xPaYrobPYt1gu95Me0qvFeQx30uoV7Qxyp6zIj6+HWNpcrXldLtbFMb6FPj9v804X/PwazlGx/ha0tK8o6H5eesI6TnV2PjzyE68WnHbvOnXLP+q4ny+XyTrx8WLfie/1vz9G41k9qXw6x+zjPtA/g9w9uJr0hi5a2Cu7ht5eo8ujSI4CccZZzfVNeXvGlbF/tkUicv4iJusWug3R7i/QLpDwDpHxDCxsLTcI41q9NSmLb+HDNz8fFtU2u1nH71/a7H6TsMjxSMa3smfpjGPiNLDOC4jW4HiNDidSlaYdLWxYfrY7RfJWkfFyzH9llyebJb6O9p7RDTp8VvEXnPFjxD6t8QeodnNs8l1PzW9yU/Hv5762pmz3nQ0K2/3LQ0/gaeH1mYxYaRNrT6z24+sx6AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA43/cbxD+6CnLP7leN/3VRs1x48m/MPWf3QRsVh8Otim5+i/mjSzW3+grbpk+isP0Pp8fJxvqPU+qPqv6l1vqqI8sbPwMX1RFe3by/G8vxO3b07ebt29Pk+z+GPqH8CJ6f/AAe5n8AZyfGnhPwU3vwInLFvPGWeN+P9Rzki313n+D5vN9d37+rkjkvjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/2Q==" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.TenantModels.TenantEnquire", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("BillingAddress") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ContactNumber") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Email") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IndustryId") + .HasColumnType("char(36)"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("OrganizationName") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("OrganizationSize") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Reference") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("IndustryId"); + + b.ToTable("TenantEnquires"); + }); + + modelBuilder.Entity("Marco.Pms.Model.TenantModels.TenantSubscriptions", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("AutoRenew") + .HasColumnType("tinyint(1)"); + + b.Property("CancellationDate") + .HasColumnType("datetime(6)"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("CreatedById") + .HasColumnType("char(36)"); + + b.Property("CurrencyId") + .HasColumnType("char(36)"); + + b.Property("EndDate") + .HasColumnType("datetime(6)"); + + b.Property("IsCancelled") + .HasColumnType("tinyint(1)"); + + b.Property("IsTrial") + .HasColumnType("tinyint(1)"); + + b.Property("MaxUsers") + .HasColumnType("double"); + + b.Property("NextBillingDate") + .HasColumnType("datetime(6)"); + + b.Property("PaymentDetailId") + .HasColumnType("char(36)"); + + b.Property("PlanId") + .HasColumnType("char(36)"); + + b.Property("StartDate") + .HasColumnType("datetime(6)"); + + b.Property("StatusId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("UpdateAt") + .HasColumnType("datetime(6)"); + + b.Property("UpdatedById") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("CurrencyId"); + + b.HasIndex("PaymentDetailId"); + + b.HasIndex("PlanId"); + + b.HasIndex("StatusId"); + + b.HasIndex("TenantId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("TenantSubscriptions"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Utilities.FCMTokenMapping", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("EmployeeId") + .HasColumnType("char(36)"); + + b.Property("ExpiredAt") + .HasColumnType("datetime(6)"); + + b.Property("FcmToken") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("FCMTokenMappings"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Utilities.Inquiries", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("About") + .HasColumnType("longtext"); + + b.Property("ContactNumber") + .HasColumnType("longtext"); + + b.Property("ContactPerson") + .HasColumnType("longtext"); + + b.Property("Email") + .HasColumnType("longtext"); + + b.Property("IndustryId") + .HasColumnType("char(36)"); + + b.Property("OragnizationSize") + .HasColumnType("longtext"); + + b.Property("OrganizatioinName") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Inquiries"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("varchar(255)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("varchar(255)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("Discriminator") + .IsRequired() + .HasMaxLength(21) + .HasColumnType("varchar(21)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnd") + .HasColumnType("datetime(6)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("longtext"); + + b.Property("PhoneNumber") + .HasColumnType("longtext"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("SecurityStamp") + .HasColumnType("longtext"); + + b.Property("TwoFactorEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + + b.HasDiscriminator().HasValue("IdentityUser"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("ProviderKey") + .HasColumnType("varchar(255)"); + + b.Property("ProviderDisplayName") + .HasColumnType("longtext"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("RoleId") + .HasColumnType("varchar(255)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.ApplicationUser", b => + { + b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("IsRootUser") + .HasColumnType("tinyint(1)"); + + b.HasDiscriminator().HasValue("ApplicationUser"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.TaskAllocation", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "ApprovedBy") + .WithMany() + .HasForeignKey("ApprovedById"); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("AssignedBy") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "ReportedBy") + .WithMany() + .HasForeignKey("ReportedById"); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Projects.WorkItem", "WorkItem") + .WithMany() + .HasForeignKey("WorkItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Master.WorkStatusMaster", "WorkStatus") + .WithMany() + .HasForeignKey("WorkStatusId"); + + b.Navigation("ApprovedBy"); + + b.Navigation("Employee"); + + b.Navigation("ReportedBy"); + + b.Navigation("Tenant"); + + b.Navigation("WorkItem"); + + b.Navigation("WorkStatus"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.TaskComment", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("CommentedBy") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Activities.TaskAllocation", "TaskAllocation") + .WithMany() + .HasForeignKey("TaskAllocationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Employee"); + + b.Navigation("TaskAllocation"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Activities.TaskMembers", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Activities.TaskAllocation", "TaskAllocation") + .WithMany() + .HasForeignKey("TaskAllocationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Employee"); + + b.Navigation("TaskAllocation"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.AttendanceModule.Attendance", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "Approver") + .WithMany() + .HasForeignKey("ApprovedById"); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "RequestedBy") + .WithMany() + .HasForeignKey("RequestedById"); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Approver"); + + b.Navigation("Employee"); + + b.Navigation("RequestedBy"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.AttendanceModule.AttendanceLog", b => + { + b.HasOne("Marco.Pms.Model.AttendanceModule.Attendance", "Attendance") + .WithMany() + .HasForeignKey("AttendanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.DocumentManager.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId"); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "UpdatedByEmployee") + .WithMany() + .HasForeignKey("UpdatedBy"); + + b.Navigation("Attendance"); + + b.Navigation("Document"); + + b.Navigation("Employee"); + + b.Navigation("Tenant"); + + b.Navigation("UpdatedByEmployee"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Authentication.RefreshToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Collection.Invoice", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Projects.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("Project"); + + b.Navigation("Tenant"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Collection.InvoiceAttachment", b => + { + b.HasOne("Marco.Pms.Model.DocumentManager.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Collection.Invoice", "Invoice") + .WithMany() + .HasForeignKey("InvoiceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Invoice"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Collection.InvoiceComment", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Collection.Invoice", "Invoice") + .WithMany() + .HasForeignKey("InvoiceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatedBy"); + + b.Navigation("Invoice"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Collection.PaymentAdjustmentHead", b => + { + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Collection.ReceivedInvoicePayment", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Collection.Invoice", "Invoice") + .WithMany() + .HasForeignKey("InvoiceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Collection.PaymentAdjustmentHead", "PaymentAdjustmentHead") + .WithMany() + .HasForeignKey("PaymentAdjustmentHeadId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatedBy"); + + b.Navigation("Invoice"); + + b.Navigation("PaymentAdjustmentHead"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.Bucket", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedByID") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatedBy"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.Contact", b => + { + b.HasOne("Marco.Pms.Model.Directory.ContactCategoryMaster", "ContactCategory") + .WithMany() + .HasForeignKey("ContactCategoryId"); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("ContactCategory"); + + b.Navigation("CreatedBy"); + + b.Navigation("Tenant"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.ContactBucketMapping", b => + { + b.HasOne("Marco.Pms.Model.Directory.Bucket", "Bucket") + .WithMany() + .HasForeignKey("BucketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Directory.Contact", "Contact") + .WithMany() + .HasForeignKey("ContactId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Bucket"); + + b.Navigation("Contact"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.ContactCategoryMaster", b => + { + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.ContactEmail", b => + { + b.HasOne("Marco.Pms.Model.Directory.Contact", "Contact") + .WithMany() + .HasForeignKey("ContactId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Contact"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.ContactNote", b => + { + b.HasOne("Marco.Pms.Model.Directory.Contact", "Contact") + .WithMany() + .HasForeignKey("ContactId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "Createdby") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("Contact"); + + b.Navigation("Createdby"); + + b.Navigation("Tenant"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.ContactPhone", b => + { + b.HasOne("Marco.Pms.Model.Directory.Contact", "Contact") + .WithMany() + .HasForeignKey("ContactId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Contact"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.ContactProjectMapping", b => + { + b.HasOne("Marco.Pms.Model.Directory.Contact", "Contact") + .WithMany() + .HasForeignKey("ContactId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Projects.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Contact"); + + b.Navigation("Project"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.ContactTagMapping", b => + { + b.HasOne("Marco.Pms.Model.Directory.Contact", "Contact") + .WithMany() + .HasForeignKey("ContactId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Directory.ContactTagMaster", "ContactTag") + .WithMany() + .HasForeignKey("ContactTagId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Contact"); + + b.Navigation("ContactTag"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.ContactTagMaster", b => + { + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.DirectoryUpdateLog", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("UpdatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Employee"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Directory.EmployeeBucketMapping", b => + { + b.HasOne("Marco.Pms.Model.Directory.Bucket", "Bucket") + .WithMany() + .HasForeignKey("BucketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Bucket"); + + b.Navigation("Employee"); + }); + + modelBuilder.Entity("Marco.Pms.Model.DocumentManager.AttachmentTagMapping", b => + { + b.HasOne("Marco.Pms.Model.DocumentManager.DocumentAttachment", "Attachment") + .WithMany() + .HasForeignKey("AttachmentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.DocumentManager.DocumentTagMaster", "DocumentTag") + .WithMany() + .HasForeignKey("DocumentTagId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Attachment"); + + b.Navigation("DocumentTag"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.DocumentManager.AttachmentVersionMapping", b => + { + b.HasOne("Marco.Pms.Model.DocumentManager.DocumentAttachment", "ChildAttachment") + .WithMany() + .HasForeignKey("ChildAttachmentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.DocumentManager.DocumentAttachment", "ParentAttachment") + .WithMany() + .HasForeignKey("ParentAttachmentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChildAttachment"); + + b.Navigation("ParentAttachment"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.DocumentManager.Document", b => + { + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "UploadedBy") + .WithMany() + .HasForeignKey("UploadedById"); + + b.Navigation("Tenant"); + + b.Navigation("UploadedBy"); + }); + + modelBuilder.Entity("Marco.Pms.Model.DocumentManager.DocumentAttachment", b => + { + b.HasOne("Marco.Pms.Model.DocumentManager.Document", "Document") + .WithMany() + .HasForeignKey("DocumentDataId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.DocumentManager.DocumentTypeMaster", "DocumentType") + .WithMany() + .HasForeignKey("DocumentTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "UploadedBy") + .WithMany() + .HasForeignKey("UploadedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "VerifiedBy") + .WithMany() + .HasForeignKey("VerifiedById"); + + b.Navigation("Document"); + + b.Navigation("DocumentType"); + + b.Navigation("Tenant"); + + b.Navigation("UpdatedBy"); + + b.Navigation("UploadedBy"); + + b.Navigation("VerifiedBy"); + }); + + modelBuilder.Entity("Marco.Pms.Model.DocumentManager.DocumentCategoryMaster", b => + { + b.HasOne("Marco.Pms.Model.Master.EntityTypeMaster", "EntityTypeMaster") + .WithMany() + .HasForeignKey("EntityTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("EntityTypeMaster"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.DocumentManager.DocumentTagMaster", b => + { + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.DocumentManager.DocumentTypeMaster", b => + { + b.HasOne("Marco.Pms.Model.DocumentManager.DocumentCategoryMaster", "DocumentCategory") + .WithMany() + .HasForeignKey("DocumentCategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DocumentCategory"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Employees.Employee", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.ApplicationUser", "ApplicationUser") + .WithMany() + .HasForeignKey("ApplicationUserId"); + + b.HasOne("Marco.Pms.Model.Roles.JobRole", "JobRole") + .WithMany() + .HasForeignKey("JobRoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.OrganizationModel.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId"); + + b.Navigation("ApplicationUser"); + + b.Navigation("JobRole"); + + b.Navigation("Organization"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Employees.EmployeeRoleMapping", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Roles.ApplicationRole", "Role") + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Employee"); + + b.Navigation("Role"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Employees.WorkShift", b => + { + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.FeaturePermission", b => + { + b.HasOne("Marco.Pms.Model.Master.Feature", "Feature") + .WithMany("FeaturePermissions") + .HasForeignKey("FeatureId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Feature"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.ProjectLevelPermissionMapping", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.FeaturePermission", "Permission") + .WithMany() + .HasForeignKey("PermissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Projects.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Employee"); + + b.Navigation("Permission"); + + b.Navigation("Project"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Entitlements.RolePermissionMappings", b => + { + b.HasOne("Marco.Pms.Model.Roles.ApplicationRole", null) + .WithMany() + .HasForeignKey("ApplicationRoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Entitlements.FeaturePermission", null) + .WithMany() + .HasForeignKey("FeaturePermissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.AdvancePaymentTransaction", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Projects.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId"); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatedBy"); + + b.Navigation("Employee"); + + b.Navigation("Project"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.BillAttachments", b => + { + b.HasOne("Marco.Pms.Model.DocumentManager.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Expenses.Expenses", "Expenses") + .WithMany() + .HasForeignKey("ExpensesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Expenses"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.ExpenseLog", b => + { + b.HasOne("Marco.Pms.Model.Expenses.Expenses", "Expense") + .WithMany() + .HasForeignKey("ExpenseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Expense"); + + b.Navigation("Tenant"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.Expenses", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "ApprovedBy") + .WithMany() + .HasForeignKey("ApprovedById"); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Master.CurrencyMaster", "Currency") + .WithMany() + .HasForeignKey("CurrencyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Expenses.Masters.ExpenseCategoryMaster", "ExpenseCategory") + .WithMany() + .HasForeignKey("ExpenseCategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "PaidBy") + .WithMany() + .HasForeignKey("PaidById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Master.PaymentModeMatser", "PaymentMode") + .WithMany() + .HasForeignKey("PaymentModeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Expenses.PaymentRequest", "PaymentRequest") + .WithMany() + .HasForeignKey("PaymentRequestId"); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "ProcessedBy") + .WithMany() + .HasForeignKey("ProcessedById"); + + b.HasOne("Marco.Pms.Model.Projects.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "ReviewedBy") + .WithMany() + .HasForeignKey("ReviewedById"); + + b.HasOne("Marco.Pms.Model.Master.ExpensesStatusMaster", "Status") + .WithMany() + .HasForeignKey("StatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ApprovedBy"); + + b.Navigation("CreatedBy"); + + b.Navigation("Currency"); + + b.Navigation("ExpenseCategory"); + + b.Navigation("PaidBy"); + + b.Navigation("PaymentMode"); + + b.Navigation("PaymentRequest"); + + b.Navigation("ProcessedBy"); + + b.Navigation("Project"); + + b.Navigation("ReviewedBy"); + + b.Navigation("Status"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.ExpensesReimburse", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "ReimburseBy") + .WithMany() + .HasForeignKey("ReimburseById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ReimburseBy"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.ExpensesReimburseMapping", b => + { + b.HasOne("Marco.Pms.Model.Expenses.Expenses", "Expenses") + .WithMany() + .HasForeignKey("ExpensesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Expenses.ExpensesReimburse", "ExpensesReimburse") + .WithMany() + .HasForeignKey("ExpensesReimburseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Expenses"); + + b.Navigation("ExpensesReimburse"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.Masters.ExpenseCategoryMaster", b => + { + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.Masters.ExpensesStatusMapping", b => + { + b.HasOne("Marco.Pms.Model.Master.ExpensesStatusMaster", "NextStatus") + .WithMany() + .HasForeignKey("NextStatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Master.ExpensesStatusMaster", "Status") + .WithMany() + .HasForeignKey("StatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("NextStatus"); + + b.Navigation("Status"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.Masters.StatusPermissionMapping", b => + { + b.HasOne("Marco.Pms.Model.Entitlements.FeaturePermission", "Permission") + .WithMany() + .HasForeignKey("PermissionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Master.ExpensesStatusMaster", "Status") + .WithMany() + .HasForeignKey("StatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Permission"); + + b.Navigation("Status"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.PaymentRequest", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Master.CurrencyMaster", "Currency") + .WithMany() + .HasForeignKey("CurrencyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Expenses.Masters.ExpenseCategoryMaster", "ExpenseCategory") + .WithMany() + .HasForeignKey("ExpenseCategoryId"); + + b.HasOne("Marco.Pms.Model.Master.ExpensesStatusMaster", "ExpenseStatus") + .WithMany() + .HasForeignKey("ExpenseStatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "PaidBy") + .WithMany() + .HasForeignKey("PaidById"); + + b.HasOne("Marco.Pms.Model.Projects.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId"); + + b.HasOne("Marco.Pms.Model.Expenses.RecurringPayment", "RecurringPayment") + .WithMany() + .HasForeignKey("RecurringPaymentId"); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("Currency"); + + b.Navigation("ExpenseCategory"); + + b.Navigation("ExpenseStatus"); + + b.Navigation("PaidBy"); + + b.Navigation("Project"); + + b.Navigation("RecurringPayment"); + + b.Navigation("Tenant"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.PaymentRequestAttachment", b => + { + b.HasOne("Marco.Pms.Model.DocumentManager.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Expenses.PaymentRequest", "PaymentRequest") + .WithMany() + .HasForeignKey("PaymentRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("PaymentRequest"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.RecurringPayment", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Master.CurrencyMaster", "Currency") + .WithMany() + .HasForeignKey("CurrencyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Expenses.Masters.ExpenseCategoryMaster", "ExpenseCategory") + .WithMany() + .HasForeignKey("ExpenseCategoryId"); + + b.HasOne("Marco.Pms.Model.Projects.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId"); + + b.HasOne("Marco.Pms.Model.Expenses.Masters.RecurringPaymentStatus", "Status") + .WithMany() + .HasForeignKey("StatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("Currency"); + + b.Navigation("ExpenseCategory"); + + b.Navigation("Project"); + + b.Navigation("Status"); + + b.Navigation("Tenant"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Forum.TicketAttachment", b => + { + b.HasOne("Marco.Pms.Model.Forum.TicketComment", "TicketComment") + .WithMany("Attachments") + .HasForeignKey("CommentId"); + + b.HasOne("Marco.Pms.Model.Forum.TicketForum", "Ticket") + .WithMany() + .HasForeignKey("TicketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Ticket"); + + b.Navigation("TicketComment"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Forum.TicketComment", b => + { + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Forum.TicketForum", b => + { + b.HasOne("Marco.Pms.Model.Master.TicketPriorityMaster", "Priority") + .WithMany() + .HasForeignKey("PriorityId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Master.TicketStatusMaster", "TicketStatusMaster") + .WithMany() + .HasForeignKey("StatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Forum.TicketTypeMaster", "TicketTypeMaster") + .WithMany() + .HasForeignKey("TypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Priority"); + + b.Navigation("Tenant"); + + b.Navigation("TicketStatusMaster"); + + b.Navigation("TicketTypeMaster"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Forum.TicketTag", b => + { + b.HasOne("Marco.Pms.Model.Master.TicketTagMaster", "Tag") + .WithMany() + .HasForeignKey("TagId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Forum.TicketForum", "Ticket") + .WithMany() + .HasForeignKey("TicketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tag"); + + b.Navigation("Ticket"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Mail.MailDetails", b => + { + b.HasOne("Marco.Pms.Model.Mail.MailingList", "MailBody") + .WithMany() + .HasForeignKey("MailListId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("MailBody"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.ActivityGroupMaster", b => + { + b.HasOne("Marco.Pms.Model.Master.ServiceMaster", "Service") + .WithMany() + .HasForeignKey("ServiceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Service"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.ActivityMaster", b => + { + b.HasOne("Marco.Pms.Model.Master.ActivityGroupMaster", "ActivityGroup") + .WithMany() + .HasForeignKey("ActivityGroupId"); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ActivityGroup"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.ExpensesTypeMaster", b => + { + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.Feature", b => + { + b.HasOne("Marco.Pms.Model.Master.Module", "Module") + .WithMany() + .HasForeignKey("ModuleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Module"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.GlobalActivityGroupMaster", b => + { + b.HasOne("Marco.Pms.Model.Master.GlobalServiceMaster", "Service") + .WithMany() + .HasForeignKey("ServiceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Service"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.GlobalActivityMaster", b => + { + b.HasOne("Marco.Pms.Model.Master.GlobalActivityGroupMaster", "ActivityGroup") + .WithMany() + .HasForeignKey("ActivityGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ActivityGroup"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.ServiceMaster", b => + { + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.StatusUpdateLog", b => + { + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.WorkCategoryMaster", b => + { + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.WorkStatusMaster", b => + { + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.OrgServiceMapping", b => + { + b.HasOne("Marco.Pms.Model.OrganizationModel.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Master.GlobalServiceMaster", "Service") + .WithMany() + .HasForeignKey("ServiceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + + b.Navigation("Service"); + }); + + modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.ProjectOrgMapping", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "AssignedBy") + .WithMany() + .HasForeignKey("AssignedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.OrganizationModel.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.OrganizationModel.OrgTypeMaster", "OrganizationType") + .WithMany() + .HasForeignKey("OrganizationTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.OrganizationModel.Organization", "ParentOrganization") + .WithMany() + .HasForeignKey("ParentOrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.OrganizationModel.ProjectServiceMapping", "ProjectService") + .WithMany() + .HasForeignKey("ProjectServiceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AssignedBy"); + + b.Navigation("Organization"); + + b.Navigation("OrganizationType"); + + b.Navigation("ParentOrganization"); + + b.Navigation("ProjectService"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.ProjectServiceMapping", b => + { + b.HasOne("Marco.Pms.Model.Projects.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Master.ServiceMaster", "Service") + .WithMany() + .HasForeignKey("ServiceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Project"); + + b.Navigation("Service"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.OrganizationModel.TenantOrgMapping", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "AssignedBy") + .WithMany() + .HasForeignKey("AssignedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.OrganizationModel.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AssignedBy"); + + b.Navigation("Organization"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Building", b => + { + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Floor", b => + { + b.HasOne("Marco.Pms.Model.Projects.Building", "Building") + .WithMany() + .HasForeignKey("BuildingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Building"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.Project", b => + { + b.HasOne("Marco.Pms.Model.OrganizationModel.Organization", "PMC") + .WithMany() + .HasForeignKey("PMCId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Master.StatusMaster", "ProjectStatus") + .WithMany() + .HasForeignKey("ProjectStatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.OrganizationModel.Organization", "Promoter") + .WithMany() + .HasForeignKey("PromoterId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PMC"); + + b.Navigation("ProjectStatus"); + + b.Navigation("Promoter"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.ProjectAllocation", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Projects.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Master.ServiceMaster", "Service") + .WithMany() + .HasForeignKey("ServiceId"); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Employee"); + + b.Navigation("Project"); + + b.Navigation("Service"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.WorkArea", b => + { + b.HasOne("Marco.Pms.Model.Projects.Floor", "Floor") + .WithMany() + .HasForeignKey("FloorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Floor"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Projects.WorkItem", b => + { + b.HasOne("Marco.Pms.Model.Master.ActivityMaster", "ActivityMaster") + .WithMany() + .HasForeignKey("ActivityId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Projects.WorkArea", "WorkArea") + .WithMany() + .HasForeignKey("WorkAreaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Master.WorkCategoryMaster", "WorkCategoryMaster") + .WithMany() + .HasForeignKey("WorkCategoryId"); + + b.Navigation("ActivityMaster"); + + b.Navigation("Tenant"); + + b.Navigation("WorkArea"); + + b.Navigation("WorkCategoryMaster"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Roles.ApplicationRole", b => + { + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", null) + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Marco.Pms.Model.Roles.JobRole", b => + { + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.TenantModels.SubscriptionPlanDetails", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Master.CurrencyMaster", "Currency") + .WithMany() + .HasForeignKey("CurrencyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.SubscriptionPlan", "Plan") + .WithMany() + .HasForeignKey("PlanId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("Currency"); + + b.Navigation("Plan"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("Marco.Pms.Model.TenantModels.Tenant", b => + { + b.HasOne("Marco.Pms.Model.Master.Industry", "Industry") + .WithMany() + .HasForeignKey("IndustryId"); + + b.HasOne("Marco.Pms.Model.OrganizationModel.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Master.TenantStatus", "TenantStatus") + .WithMany() + .HasForeignKey("TenantStatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Industry"); + + b.Navigation("Organization"); + + b.Navigation("TenantStatus"); + }); + + modelBuilder.Entity("Marco.Pms.Model.TenantModels.TenantEnquire", b => + { + b.HasOne("Marco.Pms.Model.Master.Industry", "Industry") + .WithMany() + .HasForeignKey("IndustryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Industry"); + }); + + modelBuilder.Entity("Marco.Pms.Model.TenantModels.TenantSubscriptions", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Master.CurrencyMaster", "Currency") + .WithMany() + .HasForeignKey("CurrencyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.PaymentGetway.PaymentDetail", "PaymentDetail") + .WithMany() + .HasForeignKey("PaymentDetailId"); + + b.HasOne("Marco.Pms.Model.TenantModels.SubscriptionPlanDetails", "Plan") + .WithMany() + .HasForeignKey("PlanId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Master.SubscriptionStatus", "Status") + .WithMany() + .HasForeignKey("StatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("Currency"); + + b.Navigation("PaymentDetail"); + + b.Navigation("Plan"); + + b.Navigation("Status"); + + b.Navigation("Tenant"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Utilities.FCMTokenMapping", b => + { + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Marco.Pms.Model.Forum.TicketComment", b => + { + b.Navigation("Attachments"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Master.Feature", b => + { + b.Navigation("FeaturePermissions"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Marco.Pms.DataAccess/Migrations/20251107110903_Added_Finance_Related_Tables.cs b/Marco.Pms.DataAccess/Migrations/20251107110903_Added_Finance_Related_Tables.cs new file mode 100644 index 0000000..bcc1033 --- /dev/null +++ b/Marco.Pms.DataAccess/Migrations/20251107110903_Added_Finance_Related_Tables.cs @@ -0,0 +1,950 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional + +namespace Marco.Pms.DataAccess.Migrations +{ + /// + public partial class Added_Finance_Related_Tables : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Expenses_ExpensesTypeMaster_ExpensesTypeId", + table: "Expenses"); + + migrationBuilder.DropForeignKey( + name: "FK_PaymentModeMatser_Tenants_TenantId", + table: "PaymentModeMatser"); + + migrationBuilder.DropIndex( + name: "IX_PaymentModeMatser_TenantId", + table: "PaymentModeMatser"); + + migrationBuilder.DropIndex( + name: "IX_Expenses_ExpensesTypeId", + table: "Expenses"); + + migrationBuilder.DeleteData( + table: "ExpensesTypeMaster", + keyColumn: "Id", + keyValue: new Guid("1e2d697a-76b4-4be8-bc66-87144561a1a0")); + + migrationBuilder.DeleteData( + table: "ExpensesTypeMaster", + keyColumn: "Id", + keyValue: new Guid("2de53163-0dbd-404b-8e60-1b02e6b4886a")); + + migrationBuilder.DeleteData( + table: "ExpensesTypeMaster", + keyColumn: "Id", + keyValue: new Guid("4842fa61-64eb-4241-aebd-8282065af9f9")); + + migrationBuilder.DeleteData( + table: "ExpensesTypeMaster", + keyColumn: "Id", + keyValue: new Guid("52484820-1b54-4865-8f0f-baa2b1d339b9")); + + migrationBuilder.DeleteData( + table: "ExpensesTypeMaster", + keyColumn: "Id", + keyValue: new Guid("5e0c6227-d49d-41ff-9f1f-781f0aee2469")); + + migrationBuilder.DeleteData( + table: "ExpensesTypeMaster", + keyColumn: "Id", + keyValue: new Guid("77013784-9324-4d8b-bd36-d6f928e68942")); + + migrationBuilder.DeleteData( + table: "ExpensesTypeMaster", + keyColumn: "Id", + keyValue: new Guid("dd120bc4-ab0a-45ba-8450-5cd45ff221ca")); + + migrationBuilder.DeleteData( + table: "ExpensesTypeMaster", + keyColumn: "Id", + keyValue: new Guid("fc59eb90-98ea-481c-b421-54bfa9e42d8f")); + + migrationBuilder.DropColumn( + name: "TenantId", + table: "PaymentModeMatser"); + + migrationBuilder.AlterColumn( + name: "ExpenseUId", + table: "Expenses", + type: "longtext", + nullable: true, + oldClrType: typeof(string), + oldType: "longtext") + .Annotation("MySql:CharSet", "utf8mb4") + .OldAnnotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AddColumn( + name: "BaseAmount", + table: "Expenses", + type: "double", + nullable: true); + + migrationBuilder.AddColumn( + name: "CurrencyId", + table: "Expenses", + type: "char(36)", + nullable: false, + defaultValue: new Guid("78e96e4a-7ce0-4164-ae3a-c833ad45ec2c"), + collation: "ascii_general_ci"); + + migrationBuilder.AddColumn( + name: "ExpenseCategoryId", + table: "Expenses", + type: "char(36)", + nullable: false, + defaultValue: new Guid("5e0c6227-d49d-41ff-9f1f-781f0aee2469"), + collation: "ascii_general_ci"); + + migrationBuilder.AddColumn( + name: "PaymentRequestId", + table: "Expenses", + type: "char(36)", + nullable: true, + collation: "ascii_general_ci"); + + migrationBuilder.AddColumn( + name: "TDSPercentage", + table: "Expenses", + type: "double", + nullable: true); + + migrationBuilder.AddColumn( + name: "TaxAmount", + table: "Expenses", + type: "double", + nullable: true); + + migrationBuilder.AddColumn( + name: "UIDPostfix", + table: "Expenses", + type: "int", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "UIDPrefix", + table: "Expenses", + type: "longtext", + nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "AdvancePaymentTransactions", + columns: table => new + { + Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + FinanceUIdPrefix = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + FinanceUIdPostfix = table.Column(type: "int", nullable: false), + Title = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + ProjectId = table.Column(type: "char(36)", nullable: true, collation: "ascii_general_ci"), + EmployeeId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + Amount = table.Column(type: "double", nullable: false), + CurrentBalance = table.Column(type: "double", nullable: false), + PaidAt = table.Column(type: "datetime(6)", nullable: false), + CreatedAt = table.Column(type: "datetime(6)", nullable: false), + CreatedById = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + IsActive = table.Column(type: "tinyint(1)", nullable: false), + TenantId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci") + }, + constraints: table => + { + table.PrimaryKey("PK_AdvancePaymentTransactions", x => x.Id); + table.ForeignKey( + name: "FK_AdvancePaymentTransactions_Employees_CreatedById", + column: x => x.CreatedById, + principalTable: "Employees", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AdvancePaymentTransactions_Employees_EmployeeId", + column: x => x.EmployeeId, + principalTable: "Employees", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AdvancePaymentTransactions_Projects_ProjectId", + column: x => x.ProjectId, + principalTable: "Projects", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_AdvancePaymentTransactions_Tenants_TenantId", + column: x => x.TenantId, + principalTable: "Tenants", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "ExpenseCategoryMasters", + columns: table => new + { + Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + Name = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + NoOfPersonsRequired = table.Column(type: "tinyint(1)", nullable: false), + Description = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + IsActive = table.Column(type: "tinyint(1)", nullable: false), + IsAttachmentRequried = table.Column(type: "tinyint(1)", nullable: false), + TenantId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci") + }, + constraints: table => + { + table.PrimaryKey("PK_ExpenseCategoryMasters", x => x.Id); + table.ForeignKey( + name: "FK_ExpenseCategoryMasters_Tenants_TenantId", + column: x => x.TenantId, + principalTable: "Tenants", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "RecurringPaymentStatus", + columns: table => new + { + Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + Name = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4") + }, + constraints: table => + { + table.PrimaryKey("PK_RecurringPaymentStatus", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "StatusUpdateLogs", + columns: table => new + { + Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + StatusId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + NextStatusId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + EntityId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + Comment = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + UpdatedAt = table.Column(type: "datetime(6)", nullable: false), + UpdatedById = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + TenantId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci") + }, + constraints: table => + { + table.PrimaryKey("PK_StatusUpdateLogs", x => x.Id); + table.ForeignKey( + name: "FK_StatusUpdateLogs_Employees_UpdatedById", + column: x => x.UpdatedById, + principalTable: "Employees", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_StatusUpdateLogs_Tenants_TenantId", + column: x => x.TenantId, + principalTable: "Tenants", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "RecurringPayments", + columns: table => new + { + Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + Title = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Description = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + UIDPrefix = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + UIDPostfix = table.Column(type: "int", nullable: false), + Payee = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + NotifyTo = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + CurrencyId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + Amount = table.Column(type: "double", nullable: false), + StrikeDate = table.Column(type: "datetime(6)", nullable: false), + LatestPRGeneratedAt = table.Column(type: "datetime(6)", nullable: true), + ProjectId = table.Column(type: "char(36)", nullable: true, collation: "ascii_general_ci"), + PaymentBufferDays = table.Column(type: "int", nullable: false), + NumberOfIteration = table.Column(type: "int", nullable: false), + ExpenseCategoryId = table.Column(type: "char(36)", nullable: true, collation: "ascii_general_ci"), + StatusId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + Frequency = table.Column(type: "int", nullable: false), + IsVariable = table.Column(type: "tinyint(1)", nullable: false), + IsActive = table.Column(type: "tinyint(1)", nullable: false), + CreatedAt = table.Column(type: "datetime(6)", nullable: false), + CreatedById = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + UpdatedAt = table.Column(type: "datetime(6)", nullable: true), + UpdatedById = table.Column(type: "char(36)", nullable: true, collation: "ascii_general_ci"), + TenantId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci") + }, + constraints: table => + { + table.PrimaryKey("PK_RecurringPayments", x => x.Id); + table.ForeignKey( + name: "FK_RecurringPayments_CurrencyMaster_CurrencyId", + column: x => x.CurrencyId, + principalTable: "CurrencyMaster", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_RecurringPayments_Employees_CreatedById", + column: x => x.CreatedById, + principalTable: "Employees", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_RecurringPayments_Employees_UpdatedById", + column: x => x.UpdatedById, + principalTable: "Employees", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_RecurringPayments_ExpenseCategoryMasters_ExpenseCategoryId", + column: x => x.ExpenseCategoryId, + principalTable: "ExpenseCategoryMasters", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_RecurringPayments_Projects_ProjectId", + column: x => x.ProjectId, + principalTable: "Projects", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_RecurringPayments_RecurringPaymentStatus_StatusId", + column: x => x.StatusId, + principalTable: "RecurringPaymentStatus", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_RecurringPayments_Tenants_TenantId", + column: x => x.TenantId, + principalTable: "Tenants", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "PaymentRequests", + columns: table => new + { + Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + Title = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Description = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + UIDPrefix = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + UIDPostfix = table.Column(type: "int", nullable: false), + Payee = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + IsAdvancePayment = table.Column(type: "tinyint(1)", nullable: false), + CurrencyId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + Amount = table.Column(type: "double", nullable: false), + BaseAmount = table.Column(type: "double", nullable: true), + TaxAmount = table.Column(type: "double", nullable: true), + TDSPercentage = table.Column(type: "double", nullable: true), + DueDate = table.Column(type: "datetime(6)", nullable: false), + ProjectId = table.Column(type: "char(36)", nullable: true, collation: "ascii_general_ci"), + RecurringPaymentId = table.Column(type: "char(36)", nullable: true, collation: "ascii_general_ci"), + ExpenseCategoryId = table.Column(type: "char(36)", nullable: true, collation: "ascii_general_ci"), + ExpenseStatusId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + PaidTransactionId = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + PaidAt = table.Column(type: "datetime(6)", nullable: true), + PaidById = table.Column(type: "char(36)", nullable: true, collation: "ascii_general_ci"), + IsExpenseCreated = table.Column(type: "tinyint(1)", nullable: false), + IsActive = table.Column(type: "tinyint(1)", nullable: false), + CreatedAt = table.Column(type: "datetime(6)", nullable: false), + CreatedById = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + UpdatedAt = table.Column(type: "datetime(6)", nullable: true), + UpdatedById = table.Column(type: "char(36)", nullable: true, collation: "ascii_general_ci"), + TenantId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci") + }, + constraints: table => + { + table.PrimaryKey("PK_PaymentRequests", x => x.Id); + table.ForeignKey( + name: "FK_PaymentRequests_CurrencyMaster_CurrencyId", + column: x => x.CurrencyId, + principalTable: "CurrencyMaster", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_PaymentRequests_Employees_CreatedById", + column: x => x.CreatedById, + principalTable: "Employees", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_PaymentRequests_Employees_PaidById", + column: x => x.PaidById, + principalTable: "Employees", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_PaymentRequests_Employees_UpdatedById", + column: x => x.UpdatedById, + principalTable: "Employees", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_PaymentRequests_ExpenseCategoryMasters_ExpenseCategoryId", + column: x => x.ExpenseCategoryId, + principalTable: "ExpenseCategoryMasters", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_PaymentRequests_ExpensesStatusMaster_ExpenseStatusId", + column: x => x.ExpenseStatusId, + principalTable: "ExpensesStatusMaster", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_PaymentRequests_Projects_ProjectId", + column: x => x.ProjectId, + principalTable: "Projects", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_PaymentRequests_RecurringPayments_RecurringPaymentId", + column: x => x.RecurringPaymentId, + principalTable: "RecurringPayments", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_PaymentRequests_Tenants_TenantId", + column: x => x.TenantId, + principalTable: "Tenants", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "PaymentRequestAttachments", + columns: table => new + { + Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + PaymentRequestId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + DocumentId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"), + TenantId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci") + }, + constraints: table => + { + table.PrimaryKey("PK_PaymentRequestAttachments", x => x.Id); + table.ForeignKey( + name: "FK_PaymentRequestAttachments_Documents_DocumentId", + column: x => x.DocumentId, + principalTable: "Documents", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_PaymentRequestAttachments_PaymentRequests_PaymentRequestId", + column: x => x.PaymentRequestId, + principalTable: "PaymentRequests", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_PaymentRequestAttachments_Tenants_TenantId", + column: x => x.TenantId, + principalTable: "Tenants", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.InsertData( + table: "ExpenseCategoryMasters", + columns: new[] { "Id", "Description", "IsActive", "IsAttachmentRequried", "Name", "NoOfPersonsRequired", "TenantId" }, + values: new object[,] + { + { new Guid("1e2d697a-76b4-4be8-bc66-87144561a1a0"), "Scheduled payments for external services or goods.", true, true, "Vendor/Supplier Payments", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }, + { new Guid("2de53163-0dbd-404b-8e60-1b02e6b4886a"), "Vehicle fuel, logistics services and delivery of goods or personnel.", true, false, "Transport", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }, + { new Guid("4842fa61-64eb-4241-aebd-8282065af9f9"), "Government fees, insurance, inspections and safety-related expenditures.", true, true, "Compliance & Safety", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }, + { new Guid("52484820-1b54-4865-8f0f-baa2b1d339b9"), "Site setup costs including equipment deployment and temporary infrastructure.", true, true, "Mobilization", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }, + { new Guid("5e0c6227-d49d-41ff-9f1f-781f0aee2469"), "Materials, equipment and supplies purchased for site operations.", true, true, "Procurement", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }, + { new Guid("77013784-9324-4d8b-bd36-d6f928e68942"), "Machinery servicing, electricity, water, and temporary office needs.", true, true, "Maintenance & Utilities", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }, + { new Guid("dd120bc4-ab0a-45ba-8450-5cd45ff221ca"), "Delivery of personnel.", true, false, "Travelling", true, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }, + { new Guid("fc59eb90-98ea-481c-b421-54bfa9e42d8f"), " Worker amenities like snacks, meals, safety gear, accommodation, medical support etc.", true, true, "Employee Welfare", true, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") } + }); + + migrationBuilder.UpdateData( + table: "ExpensesStatusMaster", + keyColumn: "Id", + keyValue: new Guid("6537018f-f4e9-4cb3-a210-6c3b2da999d7"), + column: "DisplayName", + value: "Submit for Review"); + + migrationBuilder.InsertData( + table: "ExpensesStatusMaster", + columns: new[] { "Id", "Color", "Description", "DisplayName", "IsActive", "IsSystem", "Name" }, + values: new object[] { new Guid("b8586f67-dc19-49c3-b4af-224149efe1d3"), "#0E9F6E", "Create new Expense.", "Create Expense", true, true, "Done" }); + + migrationBuilder.InsertData( + table: "Features", + columns: new[] { "Id", "Description", "IsActive", "ModuleId", "Name" }, + values: new object[] { new Guid("86e80017-0698-4efe-93d0-806de67266e0"), "Recurring Template Management is the automated creation and scheduling of repetitive tasks, processes, or transactions using predefined templates at set intervals to ensure consistent and efficient workflow execution without manual recreation each time.", true, new Guid("bf59fd88-b57a-4d67-bf01-3780f385896b"), "Recurring Template Management" }); + + migrationBuilder.InsertData( + table: "Modules", + columns: new[] { "Id", "Description", "Key", "Name" }, + values: new object[] { new Guid("0a79687a-86d7-430d-a2d7-8b8603cc76a1"), "Finance Module", "504ec132-e6a9-422f-8f85-050602cfce05", "Finance" }); + + migrationBuilder.InsertData( + table: "PaymentModeMatser", + columns: new[] { "Id", "Description", "IsActive", "Name" }, + values: new object[,] + { + { new Guid("95697409-baf6-4f78-86ab-42d93d9569a8"), "A debit card is a payment card that deducts funds directly from the cardholder's bank account when a purchase is made.", true, "Debit Card" }, + { new Guid("a820f240-5e9a-4ae9-9091-8a7aa7720cea"), "A credit card is a payment card that allows you to borrow funds from a financial institution to pay for goods and services", true, "Credit card" }, + { new Guid("f67beee6-6763-4108-922c-03bd86b9178d"), "When a bill is paid using the amount received in advance from a company.", true, "Advance Payment" } + }); + + migrationBuilder.InsertData( + table: "RecurringPaymentStatus", + columns: new[] { "Id", "Name" }, + values: new object[,] + { + { new Guid("306856fb-5655-42eb-bf8b-808bb5e84725"), "Completed" }, + { new Guid("3ec864d2-8bf5-42fb-ba70-5090301dd816"), "De-Activated" }, + { new Guid("8bfc9346-e092-4a80-acbf-515ae1ef6868"), "Paused" }, + { new Guid("da462422-13b2-45cc-a175-910a225f6fc8"), "Active" } + }); + + migrationBuilder.InsertData( + table: "ExpensesStatusMapping", + columns: new[] { "Id", "NextStatusId", "StatusId" }, + values: new object[] { new Guid("a1cc95ed-b276-4a3e-9f00-0a249b522d64"), new Guid("b8586f67-dc19-49c3-b4af-224149efe1d3"), new Guid("61578360-3a49-4c34-8604-7b35a3787b95") }); + + migrationBuilder.InsertData( + table: "FeaturePermissions", + columns: new[] { "Id", "Description", "FeatureId", "IsEnabled", "Name" }, + values: new object[,] + { + { new Guid("6382ea8b-aff2-4cd2-a48f-a652b35825d8"), "Manage Recurring Template payment permission allows authorized users to set up, modify, and execute automated recurring payments using predefined templates, ensuring secure and controlled handling of repetitive financial transactions.", new Guid("86e80017-0698-4efe-93d0-806de67266e0"), true, "Manage Recurring" }, + { new Guid("7ddf2fba-c44d-4fe3-b4ec-690ff70be2e3"), "The \"View All Recurring Template payment permission\" generally allows users to see and access all recurring payment templates in the system, enabling them to review, manage, and process recurring transactions efficiently.", new Guid("86e80017-0698-4efe-93d0-806de67266e0"), true, "View All Recurring" }, + { new Guid("e5d21efe-573d-4a16-a0f8-414d3e442e78"), "View Self Recurring Template payment permission allows a user to view and access their own recurring payment templates without editing rights.", new Guid("86e80017-0698-4efe-93d0-806de67266e0"), true, "View Self Recurring" } + }); + + migrationBuilder.InsertData( + table: "StatusPermissionMapping", + columns: new[] { "Id", "PermissionId", "StatusId" }, + values: new object[] { new Guid("de04b6c7-a5cd-4a61-88b0-b43b0008202e"), new Guid("ea5a1529-4ee8-4828-80ea-0e23c9d4dd11"), new Guid("b8586f67-dc19-49c3-b4af-224149efe1d3") }); + + migrationBuilder.CreateIndex( + name: "IX_Expenses_CurrencyId", + table: "Expenses", + column: "CurrencyId"); + + migrationBuilder.CreateIndex( + name: "IX_Expenses_ExpenseCategoryId", + table: "Expenses", + column: "ExpenseCategoryId"); + + migrationBuilder.CreateIndex( + name: "IX_Expenses_PaymentRequestId", + table: "Expenses", + column: "PaymentRequestId"); + + migrationBuilder.CreateIndex( + name: "IX_AdvancePaymentTransactions_CreatedById", + table: "AdvancePaymentTransactions", + column: "CreatedById"); + + migrationBuilder.CreateIndex( + name: "IX_AdvancePaymentTransactions_EmployeeId", + table: "AdvancePaymentTransactions", + column: "EmployeeId"); + + migrationBuilder.CreateIndex( + name: "IX_AdvancePaymentTransactions_ProjectId", + table: "AdvancePaymentTransactions", + column: "ProjectId"); + + migrationBuilder.CreateIndex( + name: "IX_AdvancePaymentTransactions_TenantId", + table: "AdvancePaymentTransactions", + column: "TenantId"); + + migrationBuilder.CreateIndex( + name: "IX_ExpenseCategoryMasters_TenantId", + table: "ExpenseCategoryMasters", + column: "TenantId"); + + migrationBuilder.CreateIndex( + name: "IX_PaymentRequestAttachments_DocumentId", + table: "PaymentRequestAttachments", + column: "DocumentId"); + + migrationBuilder.CreateIndex( + name: "IX_PaymentRequestAttachments_PaymentRequestId", + table: "PaymentRequestAttachments", + column: "PaymentRequestId"); + + migrationBuilder.CreateIndex( + name: "IX_PaymentRequestAttachments_TenantId", + table: "PaymentRequestAttachments", + column: "TenantId"); + + migrationBuilder.CreateIndex( + name: "IX_PaymentRequests_CreatedById", + table: "PaymentRequests", + column: "CreatedById"); + + migrationBuilder.CreateIndex( + name: "IX_PaymentRequests_CurrencyId", + table: "PaymentRequests", + column: "CurrencyId"); + + migrationBuilder.CreateIndex( + name: "IX_PaymentRequests_ExpenseCategoryId", + table: "PaymentRequests", + column: "ExpenseCategoryId"); + + migrationBuilder.CreateIndex( + name: "IX_PaymentRequests_ExpenseStatusId", + table: "PaymentRequests", + column: "ExpenseStatusId"); + + migrationBuilder.CreateIndex( + name: "IX_PaymentRequests_PaidById", + table: "PaymentRequests", + column: "PaidById"); + + migrationBuilder.CreateIndex( + name: "IX_PaymentRequests_ProjectId", + table: "PaymentRequests", + column: "ProjectId"); + + migrationBuilder.CreateIndex( + name: "IX_PaymentRequests_RecurringPaymentId", + table: "PaymentRequests", + column: "RecurringPaymentId"); + + migrationBuilder.CreateIndex( + name: "IX_PaymentRequests_TenantId", + table: "PaymentRequests", + column: "TenantId"); + + migrationBuilder.CreateIndex( + name: "IX_PaymentRequests_UpdatedById", + table: "PaymentRequests", + column: "UpdatedById"); + + migrationBuilder.CreateIndex( + name: "IX_RecurringPayments_CreatedById", + table: "RecurringPayments", + column: "CreatedById"); + + migrationBuilder.CreateIndex( + name: "IX_RecurringPayments_CurrencyId", + table: "RecurringPayments", + column: "CurrencyId"); + + migrationBuilder.CreateIndex( + name: "IX_RecurringPayments_ExpenseCategoryId", + table: "RecurringPayments", + column: "ExpenseCategoryId"); + + migrationBuilder.CreateIndex( + name: "IX_RecurringPayments_ProjectId", + table: "RecurringPayments", + column: "ProjectId"); + + migrationBuilder.CreateIndex( + name: "IX_RecurringPayments_StatusId", + table: "RecurringPayments", + column: "StatusId"); + + migrationBuilder.CreateIndex( + name: "IX_RecurringPayments_TenantId", + table: "RecurringPayments", + column: "TenantId"); + + migrationBuilder.CreateIndex( + name: "IX_RecurringPayments_UpdatedById", + table: "RecurringPayments", + column: "UpdatedById"); + + migrationBuilder.CreateIndex( + name: "IX_StatusUpdateLogs_TenantId", + table: "StatusUpdateLogs", + column: "TenantId"); + + migrationBuilder.CreateIndex( + name: "IX_StatusUpdateLogs_UpdatedById", + table: "StatusUpdateLogs", + column: "UpdatedById"); + + migrationBuilder.AddForeignKey( + name: "FK_Expenses_CurrencyMaster_CurrencyId", + table: "Expenses", + column: "CurrencyId", + principalTable: "CurrencyMaster", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_Expenses_ExpenseCategoryMasters_ExpenseCategoryId", + table: "Expenses", + column: "ExpenseCategoryId", + principalTable: "ExpenseCategoryMasters", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_Expenses_PaymentRequests_PaymentRequestId", + table: "Expenses", + column: "PaymentRequestId", + principalTable: "PaymentRequests", + principalColumn: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Expenses_CurrencyMaster_CurrencyId", + table: "Expenses"); + + migrationBuilder.DropForeignKey( + name: "FK_Expenses_ExpenseCategoryMasters_ExpenseCategoryId", + table: "Expenses"); + + migrationBuilder.DropForeignKey( + name: "FK_Expenses_PaymentRequests_PaymentRequestId", + table: "Expenses"); + + migrationBuilder.DropTable( + name: "AdvancePaymentTransactions"); + + migrationBuilder.DropTable( + name: "PaymentRequestAttachments"); + + migrationBuilder.DropTable( + name: "StatusUpdateLogs"); + + migrationBuilder.DropTable( + name: "PaymentRequests"); + + migrationBuilder.DropTable( + name: "RecurringPayments"); + + migrationBuilder.DropTable( + name: "ExpenseCategoryMasters"); + + migrationBuilder.DropTable( + name: "RecurringPaymentStatus"); + + migrationBuilder.DropIndex( + name: "IX_Expenses_CurrencyId", + table: "Expenses"); + + migrationBuilder.DropIndex( + name: "IX_Expenses_ExpenseCategoryId", + table: "Expenses"); + + migrationBuilder.DropIndex( + name: "IX_Expenses_PaymentRequestId", + table: "Expenses"); + + migrationBuilder.DeleteData( + table: "ExpensesStatusMapping", + keyColumn: "Id", + keyValue: new Guid("a1cc95ed-b276-4a3e-9f00-0a249b522d64")); + + migrationBuilder.DeleteData( + table: "FeaturePermissions", + keyColumn: "Id", + keyValue: new Guid("6382ea8b-aff2-4cd2-a48f-a652b35825d8")); + + migrationBuilder.DeleteData( + table: "FeaturePermissions", + keyColumn: "Id", + keyValue: new Guid("7ddf2fba-c44d-4fe3-b4ec-690ff70be2e3")); + + migrationBuilder.DeleteData( + table: "FeaturePermissions", + keyColumn: "Id", + keyValue: new Guid("e5d21efe-573d-4a16-a0f8-414d3e442e78")); + + migrationBuilder.DeleteData( + table: "Modules", + keyColumn: "Id", + keyValue: new Guid("0a79687a-86d7-430d-a2d7-8b8603cc76a1")); + + migrationBuilder.DeleteData( + table: "PaymentModeMatser", + keyColumn: "Id", + keyValue: new Guid("95697409-baf6-4f78-86ab-42d93d9569a8")); + + migrationBuilder.DeleteData( + table: "PaymentModeMatser", + keyColumn: "Id", + keyValue: new Guid("a820f240-5e9a-4ae9-9091-8a7aa7720cea")); + + migrationBuilder.DeleteData( + table: "PaymentModeMatser", + keyColumn: "Id", + keyValue: new Guid("f67beee6-6763-4108-922c-03bd86b9178d")); + + migrationBuilder.DeleteData( + table: "StatusPermissionMapping", + keyColumn: "Id", + keyValue: new Guid("de04b6c7-a5cd-4a61-88b0-b43b0008202e")); + + migrationBuilder.DeleteData( + table: "ExpensesStatusMaster", + keyColumn: "Id", + keyValue: new Guid("b8586f67-dc19-49c3-b4af-224149efe1d3")); + + migrationBuilder.DeleteData( + table: "Features", + keyColumn: "Id", + keyValue: new Guid("86e80017-0698-4efe-93d0-806de67266e0")); + + migrationBuilder.DropColumn( + name: "BaseAmount", + table: "Expenses"); + + migrationBuilder.DropColumn( + name: "CurrencyId", + table: "Expenses"); + + migrationBuilder.DropColumn( + name: "ExpenseCategoryId", + table: "Expenses"); + + migrationBuilder.DropColumn( + name: "PaymentRequestId", + table: "Expenses"); + + migrationBuilder.DropColumn( + name: "TDSPercentage", + table: "Expenses"); + + migrationBuilder.DropColumn( + name: "TaxAmount", + table: "Expenses"); + + migrationBuilder.DropColumn( + name: "UIDPostfix", + table: "Expenses"); + + migrationBuilder.DropColumn( + name: "UIDPrefix", + table: "Expenses"); + + migrationBuilder.AddColumn( + name: "TenantId", + table: "PaymentModeMatser", + type: "char(36)", + nullable: false, + defaultValue: new Guid("00000000-0000-0000-0000-000000000000"), + collation: "ascii_general_ci"); + + migrationBuilder.UpdateData( + table: "Expenses", + keyColumn: "ExpenseUId", + keyValue: null, + column: "ExpenseUId", + value: ""); + + migrationBuilder.AlterColumn( + name: "ExpenseUId", + table: "Expenses", + type: "longtext", + nullable: false, + oldClrType: typeof(string), + oldType: "longtext", + oldNullable: true) + .Annotation("MySql:CharSet", "utf8mb4") + .OldAnnotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.UpdateData( + table: "ExpensesStatusMaster", + keyColumn: "Id", + keyValue: new Guid("6537018f-f4e9-4cb3-a210-6c3b2da999d7"), + column: "DisplayName", + value: "Submit"); + + migrationBuilder.InsertData( + table: "ExpensesTypeMaster", + columns: new[] { "Id", "Description", "IsActive", "IsAttachmentRequried", "Name", "NoOfPersonsRequired", "TenantId" }, + values: new object[,] + { + { new Guid("1e2d697a-76b4-4be8-bc66-87144561a1a0"), "Scheduled payments for external services or goods.", true, true, "Vendor/Supplier Payments", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }, + { new Guid("2de53163-0dbd-404b-8e60-1b02e6b4886a"), "Vehicle fuel, logistics services and delivery of goods or personnel.", true, false, "Transport", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }, + { new Guid("4842fa61-64eb-4241-aebd-8282065af9f9"), "Government fees, insurance, inspections and safety-related expenditures.", true, true, "Compliance & Safety", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }, + { new Guid("52484820-1b54-4865-8f0f-baa2b1d339b9"), "Site setup costs including equipment deployment and temporary infrastructure.", true, true, "Mobilization", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }, + { new Guid("5e0c6227-d49d-41ff-9f1f-781f0aee2469"), "Materials, equipment and supplies purchased for site operations.", true, true, "Procurement", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }, + { new Guid("77013784-9324-4d8b-bd36-d6f928e68942"), "Machinery servicing, electricity, water, and temporary office needs.", true, true, "Maintenance & Utilities", false, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }, + { new Guid("dd120bc4-ab0a-45ba-8450-5cd45ff221ca"), "Delivery of personnel.", true, false, "Travelling", true, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") }, + { new Guid("fc59eb90-98ea-481c-b421-54bfa9e42d8f"), " Worker amenities like snacks, meals, safety gear, accommodation, medical support etc.", true, true, "Employee Welfare", true, new Guid("b3466e83-7e11-464c-b93a-daf047838b26") } + }); + + migrationBuilder.UpdateData( + table: "PaymentModeMatser", + keyColumn: "Id", + keyValue: new Guid("24e6b0df-7929-47d2-88a3-4cf14c1f28f9"), + column: "TenantId", + value: new Guid("b3466e83-7e11-464c-b93a-daf047838b26")); + + migrationBuilder.UpdateData( + table: "PaymentModeMatser", + keyColumn: "Id", + keyValue: new Guid("2e919e94-694c-41d9-9489-0a2b4208a027"), + column: "TenantId", + value: new Guid("b3466e83-7e11-464c-b93a-daf047838b26")); + + migrationBuilder.UpdateData( + table: "PaymentModeMatser", + keyColumn: "Id", + keyValue: new Guid("48d9b462-5d87-4dec-8dec-2bc943943172"), + column: "TenantId", + value: new Guid("b3466e83-7e11-464c-b93a-daf047838b26")); + + migrationBuilder.UpdateData( + table: "PaymentModeMatser", + keyColumn: "Id", + keyValue: new Guid("ed667353-8eea-4fd1-8750-719405932480"), + column: "TenantId", + value: new Guid("b3466e83-7e11-464c-b93a-daf047838b26")); + + migrationBuilder.CreateIndex( + name: "IX_PaymentModeMatser_TenantId", + table: "PaymentModeMatser", + column: "TenantId"); + + migrationBuilder.CreateIndex( + name: "IX_Expenses_ExpensesTypeId", + table: "Expenses", + column: "ExpensesTypeId"); + + migrationBuilder.AddForeignKey( + name: "FK_Expenses_ExpensesTypeMaster_ExpensesTypeId", + table: "Expenses", + column: "ExpensesTypeId", + principalTable: "ExpensesTypeMaster", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_PaymentModeMatser_Tenants_TenantId", + table: "PaymentModeMatser", + column: "TenantId", + principalTable: "Tenants", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/Marco.Pms.DataAccess/Migrations/ApplicationDbContextModelSnapshot.cs b/Marco.Pms.DataAccess/Migrations/ApplicationDbContextModelSnapshot.cs index 9b8c866..0e3616f 100644 --- a/Marco.Pms.DataAccess/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/Marco.Pms.DataAccess/Migrations/ApplicationDbContextModelSnapshot.cs @@ -1995,6 +1995,30 @@ namespace Marco.Pms.DataAccess.Migrations Name = "Add Payment" }, new + { + Id = new Guid("6382ea8b-aff2-4cd2-a48f-a652b35825d8"), + Description = "Manage Recurring Template payment permission allows authorized users to set up, modify, and execute automated recurring payments using predefined templates, ensuring secure and controlled handling of repetitive financial transactions.", + FeatureId = new Guid("86e80017-0698-4efe-93d0-806de67266e0"), + IsEnabled = true, + Name = "Manage Recurring" + }, + new + { + Id = new Guid("7ddf2fba-c44d-4fe3-b4ec-690ff70be2e3"), + Description = "The \"View All Recurring Template payment permission\" generally allows users to see and access all recurring payment templates in the system, enabling them to review, manage, and process recurring transactions efficiently.", + FeatureId = new Guid("86e80017-0698-4efe-93d0-806de67266e0"), + IsEnabled = true, + Name = "View All Recurring" + }, + new + { + Id = new Guid("e5d21efe-573d-4a16-a0f8-414d3e442e78"), + Description = "View Self Recurring Template payment permission allows a user to view and access their own recurring payment templates without editing rights.", + FeatureId = new Guid("86e80017-0698-4efe-93d0-806de67266e0"), + IsEnabled = true, + Name = "View Self Recurring" + }, + new { Id = new Guid("068cb3c1-49c5-4746-9f29-1fce16e820ac"), Description = "Allow user to create new organization", @@ -2066,6 +2090,63 @@ namespace Marco.Pms.DataAccess.Migrations b.ToTable("RolePermissionMappings"); }); + modelBuilder.Entity("Marco.Pms.Model.Expenses.AdvancePaymentTransaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Amount") + .HasColumnType("double"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("CreatedById") + .HasColumnType("char(36)"); + + b.Property("CurrentBalance") + .HasColumnType("double"); + + b.Property("EmployeeId") + .HasColumnType("char(36)"); + + b.Property("FinanceUIdPostfix") + .HasColumnType("int"); + + b.Property("FinanceUIdPrefix") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("PaidAt") + .HasColumnType("datetime(6)"); + + b.Property("ProjectId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("EmployeeId"); + + b.HasIndex("ProjectId"); + + b.HasIndex("TenantId"); + + b.ToTable("AdvancePaymentTransactions"); + }); + modelBuilder.Entity("Marco.Pms.Model.Expenses.BillAttachments", b => { b.Property("Id") @@ -2140,18 +2221,26 @@ namespace Marco.Pms.DataAccess.Migrations b.Property("ApprovedById") .HasColumnType("char(36)"); + b.Property("BaseAmount") + .HasColumnType("double"); + b.Property("CreatedAt") .HasColumnType("datetime(6)"); b.Property("CreatedById") .HasColumnType("char(36)"); + b.Property("CurrencyId") + .HasColumnType("char(36)"); + b.Property("Description") .IsRequired() .HasColumnType("longtext"); + b.Property("ExpenseCategoryId") + .HasColumnType("char(36)"); + b.Property("ExpenseUId") - .IsRequired() .HasColumnType("longtext"); b.Property("ExpensesTypeId") @@ -2175,6 +2264,9 @@ namespace Marco.Pms.DataAccess.Migrations b.Property("PaymentModeId") .HasColumnType("char(36)"); + b.Property("PaymentRequestId") + .HasColumnType("char(36)"); + b.Property("PreApproved") .HasColumnType("tinyint(1)"); @@ -2194,6 +2286,12 @@ namespace Marco.Pms.DataAccess.Migrations .IsRequired() .HasColumnType("longtext"); + b.Property("TDSPercentage") + .HasColumnType("double"); + + b.Property("TaxAmount") + .HasColumnType("double"); + b.Property("TenantId") .HasColumnType("char(36)"); @@ -2203,18 +2301,29 @@ namespace Marco.Pms.DataAccess.Migrations b.Property("TransactionId") .HasColumnType("longtext"); + b.Property("UIDPostfix") + .HasColumnType("int"); + + b.Property("UIDPrefix") + .IsRequired() + .HasColumnType("longtext"); + b.HasKey("Id"); b.HasIndex("ApprovedById"); b.HasIndex("CreatedById"); - b.HasIndex("ExpensesTypeId"); + b.HasIndex("CurrencyId"); + + b.HasIndex("ExpenseCategoryId"); b.HasIndex("PaidById"); b.HasIndex("PaymentModeId"); + b.HasIndex("PaymentRequestId"); + b.HasIndex("ProcessedById"); b.HasIndex("ProjectId"); @@ -2286,7 +2395,122 @@ namespace Marco.Pms.DataAccess.Migrations b.ToTable("ExpensesReimburseMapping"); }); - modelBuilder.Entity("Marco.Pms.Model.Expenses.ExpensesStatusMapping", b => + modelBuilder.Entity("Marco.Pms.Model.Expenses.Masters.ExpenseCategoryMaster", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("IsAttachmentRequried") + .HasColumnType("tinyint(1)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("NoOfPersonsRequired") + .HasColumnType("tinyint(1)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.ToTable("ExpenseCategoryMasters"); + + b.HasData( + new + { + Id = new Guid("5e0c6227-d49d-41ff-9f1f-781f0aee2469"), + Description = "Materials, equipment and supplies purchased for site operations.", + IsActive = true, + IsAttachmentRequried = true, + Name = "Procurement", + NoOfPersonsRequired = false, + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("2de53163-0dbd-404b-8e60-1b02e6b4886a"), + Description = "Vehicle fuel, logistics services and delivery of goods or personnel.", + IsActive = true, + IsAttachmentRequried = false, + Name = "Transport", + NoOfPersonsRequired = false, + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("dd120bc4-ab0a-45ba-8450-5cd45ff221ca"), + Description = "Delivery of personnel.", + IsActive = true, + IsAttachmentRequried = false, + Name = "Travelling", + NoOfPersonsRequired = true, + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("52484820-1b54-4865-8f0f-baa2b1d339b9"), + Description = "Site setup costs including equipment deployment and temporary infrastructure.", + IsActive = true, + IsAttachmentRequried = true, + Name = "Mobilization", + NoOfPersonsRequired = false, + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("fc59eb90-98ea-481c-b421-54bfa9e42d8f"), + Description = " Worker amenities like snacks, meals, safety gear, accommodation, medical support etc.", + IsActive = true, + IsAttachmentRequried = true, + Name = "Employee Welfare", + NoOfPersonsRequired = true, + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("77013784-9324-4d8b-bd36-d6f928e68942"), + Description = "Machinery servicing, electricity, water, and temporary office needs.", + IsActive = true, + IsAttachmentRequried = true, + Name = "Maintenance & Utilities", + NoOfPersonsRequired = false, + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("1e2d697a-76b4-4be8-bc66-87144561a1a0"), + Description = "Scheduled payments for external services or goods.", + IsActive = true, + IsAttachmentRequried = true, + Name = "Vendor/Supplier Payments", + NoOfPersonsRequired = false, + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }, + new + { + Id = new Guid("4842fa61-64eb-4241-aebd-8282065af9f9"), + Description = "Government fees, insurance, inspections and safety-related expenditures.", + IsActive = true, + IsAttachmentRequried = true, + Name = "Compliance & Safety", + NoOfPersonsRequired = false, + TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.Masters.ExpensesStatusMapping", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -2307,6 +2531,12 @@ namespace Marco.Pms.DataAccess.Migrations b.ToTable("ExpensesStatusMapping"); b.HasData( + new + { + Id = new Guid("a1cc95ed-b276-4a3e-9f00-0a249b522d64"), + NextStatusId = new Guid("b8586f67-dc19-49c3-b4af-224149efe1d3"), + StatusId = new Guid("61578360-3a49-4c34-8604-7b35a3787b95") + }, new { Id = new Guid("5cf7f1df-9d1f-4289-add0-1775ad614f25"), @@ -2357,7 +2587,44 @@ namespace Marco.Pms.DataAccess.Migrations }); }); - modelBuilder.Entity("Marco.Pms.Model.Expenses.StatusPermissionMapping", b => + modelBuilder.Entity("Marco.Pms.Model.Expenses.Masters.RecurringPaymentStatus", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("RecurringPaymentStatus"); + + b.HasData( + new + { + Id = new Guid("da462422-13b2-45cc-a175-910a225f6fc8"), + Name = "Active" + }, + new + { + Id = new Guid("3ec864d2-8bf5-42fb-ba70-5090301dd816"), + Name = "De-Activated" + }, + new + { + Id = new Guid("306856fb-5655-42eb-bf8b-808bb5e84725"), + Name = "Completed" + }, + new + { + Id = new Guid("8bfc9346-e092-4a80-acbf-515ae1ef6868"), + Name = "Paused" + }); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.Masters.StatusPermissionMapping", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -2419,9 +2686,251 @@ namespace Marco.Pms.DataAccess.Migrations Id = new Guid("214354e5-daad-4569-ad69-eb5bf4e87fbc"), PermissionId = new Guid("ea5a1529-4ee8-4828-80ea-0e23c9d4dd11"), StatusId = new Guid("61578360-3a49-4c34-8604-7b35a3787b95") + }, + new + { + Id = new Guid("de04b6c7-a5cd-4a61-88b0-b43b0008202e"), + PermissionId = new Guid("ea5a1529-4ee8-4828-80ea-0e23c9d4dd11"), + StatusId = new Guid("b8586f67-dc19-49c3-b4af-224149efe1d3") }); }); + modelBuilder.Entity("Marco.Pms.Model.Expenses.PaymentRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Amount") + .HasColumnType("double"); + + b.Property("BaseAmount") + .HasColumnType("double"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("CreatedById") + .HasColumnType("char(36)"); + + b.Property("CurrencyId") + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("DueDate") + .HasColumnType("datetime(6)"); + + b.Property("ExpenseCategoryId") + .HasColumnType("char(36)"); + + b.Property("ExpenseStatusId") + .HasColumnType("char(36)"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("IsAdvancePayment") + .HasColumnType("tinyint(1)"); + + b.Property("IsExpenseCreated") + .HasColumnType("tinyint(1)"); + + b.Property("PaidAt") + .HasColumnType("datetime(6)"); + + b.Property("PaidById") + .HasColumnType("char(36)"); + + b.Property("PaidTransactionId") + .HasColumnType("longtext"); + + b.Property("Payee") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ProjectId") + .HasColumnType("char(36)"); + + b.Property("RecurringPaymentId") + .HasColumnType("char(36)"); + + b.Property("TDSPercentage") + .HasColumnType("double"); + + b.Property("TaxAmount") + .HasColumnType("double"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UIDPostfix") + .HasColumnType("int"); + + b.Property("UIDPrefix") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UpdatedAt") + .HasColumnType("datetime(6)"); + + b.Property("UpdatedById") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("CurrencyId"); + + b.HasIndex("ExpenseCategoryId"); + + b.HasIndex("ExpenseStatusId"); + + b.HasIndex("PaidById"); + + b.HasIndex("ProjectId"); + + b.HasIndex("RecurringPaymentId"); + + b.HasIndex("TenantId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("PaymentRequests"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.PaymentRequestAttachment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("DocumentId") + .HasColumnType("char(36)"); + + b.Property("PaymentRequestId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.HasIndex("PaymentRequestId"); + + b.HasIndex("TenantId"); + + b.ToTable("PaymentRequestAttachments"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.RecurringPayment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Amount") + .HasColumnType("double"); + + b.Property("CreatedAt") + .HasColumnType("datetime(6)"); + + b.Property("CreatedById") + .HasColumnType("char(36)"); + + b.Property("CurrencyId") + .HasColumnType("char(36)"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("ExpenseCategoryId") + .HasColumnType("char(36)"); + + b.Property("Frequency") + .HasColumnType("int"); + + b.Property("IsActive") + .HasColumnType("tinyint(1)"); + + b.Property("IsVariable") + .HasColumnType("tinyint(1)"); + + b.Property("LatestPRGeneratedAt") + .HasColumnType("datetime(6)"); + + b.Property("NotifyTo") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("NumberOfIteration") + .HasColumnType("int"); + + b.Property("Payee") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("PaymentBufferDays") + .HasColumnType("int"); + + b.Property("ProjectId") + .HasColumnType("char(36)"); + + b.Property("StatusId") + .HasColumnType("char(36)"); + + b.Property("StrikeDate") + .HasColumnType("datetime(6)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("Title") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UIDPostfix") + .HasColumnType("int"); + + b.Property("UIDPrefix") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("UpdatedAt") + .HasColumnType("datetime(6)"); + + b.Property("UpdatedById") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("CreatedById"); + + b.HasIndex("CurrencyId"); + + b.HasIndex("ExpenseCategoryId"); + + b.HasIndex("ProjectId"); + + b.HasIndex("StatusId"); + + b.HasIndex("TenantId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("RecurringPayments"); + }); + modelBuilder.Entity("Marco.Pms.Model.Forum.TicketAttachment", b => { b.Property("Id") @@ -2922,7 +3431,7 @@ namespace Marco.Pms.DataAccess.Migrations Id = new Guid("6537018f-f4e9-4cb3-a210-6c3b2da999d7"), Color = "#696cff", Description = "Reviewer is currently reviewing the expense.", - DisplayName = "Submit", + DisplayName = "Submit for Review", IsActive = true, IsSystem = true, Name = "Review Pending" @@ -2976,6 +3485,16 @@ namespace Marco.Pms.DataAccess.Migrations IsActive = true, IsSystem = true, Name = "Processed" + }, + new + { + Id = new Guid("b8586f67-dc19-49c3-b4af-224149efe1d3"), + Color = "#0E9F6E", + Description = "Create new Expense.", + DisplayName = "Create Expense", + IsActive = true, + IsSystem = true, + Name = "Done" }); }); @@ -3010,88 +3529,6 @@ namespace Marco.Pms.DataAccess.Migrations b.HasIndex("TenantId"); b.ToTable("ExpensesTypeMaster"); - - b.HasData( - new - { - Id = new Guid("5e0c6227-d49d-41ff-9f1f-781f0aee2469"), - Description = "Materials, equipment and supplies purchased for site operations.", - IsActive = true, - IsAttachmentRequried = true, - Name = "Procurement", - NoOfPersonsRequired = false, - TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") - }, - new - { - Id = new Guid("2de53163-0dbd-404b-8e60-1b02e6b4886a"), - Description = "Vehicle fuel, logistics services and delivery of goods or personnel.", - IsActive = true, - IsAttachmentRequried = false, - Name = "Transport", - NoOfPersonsRequired = false, - TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") - }, - new - { - Id = new Guid("dd120bc4-ab0a-45ba-8450-5cd45ff221ca"), - Description = "Delivery of personnel.", - IsActive = true, - IsAttachmentRequried = false, - Name = "Travelling", - NoOfPersonsRequired = true, - TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") - }, - new - { - Id = new Guid("52484820-1b54-4865-8f0f-baa2b1d339b9"), - Description = "Site setup costs including equipment deployment and temporary infrastructure.", - IsActive = true, - IsAttachmentRequried = true, - Name = "Mobilization", - NoOfPersonsRequired = false, - TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") - }, - new - { - Id = new Guid("fc59eb90-98ea-481c-b421-54bfa9e42d8f"), - Description = " Worker amenities like snacks, meals, safety gear, accommodation, medical support etc.", - IsActive = true, - IsAttachmentRequried = true, - Name = "Employee Welfare", - NoOfPersonsRequired = true, - TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") - }, - new - { - Id = new Guid("77013784-9324-4d8b-bd36-d6f928e68942"), - Description = "Machinery servicing, electricity, water, and temporary office needs.", - IsActive = true, - IsAttachmentRequried = true, - Name = "Maintenance & Utilities", - NoOfPersonsRequired = false, - TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") - }, - new - { - Id = new Guid("1e2d697a-76b4-4be8-bc66-87144561a1a0"), - Description = "Scheduled payments for external services or goods.", - IsActive = true, - IsAttachmentRequried = true, - Name = "Vendor/Supplier Payments", - NoOfPersonsRequired = false, - TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") - }, - new - { - Id = new Guid("4842fa61-64eb-4241-aebd-8282065af9f9"), - Description = "Government fees, insurance, inspections and safety-related expenditures.", - IsActive = true, - IsAttachmentRequried = true, - Name = "Compliance & Safety", - NoOfPersonsRequired = false, - TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") - }); }); modelBuilder.Entity("Marco.Pms.Model.Master.Feature", b => @@ -3128,6 +3565,14 @@ namespace Marco.Pms.DataAccess.Migrations Name = "Project Management" }, new + { + Id = new Guid("9d4b5489-2079-40b9-bd77-6e1bf90bc19f"), + Description = "Manage Tasks", + IsActive = true, + ModuleId = new Guid("bf59fd88-b57a-4d67-bf01-3780f385896b"), + Name = "Task Management" + }, + new { Id = new Guid("a4e25142-449b-4334-a6e5-22f70e4732d7"), Description = "Expense Management is the systematic process of tracking, controlling, and reporting business-related expenditures.", @@ -3145,11 +3590,11 @@ namespace Marco.Pms.DataAccess.Migrations }, new { - Id = new Guid("9d4b5489-2079-40b9-bd77-6e1bf90bc19f"), - Description = "Manage Tasks", + Id = new Guid("86e80017-0698-4efe-93d0-806de67266e0"), + Description = "Recurring Template Management is the automated creation and scheduling of repetitive tasks, processes, or transactions using predefined templates at set intervals to ensure consistent and efficient workflow execution without manual recreation each time.", IsActive = true, ModuleId = new Guid("bf59fd88-b57a-4d67-bf01-3780f385896b"), - Name = "Task Management" + Name = "Recurring Template Management" }, new { @@ -3389,6 +3834,13 @@ namespace Marco.Pms.DataAccess.Migrations Description = "Tenant Module", Key = "504ec132-e6a9-422f-8f85-050602cfce05", Name = "Tenant" + }, + new + { + Id = new Guid("0a79687a-86d7-430d-a2d7-8b8603cc76a1"), + Description = "Finance Module", + Key = "504ec132-e6a9-422f-8f85-050602cfce05", + Name = "Finance" }); }); @@ -3409,13 +3861,8 @@ namespace Marco.Pms.DataAccess.Migrations .IsRequired() .HasColumnType("longtext"); - b.Property("TenantId") - .HasColumnType("char(36)"); - b.HasKey("Id"); - b.HasIndex("TenantId"); - b.ToTable("PaymentModeMatser"); b.HasData( @@ -3424,32 +3871,49 @@ namespace Marco.Pms.DataAccess.Migrations Id = new Guid("24e6b0df-7929-47d2-88a3-4cf14c1f28f9"), Description = "Physical currency; still used for small or informal transactions.", IsActive = true, - Name = "Cash", - TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + Name = "Cash" }, new { Id = new Guid("48d9b462-5d87-4dec-8dec-2bc943943172"), Description = "Paper-based payment order; less common now due to processing delays and fraud risks.", IsActive = true, - Name = "Cheque", - TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + Name = "Cheque" }, new { Id = new Guid("ed667353-8eea-4fd1-8750-719405932480"), Description = "Online banking portals used to transfer funds directly between accounts", IsActive = true, - Name = "NetBanking", - TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + Name = "NetBanking" }, new { Id = new Guid("2e919e94-694c-41d9-9489-0a2b4208a027"), Description = "Real-time bank-to-bank transfer using mobile apps; widely used for peer-to-peer and merchant payments.", IsActive = true, - Name = "UPI", - TenantId = new Guid("b3466e83-7e11-464c-b93a-daf047838b26") + Name = "UPI" + }, + new + { + Id = new Guid("a820f240-5e9a-4ae9-9091-8a7aa7720cea"), + Description = "A credit card is a payment card that allows you to borrow funds from a financial institution to pay for goods and services", + IsActive = true, + Name = "Credit card" + }, + new + { + Id = new Guid("95697409-baf6-4f78-86ab-42d93d9569a8"), + Description = "A debit card is a payment card that deducts funds directly from the cardholder's bank account when a purchase is made.", + IsActive = true, + Name = "Debit Card" + }, + new + { + Id = new Guid("f67beee6-6763-4108-922c-03bd86b9178d"), + Description = "When a bill is paid using the amount received in advance from a company.", + IsActive = true, + Name = "Advance Payment" }); }); @@ -3524,6 +3988,42 @@ namespace Marco.Pms.DataAccess.Migrations }); }); + modelBuilder.Entity("Marco.Pms.Model.Master.StatusUpdateLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("char(36)"); + + b.Property("Comment") + .HasColumnType("longtext"); + + b.Property("EntityId") + .HasColumnType("char(36)"); + + b.Property("NextStatusId") + .HasColumnType("char(36)"); + + b.Property("StatusId") + .HasColumnType("char(36)"); + + b.Property("TenantId") + .HasColumnType("char(36)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime(6)"); + + b.Property("UpdatedById") + .HasColumnType("char(36)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.HasIndex("UpdatedById"); + + b.ToTable("StatusUpdateLogs"); + }); + modelBuilder.Entity("Marco.Pms.Model.Master.SubscriptionStatus", b => { b.Property("Id") @@ -5853,6 +6353,39 @@ namespace Marco.Pms.DataAccess.Migrations .IsRequired(); }); + modelBuilder.Entity("Marco.Pms.Model.Expenses.AdvancePaymentTransaction", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Projects.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId"); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CreatedBy"); + + b.Navigation("Employee"); + + b.Navigation("Project"); + + b.Navigation("Tenant"); + }); + modelBuilder.Entity("Marco.Pms.Model.Expenses.BillAttachments", b => { b.HasOne("Marco.Pms.Model.DocumentManager.Document", "Document") @@ -5919,9 +6452,15 @@ namespace Marco.Pms.DataAccess.Migrations .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("Marco.Pms.Model.Master.ExpensesTypeMaster", "ExpensesType") + b.HasOne("Marco.Pms.Model.Master.CurrencyMaster", "Currency") .WithMany() - .HasForeignKey("ExpensesTypeId") + .HasForeignKey("CurrencyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Expenses.Masters.ExpenseCategoryMaster", "ExpenseCategory") + .WithMany() + .HasForeignKey("ExpenseCategoryId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); @@ -5937,6 +6476,10 @@ namespace Marco.Pms.DataAccess.Migrations .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + b.HasOne("Marco.Pms.Model.Expenses.PaymentRequest", "PaymentRequest") + .WithMany() + .HasForeignKey("PaymentRequestId"); + b.HasOne("Marco.Pms.Model.Employees.Employee", "ProcessedBy") .WithMany() .HasForeignKey("ProcessedById"); @@ -5967,12 +6510,16 @@ namespace Marco.Pms.DataAccess.Migrations b.Navigation("CreatedBy"); - b.Navigation("ExpensesType"); + b.Navigation("Currency"); + + b.Navigation("ExpenseCategory"); b.Navigation("PaidBy"); b.Navigation("PaymentMode"); + b.Navigation("PaymentRequest"); + b.Navigation("ProcessedBy"); b.Navigation("Project"); @@ -6030,7 +6577,18 @@ namespace Marco.Pms.DataAccess.Migrations b.Navigation("Tenant"); }); - modelBuilder.Entity("Marco.Pms.Model.Expenses.ExpensesStatusMapping", b => + modelBuilder.Entity("Marco.Pms.Model.Expenses.Masters.ExpenseCategoryMaster", b => + { + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.Masters.ExpensesStatusMapping", b => { b.HasOne("Marco.Pms.Model.Master.ExpensesStatusMaster", "NextStatus") .WithMany() @@ -6049,7 +6607,7 @@ namespace Marco.Pms.DataAccess.Migrations b.Navigation("Status"); }); - modelBuilder.Entity("Marco.Pms.Model.Expenses.StatusPermissionMapping", b => + modelBuilder.Entity("Marco.Pms.Model.Expenses.Masters.StatusPermissionMapping", b => { b.HasOne("Marco.Pms.Model.Entitlements.FeaturePermission", "Permission") .WithMany() @@ -6068,6 +6626,151 @@ namespace Marco.Pms.DataAccess.Migrations b.Navigation("Status"); }); + modelBuilder.Entity("Marco.Pms.Model.Expenses.PaymentRequest", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Master.CurrencyMaster", "Currency") + .WithMany() + .HasForeignKey("CurrencyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Expenses.Masters.ExpenseCategoryMaster", "ExpenseCategory") + .WithMany() + .HasForeignKey("ExpenseCategoryId"); + + b.HasOne("Marco.Pms.Model.Master.ExpensesStatusMaster", "ExpenseStatus") + .WithMany() + .HasForeignKey("ExpenseStatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "PaidBy") + .WithMany() + .HasForeignKey("PaidById"); + + b.HasOne("Marco.Pms.Model.Projects.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId"); + + b.HasOne("Marco.Pms.Model.Expenses.RecurringPayment", "RecurringPayment") + .WithMany() + .HasForeignKey("RecurringPaymentId"); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("Currency"); + + b.Navigation("ExpenseCategory"); + + b.Navigation("ExpenseStatus"); + + b.Navigation("PaidBy"); + + b.Navigation("Project"); + + b.Navigation("RecurringPayment"); + + b.Navigation("Tenant"); + + b.Navigation("UpdatedBy"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.PaymentRequestAttachment", b => + { + b.HasOne("Marco.Pms.Model.DocumentManager.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Expenses.PaymentRequest", "PaymentRequest") + .WithMany() + .HasForeignKey("PaymentRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("PaymentRequest"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Marco.Pms.Model.Expenses.RecurringPayment", b => + { + b.HasOne("Marco.Pms.Model.Employees.Employee", "CreatedBy") + .WithMany() + .HasForeignKey("CreatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Master.CurrencyMaster", "Currency") + .WithMany() + .HasForeignKey("CurrencyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Expenses.Masters.ExpenseCategoryMaster", "ExpenseCategory") + .WithMany() + .HasForeignKey("ExpenseCategoryId"); + + b.HasOne("Marco.Pms.Model.Projects.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId"); + + b.HasOne("Marco.Pms.Model.Expenses.Masters.RecurringPaymentStatus", "Status") + .WithMany() + .HasForeignKey("StatusId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Marco.Pms.Model.Employees.Employee", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById"); + + b.Navigation("CreatedBy"); + + b.Navigation("Currency"); + + b.Navigation("ExpenseCategory"); + + b.Navigation("Project"); + + b.Navigation("Status"); + + b.Navigation("Tenant"); + + b.Navigation("UpdatedBy"); + }); + modelBuilder.Entity("Marco.Pms.Model.Forum.TicketAttachment", b => { b.HasOne("Marco.Pms.Model.Forum.TicketComment", "TicketComment") @@ -6241,7 +6944,7 @@ namespace Marco.Pms.DataAccess.Migrations b.Navigation("ActivityGroup"); }); - modelBuilder.Entity("Marco.Pms.Model.Master.PaymentModeMatser", b => + modelBuilder.Entity("Marco.Pms.Model.Master.ServiceMaster", b => { b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") .WithMany() @@ -6252,7 +6955,7 @@ namespace Marco.Pms.DataAccess.Migrations b.Navigation("Tenant"); }); - modelBuilder.Entity("Marco.Pms.Model.Master.ServiceMaster", b => + modelBuilder.Entity("Marco.Pms.Model.Master.StatusUpdateLog", b => { b.HasOne("Marco.Pms.Model.TenantModels.Tenant", "Tenant") .WithMany() @@ -6260,7 +6963,15 @@ namespace Marco.Pms.DataAccess.Migrations .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + b.HasOne("Marco.Pms.Model.Employees.Employee", "UpdatedBy") + .WithMany() + .HasForeignKey("UpdatedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + b.Navigation("Tenant"); + + b.Navigation("UpdatedBy"); }); modelBuilder.Entity("Marco.Pms.Model.Master.WorkCategoryMaster", b => diff --git a/Marco.Pms.Model/Dtos/Expenses/CreateExpensesDto.cs b/Marco.Pms.Model/Dtos/Expenses/CreateExpensesDto.cs index 53c8170..d7826ad 100644 --- a/Marco.Pms.Model/Dtos/Expenses/CreateExpensesDto.cs +++ b/Marco.Pms.Model/Dtos/Expenses/CreateExpensesDto.cs @@ -5,7 +5,7 @@ namespace Marco.Pms.Model.Dtos.Expenses public class CreateExpensesDto { public required Guid ProjectId { get; set; } - public required Guid ExpensesTypeId { get; set; } + public required Guid ExpenseCategoryId { get; set; } public required Guid PaymentModeId { get; set; } public required Guid PaidById { get; set; } public DateTime TransactionDate { get; set; } = DateTime.Now; @@ -15,6 +15,7 @@ namespace Marco.Pms.Model.Dtos.Expenses public string? GSTNumber { get; set; } public required string SupplerName { get; set; } public required double Amount { get; set; } + public Guid? CurrencyId { get; set; } public int? NoOfPersons { get; set; } = 0; public bool PreApproved { get; set; } = false; public required List BillAttachments { get; set; } diff --git a/Marco.Pms.Model/Dtos/Expenses/CreateRecurringTemplateDto.cs b/Marco.Pms.Model/Dtos/Expenses/CreateRecurringTemplateDto.cs new file mode 100644 index 0000000..3ac8cd4 --- /dev/null +++ b/Marco.Pms.Model/Dtos/Expenses/CreateRecurringTemplateDto.cs @@ -0,0 +1,22 @@ +using Marco.Pms.Model.TenantModels; + +namespace Marco.Pms.Model.Dtos.Expenses +{ + public class CreateRecurringTemplateDto + { + public required string Title { get; set; } + public required string Description { get; set; } + public required string Payee { get; set; } + public required string NotifyTo { get; set; } + public required Guid CurrencyId { get; set; } + public required double Amount { get; set; } + public required DateTime StrikeDate { get; set; } + public Guid? ProjectId { get; set; } + public required int PaymentBufferDays { get; set; } + public required int NumberOfIteration { get; set; } + public required Guid ExpenseCategoryId { get; set; } + public required Guid StatusId { get; set; } + public required PLAN_FREQUENCY Frequency { get; set; } + public required bool IsVariable { get; set; } + } +} diff --git a/Marco.Pms.Model/Dtos/Expenses/ExpenseConversionDto.cs b/Marco.Pms.Model/Dtos/Expenses/ExpenseConversionDto.cs new file mode 100644 index 0000000..2eb1aea --- /dev/null +++ b/Marco.Pms.Model/Dtos/Expenses/ExpenseConversionDto.cs @@ -0,0 +1,13 @@ +using Marco.Pms.Model.Utilities; + +namespace Marco.Pms.Model.Dtos.Expenses +{ + public class ExpenseConversionDto + { + public required Guid PaymentRequestId { get; set; } + public required Guid PaymentModeId { get; set; } + public string? Location { get; set; } + public string? GSTNumber { get; set; } + public List? BillAttachments { get; set; } + } +} diff --git a/Marco.Pms.Model/Dtos/Expenses/ExpenseRecordDto.cs b/Marco.Pms.Model/Dtos/Expenses/ExpenseRecordDto.cs index d59c90e..73c9f05 100644 --- a/Marco.Pms.Model/Dtos/Expenses/ExpenseRecordDto.cs +++ b/Marco.Pms.Model/Dtos/Expenses/ExpenseRecordDto.cs @@ -5,6 +5,9 @@ public Guid ExpenseId { get; set; } public Guid StatusId { get; set; } public string? Comment { get; set; } + public double? TDSPercentage { get; set; } + public double? BaseAmount { get; set; } + public double? TaxAmount { get; set; } public string? ReimburseTransactionId { get; set; } public DateTime? ReimburseDate { get; set; } public Guid? ReimburseById { get; set; } diff --git a/Marco.Pms.Model/Dtos/Expenses/Masters/ExpenseCategoryMasterDto.cs b/Marco.Pms.Model/Dtos/Expenses/Masters/ExpenseCategoryMasterDto.cs new file mode 100644 index 0000000..e40c0c5 --- /dev/null +++ b/Marco.Pms.Model/Dtos/Expenses/Masters/ExpenseCategoryMasterDto.cs @@ -0,0 +1,11 @@ +namespace Marco.Pms.Model.Dtos.Expenses.Masters +{ + public class ExpenseCategoryMasterDto + { + public Guid? Id { get; set; } + public required string Name { get; set; } + public required bool NoOfPersonsRequired { get; set; } + public required bool IsAttachmentRequried { get; set; } + public string? Description { get; set; } + } +} diff --git a/Marco.Pms.Model/Dtos/Expenses/PaymentRequestConversionDto.cs b/Marco.Pms.Model/Dtos/Expenses/PaymentRequestConversionDto.cs new file mode 100644 index 0000000..9949e23 --- /dev/null +++ b/Marco.Pms.Model/Dtos/Expenses/PaymentRequestConversionDto.cs @@ -0,0 +1,7 @@ +namespace Marco.Pms.Model.Dtos.Expenses +{ + public class PaymentRequestConversionDto + { + public required List RecurringTemplateIds { get; set; } + } +} diff --git a/Marco.Pms.Model/Dtos/Expenses/PaymentRequestDto.cs b/Marco.Pms.Model/Dtos/Expenses/PaymentRequestDto.cs new file mode 100644 index 0000000..100b333 --- /dev/null +++ b/Marco.Pms.Model/Dtos/Expenses/PaymentRequestDto.cs @@ -0,0 +1,19 @@ +using Marco.Pms.Model.Utilities; + +namespace Marco.Pms.Model.Dtos.Expenses +{ + public class PaymentRequestDto + { + public Guid? Id { get; set; } + public required string Title { get; set; } + public required string Description { get; set; } + public required string Payee { get; set; } + public required Guid CurrencyId { get; set; } + public required double Amount { get; set; } + public required DateTime DueDate { get; set; } + public Guid? ProjectId { get; set; } + public required Guid ExpenseCategoryId { get; set; } + public bool IsAdvancePayment { get; set; } + public List? BillAttachments { get; set; } + } +} diff --git a/Marco.Pms.Model/Dtos/Expenses/PaymentRequestRecordDto.cs b/Marco.Pms.Model/Dtos/Expenses/PaymentRequestRecordDto.cs new file mode 100644 index 0000000..3a3c37e --- /dev/null +++ b/Marco.Pms.Model/Dtos/Expenses/PaymentRequestRecordDto.cs @@ -0,0 +1,15 @@ +namespace Marco.Pms.Model.Dtos.Expenses +{ + public class PaymentRequestRecordDto + { + public Guid PaymentRequestId { get; set; } + public Guid StatusId { get; set; } + public string? Comment { get; set; } + public string? PaidTransactionId { get; set; } + public double? TDSPercentage { get; set; } + public double? BaseAmount { get; set; } + public double? TaxAmount { get; set; } + public DateTime? PaidAt { get; set; } + public Guid? PaidById { get; set; } + } +} diff --git a/Marco.Pms.Model/Dtos/Expenses/UpdateRecurringTemplateDto.cs b/Marco.Pms.Model/Dtos/Expenses/UpdateRecurringTemplateDto.cs new file mode 100644 index 0000000..df56ac9 --- /dev/null +++ b/Marco.Pms.Model/Dtos/Expenses/UpdateRecurringTemplateDto.cs @@ -0,0 +1,22 @@ +using Marco.Pms.Model.TenantModels; + +namespace Marco.Pms.Model.Dtos.Expenses +{ + public class UpdateRecurringTemplateDto + { + public Guid Id { get; set; } + public required string Title { get; set; } + public required string Description { get; set; } + public required string Payee { get; set; } + public required string NotifyTo { get; set; } + public required Guid CurrencyId { get; set; } + public required double Amount { get; set; } + public Guid? ProjectId { get; set; } + public required int PaymentBufferDays { get; set; } + public required int NumberOfIteration { get; set; } + public required Guid ExpenseCategoryId { get; set; } + public required Guid StatusId { get; set; } + public required PLAN_FREQUENCY Frequency { get; set; } + public required bool IsVariable { get; set; } + } +} diff --git a/Marco.Pms.Model/Entitlements/PermissionsMaster.cs b/Marco.Pms.Model/Entitlements/PermissionsMaster.cs index 8ca11b5..80246e3 100644 --- a/Marco.Pms.Model/Entitlements/PermissionsMaster.cs +++ b/Marco.Pms.Model/Entitlements/PermissionsMaster.cs @@ -47,6 +47,10 @@ public static readonly Guid DownloadDocument = Guid.Parse("404373d0-860f-490e-a575-1c086ffbce1d"); public static readonly Guid VerifyDocument = Guid.Parse("13a1f30f-38d1-41bf-8e7a-b75189aab8e0"); + public static readonly Guid ManageRecurring = Guid.Parse("6382ea8b-aff2-4cd2-a48f-a652b35825d8"); + public static readonly Guid ViewAllRecurring = Guid.Parse("7ddf2fba-c44d-4fe3-b4ec-690ff70be2e3"); + public static readonly Guid ViewSelfRecurring = Guid.Parse("e5d21efe-573d-4a16-a0f8-414d3e442e78"); + public static readonly Guid CollectionAdmin = Guid.Parse("dbf17591-09fe-4c93-9e1a-12db8f5cc5de"); public static readonly Guid ViewCollection = Guid.Parse("c8d7eea5-4033-4aad-9ebe-76de49896830"); public static readonly Guid CreateCollection = Guid.Parse("b93141fd-dbd3-4051-8f57-bf25d18e3555"); diff --git a/Marco.Pms.Model/Expenses/AdvancePaymentTransaction.cs b/Marco.Pms.Model/Expenses/AdvancePaymentTransaction.cs new file mode 100644 index 0000000..99675b3 --- /dev/null +++ b/Marco.Pms.Model/Expenses/AdvancePaymentTransaction.cs @@ -0,0 +1,36 @@ +using Marco.Pms.Model.Employees; +using Marco.Pms.Model.Projects; +using Marco.Pms.Model.Utilities; +using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Marco.Pms.Model.Expenses +{ + public class AdvancePaymentTransaction : TenantRelation + { + public Guid Id { get; set; } + public string FinanceUIdPrefix { get; set; } = default!; + public int FinanceUIdPostfix { get; set; } + public string Title { get; set; } = default!; + public Guid? ProjectId { get; set; } + + [ValidateNever] + [ForeignKey("ProjectId")] + public Project? Project { get; set; } + public Guid EmployeeId { get; set; } + + [ValidateNever] + [ForeignKey("EmployeeId")] + public Employee? Employee { get; set; } + public double Amount { get; set; } + public double CurrentBalance { get; set; } + public DateTime PaidAt { get; set; } + public DateTime CreatedAt { get; set; } + public Guid CreatedById { get; set; } + + [ValidateNever] + [ForeignKey("CreatedById")] + public Employee? CreatedBy { get; set; } + public bool IsActive { get; set; } + } +} diff --git a/Marco.Pms.Model/Expenses/Expenses.cs b/Marco.Pms.Model/Expenses/Expenses.cs index 59d9e2e..4c55c80 100644 --- a/Marco.Pms.Model/Expenses/Expenses.cs +++ b/Marco.Pms.Model/Expenses/Expenses.cs @@ -1,4 +1,5 @@ using Marco.Pms.Model.Employees; +using Marco.Pms.Model.Expenses.Masters; using Marco.Pms.Model.Master; using Marco.Pms.Model.Projects; using Marco.Pms.Model.Utilities; @@ -10,6 +11,8 @@ namespace Marco.Pms.Model.Expenses public class Expenses : TenantRelation { public Guid Id { get; set; } + public string UIDPrefix { get; set; } = default!; + public int UIDPostfix { get; set; } public Guid ProjectId { get; set; } [ValidateNever] @@ -17,9 +20,15 @@ namespace Marco.Pms.Model.Expenses public Project? Project { get; set; } public Guid ExpensesTypeId { get; set; } + //[ValidateNever] + //[ForeignKey("ExpensesTypeId")] + //public ExpensesTypeMaster? ExpensesType { get; set; } + + public Guid ExpenseCategoryId { get; set; } + [ValidateNever] - [ForeignKey("ExpensesTypeId")] - public ExpensesTypeMaster? ExpensesType { get; set; } + [ForeignKey("ExpenseCategoryId")] + public ExpenseCategoryMaster? ExpenseCategory { get; set; } public Guid PaymentModeId { get; set; } [ValidateNever] @@ -54,12 +63,25 @@ namespace Marco.Pms.Model.Expenses public DateTime CreatedAt { get; set; } public string? TransactionId { get; set; } public string Description { get; set; } = string.Empty; - public string ExpenseUId { get; set; } = string.Empty; + public string? ExpenseUId { get; set; } public string? Location { get; set; } public string? GSTNumber { get; set; } public string SupplerName { get; set; } = string.Empty; + public Guid CurrencyId { get; set; } + + [ValidateNever] + [ForeignKey("CurrencyId")] + public CurrencyMaster? Currency { get; set; } public double Amount { get; set; } + public double? BaseAmount { get; set; } + public double? TaxAmount { get; set; } + public double? TDSPercentage { get; set; } public int? NoOfPersons { get; set; } + public Guid? PaymentRequestId { get; set; } + + [ValidateNever] + [ForeignKey("PaymentRequestId")] + public PaymentRequest? PaymentRequest { get; set; } public Guid StatusId { get; set; } [ValidateNever] diff --git a/Marco.Pms.Model/Expenses/Masters/ExpenseCategoryMaster.cs b/Marco.Pms.Model/Expenses/Masters/ExpenseCategoryMaster.cs new file mode 100644 index 0000000..34d77b8 --- /dev/null +++ b/Marco.Pms.Model/Expenses/Masters/ExpenseCategoryMaster.cs @@ -0,0 +1,14 @@ +using Marco.Pms.Model.Utilities; + +namespace Marco.Pms.Model.Expenses.Masters +{ + public class ExpenseCategoryMaster : TenantRelation + { + public Guid Id { get; set; } + public string Name { get; set; } = string.Empty; + public bool NoOfPersonsRequired { get; set; } + public string Description { get; set; } = string.Empty; + public bool IsActive { get; set; } = true; + public bool IsAttachmentRequried { get; set; } = true; + } +} diff --git a/Marco.Pms.Model/Expenses/ExpensesStatusMapping.cs b/Marco.Pms.Model/Expenses/Masters/ExpensesStatusMapping.cs similarity index 92% rename from Marco.Pms.Model/Expenses/ExpensesStatusMapping.cs rename to Marco.Pms.Model/Expenses/Masters/ExpensesStatusMapping.cs index 902927d..eced470 100644 --- a/Marco.Pms.Model/Expenses/ExpensesStatusMapping.cs +++ b/Marco.Pms.Model/Expenses/Masters/ExpensesStatusMapping.cs @@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using System.ComponentModel.DataAnnotations.Schema; -namespace Marco.Pms.Model.Expenses +namespace Marco.Pms.Model.Expenses.Masters { public class ExpensesStatusMapping { diff --git a/Marco.Pms.Model/Expenses/Masters/RecurringPaymentStatus.cs b/Marco.Pms.Model/Expenses/Masters/RecurringPaymentStatus.cs new file mode 100644 index 0000000..fadf5d1 --- /dev/null +++ b/Marco.Pms.Model/Expenses/Masters/RecurringPaymentStatus.cs @@ -0,0 +1,8 @@ +namespace Marco.Pms.Model.Expenses.Masters +{ + public class RecurringPaymentStatus + { + public Guid Id { get; set; } + public string Name { get; set; } = string.Empty; + } +} diff --git a/Marco.Pms.Model/Expenses/StatusPermissionMapping.cs b/Marco.Pms.Model/Expenses/Masters/StatusPermissionMapping.cs similarity index 93% rename from Marco.Pms.Model/Expenses/StatusPermissionMapping.cs rename to Marco.Pms.Model/Expenses/Masters/StatusPermissionMapping.cs index 2fe9334..ec32775 100644 --- a/Marco.Pms.Model/Expenses/StatusPermissionMapping.cs +++ b/Marco.Pms.Model/Expenses/Masters/StatusPermissionMapping.cs @@ -3,7 +3,7 @@ using Marco.Pms.Model.Master; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using System.ComponentModel.DataAnnotations.Schema; -namespace Marco.Pms.Model.Expenses +namespace Marco.Pms.Model.Expenses.Masters { public class StatusPermissionMapping { diff --git a/Marco.Pms.Model/Expenses/PaymentRequest.cs b/Marco.Pms.Model/Expenses/PaymentRequest.cs new file mode 100644 index 0000000..6578666 --- /dev/null +++ b/Marco.Pms.Model/Expenses/PaymentRequest.cs @@ -0,0 +1,72 @@ +using Marco.Pms.Model.Employees; +using Marco.Pms.Model.Expenses.Masters; +using Marco.Pms.Model.Master; +using Marco.Pms.Model.Projects; +using Marco.Pms.Model.Utilities; +using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Marco.Pms.Model.Expenses +{ + public class PaymentRequest : TenantRelation + { + public Guid Id { get; set; } + public string Title { get; set; } = default!; + public string Description { get; set; } = default!; + public string UIDPrefix { get; set; } = default!; + public int UIDPostfix { get; set; } + public string Payee { get; set; } = default!; + public bool IsAdvancePayment { get; set; } + public Guid CurrencyId { get; set; } + + [ValidateNever] + [ForeignKey("CurrencyId")] + public CurrencyMaster? Currency { get; set; } + public double Amount { get; set; } + public double? BaseAmount { get; set; } + public double? TaxAmount { get; set; } + public double? TDSPercentage { get; set; } + public DateTime DueDate { get; set; } + public Guid? ProjectId { get; set; } + + [ValidateNever] + [ForeignKey("ProjectId")] + public Project? Project { get; set; } + public Guid? RecurringPaymentId { get; set; } + + [ValidateNever] + [ForeignKey("RecurringPaymentId")] + public RecurringPayment? RecurringPayment { get; set; } + public Guid? ExpenseCategoryId { get; set; } + + [ValidateNever] + [ForeignKey("ExpenseCategoryId")] + public ExpenseCategoryMaster? ExpenseCategory { get; set; } + public Guid ExpenseStatusId { get; set; } + + [ValidateNever] + [ForeignKey("ExpenseStatusId")] + public ExpensesStatusMaster? ExpenseStatus { get; set; } + public string? PaidTransactionId { get; set; } + public DateTime? PaidAt { get; set; } + public Guid? PaidById { get; set; } + + [ValidateNever] + [ForeignKey("PaidById")] + public Employee? PaidBy { get; set; } + public bool IsExpenseCreated { get; set; } = false; + public bool IsActive { get; set; } + public DateTime CreatedAt { get; set; } + public Guid CreatedById { get; set; } + + [ValidateNever] + [ForeignKey("CreatedById")] + public Employee? CreatedBy { get; set; } + public DateTime? UpdatedAt { get; set; } + public Guid? UpdatedById { get; set; } + + [ValidateNever] + [ForeignKey("UpdatedById")] + public Employee? UpdatedBy { get; set; } + } +} diff --git a/Marco.Pms.Model/Expenses/PaymentRequestAttachment.cs b/Marco.Pms.Model/Expenses/PaymentRequestAttachment.cs new file mode 100644 index 0000000..4f7c01e --- /dev/null +++ b/Marco.Pms.Model/Expenses/PaymentRequestAttachment.cs @@ -0,0 +1,22 @@ +using Marco.Pms.Model.DocumentManager; +using Marco.Pms.Model.Utilities; +using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Marco.Pms.Model.Expenses +{ + public class PaymentRequestAttachment : TenantRelation + { + public Guid Id { get; set; } + public Guid PaymentRequestId { get; set; } + + [ValidateNever] + [ForeignKey("PaymentRequestId")] + public PaymentRequest? PaymentRequest { get; set; } + public Guid DocumentId { get; set; } + + [ValidateNever] + [ForeignKey("DocumentId")] + public Document? Document { get; set; } + } +} diff --git a/Marco.Pms.Model/Expenses/RecurringPayment.cs b/Marco.Pms.Model/Expenses/RecurringPayment.cs new file mode 100644 index 0000000..b6a0155 --- /dev/null +++ b/Marco.Pms.Model/Expenses/RecurringPayment.cs @@ -0,0 +1,62 @@ +using Marco.Pms.Model.Employees; +using Marco.Pms.Model.Expenses.Masters; +using Marco.Pms.Model.Master; +using Marco.Pms.Model.Projects; +using Marco.Pms.Model.TenantModels; +using Marco.Pms.Model.Utilities; +using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Marco.Pms.Model.Expenses +{ + public class RecurringPayment : TenantRelation + { + public Guid Id { get; set; } + public string Title { get; set; } = default!; + public string Description { get; set; } = default!; + public string UIDPrefix { get; set; } = default!; + public int UIDPostfix { get; set; } + public string Payee { get; set; } = default!; + public string NotifyTo { get; set; } = default!; + public Guid CurrencyId { get; set; } + + [ValidateNever] + [ForeignKey("CurrencyId")] + public CurrencyMaster? Currency { get; set; } + public double Amount { get; set; } + public DateTime StrikeDate { get; set; } + public DateTime? LatestPRGeneratedAt { get; set; } + public Guid? ProjectId { get; set; } + + [ValidateNever] + [ForeignKey("ProjectId")] + public Project? Project { get; set; } + public int PaymentBufferDays { get; set; } + public int NumberOfIteration { get; set; } + public Guid? ExpenseCategoryId { get; set; } + + [ValidateNever] + [ForeignKey("ExpenseCategoryId")] + public ExpenseCategoryMaster? ExpenseCategory { get; set; } + public Guid StatusId { get; set; } + + [ValidateNever] + [ForeignKey("StatusId")] + public RecurringPaymentStatus? Status { get; set; } + public PLAN_FREQUENCY Frequency { get; set; } + public bool IsVariable { get; set; } + public bool IsActive { get; set; } + public DateTime CreatedAt { get; set; } + public Guid CreatedById { get; set; } + + [ValidateNever] + [ForeignKey("CreatedById")] + public Employee? CreatedBy { get; set; } + public DateTime? UpdatedAt { get; set; } + public Guid? UpdatedById { get; set; } + + [ValidateNever] + [ForeignKey("UpdatedById")] + public Employee? UpdatedBy { get; set; } + } +} diff --git a/Marco.Pms.Model/Filters/ExpensesFilter.cs b/Marco.Pms.Model/Filters/ExpensesFilter.cs index bd24ab8..98faefa 100644 --- a/Marco.Pms.Model/Filters/ExpensesFilter.cs +++ b/Marco.Pms.Model/Filters/ExpensesFilter.cs @@ -6,6 +6,7 @@ public List? StatusIds { get; set; } public List? CreatedByIds { get; set; } public List? PaidById { get; set; } + public List? ExpenseCategoryIds { get; set; } public bool IsTransactionDate { get; set; } = false; public DateTime? StartDate { get; set; } public DateTime? EndDate { get; set; } diff --git a/Marco.Pms.Model/Filters/PaymentRequestFilter.cs b/Marco.Pms.Model/Filters/PaymentRequestFilter.cs new file mode 100644 index 0000000..12b2bf6 --- /dev/null +++ b/Marco.Pms.Model/Filters/PaymentRequestFilter.cs @@ -0,0 +1,14 @@ +namespace Marco.Pms.Model.Filters +{ + public class PaymentRequestFilter + { + public List? ProjectIds { get; set; } + public List? StatusIds { get; set; } + public List? CreatedByIds { get; set; } + public List? CurrencyIds { get; set; } + public List? ExpenseCategoryIds { get; set; } + public List? Payees { get; set; } + public DateTime? StartDate { get; set; } + public DateTime? EndDate { get; set; } + } +} diff --git a/Marco.Pms.Model/Filters/RecurringPaymentFilter.cs b/Marco.Pms.Model/Filters/RecurringPaymentFilter.cs new file mode 100644 index 0000000..3c6a6c9 --- /dev/null +++ b/Marco.Pms.Model/Filters/RecurringPaymentFilter.cs @@ -0,0 +1,14 @@ +namespace Marco.Pms.Model.Filters +{ + public class RecurringPaymentFilter + { + public List? ProjectIds { get; set; } + public List? StatusIds { get; set; } + public List? CreatedByIds { get; set; } + public List? CurrencyIds { get; set; } + public List? ExpenseCategoryIds { get; set; } + public List? Payees { get; set; } + public DateTime? StartDate { get; set; } + public DateTime? EndDate { get; set; } + } +} diff --git a/Marco.Pms.Model/Master/PaymentModeMatser.cs b/Marco.Pms.Model/Master/PaymentModeMatser.cs index e947c55..111772b 100644 --- a/Marco.Pms.Model/Master/PaymentModeMatser.cs +++ b/Marco.Pms.Model/Master/PaymentModeMatser.cs @@ -1,8 +1,6 @@ -using Marco.Pms.Model.Utilities; - -namespace Marco.Pms.Model.Master +namespace Marco.Pms.Model.Master { - public class PaymentModeMatser : TenantRelation + public class PaymentModeMatser { public Guid Id { get; set; } public string Name { get; set; } = string.Empty; diff --git a/Marco.Pms.Model/Master/StatusUpdateLog.cs b/Marco.Pms.Model/Master/StatusUpdateLog.cs new file mode 100644 index 0000000..dc5354c --- /dev/null +++ b/Marco.Pms.Model/Master/StatusUpdateLog.cs @@ -0,0 +1,22 @@ +using Marco.Pms.Model.Employees; +using Marco.Pms.Model.Utilities; +using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Marco.Pms.Model.Master +{ + public class StatusUpdateLog : TenantRelation + { + public Guid Id { get; set; } + public Guid StatusId { get; set; } + public Guid NextStatusId { get; set; } + public Guid EntityId { get; set; } + public string? Comment { get; set; } + public DateTime UpdatedAt { get; set; } + public Guid UpdatedById { get; set; } + + [ValidateNever] + [ForeignKey("UpdatedById")] + public Employee? UpdatedBy { get; set; } + } +} diff --git a/Marco.Pms.Model/MongoDBModels/DocumentMongoDB.cs b/Marco.Pms.Model/MongoDBModels/DocumentMongoDB.cs index d65af2a..e91e991 100644 --- a/Marco.Pms.Model/MongoDBModels/DocumentMongoDB.cs +++ b/Marco.Pms.Model/MongoDBModels/DocumentMongoDB.cs @@ -7,5 +7,6 @@ public string ContentType { get; set; } = string.Empty; public string S3Key { get; set; } = string.Empty; public string ThumbS3Key { get; set; } = string.Empty; + public long FileSize { get; set; } } } diff --git a/Marco.Pms.Model/MongoDBModels/Expenses/ExpenseDetailsMongoDB.cs b/Marco.Pms.Model/MongoDBModels/Expenses/ExpenseDetailsMongoDB.cs index ed9d053..93b63ba 100644 --- a/Marco.Pms.Model/MongoDBModels/Expenses/ExpenseDetailsMongoDB.cs +++ b/Marco.Pms.Model/MongoDBModels/Expenses/ExpenseDetailsMongoDB.cs @@ -1,4 +1,5 @@ -using Marco.Pms.Model.MongoDBModels.Employees; +using Marco.Pms.Model.Master; +using Marco.Pms.Model.MongoDBModels.Employees; using Marco.Pms.Model.MongoDBModels.Masters; using Marco.Pms.Model.MongoDBModels.Project; @@ -8,7 +9,7 @@ namespace Marco.Pms.Model.MongoDBModels.Expenses { public string Id { get; set; } = string.Empty; public ProjectBasicMongoDB Project { get; set; } = new ProjectBasicMongoDB(); - public ExpensesTypeMasterMongoDB ExpensesType { get; set; } = new ExpensesTypeMasterMongoDB(); + public ExpenseCategoryMasterMongoDB ExpenseCategory { get; set; } = new ExpenseCategoryMasterMongoDB(); public PaymentModeMatserMongoDB PaymentMode { get; set; } = new PaymentModeMatserMongoDB(); public BasicEmployeeMongoDB PaidBy { get; set; } = new BasicEmployeeMongoDB(); public BasicEmployeeMongoDB CreatedBy { get; set; } = new BasicEmployeeMongoDB(); @@ -19,8 +20,12 @@ namespace Marco.Pms.Model.MongoDBModels.Expenses public DateTime CreatedAt { get; set; } public DateTime ExpireAt { get; set; } = DateTime.UtcNow.Date.AddDays(1); public string SupplerName { get; set; } = string.Empty; - public string? ExpenseUId { get; set; } public double Amount { get; set; } + public CurrencyMaster? Currency { get; set; } + public double? BaseAmount { get; set; } + public double? TaxAmount { get; set; } + public string? PaymentRequestUID { get; set; } + public string? ExpenseUId { get; set; } public ExpensesStatusMasterMongoDB Status { get; set; } = new ExpensesStatusMasterMongoDB(); public List NextStatus { get; set; } = new List(); public bool PreApproved { get; set; } = false; diff --git a/Marco.Pms.Model/MongoDBModels/Masters/ExpenseCategoryMasterMongoDB.cs b/Marco.Pms.Model/MongoDBModels/Masters/ExpenseCategoryMasterMongoDB.cs new file mode 100644 index 0000000..88cc161 --- /dev/null +++ b/Marco.Pms.Model/MongoDBModels/Masters/ExpenseCategoryMasterMongoDB.cs @@ -0,0 +1,11 @@ +namespace Marco.Pms.Model.MongoDBModels.Masters +{ + public class ExpenseCategoryMasterMongoDB + { + public string Id { get; set; } = string.Empty; + public string Name { get; set; } = string.Empty; + public bool NoOfPersonsRequired { get; set; } + public string Description { get; set; } = string.Empty; + public string TenantId { get; set; } = string.Empty; + } +} diff --git a/Marco.Pms.Model/TenantModels/SubscriptionPlan.cs b/Marco.Pms.Model/TenantModels/SubscriptionPlan.cs index 4bdf838..3016e4c 100644 --- a/Marco.Pms.Model/TenantModels/SubscriptionPlan.cs +++ b/Marco.Pms.Model/TenantModels/SubscriptionPlan.cs @@ -10,6 +10,6 @@ public enum PLAN_FREQUENCY { - MONTHLY = 0, QUARTERLY = 1, HALF_YEARLY = 2, YEARLY = 3 + MONTHLY = 0, QUARTERLY = 1, HALF_YEARLY = 2, YEARLY = 3, DAILY = 4, WEEKLY = 5 } } diff --git a/Marco.Pms.Model/ViewModels/Expenses/AdvancePaymentTransactionVM.cs b/Marco.Pms.Model/ViewModels/Expenses/AdvancePaymentTransactionVM.cs new file mode 100644 index 0000000..32425bf --- /dev/null +++ b/Marco.Pms.Model/ViewModels/Expenses/AdvancePaymentTransactionVM.cs @@ -0,0 +1,21 @@ +using Marco.Pms.Model.ViewModels.Activities; +using Marco.Pms.Model.ViewModels.Projects; + +namespace Marco.Pms.Model.ViewModels.Expenses +{ + public class AdvancePaymentTransactionVM + { + public Guid Id { get; set; } + public string? FinanceUId { get; set; } + public string? Title { get; set; } + public BasicProjectVM? Project { get; set; } + public BasicEmployeeVM? Employee { get; set; } + public double Amount { get; set; } + public double CurrentBalance { get; set; } + public DateTime PaidAt { get; set; } + public DateTime CreatedAt { get; set; } + public BasicEmployeeVM? CreatedBy { get; set; } + public bool IsActive { get; set; } + + } +} diff --git a/Marco.Pms.Model/ViewModels/Expenses/BasicPaymentRequestVM.cs b/Marco.Pms.Model/ViewModels/Expenses/BasicPaymentRequestVM.cs new file mode 100644 index 0000000..6c39e4d --- /dev/null +++ b/Marco.Pms.Model/ViewModels/Expenses/BasicPaymentRequestVM.cs @@ -0,0 +1,9 @@ +namespace Marco.Pms.Model.ViewModels.Expenses +{ + public class BasicPaymentRequestVM + { + public Guid Id { get; set; } + public string? PaymentRequestUID { get; set; } + public double Amount { get; set; } + } +} diff --git a/Marco.Pms.Model/ViewModels/Expenses/BasicRecurringPaymentVM.cs b/Marco.Pms.Model/ViewModels/Expenses/BasicRecurringPaymentVM.cs new file mode 100644 index 0000000..4a1bba1 --- /dev/null +++ b/Marco.Pms.Model/ViewModels/Expenses/BasicRecurringPaymentVM.cs @@ -0,0 +1,10 @@ +namespace Marco.Pms.Model.ViewModels.Expenses +{ + public class BasicRecurringPaymentVM + { + public Guid Id { get; set; } + public string? RecurringPaymentUID { get; set; } + public double Amount { get; set; } + public bool IsVariable { get; set; } + } +} diff --git a/Marco.Pms.Model/ViewModels/Expenses/ExpenseList.cs b/Marco.Pms.Model/ViewModels/Expenses/ExpenseList.cs index e6ed098..a7efbe1 100644 --- a/Marco.Pms.Model/ViewModels/Expenses/ExpenseList.cs +++ b/Marco.Pms.Model/ViewModels/Expenses/ExpenseList.cs @@ -1,4 +1,6 @@ -using Marco.Pms.Model.ViewModels.Activities; +using Marco.Pms.Model.Master; +using Marco.Pms.Model.ViewModels.Activities; +using Marco.Pms.Model.ViewModels.Expenses.Masters; using Marco.Pms.Model.ViewModels.Master; using Marco.Pms.Model.ViewModels.Projects; @@ -8,20 +10,21 @@ namespace Marco.Pms.Model.ViewModels.Expanses { public Guid Id { get; set; } public ProjectInfoVM? Project { get; set; } - public ExpensesTypeMasterVM? ExpensesType { get; set; } + public ExpenseCategoryMasterVM? ExpenseCategory { get; set; } public PaymentModeMatserVM? PaymentMode { get; set; } public BasicEmployeeVM? PaidBy { get; set; } public BasicEmployeeVM? CreatedBy { get; set; } - //public BasicEmployeeVM? ReviewedBy { get; set; } - //public BasicEmployeeVM? ApprovedBy { get; set; } - //public BasicEmployeeVM? ProcessedBy { get; set; } public DateTime TransactionDate { get; set; } public DateTime CreatedAt { get; set; } public string SupplerName { get; set; } = string.Empty; public string? ExpenseUId { get; set; } + public string? PaymentRequestUID { get; set; } public string Description { get; set; } = string.Empty; public string TransactionId { get; set; } = string.Empty; public double Amount { get; set; } + public CurrencyMaster? Currency { get; set; } + public double? BaseAmount { get; set; } + public double? TaxAmount { get; set; } public ExpensesStatusMasterVM? Status { get; set; } public List? NextStatus { get; set; } public bool PreApproved { get; set; } = false; diff --git a/Marco.Pms.Model/ViewModels/Expenses/Masters/ExpenseCategoryMasterVM.cs b/Marco.Pms.Model/ViewModels/Expenses/Masters/ExpenseCategoryMasterVM.cs new file mode 100644 index 0000000..482ac11 --- /dev/null +++ b/Marco.Pms.Model/ViewModels/Expenses/Masters/ExpenseCategoryMasterVM.cs @@ -0,0 +1,11 @@ +namespace Marco.Pms.Model.ViewModels.Expenses.Masters +{ + public class ExpenseCategoryMasterVM + { + public Guid Id { get; set; } + public string Name { get; set; } = string.Empty; + public bool NoOfPersonsRequired { get; set; } + public bool IsAttachmentRequried { get; set; } + public string Description { get; set; } = string.Empty; + } +} diff --git a/Marco.Pms.Model/ViewModels/Expenses/PaymentRequestAttachmentVM.cs b/Marco.Pms.Model/ViewModels/Expenses/PaymentRequestAttachmentVM.cs new file mode 100644 index 0000000..a336473 --- /dev/null +++ b/Marco.Pms.Model/ViewModels/Expenses/PaymentRequestAttachmentVM.cs @@ -0,0 +1,12 @@ +namespace Marco.Pms.Model.ViewModels.Expenses +{ + public class PaymentRequestAttachmentVM + { + public Guid Id { get; set; } + public string? FileName { get; set; } + public string? Url { get; set; } + public string? ThumbUrl { get; set; } + public long FileSize { get; set; } + public string? ContentType { get; set; } + } +} diff --git a/Marco.Pms.Model/ViewModels/Expenses/PaymentRequestDetailsVM.cs b/Marco.Pms.Model/ViewModels/Expenses/PaymentRequestDetailsVM.cs new file mode 100644 index 0000000..cf994e5 --- /dev/null +++ b/Marco.Pms.Model/ViewModels/Expenses/PaymentRequestDetailsVM.cs @@ -0,0 +1,39 @@ +using Marco.Pms.Model.Master; +using Marco.Pms.Model.ViewModels.Activities; +using Marco.Pms.Model.ViewModels.Expenses.Masters; +using Marco.Pms.Model.ViewModels.Master; +using Marco.Pms.Model.ViewModels.Projects; + +namespace Marco.Pms.Model.ViewModels.Expenses +{ + public class PaymentRequestDetailsVM + { + public Guid Id { get; set; } + public string? Title { get; set; } + public string? Description { get; set; } + public string? PaymentRequestUID { get; set; } + public string? Payee { get; set; } + public CurrencyMaster? Currency { get; set; } + public double Amount { get; set; } + public double? BaseAmount { get; set; } + public double? TaxAmount { get; set; } + public DateTime DueDate { get; set; } + public BasicProjectVM? Project { get; set; } + public BasicRecurringPaymentVM? RecurringPayment { get; set; } + public ExpenseCategoryMasterVM? ExpenseCategory { get; set; } + public ExpensesStatusMasterVM? ExpenseStatus { get; set; } + public string? PaidTransactionId { get; set; } + public DateTime? PaidAt { get; set; } + public BasicEmployeeVM? PaidBy { get; set; } + public bool IsAdvancePayment { get; set; } + public DateTime CreatedAt { get; set; } + public BasicEmployeeVM? CreatedBy { get; set; } + public DateTime UpdatedAt { get; set; } + public BasicEmployeeVM? UpdatedBy { get; set; } + public List? NextStatus { get; set; } + public List? UpdateLogs { get; set; } + public List? Attachments { get; set; } + public bool IsActive { get; set; } + public bool IsExpenseCreated { get; set; } + } +} diff --git a/Marco.Pms.Model/ViewModels/Expenses/PaymentRequestUpdateLog.cs b/Marco.Pms.Model/ViewModels/Expenses/PaymentRequestUpdateLog.cs new file mode 100644 index 0000000..0589e30 --- /dev/null +++ b/Marco.Pms.Model/ViewModels/Expenses/PaymentRequestUpdateLog.cs @@ -0,0 +1,15 @@ +using Marco.Pms.Model.ViewModels.Activities; +using Marco.Pms.Model.ViewModels.Master; + +namespace Marco.Pms.Model.ViewModels.Expenses +{ + public class PaymentRequestUpdateLog + { + public Guid Id { get; set; } + public ExpensesStatusMasterVM? Status { get; set; } + public ExpensesStatusMasterVM? NextStatus { get; set; } + public string? Comment { get; set; } + public DateTime UpdatedAt { get; set; } + public BasicEmployeeVM? UpdatedBy { get; set; } + } +} diff --git a/Marco.Pms.Model/ViewModels/Expenses/PaymentRequestVM.cs b/Marco.Pms.Model/ViewModels/Expenses/PaymentRequestVM.cs new file mode 100644 index 0000000..666324e --- /dev/null +++ b/Marco.Pms.Model/ViewModels/Expenses/PaymentRequestVM.cs @@ -0,0 +1,29 @@ +using Marco.Pms.Model.Master; +using Marco.Pms.Model.ViewModels.Activities; +using Marco.Pms.Model.ViewModels.Expenses.Masters; +using Marco.Pms.Model.ViewModels.Master; +using Marco.Pms.Model.ViewModels.Projects; + +namespace Marco.Pms.Model.ViewModels.Expenses +{ + public class PaymentRequestVM + { + public Guid Id { get; set; } + public string? Title { get; set; } + public string? Description { get; set; } + public BasicRecurringPaymentVM? RecurringPayment { get; set; } + public string? PaymentRequestUID { get; set; } + public string? Payee { get; set; } + public CurrencyMaster? Currency { get; set; } + public double Amount { get; set; } + public DateTime DueDate { get; set; } + public BasicProjectVM? Project { get; set; } + public ExpenseCategoryMasterVM? ExpenseCategory { get; set; } + public ExpensesStatusMasterVM? ExpenseStatus { get; set; } + public bool IsAdvancePayment { get; set; } + public DateTime CreatedAt { get; set; } + public BasicEmployeeVM? CreatedBy { get; set; } + public bool IsActive { get; set; } + public bool IsExpenseCreated { get; set; } + } +} diff --git a/Marco.Pms.Model/ViewModels/Expenses/RecurringPaymentDetailsVM.cs b/Marco.Pms.Model/ViewModels/Expenses/RecurringPaymentDetailsVM.cs new file mode 100644 index 0000000..84bb576 --- /dev/null +++ b/Marco.Pms.Model/ViewModels/Expenses/RecurringPaymentDetailsVM.cs @@ -0,0 +1,36 @@ +using Marco.Pms.Model.Expenses.Masters; +using Marco.Pms.Model.Master; +using Marco.Pms.Model.TenantModels; +using Marco.Pms.Model.ViewModels.Activities; +using Marco.Pms.Model.ViewModels.Expenses.Masters; +using Marco.Pms.Model.ViewModels.Projects; + +namespace Marco.Pms.Model.ViewModels.Expenses +{ + public class RecurringPaymentDetailsVM + { + public Guid Id { get; set; } + public string? Title { get; set; } + public string? Description { get; set; } + public string? RecurringPaymentUID { get; set; } + public string? Payee { get; set; } + public List? NotifyTo { get; set; } + public CurrencyMaster? Currency { get; set; } + public double Amount { get; set; } + public DateTime StrikeDate { get; set; } + public DateTime? LatestPRGeneratedAt { get; set; } + public BasicProjectVM? Project { get; set; } + public int PaymentBufferDays { get; set; } + public int NumberOfIteration { get; set; } + public List? PaymentRequests { get; set; } + public ExpenseCategoryMasterVM? ExpenseCategory { get; set; } + public RecurringPaymentStatus? Status { get; set; } + public PLAN_FREQUENCY Frequency { get; set; } + public bool IsVariable { get; set; } + public bool IsActive { get; set; } + public DateTime CreatedAt { get; set; } + public BasicEmployeeVM? CreatedBy { get; set; } + public DateTime? UpdatedAt { get; set; } + public BasicEmployeeVM? UpdatedBy { get; set; } + } +} diff --git a/Marco.Pms.Model/ViewModels/Expenses/RecurringPaymentVM.cs b/Marco.Pms.Model/ViewModels/Expenses/RecurringPaymentVM.cs new file mode 100644 index 0000000..5017c2f --- /dev/null +++ b/Marco.Pms.Model/ViewModels/Expenses/RecurringPaymentVM.cs @@ -0,0 +1,33 @@ +using Marco.Pms.Model.Expenses.Masters; +using Marco.Pms.Model.Master; +using Marco.Pms.Model.TenantModels; +using Marco.Pms.Model.ViewModels.Activities; +using Marco.Pms.Model.ViewModels.Expenses.Masters; +using Marco.Pms.Model.ViewModels.Projects; + +namespace Marco.Pms.Model.ViewModels.Expenses +{ + public class RecurringPaymentVM + { + public Guid Id { get; set; } + public string? Title { get; set; } + public string? Description { get; set; } + public string? RecurringPaymentUId { get; set; } + public string? Payee { get; set; } + public string? NotifyTo { get; set; } + public CurrencyMaster? Currency { get; set; } + public double Amount { get; set; } + public DateTime StrikeDate { get; set; } + public DateTime? LatestPRGeneratedAt { get; set; } + public BasicProjectVM? Project { get; set; } + public int PaymentBufferDays { get; set; } + public int NumberOfIteration { get; set; } + public ExpenseCategoryMasterVM? ExpenseCategory { get; set; } + public RecurringPaymentStatus? Status { get; set; } + public PLAN_FREQUENCY Frequency { get; set; } + public bool IsVariable { get; set; } + public bool IsActive { get; set; } + public DateTime CreatedAt { get; set; } + public BasicEmployeeVM? CreatedBy { get; set; } + } +} diff --git a/Marco.Pms.Services/Controllers/AuthController.cs b/Marco.Pms.Services/Controllers/AuthController.cs index 43a5703..a9801e3 100644 --- a/Marco.Pms.Services/Controllers/AuthController.cs +++ b/Marco.Pms.Services/Controllers/AuthController.cs @@ -60,7 +60,7 @@ namespace MarcoBMS.Services.Controllers { var user = await _context.ApplicationUsers - .FirstOrDefaultAsync(u => u.Email == loginDto.Username || u.PhoneNumber == loginDto.Username); + .FirstOrDefaultAsync(u => u.Email == loginDto.Username || u.UserName == loginDto.Username); if (user == null) { @@ -104,9 +104,13 @@ namespace MarcoBMS.Services.Controllers return NotFound(ApiResponse.ErrorResponse("Username not found", "Username not found", 404)); } + var tenants = await _context.Tenants.Where(t => t.OrganizationId == emp.OrganizationId).ToListAsync(); + + var tenant = tenants.OrderBy(t => t.OnBoardingDate).FirstOrDefault(); + // Generate tokens - var token = _refreshTokenService.GenerateJwtToken(user.UserName, emp.TenantId ?? Guid.Empty, emp.OrganizationId, _jwtSettings); - var refreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, emp.TenantId.ToString(), emp.OrganizationId, _jwtSettings); + var token = _refreshTokenService.GenerateJwtToken(user.UserName, tenant?.Id ?? Guid.Empty, emp.OrganizationId, _jwtSettings); + var refreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, tenant?.Id.ToString(), emp.OrganizationId, _jwtSettings); _logger.LogInfo("User login successful - UserId: {UserId}", user.Id); return Ok(ApiResponse.SuccessResponse(new @@ -202,12 +206,17 @@ namespace MarcoBMS.Services.Controllers } _logger.LogInfo("Successfully found employee details for tenant ID: {TenantId}", emp.TenantId ?? Guid.Empty); + + var tenants = await _context.Tenants.Where(t => t.OrganizationId == emp.OrganizationId).ToListAsync(); + + var tenant = tenants.OrderBy(t => t.OnBoardingDate).FirstOrDefault(); + // Generate JWT token - var token = _refreshTokenService.GenerateJwtToken(user.UserName, emp.TenantId ?? Guid.Empty, emp.OrganizationId, _jwtSettings); + var token = _refreshTokenService.GenerateJwtToken(user.UserName, tenant?.Id ?? Guid.Empty, emp.OrganizationId, _jwtSettings); // Generate a new refresh token and store it in the database. _logger.LogInfo("Generating and storing Refresh Token for user: {Username}", user.UserName); - var refreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, emp.TenantId.ToString(), emp.OrganizationId, _jwtSettings); + var refreshToken = await _refreshTokenService.CreateRefreshToken(user.Id, tenant?.Id.ToString(), emp.OrganizationId, _jwtSettings); // Fetch MPIN Token var mpinToken = await _context.MPINDetails.FirstOrDefaultAsync(p => p.UserId == Guid.Parse(user.Id)); @@ -265,31 +274,32 @@ namespace MarcoBMS.Services.Controllers } string? tokenType = claimsPrincipal.FindFirst("token_type")?.Value; - string? tokenTenantId = claimsPrincipal.FindFirst("TenantId")?.Value; string? tokenUserId = claimsPrincipal.FindFirst(ClaimTypes.NameIdentifier)?.Value; // Validate essential claims - if (string.IsNullOrWhiteSpace(tokenType) || string.IsNullOrWhiteSpace(tokenTenantId) || string.IsNullOrWhiteSpace(tokenUserId)) + if (string.IsNullOrWhiteSpace(tokenType) || string.IsNullOrWhiteSpace(tokenUserId)) { _logger.LogWarning("MPIN token claims are incomplete"); return Unauthorized(ApiResponse.ErrorResponse("Invalid token claims", "MPIN token does not match your identity", 401)); } - Guid tenantId = Guid.Parse(tokenTenantId); - // Fetch employee by ID and tenant var requestEmployee = await _context.Employees .Include(e => e.ApplicationUser) - .FirstOrDefaultAsync(e => e.Id == verifyMPIN.EmployeeId && e.TenantId == tenantId && e.ApplicationUserId == tokenUserId && e.IsActive); + .FirstOrDefaultAsync(e => e.Id == verifyMPIN.EmployeeId && e.HasApplicationAccess && e.ApplicationUserId == tokenUserId && e.IsActive); if (requestEmployee == null || string.IsNullOrWhiteSpace(requestEmployee.ApplicationUserId)) { _logger.LogWarning("Employee not found or invalid for verification - EmployeeId: {EmployeeId}", verifyMPIN.EmployeeId); return BadRequest(ApiResponse.ErrorResponse("Invalid request", "Provided invalid employee information", 400)); } + var tenants = await _context.Tenants.Where(t => t.OrganizationId == requestEmployee.OrganizationId).ToListAsync(); + + var tenant = tenants.OrderBy(t => t.OnBoardingDate).FirstOrDefault(); + Guid tenantId = tenant?.Id ?? Guid.Empty; // Validate that the token belongs to the same employee making the request - if (requestEmployee.ApplicationUserId != tokenUserId || tokenType != "mpin") + if (requestEmployee.ApplicationUserId != tokenUserId || tokenType != "mpin" || tenantId == Guid.Empty) { _logger.LogWarning("Token identity does not match employee info - EmployeeId: {EmployeeId}", requestEmployee.Id); return Unauthorized(ApiResponse.ErrorResponse("Unauthorized", "MPIN token does not match your identity", 401)); @@ -402,7 +412,9 @@ namespace MarcoBMS.Services.Controllers //var accessToken = _refreshTokenService.GenerateJwtTokenWithOrganization(requestEmployee.ApplicationUser?.UserName, requestEmployee.OrganizationId, _jwtSettings); //var refreshToken = await _refreshTokenService.CreateRefreshTokenWithOrganization(requestEmployee.ApplicationUserId, requestEmployee.OrganizationId, _jwtSettings); - var tenant = await _context.Tenants.FirstOrDefaultAsync(t => t.OrganizationId == requestEmployee.OrganizationId); + var tenants = await _context.Tenants.Where(t => t.OrganizationId == requestEmployee.OrganizationId).ToListAsync(); + + var tenant = tenants.OrderBy(t => t.OnBoardingDate).FirstOrDefault(); var accessToken = _refreshTokenService.GenerateJwtToken(requestEmployee.ApplicationUser?.UserName, tenant?.Id ?? Guid.Empty, requestEmployee.OrganizationId, _jwtSettings); diff --git a/Marco.Pms.Services/Controllers/DashboardController.cs b/Marco.Pms.Services/Controllers/DashboardController.cs index 0afd219..891fcbe 100644 --- a/Marco.Pms.Services/Controllers/DashboardController.cs +++ b/Marco.Pms.Services/Controllers/DashboardController.cs @@ -772,7 +772,7 @@ namespace Marco.Pms.Services.Controllers baseQuery = baseQuery.Where(e => e.ProjectId == projectId); if (categoryId.HasValue) - baseQuery = baseQuery.Where(e => e.ExpensesTypeId == categoryId); + baseQuery = baseQuery.Where(e => e.ExpenseCategoryId == categoryId); // Single server-side group/aggregate by project var report = await baseQuery @@ -851,10 +851,10 @@ namespace Marco.Pms.Services.Controllers // Project to a minimal shape before grouping to avoid loading navigation graphs // Group by expense type name; adjust to the correct key if ExpensesCategory is an enum or navigation var query = baseQuery - .Where(e => e.ExpensesType != null) + .Where(e => e.ExpenseCategory != null) .Select(e => new { - ExpenseTypeName = e.ExpensesType!.Name, // If enum, use e.ExpensesCategory.ToString() + ExpenseTypeName = e.ExpenseCategory!.Name, // If enum, use e.ExpensesCategory.ToString() Amount = e.Amount, StatusId = e.StatusId }) diff --git a/Marco.Pms.Services/Controllers/ExpenseController.cs b/Marco.Pms.Services/Controllers/ExpenseController.cs index 36b0f74..60d9e56 100644 --- a/Marco.Pms.Services/Controllers/ExpenseController.cs +++ b/Marco.Pms.Services/Controllers/ExpenseController.cs @@ -1,5 +1,4 @@ using Marco.Pms.Model.Dtos.Expenses; -using Marco.Pms.Model.Utilities; using Marco.Pms.Services.Service.ServiceInterfaces; using MarcoBMS.Services.Helpers; using Microsoft.AspNetCore.Authorization; @@ -29,6 +28,7 @@ namespace Marco.Pms.Services.Controllers tenantId = userHelper.GetTenantId(); } + #region =================================================================== Expense Functions =================================================================== /// /// Retrieves a paginated list of expenses based on user permissions and optional filters. @@ -46,11 +46,11 @@ namespace Marco.Pms.Services.Controllers return StatusCode(response.StatusCode, response); } - [HttpGet("details/{id}")] - public async Task GetExpenseDetails(Guid id) + [HttpGet("details/{id?}")] + public async Task GetExpenseDetails(Guid? id, [FromQuery] string? expenseUId) { var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); - var response = await _expensesService.GetExpenseDetailsAsync(id, loggedInEmployee, tenantId); + var response = await _expensesService.GetExpenseDetailsAsync(id, expenseUId, loggedInEmployee, tenantId); return StatusCode(response.StatusCode, response); } @@ -122,5 +122,7 @@ namespace Marco.Pms.Services.Controllers return StatusCode(response.StatusCode, response); } + #endregion + } } diff --git a/Marco.Pms.Services/Controllers/MasterController.cs b/Marco.Pms.Services/Controllers/MasterController.cs index e0b969d..89ae969 100644 --- a/Marco.Pms.Services/Controllers/MasterController.cs +++ b/Marco.Pms.Services/Controllers/MasterController.cs @@ -2,6 +2,7 @@ using Marco.Pms.Model.Dtos.Activities; using Marco.Pms.Model.Dtos.Collection; using Marco.Pms.Model.Dtos.DocumentManager; +using Marco.Pms.Model.Dtos.Expenses.Masters; using Marco.Pms.Model.Dtos.Master; using Marco.Pms.Model.Forum; using Marco.Pms.Model.Mapper; @@ -37,6 +38,30 @@ namespace Marco.Pms.Services.Controllers tenantId = userHelper.GetTenantId(); } + #region =================================================================== Recurring Payment Status APIs =================================================================== + + [HttpGet("recurring-status/list")] + public async Task GetRecurringPaymentStatus() + { + var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); + var response = await _masterService.GetRecurringPaymentStatusAsync(loggedInEmployee, tenantId); + return StatusCode(response.StatusCode, response); + } + + #endregion + + #region =================================================================== Currency APIs =================================================================== + + [HttpGet("currencies/list")] + public async Task GetCurrency() + { + var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); + var response = await _masterService.GetCurrencyAsync(loggedInEmployee, tenantId); + return StatusCode(response.StatusCode, response); + } + + #endregion + #region =================================================================== Organization Type APIs =================================================================== [HttpGet("organization-type/list")] @@ -821,37 +846,37 @@ namespace Marco.Pms.Services.Controllers } #endregion - #region =================================================================== Expenses Type APIs =================================================================== + #region =================================================================== Expenses Category APIs =================================================================== - [HttpGet("expenses-types")] - public async Task GetExpenseTypeList([FromQuery] bool isActive = true) + [HttpGet("expenses-categories")] + public async Task GetExpenseCategoryList([FromQuery] bool isActive = true) { var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); - var response = await _masterService.GetExpenseTypeListAsync(loggedInEmployee, tenantId, isActive); + var response = await _masterService.GetExpenseCategoryListAsync(loggedInEmployee, tenantId, isActive); return StatusCode(response.StatusCode, response); } - [HttpPost("expenses-type")] - public async Task CreateExpenseType([FromBody] ExpensesTypeMasterDto dto) + [HttpPost("expenses-category")] + public async Task CreateExpenseCategory([FromBody] ExpenseCategoryMasterDto dto) { var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); - var response = await _masterService.CreateExpenseTypeAsync(dto, loggedInEmployee, tenantId); + var response = await _masterService.CreateExpenseCategoryAsync(dto, loggedInEmployee, tenantId); return StatusCode(response.StatusCode, response); } - [HttpPut("expenses-type/edit/{id}")] - public async Task UpdateExpenseType(Guid id, [FromBody] ExpensesTypeMasterDto dto) + [HttpPut("expenses-category/edit/{id}")] + public async Task UpdateExpenseCategory(Guid id, [FromBody] ExpenseCategoryMasterDto dto) { var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); - var response = await _masterService.UpdateExpenseTypeAsync(id, dto, loggedInEmployee, tenantId); + var response = await _masterService.UpdateExpenseCategoryAsync(id, dto, loggedInEmployee, tenantId); return StatusCode(response.StatusCode, response); } - [HttpDelete("expenses-type/delete/{id}")] - public async Task DeleteExpenseType(Guid id, [FromQuery] bool isActive = false) + [HttpDelete("expenses-category/delete/{id}")] + public async Task DeleteExpenseCategory(Guid id, [FromQuery] bool isActive = false) { var loggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); - var response = await _masterService.DeleteExpenseTypeAsync(id, isActive, loggedInEmployee, tenantId); + var response = await _masterService.DeleteExpenseCategoryAsync(id, isActive, loggedInEmployee, tenantId); return StatusCode(response.StatusCode, response); } diff --git a/Marco.Pms.Services/Controllers/TenantController.cs b/Marco.Pms.Services/Controllers/TenantController.cs index 511fa34..707b1d9 100644 --- a/Marco.Pms.Services/Controllers/TenantController.cs +++ b/Marco.Pms.Services/Controllers/TenantController.cs @@ -1202,11 +1202,9 @@ namespace Marco.Pms.Services.Controllers } if (features.Modules?.Expense?.Enabled ?? false) { - var expensesTypeMaster = _masteData.GetExpensesTypeesData(tenant.Id); - var paymentModeMatser = _masteData.GetPaymentModesData(tenant.Id); + var expenseCategoryMaster = _masteData.GetExpenseCategoryData(tenant.Id); - _context.ExpensesTypeMaster.AddRange(expensesTypeMaster); - _context.PaymentModeMatser.AddRange(paymentModeMatser); + _context.ExpenseCategoryMasters.AddRange(expenseCategoryMaster); } await _context.SaveChangesAsync(); @@ -1535,33 +1533,14 @@ namespace Marco.Pms.Services.Controllers } if (features.Modules?.Expense?.Enabled ?? false) { - var expensesTypeMaster = _masteData.GetExpensesTypeesData(tenant.Id); - var paymentModeMatser = _masteData.GetPaymentModesData(tenant.Id); + var expenseCategoryMaster = _masteData.GetExpenseCategoryData(tenant.Id); - var expensesTypeTask = Task.Run(async () => - { - await using var _context = await _dbContextFactory.CreateDbContextAsync(); - var expensesTypeNames = expensesTypeMaster.Select(et => et.Name).ToList(); - return await _context.ExpensesTypeMaster.AnyAsync(et => expensesTypeNames.Contains(et.Name) && et.TenantId == tenant.Id); - }); - var paymentModeTask = Task.Run(async () => - { - await using var _context = await _dbContextFactory.CreateDbContextAsync(); - var paymentModeNames = paymentModeMatser.Select(py => py.Name).ToList(); - return await _context.PaymentModeMatser.AnyAsync(py => paymentModeNames.Contains(py.Name) && py.TenantId == tenant.Id); - }); + var expenseCategoryNames = expenseCategoryMaster.Select(et => et.Name).ToList(); + var expenseCategoryExist = await context.ExpensesTypeMaster.AnyAsync(et => expenseCategoryNames.Contains(et.Name) && et.TenantId == tenant.Id); - await Task.WhenAll(expensesTypeTask, paymentModeTask); - - var expensesTypeExist = expensesTypeTask.Result; - var paymentModeExist = paymentModeTask.Result; - if (!expensesTypeExist) + if (!expenseCategoryExist) { - context.ExpensesTypeMaster.AddRange(expensesTypeMaster); - } - if (!paymentModeExist) - { - context.PaymentModeMatser.AddRange(paymentModeMatser); + context.ExpenseCategoryMasters.AddRange(expenseCategoryMaster); } } diff --git a/Marco.Pms.Services/Helpers/CacheUpdateHelper.cs b/Marco.Pms.Services/Helpers/CacheUpdateHelper.cs index a769991..f396eb6 100644 --- a/Marco.Pms.Services/Helpers/CacheUpdateHelper.cs +++ b/Marco.Pms.Services/Helpers/CacheUpdateHelper.cs @@ -1154,7 +1154,7 @@ namespace Marco.Pms.Services.Helpers var expenseIds = model.Select(m => m.Id).ToList(); var projectIds = model.Select(m => m.ProjectId).ToList(); var statusIds = model.Select(m => m.StatusId).ToList(); - var expensesTypeIds = model.Select(m => m.ExpensesTypeId).ToList(); + var expenseCategoryIds = model.Select(m => m.ExpenseCategoryId).ToList(); var paymentModeIds = model.Select(m => m.PaymentModeId).ToList(); var createdByIds = model.Select(m => m.CreatedById).ToList(); var reviewedByIds = model.Select(m => m.ReviewedById).ToList(); @@ -1192,15 +1192,15 @@ namespace Marco.Pms.Services.Helpers await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); return await dbContext.Employees.Include(e => e.JobRole).AsNoTracking().Where(e => processedByIds.Contains(e.Id) && e.TenantId == tenantId).ToListAsync(); }); - var expenseTypeTask = Task.Run(async () => + var expenseCategoryTask = Task.Run(async () => { await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.ExpensesTypeMaster.AsNoTracking().Where(et => expensesTypeIds.Contains(et.Id) && et.TenantId == tenantId).ToListAsync(); + return await dbContext.ExpenseCategoryMasters.AsNoTracking().Where(et => expenseCategoryIds.Contains(et.Id) && et.TenantId == tenantId).ToListAsync(); }); var paymentModeTask = Task.Run(async () => { await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.PaymentModeMatser.AsNoTracking().Where(pm => paymentModeIds.Contains(pm.Id) && pm.TenantId == tenantId).ToListAsync(); + return await dbContext.PaymentModeMatser.AsNoTracking().Where(pm => paymentModeIds.Contains(pm.Id)).ToListAsync(); }); var statusMappingTask = Task.Run(async () => { @@ -1250,11 +1250,11 @@ namespace Marco.Pms.Services.Helpers }); // Await all prerequisite checks at once. - await Task.WhenAll(projectTask, expenseTypeTask, paymentModeTask, statusMappingTask, paidByTask, createdByTask, reviewedByTask, approvedByTask, + await Task.WhenAll(projectTask, expenseCategoryTask, paymentModeTask, statusMappingTask, paidByTask, createdByTask, reviewedByTask, approvedByTask, processedByTask, statusTask, billAttachmentsTask); var projects = projectTask.Result; - var expenseTypes = expenseTypeTask.Result; + var expenseCategories = expenseCategoryTask.Result; var paymentModes = paymentModeTask.Result; var statusMappings = statusMappingTask.Result; var paidBys = paidByTask.Result; @@ -1283,7 +1283,7 @@ namespace Marco.Pms.Services.Helpers response.NextStatus = statusMappings.Where(s => s.StatusId == m.StatusId).Select(s => _mapper.Map>(s.NextStatus)).FirstOrDefault() ?? new List(); response.PaymentMode = paymentModes.Where(pm => pm.Id == m.PaymentModeId).Select(pm => _mapper.Map(pm)).FirstOrDefault() ?? new PaymentModeMatserMongoDB(); - response.ExpensesType = expenseTypes.Where(et => et.Id == m.ExpensesTypeId).Select(et => _mapper.Map(et)).FirstOrDefault() ?? new ExpensesTypeMasterMongoDB(); + response.ExpenseCategory = expenseCategories.Where(et => et.Id == m.ExpenseCategoryId).Select(et => _mapper.Map(et)).FirstOrDefault() ?? new ExpenseCategoryMasterMongoDB(); response.Documents = billAttachments.Where(ba => ba.ExpensesId == m.Id).Select(ba => ba.Documents).FirstOrDefault() ?? new List(); return response; }).ToList(); @@ -1322,15 +1322,15 @@ namespace Marco.Pms.Services.Helpers await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); return await dbContext.Employees.Include(e => e.JobRole).AsNoTracking().FirstOrDefaultAsync(e => e.Id == model.ProcessedById && e.TenantId == tenantId); }); - var expenseTypeTask = Task.Run(async () => + var expenseCategoryTask = Task.Run(async () => { await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.ExpensesTypeMaster.AsNoTracking().FirstOrDefaultAsync(et => et.Id == model.ExpensesTypeId && et.TenantId == tenantId); + return await dbContext.ExpenseCategoryMasters.AsNoTracking().FirstOrDefaultAsync(et => et.Id == model.ExpenseCategoryId && et.TenantId == tenantId); }); var paymentModeTask = Task.Run(async () => { await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.PaymentModeMatser.AsNoTracking().FirstOrDefaultAsync(pm => pm.Id == model.PaymentModeId && pm.TenantId == tenantId); + return await dbContext.PaymentModeMatser.AsNoTracking().FirstOrDefaultAsync(pm => pm.Id == model.PaymentModeId); }); var statusMappingTask = Task.Run(async () => { @@ -1379,11 +1379,11 @@ namespace Marco.Pms.Services.Helpers }); // Await all prerequisite checks at once. - await Task.WhenAll(projectTask, expenseTypeTask, paymentModeTask, statusMappingTask, paidByTask, createdByTask, reviewedByTask, approvedByTask, + await Task.WhenAll(projectTask, expenseCategoryTask, paymentModeTask, statusMappingTask, paidByTask, createdByTask, reviewedByTask, approvedByTask, processedByTask, statusTask, billAttachmentsTask); var project = projectTask.Result; - var expenseType = expenseTypeTask.Result; + var expenseCategory = expenseCategoryTask.Result; var paymentMode = paymentModeTask.Result; var statusMapping = statusMappingTask.Result; var paidBy = paidByTask.Result; @@ -1413,7 +1413,7 @@ namespace Marco.Pms.Services.Helpers response.Status = _mapper.Map(status); } response.PaymentMode = _mapper.Map(paymentMode); - response.ExpensesType = _mapper.Map(expenseType); + response.ExpenseCategory = _mapper.Map(expenseCategory); if (billAttachment != null) response.Documents = billAttachment.Documents; return response; diff --git a/Marco.Pms.Services/MappingProfiles/MappingProfile.cs b/Marco.Pms.Services/MappingProfiles/MappingProfile.cs index e3331db..26f9691 100644 --- a/Marco.Pms.Services/MappingProfiles/MappingProfile.cs +++ b/Marco.Pms.Services/MappingProfiles/MappingProfile.cs @@ -10,6 +10,7 @@ using Marco.Pms.Model.Dtos.Directory; using Marco.Pms.Model.Dtos.DocumentManager; using Marco.Pms.Model.Dtos.Employees; using Marco.Pms.Model.Dtos.Expenses; +using Marco.Pms.Model.Dtos.Expenses.Masters; using Marco.Pms.Model.Dtos.Master; using Marco.Pms.Model.Dtos.Organization; using Marco.Pms.Model.Dtos.Project; @@ -17,6 +18,7 @@ using Marco.Pms.Model.Dtos.Tenant; using Marco.Pms.Model.Employees; using Marco.Pms.Model.Entitlements; using Marco.Pms.Model.Expenses; +using Marco.Pms.Model.Expenses.Masters; using Marco.Pms.Model.Master; using Marco.Pms.Model.MongoDBModels; using Marco.Pms.Model.MongoDBModels.Employees; @@ -34,6 +36,7 @@ using Marco.Pms.Model.ViewModels.DocumentManager; using Marco.Pms.Model.ViewModels.Employee; using Marco.Pms.Model.ViewModels.Expanses; using Marco.Pms.Model.ViewModels.Expenses; +using Marco.Pms.Model.ViewModels.Expenses.Masters; using Marco.Pms.Model.ViewModels.Master; using Marco.Pms.Model.ViewModels.Organization; using Marco.Pms.Model.ViewModels.Projects; @@ -223,6 +226,8 @@ namespace Marco.Pms.Services.MappingProfiles opt => opt.MapFrom(src => Guid.Parse(src.JobRoleId ?? ""))); #endregion + #region ======================================================= Finance ======================================================= + #region ======================================================= Expenses ======================================================= CreateMap(); @@ -252,6 +257,7 @@ namespace Marco.Pms.Services.MappingProfiles dest => dest.Id, opt => opt.MapFrom(src => Guid.Parse(src.Id))); + CreateMap(); CreateMap() .ForMember( dest => dest.Id, @@ -259,6 +265,34 @@ namespace Marco.Pms.Services.MappingProfiles #endregion + #region ======================================================= Payment Request ======================================================= + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap() + .ForMember( + dest => dest.PaymentRequestUID, + opt => opt.MapFrom(src => $"{src.UIDPrefix}/{src.UIDPostfix:D5}")); + CreateMap(); + #endregion + + #region ======================================================= Recurring Request ======================================================= + CreateMap(); + CreateMap(); + CreateMap(); + CreateMap() + .ForMember( + dest => dest.RecurringPaymentUID, + opt => opt.MapFrom(src => $"{src.UIDPrefix}/{src.UIDPostfix:D5}")) + .ForMember( + dest => dest.NotifyTo, + opt => opt.MapFrom(src => new List())); + CreateMap() + .ForMember( + dest => dest.RecurringPaymentUID, + opt => opt.MapFrom(src => $"{src.UIDPrefix}/{src.UIDPostfix:D5}")); + #endregion + #region ======================================================= Collection ======================================================= CreateMap(); CreateMap(); @@ -272,6 +306,10 @@ namespace Marco.Pms.Services.MappingProfiles CreateMap(); #endregion + CreateMap(); + + #endregion + #region ======================================================= Master ======================================================= CreateMap(); @@ -325,17 +363,17 @@ namespace Marco.Pms.Services.MappingProfiles #endregion - #region ======================================================= Expenses Type Master ======================================================= + #region ======================================================= Expenses Category Master ======================================================= - CreateMap() + CreateMap() .ForMember( dest => dest.Id, // Explicitly and safely convert nullable Guid to non-nullable Guid opt => opt.MapFrom(src => src.Id ?? Guid.Empty) ); - CreateMap(); + CreateMap(); - CreateMap() + CreateMap() .ForMember( dest => dest.Id, opt => opt.MapFrom(src => src.Id.ToString())) @@ -343,7 +381,7 @@ namespace Marco.Pms.Services.MappingProfiles dest => dest.TenantId, opt => opt.MapFrom(src => src.TenantId.ToString())); - CreateMap() + CreateMap() .ForMember( dest => dest.Id, opt => opt.MapFrom(src => Guid.Parse(src.Id))); @@ -384,10 +422,7 @@ namespace Marco.Pms.Services.MappingProfiles CreateMap() .ForMember( dest => dest.Id, - opt => opt.MapFrom(src => src.Id.ToString())) - .ForMember( - dest => dest.TenantId, - opt => opt.MapFrom(src => src.TenantId.ToString())); + opt => opt.MapFrom(src => src.Id.ToString())); CreateMap() .ForMember( diff --git a/Marco.Pms.Services/Service/ExpensesService.cs b/Marco.Pms.Services/Service/ExpensesService.cs index 48bc2a1..7f37a98 100644 --- a/Marco.Pms.Services/Service/ExpensesService.cs +++ b/Marco.Pms.Services/Service/ExpensesService.cs @@ -1,30 +1,31 @@ using AutoMapper; using Marco.Pms.DataAccess.Data; using Marco.Pms.Helpers.Utility; +using Marco.Pms.Model.DocumentManager; using Marco.Pms.Model.Dtos.Expenses; using Marco.Pms.Model.Employees; using Marco.Pms.Model.Entitlements; using Marco.Pms.Model.Expenses; +using Marco.Pms.Model.Filters; using Marco.Pms.Model.MongoDBModels; using Marco.Pms.Model.MongoDBModels.Employees; using Marco.Pms.Model.MongoDBModels.Expenses; using Marco.Pms.Model.MongoDBModels.Masters; using Marco.Pms.Model.MongoDBModels.Project; using Marco.Pms.Model.MongoDBModels.Utility; +using Marco.Pms.Model.TenantModels; using Marco.Pms.Model.Utilities; using Marco.Pms.Model.ViewModels.Activities; using Marco.Pms.Model.ViewModels.Expanses; using Marco.Pms.Model.ViewModels.Expenses; +using Marco.Pms.Model.ViewModels.Expenses.Masters; using Marco.Pms.Model.ViewModels.Master; using Marco.Pms.Model.ViewModels.Projects; using Marco.Pms.Services.Helpers; using Marco.Pms.Services.Service.ServiceInterfaces; using MarcoBMS.Services.Service; -using Microsoft.CodeAnalysis; using Microsoft.EntityFrameworkCore; using System.Text.Json; -using System.Text.RegularExpressions; -using Document = Marco.Pms.Model.DocumentManager.Document; namespace Marco.Pms.Services.Service { @@ -38,6 +39,7 @@ namespace Marco.Pms.Services.Service private readonly UtilityMongoDBHelper _updateLogHelper; private readonly CacheUpdateHelper _cache; private readonly IMapper _mapper; + private static readonly Guid Draft = Guid.Parse("297e0d8f-f668-41b5-bfea-e03b354251c8"); private static readonly Guid Review = Guid.Parse("6537018f-f4e9-4cb3-a210-6c3b2da999d7"); private static readonly Guid RejectedByReviewer = Guid.Parse("965eda62-7907-4963-b4a1-657fb0b2724b"); @@ -45,6 +47,12 @@ namespace Marco.Pms.Services.Service private static readonly Guid RejectedByApprover = Guid.Parse("d1ee5eec-24b6-4364-8673-a8f859c60729"); private static readonly Guid ProcessPending = Guid.Parse("f18c5cfd-7815-4341-8da2-2c2d65778e27"); private static readonly Guid Processed = Guid.Parse("61578360-3a49-4c34-8604-7b35a3787b95"); + + private static readonly Guid AdvancePayment = Guid.Parse("f67beee6-6763-4108-922c-03bd86b9178d"); + + private static readonly Guid ActiveTemplateStatus = Guid.Parse("da462422-13b2-45cc-a175-910a225f6fc8"); + + private static readonly string Collection = "ExpensesModificationLog"; public ExpensesService( IDbContextFactory dbContextFactory, @@ -66,6 +74,8 @@ namespace Marco.Pms.Services.Service _mapper = mapper; } + #region =================================================================== Expense Functions =================================================================== + #region =================================================================== Get Functions =================================================================== /// @@ -130,11 +140,23 @@ namespace Marco.Pms.Services.Service // 3. --- Build Base Query and Apply Permissions --- // Start with a base IQueryable. Filters will be chained onto this. var expensesQuery = _context.Expenses + .Include(e => e.PaidBy) + .Include(e => e.CreatedBy) + .Include(e => e.ProcessedBy) + .Include(e => e.ApprovedBy) + .Include(e => e.ReviewedBy) + .Include(e => e.PaymentMode) + .Include(e => e.Project) + .Include(e => e.PaymentMode) + .Include(e => e.ExpenseCategory) + .Include(e => e.PaymentRequest) + .Include(e => e.Status) + .Include(e => e.Currency) .Where(e => e.TenantId == tenantId); // Always filter by TenantId first. if (cacheList == null) { - await _cache.AddExpensesListToCache(expenses: await expensesQuery.ToListAsync(), tenantId); + //await _cache.AddExpensesListToCache(expenses: await expensesQuery.ToListAsync(), tenantId); // Apply permission-based filtering BEFORE any other filters or pagination. if (hasViewAllPermissionTask.Result) @@ -177,6 +199,10 @@ namespace Marco.Pms.Services.Service { expensesQuery = expensesQuery.Where(e => expenseFilter.PaidById.Contains(e.PaidById)); } + if (expenseFilter.ExpenseCategoryIds?.Any() == true) + { + expensesQuery = expensesQuery.Where(e => expenseFilter.ExpenseCategoryIds.Contains(e.ExpenseCategoryId)); + } // Only allow filtering by 'CreatedBy' if the user has 'View All' permission. if (expenseFilter.CreatedByIds?.Any() == true && hasViewAllPermissionTask.Result) @@ -200,13 +226,11 @@ namespace Marco.Pms.Services.Service totalEntites = await expensesQuery.CountAsync(); - var paginatedQuery = expensesQuery + // 5. --- Execute Query and Map Results --- + var expensesList = await expensesQuery .OrderByDescending(e => e.CreatedAt) .Skip((pageNumber - 1) * pageSize) - .Take(pageSize); - - // 5. --- Execute Query and Map Results --- - var expensesList = await paginatedQuery.ToListAsync(); + .Take(pageSize).ToListAsync(); if (!expensesList.Any()) { @@ -214,7 +238,15 @@ namespace Marco.Pms.Services.Service return ApiResponse.SuccessResponse(new List(), "No expenses found for the given criteria.", 200); } - expenseVM = await GetAllExpnesRelatedTables(expensesList, tenantId); + //expenseVM = await GetAllExpnesRelatedTables(expensesList, tenantId); + expenseVM = expensesList.Select(e => + { + var result = _mapper.Map(e); + result.ExpenseUId = $"{e.UIDPrefix}/{e.UIDPostfix:D5}"; + if (e.PaymentRequest != null) + result.PaymentRequestUID = $"{e.PaymentRequest.UIDPrefix}/{e.PaymentRequest.UIDPostfix:D5}"; + return result; + }).ToList(); totalPages = (int)Math.Ceiling((double)totalEntites / pageSize); } @@ -229,18 +261,18 @@ namespace Marco.Pms.Services.Service }).ToListAsync(); expenseVM = cacheList.Select(m => + { + var response = _mapper.Map(m); + if (response.Status != null && (response.NextStatus?.Any() ?? false)) { - var response = _mapper.Map(m); - if (response.Status != null && (response.NextStatus?.Any() ?? false)) + response.Status.PermissionIds = permissionStatusMapping.Where(ps => ps.StatusId == Guid.Parse(m.Status.Id)).Select(ps => ps.PermissionIds).FirstOrDefault(); + foreach (var status in response.NextStatus) { - response.Status.PermissionIds = permissionStatusMapping.Where(ps => ps.StatusId == Guid.Parse(m.Status.Id)).Select(ps => ps.PermissionIds).FirstOrDefault(); - foreach (var status in response.NextStatus) - { - status.PermissionIds = permissionStatusMapping.Where(ps => ps.StatusId == status.Id).Select(ps => ps.PermissionIds).FirstOrDefault(); - } + status.PermissionIds = permissionStatusMapping.Where(ps => ps.StatusId == status.Id).Select(ps => ps.PermissionIds).FirstOrDefault(); } - return response; - }).ToList(); + } + return response; + }).ToList(); totalEntites = (int)totalCount; } // 7. --- Return Final Success Response --- @@ -269,36 +301,65 @@ namespace Marco.Pms.Services.Service return ApiResponse.ErrorResponse("Error Occured", ExceptionMapper(ex), 500); } } - public async Task> GetExpenseDetailsAsync(Guid id, Employee loggedInEmployee, Guid tenantId) + public async Task> GetExpenseDetailsAsync(Guid? id, string? expenseUId, Employee loggedInEmployee, Guid tenantId) { try { - //ExpenseDetailsMongoDB? expenseDetails = await _cache.GetExpenseDetailsById(id, tenantId); + if (!id.HasValue && string.IsNullOrWhiteSpace(expenseUId)) + { + _logger.LogWarning("Invalid parameters: Both Id and PaymentRequestUID are null or empty."); + return ApiResponse.ErrorResponse("At least one parameter (Id or expenseUId) must be provided.", "Invalid argument.", 400); + } ExpenseDetailsMongoDB? expenseDetails = null; if (expenseDetails == null) { - var expense = await _context.Expenses.AsNoTracking().FirstOrDefaultAsync(e => e.Id == id && e.TenantId == tenantId); + var expense = await _context.Expenses + .Include(e => e.PaidBy) + .Include(e => e.CreatedBy) + .Include(e => e.ProcessedBy) + .Include(e => e.ApprovedBy) + .Include(e => e.ReviewedBy) + .Include(e => e.PaymentMode) + .Include(e => e.Project) + .Include(e => e.PaymentMode) + .Include(e => e.ExpenseCategory) + .Include(e => e.Status) + .Include(e => e.Currency) + .Include(e => e.PaymentRequest) + .AsNoTracking().FirstOrDefaultAsync(e => (e.Id == id || (e.UIDPrefix + "/" + e.UIDPostfix.ToString().PadLeft(5, '0')) == expenseUId) && e.TenantId == tenantId); if (expense == null) { - _logger.LogWarning("User attempted to fetch expense details with ID {ExpenseId}, but not found in both database and cache", id); + if (id.HasValue) + { + _logger.LogWarning("User attempted to fetch expense details with ID {ExpenseId}, but not found in both database and cache", id); + } + else if (!string.IsNullOrWhiteSpace(expenseUId)) + { + _logger.LogWarning("User attempted to fetch expense details with expenseUId {ExpenseUId}, but not found in both database and cache", expenseUId); + } return ApiResponse.ErrorResponse("Expense Not Found", "Expense Not Found", 404); } - expenseDetails = await GetAllExpnesRelatedTablesForSingle(expense, expense.TenantId); + + using var scope = _serviceScopeFactory.CreateScope(); + var permissionService = scope.ServiceProvider.GetRequiredService(); + var hasManagePermission = await permissionService.HasPermission(PermissionsMaster.ExpenseManage, loggedInEmployee.Id); + + expenseDetails = await GetAllExpnesRelatedTablesForSingle(expense, hasManagePermission, loggedInEmployee.Id, expense.TenantId); } var vm = _mapper.Map(expenseDetails); var permissionStatusMappingTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.StatusPermissionMapping - .GroupBy(ps => ps.StatusId) - .Select(g => new - { - StatusId = g.Key, - PermissionIds = g.Select(ps => ps.PermissionId).ToList() - }).ToListAsync(); - }); + { + await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); + return await dbContext.StatusPermissionMapping + .GroupBy(ps => ps.StatusId) + .Select(g => new + { + StatusId = g.Key, + PermissionIds = g.Select(ps => ps.PermissionId).ToList() + }).ToListAsync(); + }); var expenseReimburseTask = Task.Run(async () => { await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); @@ -347,7 +408,7 @@ namespace Marco.Pms.Services.Service } catch (Exception ex) { - _logger.LogError(ex, "An unhandled exception occurred while fetching an expense details {ExpenseId}.", id); + _logger.LogError(ex, "An unhandled exception occurred while fetching an expense details {ExpenseId} or {ExpenseUId}.", id ?? Guid.Empty, expenseUId ?? "EX_00000"); return ApiResponse.ErrorResponse("An internal server error occurred.", ExceptionMapper(ex), 500); } } @@ -369,66 +430,25 @@ namespace Marco.Pms.Services.Service { try { - // Task 1: Get all distinct projects associated with the tenant's expenses. - var projectsTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.Expenses - .Where(e => e.TenantId == tenantId && e.Project != null) - .Select(e => e.Project!) - .Distinct() - .Select(p => new { p.Id, Name = $"{p.Name}" }) - .ToListAsync(); - }); - - // Task 2: Get all distinct users who paid for the tenant's expenses. - var paidByTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.Expenses - .Where(e => e.TenantId == tenantId && e.PaidBy != null) - .Select(e => e.PaidBy!) - .Distinct() - .Select(u => new { u.Id, Name = $"{u.FirstName} {u.LastName}" }) - .ToListAsync(); - }); - - // Task 3: Get all distinct users who created the tenant's expenses. - var createdByTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.Expenses - .Where(e => e.TenantId == tenantId && e.CreatedBy != null) - .Select(e => e.CreatedBy!) - .Distinct() - .Select(u => new { u.Id, Name = $"{u.FirstName} {u.LastName}" }) - .ToListAsync(); - }); - - // Task 4: Get all distinct statuses associated with the tenant's expenses. - var statusTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.Expenses - .Where(e => e.TenantId == tenantId && e.Status != null) - .Select(e => e.Status!) - .Distinct() - .Select(s => new { s.Id, s.Name }) - .ToListAsync(); - }); - - // Execute all four queries concurrently. The total wait time will be determined - // by the longest-running query, not the sum of all four. - await Task.WhenAll(projectsTask, paidByTask, createdByTask, statusTask); + var expenses = await _context.Expenses + .Include(e => e.PaidBy) + .Include(e => e.Project) + .Include(e => e.CreatedBy) + .Include(e => e.Status) + .Include(e => e.ExpenseCategory) + .Where(e => e.TenantId == tenantId) + .ToListAsync(); // Construct the final object from the results of the completed tasks. - return ApiResponse.SuccessResponse(new + var response = new { - Projects = await projectsTask, - PaidBy = await paidByTask, - CreatedBy = await createdByTask, - Status = await statusTask - }, "Successfully fetched the filter list", 200); + Projects = expenses.Where(e => e.Project != null).Select(e => new { Id = e.Project!.Id, Name = e.Project.Name }).Distinct().ToList(), + PaidBy = expenses.Where(e => e.PaidBy != null).Select(e => new { Id = e.PaidBy!.Id, Name = $"{e.PaidBy.FirstName} {e.PaidBy.LastName}" }).Distinct().ToList(), + CreatedBy = expenses.Where(e => e.CreatedBy != null).Select(e => new { Id = e.CreatedBy!.Id, Name = $"{e.CreatedBy.FirstName} {e.CreatedBy.LastName}" }).Distinct().ToList(), + Status = expenses.Where(e => e.Status != null).Select(e => new { Id = e.Status!.Id, Name = e.Status.Name }).Distinct().ToList(), + ExpensesCategory = expenses.Where(e => e.ExpenseCategory != null).Select(e => new { Id = e.ExpenseCategory!.Id, Name = e.ExpenseCategory.Name }).Distinct().ToList() + }; + return ApiResponse.SuccessResponse(response, "Successfully fetched the filter list", 200); } catch (Exception ex) { @@ -466,13 +486,6 @@ namespace Marco.Pms.Services.Service return await permissionService.HasPermission(PermissionsMaster.ExpenseUpload, loggedInEmployee.Id); }); - var hasProjectPermissionTask = Task.Run(async () => - { - using var scope = _serviceScopeFactory.CreateScope(); - var permissionService = scope.ServiceProvider.GetRequiredService(); - return await permissionService.HasProjectPermission(loggedInEmployee, dto.ProjectId); - }); - // VALIDATION CHECKS: Use IDbContextFactory for thread-safe, parallel database queries. // Each task gets its own DbContext instance. var projectTask = Task.Run(async () => @@ -485,25 +498,16 @@ namespace Marco.Pms.Services.Service await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); return await dbContext.Employees.AsNoTracking().FirstOrDefaultAsync(e => e.Id == dto.PaidById); }); - var expenseTypeTask = Task.Run(async () => + var expenseCategoriesTask = Task.Run(async () => { await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.ExpensesTypeMaster.AsNoTracking().FirstOrDefaultAsync(et => et.Id == dto.ExpensesTypeId); + return await dbContext.ExpenseCategoryMasters.AsNoTracking().FirstOrDefaultAsync(et => et.Id == dto.ExpenseCategoryId); }); var paymentModeTask = Task.Run(async () => { await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); return await dbContext.PaymentModeMatser.AsNoTracking().FirstOrDefaultAsync(pm => pm.Id == dto.PaymentModeId); }); - var expenseUIdTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - var result = await dbContext.Expenses - .Where(e => !string.IsNullOrWhiteSpace(e.ExpenseUId)).ToListAsync(); - return result - .Select(e => ExtractNumber(e.ExpenseUId)) - .OrderByDescending(id => id).FirstOrDefault(); - }); var statusMappingTask = Task.Run(async () => { await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); @@ -523,29 +527,28 @@ namespace Marco.Pms.Services.Service // Await all prerequisite checks at once. - await Task.WhenAll(hasUploadPermissionTask, hasProjectPermissionTask, projectTask, expenseTypeTask, paymentModeTask, statusMappingTask, paidByTask, expenseUIdTask); + await Task.WhenAll(hasUploadPermissionTask, projectTask, expenseCategoriesTask, paymentModeTask, statusMappingTask, paidByTask); // 2. Aggregate and Check Results - if (!await hasUploadPermissionTask || !await hasProjectPermissionTask) + if (!await hasUploadPermissionTask) { _logger.LogWarning("Access DENIED for employee {EmployeeId} on project {ProjectId}.", loggedInEmployee.Id, dto.ProjectId); return ApiResponse.ErrorResponse("Access Denied.", "You do not have permission to upload expenses for this project.", 403); } var validationErrors = new List(); - var project = projectTask.Result; - var expenseType = expenseTypeTask.Result; - var paymentMode = paymentModeTask.Result; - var statusMapping = statusMappingTask.Result; - var paidBy = paidByTask.Result; - var lastExpenseUId = expenseUIdTask.Result; + var project = await projectTask; + var expenseCategory = await expenseCategoriesTask; + var paymentMode = await paymentModeTask; + var statusMapping = await statusMappingTask; + var paidBy = await paidByTask; if (project == null) validationErrors.Add("Project not found."); if (paidBy == null) validationErrors.Add("Paid by employee not found"); - if (expenseType == null) validationErrors.Add("Expense Type not found."); + if (expenseCategory == null) validationErrors.Add("Expense Category not found."); if (paymentMode == null) validationErrors.Add("Payment Mode not found."); if (statusMapping == null) validationErrors.Add("Default status 'Draft' not found."); - if ((expenseType?.IsAttachmentRequried ?? true) && !(dto.BillAttachments?.Any() ?? false)) validationErrors.Add("Bill Attachment is requried, but not found"); + if ((expenseCategory?.IsAttachmentRequried ?? true) && !(dto.BillAttachments?.Any() ?? false)) validationErrors.Add("Bill Attachment is requried, but not found"); if (validationErrors.Any()) { @@ -554,10 +557,21 @@ namespace Marco.Pms.Services.Service _logger.LogWarning("Expense creation failed due to validation errors: {ValidationErrors}", errorMessage); return ApiResponse.ErrorResponse("Invalid input data.", errorMessage, 400); } - var currentexpenseUId = (lastExpenseUId + 1).ToString("D5"); + + + string uIDPrefix = $"EX/{DateTime.Now:MMyy}"; + + // Generate unique UID postfix based on existing requests for the current prefix + var lastPR = await _context.Expenses.Where(pr => pr.UIDPrefix == uIDPrefix) + .OrderByDescending(pr => pr.UIDPostfix) + .FirstOrDefaultAsync(); + int uIDPostfix = lastPR == null ? 1 : (lastPR.UIDPostfix + 1); + // 3. Entity Creation var expense = _mapper.Map(dto); - expense.ExpenseUId = $"EX-{currentexpenseUId}"; + expense.CurrencyId = dto.CurrencyId ?? Guid.Parse("78e96e4a-7ce0-4164-ae3a-c833ad45ec2c"); + expense.UIDPostfix = uIDPostfix; + expense.UIDPrefix = uIDPrefix; expense.CreatedById = loggedInEmployee.Id; expense.CreatedAt = DateTime.UtcNow; expense.TenantId = tenantId; @@ -572,6 +586,18 @@ namespace Marco.Pms.Services.Service await ProcessAndUploadAttachmentsAsync(dto.BillAttachments, expense, loggedInEmployee.Id, tenantId); } + var expenseLog = new ExpenseLog + { + ExpenseId = expense.Id, + Action = $"Status changed to '{statusMapping!.Status?.Name}'", + UpdatedById = loggedInEmployee.Id, + UpdateAt = DateTime.UtcNow, + Comment = $"Status changed to '{statusMapping!.Status?.Name}'", + TenantId = tenantId + }; + + _context.ExpenseLogs.Add(expenseLog); + // 5. Database Commit await _context.SaveChangesAsync(); @@ -581,12 +607,13 @@ namespace Marco.Pms.Services.Service await _cache.AddExpenseByObjectAsync(expense); var response = _mapper.Map(expense); + response.ExpenseUId = $"{expense.UIDPrefix}/{expense.UIDPostfix:D5}"; response.PaidBy = _mapper.Map(paidBy); response.Project = _mapper.Map(project); response.Status = _mapper.Map(statusMapping!.Status); response.NextStatus = _mapper.Map>(statusMapping.NextStatus); response.PaymentMode = _mapper.Map(paymentMode); - response.ExpensesType = _mapper.Map(expenseType); + response.ExpenseCategory = _mapper.Map(expenseCategory); _logger.LogInfo("Successfully created Expense {ExpenseId} for Project {ProjectId}.", expense.Id, expense.ProjectId); return ApiResponse.SuccessResponse(response, "Expense created successfully.", 201); @@ -623,11 +650,12 @@ namespace Marco.Pms.Services.Service // 1. Fetch Existing Expense with Related Entities (Single Query) var expense = await _context.Expenses - .Include(e => e.ExpensesType) + .Include(e => e.ExpenseCategory) .Include(e => e.Project) .Include(e => e.PaidBy).ThenInclude(e => e!.JobRole) .Include(e => e.PaymentMode) .Include(e => e.Status) + .Include(e => e.Currency) .Include(e => e.CreatedBy) .Include(e => e.ReviewedBy) .Include(e => e.ApprovedBy) @@ -648,6 +676,12 @@ namespace Marco.Pms.Services.Service expense.Id, expense.StatusId, model.StatusId); // 2. Run Prerequisite Checks in Parallel (Status transition + Permissions) + var processedStatusTask = Task.Run(async () => + { + await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); + return await dbContext.ExpensesStatusMaster + .FirstOrDefaultAsync(es => es.Id == Processed); + }); var statusTransitionTask = Task.Run(async () => { await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); @@ -664,9 +698,10 @@ namespace Marco.Pms.Services.Service .ToListAsync(); }); - await Task.WhenAll(statusTransitionTask, targetStatusPermissionsTask); - var statusTransition = await statusTransitionTask; - var requiredPermissions = await targetStatusPermissionsTask; + await Task.WhenAll(statusTransitionTask, targetStatusPermissionsTask, processedStatusTask); + var statusTransition = statusTransitionTask.Result; + var requiredPermissions = targetStatusPermissionsTask.Result; + var processedStatus = processedStatusTask.Result; // 3. Validate Transition and Required Fields if (statusTransition == null) @@ -716,10 +751,66 @@ namespace Marco.Pms.Services.Service // 5. Prepare for update (Audit snapshot) var expenseStateBeforeChange = _updateLogHelper.EntityToBsonDocument(expense); - // 6. Apply Status Transition - expense.StatusId = statusTransition.NextStatusId; - expense.Status = statusTransition.NextStatus; + var expenseLogs = new List + { + new ExpenseLog + { + ExpenseId = expense.Id, + Action = $"Status changed to '{statusTransition.NextStatus?.Name}'", + UpdatedById = loggedInEmployee.Id, + UpdateAt = DateTime.UtcNow, + Comment = model.Comment, + TenantId = tenantId + }, + }; + // 6. Apply Status Transition + if (model.StatusId == ProcessPending && expense.PaymentModeId == AdvancePayment) + { + expense.StatusId = Processed; + expense.Status = processedStatus; + expense.ProcessedById = loggedInEmployee.Id; + + var lastTransaction = await _context.AdvancePaymentTransactions.OrderByDescending(apt => apt.CreatedAt).FirstOrDefaultAsync(apt => apt.TenantId == tenantId); + double lastBalance = 0; + if (lastTransaction != null) + { + lastBalance = lastTransaction.CurrentBalance; + } + + _context.AdvancePaymentTransactions.Add(new AdvancePaymentTransaction + { + Id = Guid.NewGuid(), + FinanceUIdPostfix = expense.UIDPostfix, + FinanceUIdPrefix = expense.UIDPrefix, + Title = expense.Description, + ProjectId = expense.ProjectId, + EmployeeId = expense.PaidById, + Amount = 0 - expense.Amount, + CurrentBalance = lastBalance - expense.Amount, + PaidAt = expense.TransactionDate, + CreatedAt = DateTime.UtcNow, + CreatedById = loggedInEmployee.Id, + IsActive = true, + TenantId = tenantId + }); + + var expenseLog = new ExpenseLog + { + ExpenseId = expense.Id, + Action = $"Status changed to '{processedStatus?.Name}'", + UpdatedById = loggedInEmployee.Id, + UpdateAt = DateTime.UtcNow, + Comment = model.Comment, + TenantId = tenantId + }; + expenseLogs.Add(expenseLog); + } + else + { + expense.StatusId = statusTransition.NextStatusId; + expense.Status = statusTransition.NextStatus; + } // Handle reviewer/approver/processor fields based on target StatusId (Guid) if (model.StatusId == Approve || model.StatusId == RejectedByReviewer) { @@ -731,12 +822,27 @@ namespace Marco.Pms.Services.Service } else if (model.StatusId == Processed) { + var totalAmount = model.BaseAmount + model.TaxAmount; + if (!totalAmount.HasValue || totalAmount != expense.Amount) + { + // Log the mismatch error with relevant details + _logger.LogWarning("Payment amount mismatch: calculated totalAmount = {TotalAmount}, expected Amount = {ExpectedAmount}", totalAmount ?? 0, expense.Amount); + + // Return a structured error response indicating the amount discrepancy + return ApiResponse.ErrorResponse( + "Payment amount validation failed.", + $"The sum of the base amount and tax amount ({totalAmount}) does not match the expected expense amount ({expense.Amount}).", + 400); + } expense.ProcessedById = loggedInEmployee.Id; + expense.BaseAmount = model.BaseAmount; + expense.TaxAmount = model.TaxAmount; } // 7. Add Reimbursement if applicable if (model.StatusId == Processed) { + expense.TDSPercentage = model.TDSPercentage; var reimbursement = new ExpensesReimburse { ReimburseTransactionId = model.ReimburseTransactionId!, @@ -755,15 +861,7 @@ namespace Marco.Pms.Services.Service } // 8. Add Expense Log Entry - _context.ExpenseLogs.Add(new ExpenseLog - { - ExpenseId = expense.Id, - Action = $"Status changed to '{statusTransition.NextStatus?.Name}'", - UpdatedById = loggedInEmployee.Id, - UpdateAt = DateTime.UtcNow, - Comment = model.Comment, - TenantId = tenantId - }); + _context.ExpenseLogs.AddRange(expenseLogs); // 9. Commit database transaction try @@ -838,13 +936,25 @@ namespace Marco.Pms.Services.Service public async Task> UpdateExpanseAsync(Guid id, UpdateExpensesDto model, Employee loggedInEmployee, Guid tenantId) { + // Validate if the employee Id from the URL path matches the Id in the request body (model) if (id != model.Id) { - _logger.LogWarning("Id provided by path parameter and Id from body not matches for employee {EmployeeId}", loggedInEmployee.Id); - return ApiResponse.ErrorResponse("Invalid Parameters", "Invalid Parameters", 400); + // Log a warning with details for traceability when Ids do not match + _logger.LogWarning("Mismatch detected: Path parameter Id ({PathId}) does not match body Id ({BodyId}) for employee {EmployeeId}", + id, model.Id, loggedInEmployee.Id); + + // Return standardized error response with HTTP 400 Bad Request status and clear message + return ApiResponse.ErrorResponse("The employee Id in the path does not match the Id in the request body.", + "The employee Id in the path does not match the Id in the request body.", 400); } + + using var scope = _serviceScopeFactory.CreateScope(); + var permissionService = scope.ServiceProvider.GetRequiredService(); + + var hasManagePermission = await permissionService.HasPermission(PermissionsMaster.ExpenseManage, loggedInEmployee.Id); + var existingExpense = await _context.Expenses - .Include(e => e.ExpensesType) + .Include(e => e.ExpenseCategory) .Include(e => e.Project) .Include(e => e.PaidBy) .ThenInclude(e => e!.JobRole) @@ -870,7 +980,7 @@ namespace Marco.Pms.Services.Service _logger.LogWarning("User attempted to update expense with ID {ExpenseId}, but donot have status of DRAFT or REJECTED, but is {StatusId}", existingExpense.Id, existingExpense.StatusId); return ApiResponse.ErrorResponse("Expense connot be updated", "Expense connot be updated", 400); } - if (existingExpense.CreatedById != loggedInEmployee.Id) + if (!hasManagePermission && existingExpense.CreatedById != loggedInEmployee.Id) { _logger.LogWarning("User attempted to update expense with ID {ExpenseId} which not created by them", existingExpense.Id); return ApiResponse.ErrorResponse("You donot have access to update this expense", "You donot have access to update this expense", 400); @@ -878,7 +988,7 @@ namespace Marco.Pms.Services.Service var existingEntityBson = _updateLogHelper.EntityToBsonDocument(existingExpense); // Capture state for audit log BEFORE changes _mapper.Map(model, existingExpense); - _context.Entry(existingExpense).State = EntityState.Modified; + existingExpense.StatusId = Draft; try { @@ -1099,14 +1209,10 @@ namespace Marco.Pms.Services.Service #endregion - #region =================================================================== Helper Functions =================================================================== + #endregion - private int ExtractNumber(string id) - { - // Extract trailing number; handles EX_0001, EX-0001, EX0001 - var m = Regex.Match(id ?? string.Empty, @"(\d+)$"); - return m.Success ? int.Parse(m.Value) : int.MinValue; // put invalid IDs at the bottom - } + + #region =================================================================== Helper Functions =================================================================== private static object ExceptionMapper(Exception ex) { return new @@ -1122,164 +1228,8 @@ namespace Marco.Pms.Services.Service } }; } - private async Task> GetAllExpnesRelatedTables(List model, Guid tenantId) + private async Task GetAllExpnesRelatedTablesForSingle(Expenses model, bool hasManagePermission, Guid loggedInEmployeeId, Guid tenantId) { - List expenseList = new List(); - var projectIds = model.Select(m => m.ProjectId).ToList(); - var statusIds = model.Select(m => m.StatusId).ToList(); - var expensesTypeIds = model.Select(m => m.ExpensesTypeId).ToList(); - var paymentModeIds = model.Select(m => m.PaymentModeId).ToList(); - var createdByIds = model.Select(m => m.CreatedById).ToList(); - var paidByIds = model.Select(m => m.PaidById).ToList(); - - var projectTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.Projects.AsNoTracking().Where(p => projectIds.Contains(p.Id) && p.TenantId == tenantId).ToListAsync(); - }); - var paidByTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.Employees.AsNoTracking().Where(e => paidByIds.Contains(e.Id) && e.TenantId == tenantId).ToListAsync(); - }); - var createdByTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.Employees.AsNoTracking().Where(e => createdByIds.Contains(e.Id) && e.TenantId == tenantId).ToListAsync(); - }); - var expenseTypeTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.ExpensesTypeMaster.AsNoTracking().Where(et => expensesTypeIds.Contains(et.Id) && et.TenantId == tenantId).ToListAsync(); - }); - var paymentModeTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.PaymentModeMatser.AsNoTracking().Where(pm => paymentModeIds.Contains(pm.Id) && pm.TenantId == tenantId).ToListAsync(); - }); - var statusMappingTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.ExpensesStatusMapping - .Include(s => s.Status) - .Include(s => s.NextStatus) - .AsNoTracking() - .Where(es => statusIds.Contains(es.StatusId) && es.Status != null) - .GroupBy(s => s.StatusId) - .Select(g => new - { - StatusId = g.Key, - Status = g.Select(s => s.Status).FirstOrDefault(), - NextStatus = g.Select(s => s.NextStatus).OrderBy(s => s!.Name).ToList() - }).ToListAsync(); - }); - var statusTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.ExpensesStatusMaster - .AsNoTracking() - .Where(es => statusIds.Contains(es.Id)) - .ToListAsync(); - }); - var permissionStatusMappingTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.StatusPermissionMapping - .GroupBy(ps => ps.StatusId) - .Select(g => new - { - StatusId = g.Key, - PermissionIds = g.Select(ps => ps.PermissionId).ToList() - }).ToListAsync(); - }); - - // Await all prerequisite checks at once. - await Task.WhenAll(projectTask, expenseTypeTask, paymentModeTask, statusMappingTask, paidByTask, createdByTask, statusTask, permissionStatusMappingTask); - - var projects = projectTask.Result; - var expenseTypes = expenseTypeTask.Result; - var paymentModes = paymentModeTask.Result; - var statusMappings = statusMappingTask.Result; - var permissionStatusMappings = permissionStatusMappingTask.Result; - var paidBys = paidByTask.Result; - var createdBys = createdByTask.Result; - - expenseList = model.Select(m => - { - var response = _mapper.Map(m); - - response.Project = projects.Where(p => p.Id == m.ProjectId).Select(p => _mapper.Map(p)).FirstOrDefault(); - response.PaidBy = paidBys.Where(p => p.Id == m.PaidById).Select(p => _mapper.Map(p)).FirstOrDefault(); - response.CreatedBy = createdBys.Where(e => e.Id == m.CreatedById).Select(e => _mapper.Map(e)).FirstOrDefault(); - response.Status = statusMappings.Where(s => s.StatusId == m.StatusId).Select(s => _mapper.Map(s.Status)).FirstOrDefault(); - if (response.Status == null) - { - var status = statusTask.Result; - response.Status = status.Where(s => s.Id == m.StatusId).Select(s => _mapper.Map(s)).FirstOrDefault(); - } - if (response.Status != null) - { - response.Status.PermissionIds = permissionStatusMappings.Where(ps => ps.StatusId == m.StatusId).Select(ps => ps.PermissionIds).FirstOrDefault(); - } - response.NextStatus = statusMappings.Where(s => s.StatusId == m.StatusId).Select(s => _mapper.Map>(s.NextStatus)).FirstOrDefault(); - if (response.NextStatus != null) - { - foreach (var status in response.NextStatus) - { - status.PermissionIds = permissionStatusMappings.Where(ps => ps.StatusId == status.Id).Select(ps => ps.PermissionIds).FirstOrDefault(); - } - } - response.PaymentMode = paymentModes.Where(pm => pm.Id == m.PaymentModeId).Select(pm => _mapper.Map(pm)).FirstOrDefault(); - response.ExpensesType = expenseTypes.Where(et => et.Id == m.ExpensesTypeId).Select(et => _mapper.Map(et)).FirstOrDefault(); - - return response; - }).ToList(); - - return expenseList; - } - - private async Task GetAllExpnesRelatedTablesForSingle(Expenses model, Guid tenantId) - { - var projectTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.Projects.AsNoTracking().FirstOrDefaultAsync(p => p.Id == model.ProjectId && p.TenantId == tenantId); - }); - var paidByTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.Employees.Include(e => e.JobRole).AsNoTracking().FirstOrDefaultAsync(e => e.Id == model.PaidById && e.TenantId == tenantId); - }); - var createdByTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.Employees.Include(e => e.JobRole).AsNoTracking().FirstOrDefaultAsync(e => e.Id == model.CreatedById && e.TenantId == tenantId); - }); - var reviewedByTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.Employees.Include(e => e.JobRole).AsNoTracking().FirstOrDefaultAsync(e => e.Id == model.ReviewedById && e.TenantId == tenantId); - }); - var approvedByTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.Employees.Include(e => e.JobRole).AsNoTracking().FirstOrDefaultAsync(e => e.Id == model.ApprovedById && e.TenantId == tenantId); - }); - var processedByTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.Employees.Include(e => e.JobRole).AsNoTracking().FirstOrDefaultAsync(e => e.Id == model.ProcessedById && e.TenantId == tenantId); - }); - var expenseTypeTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.ExpensesTypeMaster.AsNoTracking().FirstOrDefaultAsync(et => et.Id == model.ExpensesTypeId && et.TenantId == tenantId); - }); - var paymentModeTask = Task.Run(async () => - { - await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); - return await dbContext.PaymentModeMatser.AsNoTracking().FirstOrDefaultAsync(pm => pm.Id == model.PaymentModeId && pm.TenantId == tenantId); - }); var statusMappingTask = Task.Run(async () => { await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); @@ -1320,60 +1270,58 @@ namespace Marco.Pms.Services.Service FileName = ba.Document.FileName, ContentType = ba.Document.ContentType, S3Key = ba.Document.S3Key, - ThumbS3Key = ba.Document.ThumbS3Key ?? ba.Document.S3Key + ThumbS3Key = ba.Document.ThumbS3Key ?? ba.Document.S3Key, + FileSize = ba.Document.FileSize, }).ToList() }) .FirstOrDefaultAsync(); }); // Await all prerequisite checks at once. - await Task.WhenAll(projectTask, expenseTypeTask, paymentModeTask, statusMappingTask, paidByTask, createdByTask, reviewedByTask, approvedByTask, - processedByTask, statusTask, billAttachmentsTask); + await Task.WhenAll(statusTask, billAttachmentsTask); - var project = projectTask.Result; - var expenseType = expenseTypeTask.Result; - var paymentMode = paymentModeTask.Result; var statusMapping = statusMappingTask.Result; - var paidBy = paidByTask.Result; - var createdBy = createdByTask.Result; - var reviewedBy = reviewedByTask.Result; - var approvedBy = approvedByTask.Result; - var processedBy = processedByTask.Result; var billAttachment = billAttachmentsTask.Result; var response = _mapper.Map(model); - response.Project = _mapper.Map(project); - response.PaidBy = _mapper.Map(paidBy); - response.CreatedBy = _mapper.Map(createdBy); - response.ReviewedBy = _mapper.Map(reviewedBy); - response.ApprovedBy = _mapper.Map(approvedBy); - response.ProcessedBy = _mapper.Map(processedBy); + response.ExpenseUId = $"{model.UIDPrefix}/{model.UIDPostfix:D5}"; + if (model.PaymentRequest != null) + response.PaymentRequestUID = $"{model.PaymentRequest.UIDPrefix}/{model.PaymentRequest.UIDPostfix:D5}"; + response.Project = _mapper.Map(model.Project); + response.PaidBy = _mapper.Map(model.PaidBy); + response.CreatedBy = _mapper.Map(model.CreatedBy); + response.ReviewedBy = _mapper.Map(model.ReviewedBy); + response.ApprovedBy = _mapper.Map(model.ApprovedBy); + response.ProcessedBy = _mapper.Map(model.ProcessedBy); if (statusMapping != null) { response.Status = _mapper.Map(statusMapping.Status); - response.NextStatus = _mapper.Map>(statusMapping.NextStatus); + + // Assign nextStatuses only if: + // 1. The expense was rejected by approver/reviewer AND the current user is the creator, OR + // 2. The expense is in any other status (not rejected) + var isRejected = model.StatusId == RejectedByApprover + || model.StatusId == RejectedByReviewer; + + if ((!isRejected) || (isRejected && (loggedInEmployeeId == model.CreatedById || hasManagePermission))) + { + response.NextStatus = _mapper.Map>(statusMapping.NextStatus); + } } if (response.Status == null) { var status = statusTask.Result; response.Status = _mapper.Map(status); } - response.PaymentMode = _mapper.Map(paymentMode); - response.ExpensesType = _mapper.Map(expenseType); + response.PaymentMode = _mapper.Map(model.PaymentMode); + response.ExpenseCategory = _mapper.Map(model.ExpenseCategory); if (billAttachment != null) response.Documents = billAttachment.Documents; return response; } - - - /// - /// Deserializes the filter string, handling multiple potential formats (e.g., direct JSON vs. escaped JSON string). - /// - /// The JSON filter string from the request. - /// An object or null if deserialization fails. private ExpensesFilter? TryDeserializeFilter(string? filter) { if (string.IsNullOrWhiteSpace(filter)) @@ -1412,6 +1360,82 @@ namespace Marco.Pms.Services.Service } return expenseFilter; } + private PaymentRequestFilter? TryDeserializePaymentRequestFilter(string? filter) + { + if (string.IsNullOrWhiteSpace(filter)) + { + return null; + } + + var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; + PaymentRequestFilter? expenseFilter = null; + + try + { + // First, try to deserialize directly. This is the expected case (e.g., from a web client). + expenseFilter = JsonSerializer.Deserialize(filter, options); + } + catch (JsonException ex) + { + _logger.LogError(ex, "[{MethodName}] Failed to directly deserialize filter. Attempting to unescape and re-parse. Filter: {Filter}", nameof(TryDeserializePaymentRequestFilter), filter); + + // If direct deserialization fails, it might be an escaped string (common with tools like Postman or some mobile clients). + try + { + // Unescape the string first, then deserialize the result. + string unescapedJsonString = JsonSerializer.Deserialize(filter, options) ?? ""; + if (!string.IsNullOrWhiteSpace(unescapedJsonString)) + { + expenseFilter = JsonSerializer.Deserialize(unescapedJsonString, options); + } + } + catch (JsonException ex1) + { + // If both attempts fail, log the final error and return null. + _logger.LogError(ex1, "[{MethodName}] All attempts to deserialize the filter failed. Filter will be ignored. Filter: {Filter}", nameof(TryDeserializePaymentRequestFilter), filter); + return null; + } + } + return expenseFilter; + } + private RecurringPaymentFilter? TryDeserializeRecurringPaymentFilter(string? filter) + { + if (string.IsNullOrWhiteSpace(filter)) + { + return null; + } + + var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; + RecurringPaymentFilter? expenseFilter = null; + + try + { + // First, try to deserialize directly. This is the expected case (e.g., from a web client). + expenseFilter = JsonSerializer.Deserialize(filter, options); + } + catch (JsonException ex) + { + _logger.LogError(ex, "[{MethodName}] Failed to directly deserialize filter. Attempting to unescape and re-parse. Filter: {Filter}", nameof(TryDeserializeRecurringPaymentFilter), filter); + + // If direct deserialization fails, it might be an escaped string (common with tools like Postman or some mobile clients). + try + { + // Unescape the string first, then deserialize the result. + string unescapedJsonString = JsonSerializer.Deserialize(filter, options) ?? ""; + if (!string.IsNullOrWhiteSpace(unescapedJsonString)) + { + expenseFilter = JsonSerializer.Deserialize(unescapedJsonString, options); + } + } + catch (JsonException ex1) + { + // If both attempts fail, log the final error and return null. + _logger.LogError(ex1, "[{MethodName}] All attempts to deserialize the filter failed. Filter will be ignored. Filter: {Filter}", nameof(TryDeserializeRecurringPaymentFilter), filter); + return null; + } + } + return expenseFilter; + } /// /// Processes and uploads attachments concurrently, then adds the resulting entities to the main DbContext. @@ -1431,7 +1455,7 @@ namespace Marco.Pms.Services.Service // Create a list of tasks to be executed concurrently. var processingTasks = attachments.Select(attachment => - ProcessSingleAttachmentAsync(attachment, expense, employeeId, tenantId, batchId) + ProcessSingleExpenseAttachmentAsync(attachment, expense, employeeId, tenantId, batchId) ).ToList(); var results = await Task.WhenAll(processingTasks); @@ -1448,7 +1472,7 @@ namespace Marco.Pms.Services.Service /// /// Handles the logic for a single attachment: upload to S3 and create corresponding entities. /// - private async Task<(Document document, BillAttachments billAttachment)> ProcessSingleAttachmentAsync( + private async Task<(Document document, BillAttachments billAttachment)> ProcessSingleExpenseAttachmentAsync( FileUploadModel attachment, Expenses expense, Guid employeeId, Guid tenantId, Guid batchId) { var base64Data = attachment.Base64Data!.Contains(',') ? attachment.Base64Data[(attachment.Base64Data.IndexOf(",") + 1)..] : attachment.Base64Data; @@ -1460,7 +1484,7 @@ namespace Marco.Pms.Services.Service await _s3Service.UploadFileAsync(base64Data, fileType, objectKey); _logger.LogInfo("Uploaded file to S3 with key: {ObjectKey}", objectKey); - return CreateAttachmentEntities(batchId, expense.Id, employeeId, tenantId, objectKey, attachment); + return CreateExpenseAttachmentEntities(batchId, expense.Id, employeeId, tenantId, objectKey, attachment); } @@ -1468,7 +1492,7 @@ namespace Marco.Pms.Services.Service /// A private static helper method to create Document and BillAttachment entities. /// This remains unchanged as it's a pure data-shaping method. /// - private static (Document document, BillAttachments billAttachment) CreateAttachmentEntities( + private static (Document document, BillAttachments billAttachment) CreateExpenseAttachmentEntities( Guid batchId, Guid expenseId, Guid uploadedById, Guid tenantId, string s3Key, FileUploadModel attachmentDto) { var document = new Document @@ -1486,6 +1510,54 @@ namespace Marco.Pms.Services.Service return (document, billAttachment); } + /// + /// Handles the logic for a single attachment: upload to S3 and create corresponding entities. + /// + private async Task<(Document document, PaymentRequestAttachment billAttachment)> ProcessSinglePaymentRequestAttachmentAsync( + FileUploadModel attachment, PaymentRequest paymentRequest, Guid employeeId, Guid tenantId, Guid batchId) + { + var base64Data = attachment.Base64Data!.Contains(',') ? attachment.Base64Data[(attachment.Base64Data.IndexOf(",") + 1)..] : attachment.Base64Data; + var fileType = _s3Service.GetContentTypeFromBase64(base64Data); + var fileName = _s3Service.GenerateFileName(fileType, paymentRequest.Id, "PaymentRequest"); + string objectKey; + if (paymentRequest.ProjectId.HasValue) + { + objectKey = $"tenant-{tenantId}/project-{paymentRequest.ProjectId}/PaymentRequest/{fileName}"; + } + else + { + objectKey = $"tenant-{tenantId}/PaymentRequest/{fileName}"; + } + + // Await the I/O-bound upload operation directly. + await _s3Service.UploadFileAsync(base64Data, fileType, objectKey); + _logger.LogInfo("Uploaded file to S3 with key: {ObjectKey}", objectKey); + + return CreatePaymentRequestAttachmentEntities(batchId, paymentRequest.Id, employeeId, tenantId, objectKey, attachment); + } + + /// + /// A private static helper method to create Document and BillAttachment entities. + /// This remains unchanged as it's a pure data-shaping method. + /// + private static (Document document, PaymentRequestAttachment paymentRequestAttachment) CreatePaymentRequestAttachmentEntities( + Guid batchId, Guid paymentRequestId, Guid uploadedById, Guid tenantId, string s3Key, FileUploadModel attachmentDto) + { + var document = new Document + { + BatchId = batchId, + UploadedById = uploadedById, + FileName = attachmentDto.FileName ?? "", + ContentType = attachmentDto.ContentType ?? "", + S3Key = s3Key, + FileSize = attachmentDto.FileSize, + UploadedAt = DateTime.UtcNow, + TenantId = tenantId + }; + var paymentRequestAttachment = new PaymentRequestAttachment { Document = document, PaymentRequestId = paymentRequestId, TenantId = tenantId }; + return (document, paymentRequestAttachment); + } + private async Task DeleteAttachemnts(List documentIds) { var attachmentTask = Task.Run(async () => @@ -1527,6 +1599,118 @@ namespace Marco.Pms.Services.Service await Task.WhenAll(attachmentTask, documentsTask); } + private async Task DeletePaymentRequestAttachemnts(List documentIds) + { + var attachmentTask = Task.Run(async () => + { + await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); + var attachments = await dbContext.PaymentRequestAttachments.AsNoTracking().Where(ba => documentIds.Contains(ba.DocumentId)).ToListAsync(); + + dbContext.PaymentRequestAttachments.RemoveRange(attachments); + await dbContext.SaveChangesAsync(); + }); + var documentsTask = Task.Run(async () => + { + await using var dbContext = await _dbContextFactory.CreateDbContextAsync(); + var documents = await dbContext.Documents.AsNoTracking().Where(ba => documentIds.Contains(ba.Id)).ToListAsync(); + + if (documents.Any()) + { + dbContext.Documents.RemoveRange(documents); + await dbContext.SaveChangesAsync(); + + List deletionObject = new List(); + foreach (var document in documents) + { + deletionObject.Add(new S3DeletionObject + { + Key = document.S3Key + }); + if (!string.IsNullOrWhiteSpace(document.ThumbS3Key) && document.ThumbS3Key != document.S3Key) + { + deletionObject.Add(new S3DeletionObject + { + Key = document.ThumbS3Key + }); + } + } + await _updateLogHelper.PushToS3DeletionAsync(deletionObject); + } + }); + + await Task.WhenAll(attachmentTask, documentsTask); + } + + private static bool IsRecurringApplicable(int numberOfIteration, PLAN_FREQUENCY frequency, DateTime strikeDate, DateTime? latestPRGeneratedAt) + { + List dates = new List(); + DateTime currentDate = strikeDate; + DateTime endDate = DateTime.UtcNow.Date; + + switch (frequency) + { + case PLAN_FREQUENCY.MONTHLY: + while (currentDate <= endDate) + { + dates.Add(currentDate); + currentDate = currentDate.AddMonths(1); + } + break; + case PLAN_FREQUENCY.QUARTERLY: + while (currentDate <= endDate) + { + dates.Add(currentDate); + currentDate = currentDate.AddMonths(3); + } + break; + case PLAN_FREQUENCY.HALF_YEARLY: + while (currentDate <= endDate) + { + dates.Add(currentDate); + currentDate = currentDate.AddMonths(6); + } + break; + case PLAN_FREQUENCY.YEARLY: + while (currentDate <= endDate) + { + dates.Add(currentDate); + currentDate = currentDate.AddYears(1); + } + break; + case PLAN_FREQUENCY.DAILY: + while (currentDate <= endDate) + { + dates.Add(currentDate); + currentDate = currentDate.AddDays(1); + } + break; + case PLAN_FREQUENCY.WEEKLY: + while (currentDate <= endDate) + { + dates.Add(currentDate); + currentDate = currentDate.AddDays(7); + } + break; + } + + if (!dates.Any() || dates.Count > numberOfIteration) + { + return false; + } + + if (dates.Last() != endDate) + { + return false; + } + + if (latestPRGeneratedAt.HasValue && latestPRGeneratedAt.Value == endDate) + { + return false; + } + + return true; + + } #endregion } diff --git a/Marco.Pms.Services/Service/MasterDataService.cs b/Marco.Pms.Services/Service/MasterDataService.cs index 7e4a735..2372b6e 100644 --- a/Marco.Pms.Services/Service/MasterDataService.cs +++ b/Marco.Pms.Services/Service/MasterDataService.cs @@ -1,4 +1,5 @@ -using Marco.Pms.Model.Forum; +using Marco.Pms.Model.Expenses.Masters; +using Marco.Pms.Model.Forum; using Marco.Pms.Model.Master; namespace Marco.Pms.Services.Service @@ -211,11 +212,11 @@ namespace Marco.Pms.Services.Service } }; } - public List GetExpensesTypeesData(Guid tenantId) + public List GetExpenseCategoryData(Guid tenantId) { - return new List + return new List { - new ExpensesTypeMaster + new ExpenseCategoryMaster { Id = Guid.NewGuid(), Name = "Procurement", @@ -225,7 +226,7 @@ namespace Marco.Pms.Services.Service IsAttachmentRequried = true, TenantId = tenantId }, - new ExpensesTypeMaster + new ExpenseCategoryMaster { Id = Guid.NewGuid(), Name = "Transport", @@ -235,7 +236,7 @@ namespace Marco.Pms.Services.Service IsAttachmentRequried = false, TenantId = tenantId }, - new ExpensesTypeMaster + new ExpenseCategoryMaster { Id = Guid.NewGuid(), Name = "Travelling", @@ -245,7 +246,7 @@ namespace Marco.Pms.Services.Service IsAttachmentRequried = false, TenantId = tenantId }, - new ExpensesTypeMaster + new ExpenseCategoryMaster { Id = Guid.NewGuid(), Name = "Mobilization", @@ -255,7 +256,7 @@ namespace Marco.Pms.Services.Service IsAttachmentRequried = true, TenantId = tenantId }, - new ExpensesTypeMaster + new ExpenseCategoryMaster { Id = Guid.NewGuid(), Name = "Employee Welfare", @@ -265,7 +266,7 @@ namespace Marco.Pms.Services.Service IsAttachmentRequried = true, TenantId = tenantId }, - new ExpensesTypeMaster + new ExpenseCategoryMaster { Id = Guid.NewGuid(), Name = "Maintenance & Utilities", @@ -275,7 +276,7 @@ namespace Marco.Pms.Services.Service IsAttachmentRequried = true, TenantId = tenantId }, - new ExpensesTypeMaster + new ExpenseCategoryMaster { Id = Guid.NewGuid(), Name = "Vendor/Supplier Payments", @@ -285,7 +286,7 @@ namespace Marco.Pms.Services.Service IsAttachmentRequried = true, TenantId = tenantId }, - new ExpensesTypeMaster + new ExpenseCategoryMaster { Id = Guid.NewGuid(), Name = "Compliance & Safety", @@ -297,44 +298,6 @@ namespace Marco.Pms.Services.Service } }; } - public List GetPaymentModesData(Guid tenantId) - { - return new List - { - new PaymentModeMatser - { - Id = Guid.NewGuid(), - Name = "Cash", - Description = "Physical currency; still used for small or informal transactions.", - IsActive = true, - TenantId = tenantId - }, - new PaymentModeMatser - { - Id = Guid.NewGuid(), - Name = "Cheque", - Description = "Paper-based payment order; less common now due to processing delays and fraud risks.", - IsActive = true, - TenantId = tenantId - }, - new PaymentModeMatser - { - Id = Guid.NewGuid(), - Name = "NetBanking", - Description = "Online banking portals used to transfer funds directly between accounts", - IsActive = true, - TenantId = tenantId - }, - new PaymentModeMatser - { - Id = Guid.NewGuid(), - Name = "UPI", - Description = "Real-time bank-to-bank transfer using mobile apps; widely used for peer-to-peer and merchant payments.", - IsActive = true, - TenantId = tenantId - } - }; - } public List GetData(Guid tenantId) { return new List diff --git a/Marco.Pms.Services/Service/MasterService.cs b/Marco.Pms.Services/Service/MasterService.cs index f60ee38..354f2bf 100644 --- a/Marco.Pms.Services/Service/MasterService.cs +++ b/Marco.Pms.Services/Service/MasterService.cs @@ -7,19 +7,21 @@ using Marco.Pms.Model.DocumentManager; using Marco.Pms.Model.Dtos.Activities; using Marco.Pms.Model.Dtos.Collection; using Marco.Pms.Model.Dtos.DocumentManager; +using Marco.Pms.Model.Dtos.Expenses.Masters; using Marco.Pms.Model.Dtos.Master; using Marco.Pms.Model.Employees; using Marco.Pms.Model.Entitlements; +using Marco.Pms.Model.Expenses.Masters; using Marco.Pms.Model.Master; using Marco.Pms.Model.MongoDBModels.Utility; using Marco.Pms.Model.Utilities; using Marco.Pms.Model.ViewModels.Activities; using Marco.Pms.Model.ViewModels.Collection; using Marco.Pms.Model.ViewModels.DocumentManager; +using Marco.Pms.Model.ViewModels.Expenses.Masters; using Marco.Pms.Model.ViewModels.Master; using Marco.Pms.Services.Service.ServiceInterfaces; using MarcoBMS.Services.Service; -using Microsoft.CodeAnalysis; using Microsoft.EntityFrameworkCore; namespace Marco.Pms.Services.Service @@ -52,6 +54,53 @@ namespace Marco.Pms.Services.Service _updateLogHelper = updateLogHelper ?? throw new ArgumentNullException(nameof(updateLogHelper)); } + #region =================================================================== Recurring Payment Status APIs =================================================================== + + public async Task> GetRecurringPaymentStatusAsync(Employee loggedInEmployee, Guid tenantId) + { + _logger.LogDebug("GetRecurringPaymentStatusAsync called"); + + try + { + // Step 1: Fetch global recurring payment status + var status = await _context.RecurringPaymentStatus.OrderBy(rps => rps.Name).ToListAsync(); + + _logger.LogInfo("Fetched {Count} recurring payment status records for tenantId: {TenantId}", status.Count, tenantId); + + return ApiResponse.SuccessResponse(status, $"{status.Count} record(s) of recurring payment status fetched successfully", 200); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error fetching recurring payment status"); + return ApiResponse.ErrorResponse("An error occurred while fetching recurring payment status", ex.Message, 500); + } + } + #endregion + + #region =================================================================== Currency APIs =================================================================== + + public async Task> GetCurrencyAsync(Employee loggedInEmployee, Guid tenantId) + { + _logger.LogDebug("GetCurrencyAsync called"); + + try + { + // Step 1: Fetch global currencies + var currencies = await _context.CurrencyMaster.OrderBy(ot => ot.CurrencyName).ToListAsync(); + + _logger.LogInfo("Fetched {Count} currency records for tenantId: {TenantId}", currencies.Count, tenantId); + + return ApiResponse.SuccessResponse(currencies, $"{currencies.Count} record(s) of currency fetched successfully", 200); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error fetching currency"); + return ApiResponse.ErrorResponse("An error occurred while fetching currency", ex.Message, 500); + } + } + + #endregion + #region =================================================================== Organization Type APIs =================================================================== public async Task> GetOrganizationTypesAsync(Employee loggedInEmployee, Guid tenantId) @@ -2044,59 +2093,59 @@ namespace Marco.Pms.Services.Service #endregion - #region =================================================================== Expenses Type APIs =================================================================== + #region =================================================================== Expenses Category APIs =================================================================== - public async Task> GetExpenseTypeListAsync(Employee loggedInEmployee, Guid tenantId, bool isActive) + public async Task> GetExpenseCategoryListAsync(Employee loggedInEmployee, Guid tenantId, bool isActive) { try { - // Featching the list of Expenses Type. - var typeList = await _context.ExpensesTypeMaster.Where(et => et.TenantId == tenantId && et.IsActive == isActive).ToListAsync(); - var response = _mapper.Map>(typeList); + // Featching the list of Expenses Category. + var categories = await _context.ExpenseCategoryMasters.Where(et => et.TenantId == tenantId && et.IsActive == isActive).ToListAsync(); + var response = _mapper.Map>(categories); - _logger.LogInfo("{Count} records of expense type have been fetched successfully by employee {EmployeeId}", response.Count, loggedInEmployee.Id); - return ApiResponse.SuccessResponse(response, $"{response.Count} records of expense type have been fetched successfully.", 200); + _logger.LogInfo("{Count} records of expense category have been fetched successfully by employee {EmployeeId}", response.Count, loggedInEmployee.Id); + return ApiResponse.SuccessResponse(response, $"{response.Count} records of expense category have been fetched successfully.", 200); } catch (Exception ex) { - _logger.LogError(ex, "Error occured while fetching list of expense type list by employee {EmployeeId}", loggedInEmployee.Id); + _logger.LogError(ex, "Error occured while fetching list of expense category list by employee {EmployeeId}", loggedInEmployee.Id); return ApiResponse.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500); } } - public async Task> CreateExpenseTypeAsync(ExpensesTypeMasterDto model, Employee loggedInEmployee, Guid tenantId) + public async Task> CreateExpenseCategoryAsync(ExpenseCategoryMasterDto model, Employee loggedInEmployee, Guid tenantId) { try { var hasManagePermission = await _permission.HasPermission(PermissionsMaster.ManageMasters, loggedInEmployee.Id); if (!hasManagePermission) { - _logger.LogWarning("Access DENIED for employee {EmployeeId} for managing EXPANSES TYPE MASTER.", loggedInEmployee.Id); + _logger.LogWarning("Access DENIED for employee {EmployeeId} for managing EXPANSES CATEGORY MASTER.", loggedInEmployee.Id); return ApiResponse.ErrorResponse("Access Denied.", "You do not have permission to Manage masters", 403); } - var expensesType = _mapper.Map(model); - expensesType.TenantId = tenantId; + var expensesCategory = _mapper.Map(model); + expensesCategory.TenantId = tenantId; - _context.ExpensesTypeMaster.Add(expensesType); + _context.ExpenseCategoryMasters.Add(expensesCategory); await _context.SaveChangesAsync(); - _logger.LogInfo("New Expense Type {ExpensesTypeId} was added by employee {EmployeeId}", expensesType.Id, loggedInEmployee.Id); + _logger.LogInfo("New Expense Category {ExpensesCategoryId} was added by employee {EmployeeId}", expensesCategory.Id, loggedInEmployee.Id); - var response = _mapper.Map(expensesType); - return ApiResponse.SuccessResponse(response, "Expense type craeted Successfully", 201); + var response = _mapper.Map(expensesCategory); + return ApiResponse.SuccessResponse(response, "Expense category craeted Successfully", 201); } catch (DbUpdateException dbEx) { - _logger.LogError(dbEx, "Database Exception occured while adding new expense type by employee {EmployeeId}", loggedInEmployee.Id); + _logger.LogError(dbEx, "Database Exception occured while adding new expense category by employee {EmployeeId}", loggedInEmployee.Id); return ApiResponse.ErrorResponse("Internal Error occured", ExceptionMapper(dbEx), 500); } catch (Exception ex) { - _logger.LogError(ex, "Exception occured while adding new expense type by employee {EmployeeId}", loggedInEmployee.Id); + _logger.LogError(ex, "Exception occured while adding new expense category by employee {EmployeeId}", loggedInEmployee.Id); return ApiResponse.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500); } } - public async Task> UpdateExpenseTypeAsync(Guid id, ExpensesTypeMasterDto model, Employee loggedInEmployee, Guid tenantId) + public async Task> UpdateExpenseCategoryAsync(Guid id, ExpenseCategoryMasterDto model, Employee loggedInEmployee, Guid tenantId) { try { @@ -2104,7 +2153,7 @@ namespace Marco.Pms.Services.Service var hasManagePermission = await _permission.HasPermission(PermissionsMaster.ManageMasters, loggedInEmployee.Id); if (!hasManagePermission) { - _logger.LogWarning("Access DENIED for employee {EmployeeId} for managing EXPANSES TYPE MASTER.", loggedInEmployee.Id); + _logger.LogWarning("Access DENIED for employee {EmployeeId} for managing EXPANSES CATEGORY MASTER.", loggedInEmployee.Id); return ApiResponse.ErrorResponse("Access Denied.", "You do not have permission to Manage masters", 403); } @@ -2115,52 +2164,52 @@ namespace Marco.Pms.Services.Service return ApiResponse.ErrorResponse("Invalid Data", "User has send invalid payload", 400); } - var expensesType = await _context.ExpensesTypeMaster.AsNoTracking().FirstOrDefaultAsync(et => et.Id == model.Id.Value && et.TenantId == tenantId); + var expenseCategory = await _context.ExpenseCategoryMasters.AsNoTracking().FirstOrDefaultAsync(et => et.Id == model.Id.Value && et.TenantId == tenantId); - // Checking if expense type exists - if (expensesType == null) + // Checking if expense category exists + if (expenseCategory == null) { - _logger.LogWarning("Employee {EmployeeId} tries to update expense type, but not found in database", loggedInEmployee.Id); - return ApiResponse.ErrorResponse("Expense Type not found", "Expense Type not found", 404); + _logger.LogWarning("Employee {EmployeeId} tries to update expense category, but not found in database", loggedInEmployee.Id); + return ApiResponse.ErrorResponse("Expense Category not found", "Expense Category not found", 404); } - // Mapping ExpensesTypeMaster to BsonDocument - var existingEntityBson = _updateLogHelper.EntityToBsonDocument(expensesType); + // Mapping ExpenseCategoryMaster to BsonDocument + var existingEntityBson = _updateLogHelper.EntityToBsonDocument(expenseCategory); - // Mapping ExpensesTypeMasterDto to ExpensesTypeMaster - _mapper.Map(model, expensesType); + // Mapping ExpenseCategoryMasterDto to ExpenseCategoryMaster + _mapper.Map(model, expenseCategory); - _context.ExpensesTypeMaster.Update(expensesType); + _context.ExpenseCategoryMasters.Update(expenseCategory); await _context.SaveChangesAsync(); - _logger.LogInfo("Expense Type {ExpensesTypeId} was updated by employee {EmployeeId}", expensesType.Id, loggedInEmployee.Id); + _logger.LogInfo("Expense Category {ExpensesCategoryId} was updated by employee {EmployeeId}", expenseCategory.Id, loggedInEmployee.Id); // Saving the old entity in mongoDB await _updateLogHelper.PushToUpdateLogsAsync(new UpdateLogsObject { - EntityId = expensesType.Id.ToString(), + EntityId = expenseCategory.Id.ToString(), UpdatedById = loggedInEmployee.Id.ToString(), OldObject = existingEntityBson, UpdatedAt = DateTime.UtcNow - }, "ExpensesTypeMasterModificationLog"); + }, "ExpensesCategoryMasterModificationLog"); - // Mapping ExpensesTypeMaster to ExpensesTypeMasterVM - var response = _mapper.Map(expensesType); - return ApiResponse.SuccessResponse(response, "Expense type updated Successfully", 200); + // Mapping ExpenseCategoryMaster to ExpenseCategoryMasterVM + var response = _mapper.Map(expenseCategory); + return ApiResponse.SuccessResponse(response, "Expense category updated Successfully", 200); } catch (DbUpdateException dbEx) { - _logger.LogError(dbEx, "Database Exception occured while updating expense type by employee {EmployeeId}", loggedInEmployee.Id); + _logger.LogError(dbEx, "Database Exception occured while updating expense category by employee {EmployeeId}", loggedInEmployee.Id); return ApiResponse.ErrorResponse("Internal Error occured", ExceptionMapper(dbEx), 500); } catch (Exception ex) { - _logger.LogError(ex, "Exception occured while updating expense type by employee {EmployeeId}", loggedInEmployee.Id); + _logger.LogError(ex, "Exception occured while updating expense category by employee {EmployeeId}", loggedInEmployee.Id); return ApiResponse.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500); } } - public async Task> DeleteExpenseTypeAsync(Guid id, bool isActive, Employee loggedInEmployee, Guid tenantId) + public async Task> DeleteExpenseCategoryAsync(Guid id, bool isActive, Employee loggedInEmployee, Guid tenantId) { string action = isActive ? "restore" : "delete"; try @@ -2169,49 +2218,49 @@ namespace Marco.Pms.Services.Service var hasManagePermission = await _permission.HasPermission(PermissionsMaster.ManageMasters, loggedInEmployee.Id); if (!hasManagePermission) { - _logger.LogWarning("Access DENIED for employee {EmployeeId} for managing EXPANSES TYPE MASTER.", loggedInEmployee.Id); + _logger.LogWarning("Access DENIED for employee {EmployeeId} for managing EXPANSES CATEGORY MASTER.", loggedInEmployee.Id); return ApiResponse.ErrorResponse("Access Denied.", "You do not have permission to Manage masters", 403); } - var expensesType = await _context.ExpensesTypeMaster.FirstOrDefaultAsync(et => et.Id == id && et.TenantId == tenantId); + var expenseCategory = await _context.ExpenseCategoryMasters.FirstOrDefaultAsync(et => et.Id == id && et.TenantId == tenantId); - // Checking if expense type exists - if (expensesType == null) + // Checking if expense category exists + if (expenseCategory == null) { - _logger.LogWarning("Employee {EmployeeId} tries to {Action} expense type, but not found in database", loggedInEmployee.Id, action); - return ApiResponse.ErrorResponse("Expense Type not found", "Expense Type not found", 404); + _logger.LogWarning("Employee {EmployeeId} tries to {Action} expense category, but not found in database", loggedInEmployee.Id, action); + return ApiResponse.ErrorResponse("Expense Category not found", "Expense Category not found", 404); } - // Mapping ExpensesTypeMaster to BsonDocument - var existingEntityBson = _updateLogHelper.EntityToBsonDocument(expensesType); + // Mapping ExpenseCategoryMaster to BsonDocument + var existingEntityBson = _updateLogHelper.EntityToBsonDocument(expenseCategory); - expensesType.IsActive = isActive; + expenseCategory.IsActive = isActive; await _context.SaveChangesAsync(); - _logger.LogInfo("Expense Type {ExpensesTypeId} was {Action}d by employee {EmployeeId}", expensesType.Id, action, loggedInEmployee.Id); + _logger.LogInfo("Expense Category {ExpensesCategoryId} was {Action}d by employee {EmployeeId}", expenseCategory.Id, action, loggedInEmployee.Id); // Saving the old entity in mongoDB await _updateLogHelper.PushToUpdateLogsAsync(new UpdateLogsObject { - EntityId = expensesType.Id.ToString(), + EntityId = expenseCategory.Id.ToString(), UpdatedById = loggedInEmployee.Id.ToString(), OldObject = existingEntityBson, UpdatedAt = DateTime.UtcNow - }, "ExpensesTypeMasterModificationLog"); + }, "ExpensesCategoryMasterModificationLog"); - // Mapping ExpensesTypeMaster to ExpensesTypeMasterVM - var response = _mapper.Map(expensesType); - return ApiResponse.SuccessResponse(response, $"Expense type {action}d Successfully", 200); + // Mapping ExpenseCategoryMaster to ExpenseCategoryMasterVM + var response = _mapper.Map(expenseCategory); + return ApiResponse.SuccessResponse(response, $"Expense category {action}d Successfully", 200); } catch (DbUpdateException dbEx) { - _logger.LogError(dbEx, "Database Exception occured while {Action}ing expense type by employee {EmployeeId}", action, loggedInEmployee.Id); + _logger.LogError(dbEx, "Database Exception occured while {Action}ing expense category by employee {EmployeeId}", action, loggedInEmployee.Id); return ApiResponse.ErrorResponse("Internal Error occured", ExceptionMapper(dbEx), 500); } catch (Exception ex) { - _logger.LogError(ex, "Exception occured while {Action}ing expense type by employee {EmployeeId}", action, loggedInEmployee.Id); + _logger.LogError(ex, "Exception occured while {Action}ing expense category by employee {EmployeeId}", action, loggedInEmployee.Id); return ApiResponse.ErrorResponse("Internal Error occured", ExceptionMapper(ex), 500); } } @@ -2259,7 +2308,7 @@ namespace Marco.Pms.Services.Service try { // Featching the list of Payment Modes. - var paymentModes = await _context.PaymentModeMatser.Where(pm => pm.TenantId == tenantId && pm.IsActive == isActive).ToListAsync(); + var paymentModes = await _context.PaymentModeMatser.Where(pm => pm.IsActive == isActive).ToListAsync(); var response = _mapper.Map>(paymentModes); _logger.LogInfo("{Count} records of payment modes have been fetched successfully by employee {EmployeeId}", response.Count, loggedInEmployee.Id); @@ -2284,7 +2333,6 @@ namespace Marco.Pms.Services.Service } // Mapping the DTO to PaymentModeMatser Model var paymentMode = _mapper.Map(model); - paymentMode.TenantId = tenantId; _context.PaymentModeMatser.Add(paymentMode); await _context.SaveChangesAsync(); @@ -2325,7 +2373,7 @@ namespace Marco.Pms.Services.Service return ApiResponse.ErrorResponse("Invalid Data", "User has send invalid payload", 400); } - var paymentMode = await _context.PaymentModeMatser.AsNoTracking().FirstOrDefaultAsync(et => et.Id == model.Id.Value && et.TenantId == tenantId); + var paymentMode = await _context.PaymentModeMatser.AsNoTracking().FirstOrDefaultAsync(et => et.Id == model.Id.Value); // Checking if Payment Mode exists if (paymentMode == null) @@ -2383,7 +2431,7 @@ namespace Marco.Pms.Services.Service return ApiResponse.ErrorResponse("Access Denied.", "You do not have permission to Manage masters", 403); } - var paymentMode = await _context.PaymentModeMatser.FirstOrDefaultAsync(et => et.Id == id && et.TenantId == tenantId); + var paymentMode = await _context.PaymentModeMatser.FirstOrDefaultAsync(et => et.Id == id); // Checking if Payment Mode exists if (paymentMode == null) diff --git a/Marco.Pms.Services/Service/ServiceInterfaces/IExpensesService.cs b/Marco.Pms.Services/Service/ServiceInterfaces/IExpensesService.cs index 5d84eab..70c339c 100644 --- a/Marco.Pms.Services/Service/ServiceInterfaces/IExpensesService.cs +++ b/Marco.Pms.Services/Service/ServiceInterfaces/IExpensesService.cs @@ -6,13 +6,18 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces { public interface IExpensesService { + #region =================================================================== Expenses Functions =================================================================== Task> GetExpensesListAsync(Employee loggedInEmployee, Guid tenantId, string? searchString, string? filter, int pageSize, int pageNumber); - Task> GetExpenseDetailsAsync(Guid id, Employee loggedInEmployee, Guid tenantId); + Task> GetExpenseDetailsAsync(Guid? id, string? expenseUId, Employee loggedInEmployee, Guid tenantId); Task> GetSupplerNameListAsync(Employee loggedInEmployee, Guid tenantId); Task> GetFilterObjectAsync(Employee loggedInEmployee, Guid tenantId); Task> CreateExpenseAsync(CreateExpensesDto dto, Employee loggedInEmployee, Guid tenantId); Task> ChangeStatusAsync(ExpenseRecordDto model, Employee loggedInEmployee, Guid tenantId); Task> UpdateExpanseAsync(Guid id, UpdateExpensesDto model, Employee loggedInEmployee, Guid tenantId); Task> DeleteExpanseAsync(Guid id, Employee loggedInEmployee, Guid tenantId); + #endregion + + + } } diff --git a/Marco.Pms.Services/Service/ServiceInterfaces/IMasterService.cs b/Marco.Pms.Services/Service/ServiceInterfaces/IMasterService.cs index 4515b99..423cfcf 100644 --- a/Marco.Pms.Services/Service/ServiceInterfaces/IMasterService.cs +++ b/Marco.Pms.Services/Service/ServiceInterfaces/IMasterService.cs @@ -1,6 +1,7 @@ using Marco.Pms.Model.Dtos.Activities; using Marco.Pms.Model.Dtos.Collection; using Marco.Pms.Model.Dtos.DocumentManager; +using Marco.Pms.Model.Dtos.Expenses.Masters; using Marco.Pms.Model.Dtos.Master; using Marco.Pms.Model.Employees; using Marco.Pms.Model.Utilities; @@ -9,8 +10,17 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces { public interface IMasterService { - #region =================================================================== Organization Type APIs =================================================================== + #region =================================================================== Recurring Payment Status APIs =================================================================== + Task> GetRecurringPaymentStatusAsync(Employee loggedInEmployee, Guid tenantId); + #endregion + + #region =================================================================== Currency APIs =================================================================== + Task> GetCurrencyAsync(Employee loggedInEmployee, Guid tenantId); + + #endregion + + #region =================================================================== Organization Type APIs =================================================================== Task> GetOrganizationTypesAsync(Employee loggedInEmployee, Guid tenantId); #endregion @@ -71,11 +81,11 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces Task> DeleteWorkStatus(Guid id, Employee loggedInEmployee, Guid tenantId); #endregion - #region =================================================================== Expenses Type APIs =================================================================== - Task> GetExpenseTypeListAsync(Employee loggedInEmployee, Guid tenantId, bool isActive); - Task> CreateExpenseTypeAsync(ExpensesTypeMasterDto model, Employee loggedInEmployee, Guid tenantId); - Task> UpdateExpenseTypeAsync(Guid id, ExpensesTypeMasterDto model, Employee loggedInEmployee, Guid tenantId); - Task> DeleteExpenseTypeAsync(Guid id, bool isActive, Employee loggedInEmployee, Guid tenantId); + #region =================================================================== Expenses Category APIs =================================================================== + Task> GetExpenseCategoryListAsync(Employee loggedInEmployee, Guid tenantId, bool isActive); + Task> CreateExpenseCategoryAsync(ExpenseCategoryMasterDto model, Employee loggedInEmployee, Guid tenantId); + Task> UpdateExpenseCategoryAsync(Guid id, ExpenseCategoryMasterDto model, Employee loggedInEmployee, Guid tenantId); + Task> DeleteExpenseCategoryAsync(Guid id, bool isActive, Employee loggedInEmployee, Guid tenantId); #endregion diff --git a/Marco.Pms.Services/Service/TenantService.cs b/Marco.Pms.Services/Service/TenantService.cs index e085f7b..711ca33 100644 --- a/Marco.Pms.Services/Service/TenantService.cs +++ b/Marco.Pms.Services/Service/TenantService.cs @@ -521,11 +521,9 @@ namespace Marco.Pms.Services.Service } if (features.Modules?.Expense?.Enabled ?? false) { - var expensesTypeMaster = _masteData.GetExpensesTypeesData(tenant.Id); - var paymentModeMatser = _masteData.GetPaymentModesData(tenant.Id); + var expenseCategoryMaster = _masteData.GetExpenseCategoryData(tenant.Id); - _context.ExpensesTypeMaster.AddRange(expensesTypeMaster); - _context.PaymentModeMatser.AddRange(paymentModeMatser); + _context.ExpenseCategoryMasters.AddRange(expenseCategoryMaster); } await _context.SaveChangesAsync(); @@ -805,33 +803,14 @@ namespace Marco.Pms.Services.Service } if (features.Modules?.Expense?.Enabled ?? false) { - var expensesTypeMaster = _masteData.GetExpensesTypeesData(tenant.Id); - var paymentModeMatser = _masteData.GetPaymentModesData(tenant.Id); + var expenseCategoryMaster = _masteData.GetExpenseCategoryData(tenant.Id); - var expensesTypeTask = Task.Run(async () => - { - await using var _context = await _dbContextFactory.CreateDbContextAsync(); - var expensesTypeNames = expensesTypeMaster.Select(et => et.Name).ToList(); - return await _context.ExpensesTypeMaster.AnyAsync(et => expensesTypeNames.Contains(et.Name) && et.TenantId == tenant.Id); - }); - var paymentModeTask = Task.Run(async () => - { - await using var _context = await _dbContextFactory.CreateDbContextAsync(); - var paymentModeNames = paymentModeMatser.Select(py => py.Name).ToList(); - return await _context.PaymentModeMatser.AnyAsync(py => paymentModeNames.Contains(py.Name) && py.TenantId == tenant.Id); - }); + var expensesTypeNames = expenseCategoryMaster.Select(et => et.Name).ToList(); + var expenseCategoryExist = await context.ExpenseCategoryMasters.AnyAsync(et => expensesTypeNames.Contains(et.Name) && et.TenantId == tenant.Id); - await Task.WhenAll(expensesTypeTask, paymentModeTask); - - var expensesTypeExist = expensesTypeTask.Result; - var paymentModeExist = paymentModeTask.Result; - if (!expensesTypeExist) + if (!expenseCategoryExist) { - context.ExpensesTypeMaster.AddRange(expensesTypeMaster); - } - if (!paymentModeExist) - { - context.PaymentModeMatser.AddRange(paymentModeMatser); + context.ExpenseCategoryMasters.AddRange(expenseCategoryMaster); } }