diff --git a/PartSource.Api/Controllers/PartsController.cs b/PartSource.Api/Controllers/PartsController.cs index cc9f5ad..02e1f50 100644 --- a/PartSource.Api/Controllers/PartsController.cs +++ b/PartSource.Api/Controllers/PartsController.cs @@ -14,7 +14,7 @@ namespace PartSource.Api.Controllers { [Route("v2/[controller]")] [ApiController] - [ApiExplorerSettings(GroupName = "v1")] + [ApiExplorerSettings(GroupName = "v2")] public class PartsController : BaseNexpartController { private readonly NexpartService _nexpartService; diff --git a/PartSource.Api/PartSource.Api.csproj b/PartSource.Api/PartSource.Api.csproj index 09e7782..1d153ef 100644 --- a/PartSource.Api/PartSource.Api.csproj +++ b/PartSource.Api/PartSource.Api.csproj @@ -41,6 +41,7 @@ + diff --git a/PartSource.Api/Startup.cs b/PartSource.Api/Startup.cs index b555ea1..8ea993d 100644 --- a/PartSource.Api/Startup.cs +++ b/PartSource.Api/Startup.cs @@ -1,4 +1,4 @@ -using AutoMapper; +using System.IO; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Formatters; @@ -8,10 +8,8 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.OpenApi.Models; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; -using PartSource.Data.AutoMapper; using PartSource.Data.Contexts; using PartSource.Services; -using System.IO; namespace PartSource.Api { @@ -49,8 +47,6 @@ namespace PartSource.Api c.IncludeXmlComments(Path.Combine(System.AppContext.BaseDirectory, "PartSource.Data.xml")); }); - services.AddAutoMapper(typeof(PartSourceProfile)); - services.AddTransient(); services.AddTransient(); services.AddTransient(); diff --git a/PartSource.Api/appsettings.json b/PartSource.Api/appsettings.json index fe5b261..7ec2431 100644 --- a/PartSource.Api/appsettings.json +++ b/PartSource.Api/appsettings.json @@ -1,8 +1,8 @@ { "ConnectionStrings": { "PartSourceDatabase": "Server=tcp:ps-whi.database.windows.net,1433;Initial Catalog=ps-whi-stage;Persist Security Info=False;User ID=ps-whi;Password=9-^*N5dw!6:|.5Q;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;", - //"FitmentDatabase": "Data Source=localhost;Initial Catalog=WhiFitment;Integrated Security=true" - "FitmentDatabase": "Server=tcp:ps-automation.eastus2.cloudapp.azure.com,1433;Initial Catalog=WhiFitment;User ID=sa;Password=GZ0`-ekd~[2u;Encrypt=True;TrustServerCertificate=True;Connection Timeout=300" + "FitmentDatabase": "Data Source=localhost;Initial Catalog=WhiFitment;Integrated Security=true" + // "FitmentDatabase": "Server=tcp:ps-automation.eastus2.cloudapp.azure.com,1433;Initial Catalog=WhiFitment;User ID=sa;Password=GZ0`-ekd~[2u;Encrypt=True;TrustServerCertificate=True;Connection Timeout=300" }, "Logging": { "LogLevel": { diff --git a/PartSource.Automation/Jobs/ExecuteSsisPackages.cs b/PartSource.Automation/Jobs/ExecuteSsisPackages.cs index 605dc15..6484fd9 100644 --- a/PartSource.Automation/Jobs/ExecuteSsisPackages.cs +++ b/PartSource.Automation/Jobs/ExecuteSsisPackages.cs @@ -38,18 +38,18 @@ namespace PartSource.Automation.Jobs { try { - FtpFileInfo lastUploadedFile = _ftpService.ListFilesExtended() - .Where(f => f.FileType == FtpFileType.File && f.Filename.IndexOf(package) > -1) - .OrderByDescending(f => f.Modified) - .FirstOrDefault(); + // FtpFileInfo lastUploadedFile = _ftpService.ListFilesExtended() + //.Where(f => f.FileType == FtpFileType.File && f.Filename.IndexOf(package) > -1) + //.OrderByDescending(f => f.Modified) + //.FirstOrDefault(); - if (lastUploadedFile == null) - { - _logger.LogInformation($"No {package} file available."); - return; - } + // if (lastUploadedFile == null) + // { + // _logger.LogInformation($"No {package} file available."); + // return; + // } - _ftpService.Download($"{package}.txt"); + // _ftpService.Download($"{package}.txt"); _ssisService.Execute($"{package}.dtsx"); _logger.LogInformation($"Execution of SSIS package {package} completed successfully."); diff --git a/PartSource.Automation/Jobs/PartsSync.cs b/PartSource.Automation/Jobs/PartsSync.cs index 34e1cee..f1fe8a5 100644 --- a/PartSource.Automation/Jobs/PartsSync.cs +++ b/PartSource.Automation/Jobs/PartsSync.cs @@ -63,6 +63,8 @@ namespace PartSource.Automation.Jobs Part? existing = await _fitmentContext.Parts.FirstOrDefaultAsync(p => p.Sku == part.Sku); if (existing == null) { + _logger.LogInformation("Adding SKU {Sku}: {LineCode} {PartNumber}", part.Sku, part.LineCode, part.PartNumber); + await _fitmentContext.Parts.AddAsync(part); await _fitmentContext.SaveChangesAsync(); } diff --git a/PartSource.Automation/Jobs/ProcessWhiFitment.cs b/PartSource.Automation/Jobs/ProcessWhiFitment.cs index 44e601c..72c805c 100644 --- a/PartSource.Automation/Jobs/ProcessWhiFitment.cs +++ b/PartSource.Automation/Jobs/ProcessWhiFitment.cs @@ -32,15 +32,11 @@ namespace PartSource.Automation.Jobs { _logger = logger; _whiSeoService = whiSeoService; - _seoDataType = SeoDataType.Fitment; - _ftpConfiguration = configuration.GetSection("ftpServers:WhiConfiguration").Get(); - _noteDictionary = new ConcurrentDictionary(); } - [System.Diagnostics.CodeAnalysis.SuppressMessage("Reliability", "CA2008:Do not create tasks without passing a TaskScheduler", Justification = "")] public async Task Run(CancellationToken token, params string[] arguments) { _whiSeoService.TruncateFitmentTables(); @@ -56,7 +52,7 @@ namespace PartSource.Automation.Jobs fileGroups.Enqueue(fileGroup); } - Task[] taskArray = new Task[18]; + Task[] taskArray = new Task[12]; for (int i = 0; i < taskArray.Length; i++) { taskArray[i] = Task.Factory.StartNew(() => @@ -91,12 +87,12 @@ namespace PartSource.Automation.Jobs _logger.LogInformation($"Created fitment table for part group {tableName}."); } - }); + }, token, TaskCreationOptions.LongRunning, TaskScheduler.Default); } Task.WaitAll(taskArray); - _whiSeoService.SaveNotes(_noteDictionary); + _whiSeoService.SaveNotes(_noteDictionary); _whiSeoService.CreateFitmentView(); } diff --git a/PartSource.Automation/Jobs/ProcessWhiVehicles.cs b/PartSource.Automation/Jobs/ProcessWhiVehicles.cs index 07cf3ca..1e68e6f 100644 --- a/PartSource.Automation/Jobs/ProcessWhiVehicles.cs +++ b/PartSource.Automation/Jobs/ProcessWhiVehicles.cs @@ -121,7 +121,8 @@ namespace PartSource.Automation.Jobs && int.TryParse(columns[35], out int engineConfigId) && int.TryParse(columns[36], out int vehicleToEngineConfigId)) { - if (regionId == 2 && new[] { 5, 6, 7 }.Contains(vehicleTypeId)) + if (new[] { 5, 6, 7 }.Contains(vehicleTypeId)) + //if (regionId == 2 && new[] { 5, 6, 7 }.Contains(vehicleTypeId)) { dataTable.Rows.Add(new object[] { year, makeId, makeName, modelId, modelName, regionId, regionName, vehicleTypeId, engineConfigId, engineDescription, baseVehicleId, vehicleToEngineConfigId, submodelId, submodelName }); } diff --git a/PartSource.Automation/Jobs/UpdateFitment.cs b/PartSource.Automation/Jobs/UpdateFitment.cs index 9e689e5..fb7f3a5 100644 --- a/PartSource.Automation/Jobs/UpdateFitment.cs +++ b/PartSource.Automation/Jobs/UpdateFitment.cs @@ -15,6 +15,7 @@ using Ratermania.Automation.Interfaces; using Ratermania.Shopify; using Ratermania.Shopify.Resources; using System.Web; +using System.IO; namespace PartSource.Automation.Jobs { @@ -37,20 +38,24 @@ namespace PartSource.Automation.Jobs public async Task Run(CancellationToken token, params string[] arguments) { + string logfile = Path.Combine(Path.GetTempPath(), $"missing_fitment_{DateTime.Now:yyyy-MM-dd}.csv"); + using StreamWriter noFitmentWriter = File.AppendText(logfile); + noFitmentWriter.WriteLine("SKU,LineCode,PartNumber"); - IList productTypes = await _fitmentContext.ProductTypes + _logger.LogInformation($"Logging products without fitment to {logfile}"); + + IList productTypes = await _fitmentContext.ProductTypes .Where(p => p.Active) - .Select(p => HttpUtility.UrlEncode(p.Name)) .ToListAsync(); - foreach (string productType in productTypes) + foreach (ProductType productType in productTypes) { - _logger.LogInformation("Processing {productType}", HttpUtility.UrlDecode(productType)); + _logger.LogInformation("Processing {productType}", productType.Name); IEnumerable products = null; try { - products = await _shopifyClient.Products.Get(new Dictionary { { "limit", 250 }, { "product_type", productType } }); + products = await _shopifyClient.Products.Get(new Dictionary { { "limit", 250 }, { "product_type", HttpUtility.UrlEncode(productType.Name) } }); //products = new List //{ // await _shopifyClient.Products.GetById(7458071052335) @@ -88,6 +93,12 @@ namespace PartSource.Automation.Jobs continue; } + // Temporarily skip castrol oils + if (importData.LineCode == "CST") + { + continue; + } + // Extract Partsource bullet points if present. string bodyHtml = string.IsNullOrEmpty(product.BodyHtml) ? string.Empty @@ -99,6 +110,8 @@ namespace PartSource.Automation.Jobs if (!vehicleIdFitment.Any()) { Console.WriteLine($"No fitment data for {importData.LineCode} {importData.PartNumber}"); + noFitmentWriter.WriteLine($"\"{importData.VariantSku}\",\"{importData.LineCode}\",\"{importData.PartNumber}\""); + continue; } @@ -181,6 +194,9 @@ namespace PartSource.Automation.Jobs products = await _shopifyClient.Products.GetPrevious(); } } + + productType.Active = false; + await _fitmentContext.SaveChangesAsync(); } } } diff --git a/PartSource.Automation/Jobs/UpdatePricing.cs b/PartSource.Automation/Jobs/UpdatePricing.cs index c6112b6..a60886b 100644 --- a/PartSource.Automation/Jobs/UpdatePricing.cs +++ b/PartSource.Automation/Jobs/UpdatePricing.cs @@ -100,20 +100,20 @@ namespace PartSource.Automation.Jobs } } - try - { - count += products.Count(); - products = await _shopifyClient.Products.GetNext(); - _logger.LogInformation($"Total updated: {count}"); - } + //try + //{ + // count += products.Count(); + // products = await _shopifyClient.Products.GetNext(); + // _logger.LogInformation($"Total updated: {count}"); + //} - catch (Exception ex) - { - _logger.LogWarning(ex, "Failed to get the next set of products. Retrying"); - products = await _shopifyClient.Products.GetPrevious(); - } + //catch (Exception ex) + //{ + // _logger.LogWarning(ex, "Failed to get the next set of products. Retrying"); + // products = await _shopifyClient.Products.GetPrevious(); + //} - _emailService.Send("Pricing Update Completed", $"The pricing update has completed."); + // _emailService.Send("Pricing Update Completed", $"The pricing update has completed."); } } } diff --git a/PartSource.Automation/PartSource.Automation.csproj b/PartSource.Automation/PartSource.Automation.csproj index 68b6933..0e317bd 100644 --- a/PartSource.Automation/PartSource.Automation.csproj +++ b/PartSource.Automation/PartSource.Automation.csproj @@ -4,11 +4,10 @@ Exe net6.0 Debug;Release;Also Debug + true - - - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -21,11 +20,11 @@ - + diff --git a/PartSource.Automation/Program.cs b/PartSource.Automation/Program.cs index 75027f0..e0598b7 100644 --- a/PartSource.Automation/Program.cs +++ b/PartSource.Automation/Program.cs @@ -1,18 +1,17 @@ -using Microsoft.EntityFrameworkCore; +using System; +using System.IO; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using PartSource.Automation.Jobs; using PartSource.Automation.Services; -using PartSource.Data.AutoMapper; using PartSource.Data.Contexts; using PartSource.Services; using Ratermania.Automation.DependencyInjection; using Ratermania.Shopify.DependencyInjection; -using System; -using System.IO; -using System.Threading.Tasks; namespace PartSource.Automation { @@ -63,7 +62,7 @@ namespace PartSource.Automation { options.ApiKey = builder.Configuration["Shopify:ApiKey"]; options.ApiSecret = builder.Configuration["Shopify:ApiSecret"]; - options.ApiVersion = "2024-10"; + options.ApiVersion = "2025-10"; options.ShopDomain = builder.Configuration["Shopify:ShopDomain"]; //options.ApiKey = "9a533dad460321c6ce8f30bf5b8691ed"; @@ -74,7 +73,7 @@ namespace PartSource.Automation .AddAutomation(options => { - options.HasBaseInterval(new TimeSpan(0, 5, 0)) + options.HasBaseInterval(new TimeSpan(24, 0, 0)) .HasMaxFailures(5) //.HasJob(options => options.HasInterval(new TimeSpan(7, 0, 0, 0))); // @@ -96,19 +95,19 @@ namespace PartSource.Automation // options.HasInterval(new TimeSpan(24, 0, 0)) // .StartsAt(DateTime.Today.AddHours(-24)) // ) - .HasJob(options => + .HasJob(options => options.HasInterval(new TimeSpan(24, 0, 0)) .StartsAt(DateTime.Today.AddHours(-22)) - //.HasDependency() + //.HasDependency() ); - //.HasJob(options => - // options.HasInterval(new TimeSpan(1, 0, 0)) - // .StartsAt(DateTime.Today.AddHours(-27)) - // ); - //.HasJob(options => - // options.HasInterval(new TimeSpan(1, 0, 0)) - // .StartsAt(DateTime.Today.AddHours(-27).AddMinutes(30)) - //); + //.HasJob(options => + // options.HasInterval(new TimeSpan(1, 0, 0)) + // .StartsAt(DateTime.Today.AddHours(-27)) + // ); + //.HasJob(options => + // options.HasInterval(new TimeSpan(1, 0, 0)) + // .StartsAt(DateTime.Today.AddHours(-27).AddMinutes(30)) + //); //.HasJob(options => options.HasInterval(new TimeSpan(1, 0, 0)) //.HasDependency() @@ -124,9 +123,7 @@ namespace PartSource.Automation .AddSingleton() .AddSingleton() .AddSingleton() - .AddSingleton() - - .AddAutoMapper(typeof(PartSourceProfile)); + .AddSingleton(); }) .ConfigureLogging((builder, logging) => { diff --git a/PartSource.Automation/Services/WhiSeoService.cs b/PartSource.Automation/Services/WhiSeoService.cs index 0f35c91..c8b4c89 100644 --- a/PartSource.Automation/Services/WhiSeoService.cs +++ b/PartSource.Automation/Services/WhiSeoService.cs @@ -87,9 +87,7 @@ namespace PartSource.Automation.Services using SqlConnection connection = new SqlConnection(_connectionString); connection.Open(); - string sql = string.Empty; - - using SqlCommand command = new SqlCommand($"EXEC CreateFitmentTempTable @tableName = '{tableName}'", connection); + using SqlCommand command = new SqlCommand($"CREATE TABLE [FitmentTemp].[{tableName}]([LineCode] [nvarchar](10) NOT NULL, [PartNumber] [nvarchar](25) NOT NULL, [BaseVehicleId] [int] NOT NULL, [EngineConfigId] [int] NOT NULL, [Position] [nvarchar](250) null, [FitmentNoteHash] [nvarchar](40) null, PartTerminologyId [int] not null)", connection); command.ExecuteNonQuery(); using SqlBulkCopy bulk = new SqlBulkCopy(connection) diff --git a/PartSource.Automation/appsettings.json b/PartSource.Automation/appsettings.json index 84e9124..6363cae 100644 --- a/PartSource.Automation/appsettings.json +++ b/PartSource.Automation/appsettings.json @@ -1,7 +1,7 @@ { "ConnectionStrings": { - "FitmentDatabase": "Data Source=localhost;Initial Catalog=WhiFitment;Integrated Security=true;TrustServerCertificate=true", - //"FitmentDatabase": "Server=tcp:ps-automation.eastus2.cloudapp.azure.com,1433;Initial Catalog=WhiFitment;User ID=sa;Password=GZ0`-ekd~[2u;Encrypt=True;TrustServerCertificate=True;Connection Timeout=300", + //"FitmentDatabase": "Data Source=localhost;Initial Catalog=WhiFitment;Integrated Security=true;TrustServerCertificate=true", + "FitmentDatabase": "Server=tcp:ps-automation.eastus2.cloudapp.azure.com,1433;Initial Catalog=WhiFitment;User ID=sa;Password=GZ0`-ekd~[2u;Encrypt=True;TrustServerCertificate=True;Connection Timeout=300", "PartSourceDatabase": "Server=tcp:ps-whi.database.windows.net,1433;Initial Catalog=ps-whi-stage;Persist Security Info=False;User ID=ps-whi;Password=9-^*N5dw!6:|.5Q;MultipleActiveResultSets=True;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;" }, "emailConfiguration": { diff --git a/PartSource.Data/AutoMapper/PartSourceProfile.cs b/PartSource.Data/AutoMapper/PartSourceProfile.cs deleted file mode 100644 index 29f6f24..0000000 --- a/PartSource.Data/AutoMapper/PartSourceProfile.cs +++ /dev/null @@ -1,22 +0,0 @@ -using AutoMapper; -using PartSource.Data.Dtos; -using PartSource.Data.Models; -using System; -using System.Collections.Generic; -using System.Text; - -namespace PartSource.Data.AutoMapper -{ - public class PartSourceProfile : Profile - { - public PartSourceProfile() - { - CreateMap(); - CreateMap(); - CreateMap(); - CreateMap(); - CreateMap(); - CreateMap(); - } - } -} diff --git a/PartSource.Data/PartSource.Data.csproj b/PartSource.Data/PartSource.Data.csproj index c5f77b4..df96b3a 100644 --- a/PartSource.Data/PartSource.Data.csproj +++ b/PartSource.Data/PartSource.Data.csproj @@ -17,7 +17,6 @@ - all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/PartSource.Services/PartSource.Services.csproj b/PartSource.Services/PartSource.Services.csproj index 6d967c3..38a3ec3 100644 --- a/PartSource.Services/PartSource.Services.csproj +++ b/PartSource.Services/PartSource.Services.csproj @@ -14,10 +14,10 @@ - + diff --git a/PartSource.sln b/PartSource.sln index 198692f..75f1749 100644 --- a/PartSource.sln +++ b/PartSource.sln @@ -11,11 +11,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PartSource.Services", "Part EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PartSource.Automation", "PartSource.Automation\PartSource.Automation.csproj", "{C85D675B-A76C-4F9C-9C57-1E063211C946}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shopify", "..\ratermania\Packages\Shopify\Shopify.csproj", "{DBAE670D-D4DC-CF6C-0615-1026D17A92D0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shopify.BulkUpdate", "..\ratermania\Packages\Shopify.BulkUpdate\Shopify.BulkUpdate.csproj", "{E9F85D14-D6A6-1412-E0E6-69D47766694A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Also Debug|Any CPU = Also Debug|Any CPU - Also Debug|x64 = Also Debug|x64 - Also Debug|x86 = Also Debug|x86 Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 @@ -24,12 +25,6 @@ Global Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {126B8961-1D86-4F73-9BB9-79ECE78E9257}.Also Debug|Any CPU.ActiveCfg = Also Debug|Any CPU - {126B8961-1D86-4F73-9BB9-79ECE78E9257}.Also Debug|Any CPU.Build.0 = Also Debug|Any CPU - {126B8961-1D86-4F73-9BB9-79ECE78E9257}.Also Debug|x64.ActiveCfg = Also Debug|Any CPU - {126B8961-1D86-4F73-9BB9-79ECE78E9257}.Also Debug|x64.Build.0 = Also Debug|Any CPU - {126B8961-1D86-4F73-9BB9-79ECE78E9257}.Also Debug|x86.ActiveCfg = Also Debug|Any CPU - {126B8961-1D86-4F73-9BB9-79ECE78E9257}.Also Debug|x86.Build.0 = Also Debug|Any CPU {126B8961-1D86-4F73-9BB9-79ECE78E9257}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {126B8961-1D86-4F73-9BB9-79ECE78E9257}.Debug|Any CPU.Build.0 = Debug|Any CPU {126B8961-1D86-4F73-9BB9-79ECE78E9257}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -42,12 +37,6 @@ Global {126B8961-1D86-4F73-9BB9-79ECE78E9257}.Release|x64.Build.0 = Release|Any CPU {126B8961-1D86-4F73-9BB9-79ECE78E9257}.Release|x86.ActiveCfg = Release|Any CPU {126B8961-1D86-4F73-9BB9-79ECE78E9257}.Release|x86.Build.0 = Release|Any CPU - {B4848BCD-6BCC-44BD-AD6E-38511AEC1851}.Also Debug|Any CPU.ActiveCfg = Also Debug|Any CPU - {B4848BCD-6BCC-44BD-AD6E-38511AEC1851}.Also Debug|Any CPU.Build.0 = Also Debug|Any CPU - {B4848BCD-6BCC-44BD-AD6E-38511AEC1851}.Also Debug|x64.ActiveCfg = Also Debug|Any CPU - {B4848BCD-6BCC-44BD-AD6E-38511AEC1851}.Also Debug|x64.Build.0 = Also Debug|Any CPU - {B4848BCD-6BCC-44BD-AD6E-38511AEC1851}.Also Debug|x86.ActiveCfg = Also Debug|Any CPU - {B4848BCD-6BCC-44BD-AD6E-38511AEC1851}.Also Debug|x86.Build.0 = Also Debug|Any CPU {B4848BCD-6BCC-44BD-AD6E-38511AEC1851}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B4848BCD-6BCC-44BD-AD6E-38511AEC1851}.Debug|Any CPU.Build.0 = Debug|Any CPU {B4848BCD-6BCC-44BD-AD6E-38511AEC1851}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -60,12 +49,6 @@ Global {B4848BCD-6BCC-44BD-AD6E-38511AEC1851}.Release|x64.Build.0 = Release|Any CPU {B4848BCD-6BCC-44BD-AD6E-38511AEC1851}.Release|x86.ActiveCfg = Release|Any CPU {B4848BCD-6BCC-44BD-AD6E-38511AEC1851}.Release|x86.Build.0 = Release|Any CPU - {2E7BCDF6-643E-405A-A69A-4907DF5491AF}.Also Debug|Any CPU.ActiveCfg = Also Debug|Any CPU - {2E7BCDF6-643E-405A-A69A-4907DF5491AF}.Also Debug|Any CPU.Build.0 = Also Debug|Any CPU - {2E7BCDF6-643E-405A-A69A-4907DF5491AF}.Also Debug|x64.ActiveCfg = Also Debug|Any CPU - {2E7BCDF6-643E-405A-A69A-4907DF5491AF}.Also Debug|x64.Build.0 = Also Debug|Any CPU - {2E7BCDF6-643E-405A-A69A-4907DF5491AF}.Also Debug|x86.ActiveCfg = Also Debug|Any CPU - {2E7BCDF6-643E-405A-A69A-4907DF5491AF}.Also Debug|x86.Build.0 = Also Debug|Any CPU {2E7BCDF6-643E-405A-A69A-4907DF5491AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2E7BCDF6-643E-405A-A69A-4907DF5491AF}.Debug|Any CPU.Build.0 = Debug|Any CPU {2E7BCDF6-643E-405A-A69A-4907DF5491AF}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -78,12 +61,6 @@ Global {2E7BCDF6-643E-405A-A69A-4907DF5491AF}.Release|x64.Build.0 = Release|Any CPU {2E7BCDF6-643E-405A-A69A-4907DF5491AF}.Release|x86.ActiveCfg = Release|Any CPU {2E7BCDF6-643E-405A-A69A-4907DF5491AF}.Release|x86.Build.0 = Release|Any CPU - {C85D675B-A76C-4F9C-9C57-1E063211C946}.Also Debug|Any CPU.ActiveCfg = Also Debug|Any CPU - {C85D675B-A76C-4F9C-9C57-1E063211C946}.Also Debug|Any CPU.Build.0 = Also Debug|Any CPU - {C85D675B-A76C-4F9C-9C57-1E063211C946}.Also Debug|x64.ActiveCfg = Also Debug|Any CPU - {C85D675B-A76C-4F9C-9C57-1E063211C946}.Also Debug|x64.Build.0 = Also Debug|Any CPU - {C85D675B-A76C-4F9C-9C57-1E063211C946}.Also Debug|x86.ActiveCfg = Also Debug|Any CPU - {C85D675B-A76C-4F9C-9C57-1E063211C946}.Also Debug|x86.Build.0 = Also Debug|Any CPU {C85D675B-A76C-4F9C-9C57-1E063211C946}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C85D675B-A76C-4F9C-9C57-1E063211C946}.Debug|Any CPU.Build.0 = Debug|Any CPU {C85D675B-A76C-4F9C-9C57-1E063211C946}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -96,6 +73,30 @@ Global {C85D675B-A76C-4F9C-9C57-1E063211C946}.Release|x64.Build.0 = Release|Any CPU {C85D675B-A76C-4F9C-9C57-1E063211C946}.Release|x86.ActiveCfg = Release|Any CPU {C85D675B-A76C-4F9C-9C57-1E063211C946}.Release|x86.Build.0 = Release|Any CPU + {DBAE670D-D4DC-CF6C-0615-1026D17A92D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DBAE670D-D4DC-CF6C-0615-1026D17A92D0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DBAE670D-D4DC-CF6C-0615-1026D17A92D0}.Debug|x64.ActiveCfg = Debug|Any CPU + {DBAE670D-D4DC-CF6C-0615-1026D17A92D0}.Debug|x64.Build.0 = Debug|Any CPU + {DBAE670D-D4DC-CF6C-0615-1026D17A92D0}.Debug|x86.ActiveCfg = Debug|Any CPU + {DBAE670D-D4DC-CF6C-0615-1026D17A92D0}.Debug|x86.Build.0 = Debug|Any CPU + {DBAE670D-D4DC-CF6C-0615-1026D17A92D0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DBAE670D-D4DC-CF6C-0615-1026D17A92D0}.Release|Any CPU.Build.0 = Release|Any CPU + {DBAE670D-D4DC-CF6C-0615-1026D17A92D0}.Release|x64.ActiveCfg = Release|Any CPU + {DBAE670D-D4DC-CF6C-0615-1026D17A92D0}.Release|x64.Build.0 = Release|Any CPU + {DBAE670D-D4DC-CF6C-0615-1026D17A92D0}.Release|x86.ActiveCfg = Release|Any CPU + {DBAE670D-D4DC-CF6C-0615-1026D17A92D0}.Release|x86.Build.0 = Release|Any CPU + {E9F85D14-D6A6-1412-E0E6-69D47766694A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E9F85D14-D6A6-1412-E0E6-69D47766694A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E9F85D14-D6A6-1412-E0E6-69D47766694A}.Debug|x64.ActiveCfg = Debug|Any CPU + {E9F85D14-D6A6-1412-E0E6-69D47766694A}.Debug|x64.Build.0 = Debug|Any CPU + {E9F85D14-D6A6-1412-E0E6-69D47766694A}.Debug|x86.ActiveCfg = Debug|Any CPU + {E9F85D14-D6A6-1412-E0E6-69D47766694A}.Debug|x86.Build.0 = Debug|Any CPU + {E9F85D14-D6A6-1412-E0E6-69D47766694A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E9F85D14-D6A6-1412-E0E6-69D47766694A}.Release|Any CPU.Build.0 = Release|Any CPU + {E9F85D14-D6A6-1412-E0E6-69D47766694A}.Release|x64.ActiveCfg = Release|Any CPU + {E9F85D14-D6A6-1412-E0E6-69D47766694A}.Release|x64.Build.0 = Release|Any CPU + {E9F85D14-D6A6-1412-E0E6-69D47766694A}.Release|x86.ActiveCfg = Release|Any CPU + {E9F85D14-D6A6-1412-E0E6-69D47766694A}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE