diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index e2e0b92..2256c24 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -28,6 +28,8 @@ jobs: image: develop - service: Gateway image: gateway + - service: Insight + image: insight steps: - name: Checkout repository diff --git a/DysonNetwork.Control/AppHost.cs b/DysonNetwork.Control/AppHost.cs index 9e77ae6..2b43345 100644 --- a/DysonNetwork.Control/AppHost.cs +++ b/DysonNetwork.Control/AppHost.cs @@ -22,10 +22,16 @@ var developService = builder.AddProject("develop" .WithReference(ringService) .WithReference(sphereService); +var insightService = builder.AddProject("insight") + .WithReference(passService) + .WithReference(ringService) + .WithReference(sphereService) + .WithReference(developService); + passService.WithReference(developService).WithReference(driveService); List> services = - [ringService, passService, driveService, sphereService, developService]; + [ringService, passService, driveService, sphereService, developService, insightService]; for (var idx = 0; idx < services.Count; idx++) { diff --git a/DysonNetwork.Control/DysonNetwork.Control.csproj b/DysonNetwork.Control/DysonNetwork.Control.csproj index 7f84643..7de8863 100644 --- a/DysonNetwork.Control/DysonNetwork.Control.csproj +++ b/DysonNetwork.Control/DysonNetwork.Control.csproj @@ -21,5 +21,6 @@ + \ No newline at end of file diff --git a/DysonNetwork.Insight/AppDatabase.cs b/DysonNetwork.Insight/AppDatabase.cs new file mode 100644 index 0000000..48b0ae2 --- /dev/null +++ b/DysonNetwork.Insight/AppDatabase.cs @@ -0,0 +1,42 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; + +namespace DysonNetwork.Insight; + +public class AppDatabase( + DbContextOptions options, + IConfiguration configuration +) : DbContext(options) +{ + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseNpgsql( + configuration.GetConnectionString("App"), + opt => opt + .ConfigureDataSource(optSource => optSource.EnableDynamicJson()) + .UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery) + .UseNodaTime() + ).UseSnakeCaseNamingConvention(); + + base.OnConfiguring(optionsBuilder); + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + } +} + +public class AppDatabaseFactory : IDesignTimeDbContextFactory +{ + public AppDatabase CreateDbContext(string[] args) + { + var configuration = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json") + .Build(); + + var optionsBuilder = new DbContextOptionsBuilder(); + return new AppDatabase(optionsBuilder.Options, configuration); + } +} diff --git a/DysonNetwork.Insight/Dockerfile b/DysonNetwork.Insight/Dockerfile new file mode 100644 index 0000000..aa97b6e --- /dev/null +++ b/DysonNetwork.Insight/Dockerfile @@ -0,0 +1,27 @@ +#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base +USER app +WORKDIR /app +EXPOSE 8080 +EXPOSE 8081 + +FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build +ARG BUILD_CONFIGURATION=Release +WORKDIR /src +COPY ["DysonNetwork.Insight/DysonNetwork.Insight.csproj", "DysonNetwork.Insight/"] +COPY ["DysonNetwork.Shared/DysonNetwork.Shared.csproj", "DysonNetwork.Shared/"] +COPY ["DysonNetwork.Develop/DysonNetwork.Develop.csproj", "DysonNetwork.Develop/"] +RUN dotnet restore "DysonNetwork.Insight/DysonNetwork.Insight.csproj" +COPY . . +WORKDIR "/src/DysonNetwork.Insight" +RUN dotnet build "DysonNetwork.Insight.csproj" -c $BUILD_CONFIGURATION -o /app/build + +FROM build AS publish +ARG BUILD_CONFIGURATION=Release +RUN dotnet publish "DysonNetwork.Insight.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "DysonNetwork.Insight.dll"] diff --git a/DysonNetwork.Insight/DysonNetwork.Insight.csproj b/DysonNetwork.Insight/DysonNetwork.Insight.csproj new file mode 100644 index 0000000..d62eee4 --- /dev/null +++ b/DysonNetwork.Insight/DysonNetwork.Insight.csproj @@ -0,0 +1,20 @@ + + + + net9.0 + enable + enable + + + + + + + + + + + + + + diff --git a/DysonNetwork.Insight/DysonNetwork.Insight.http b/DysonNetwork.Insight/DysonNetwork.Insight.http new file mode 100644 index 0000000..1959c32 --- /dev/null +++ b/DysonNetwork.Insight/DysonNetwork.Insight.http @@ -0,0 +1,6 @@ +@DysonNetwork.Insight_HostAddress = http://localhost:5232 + +GET {{DysonNetwork.Insight_HostAddress}}/weatherforecast/ +Accept: application/json + +### diff --git a/DysonNetwork.Insight/Program.cs b/DysonNetwork.Insight/Program.cs new file mode 100644 index 0000000..e5cea3a --- /dev/null +++ b/DysonNetwork.Insight/Program.cs @@ -0,0 +1,33 @@ +using DysonNetwork.Insight; +using DysonNetwork.Insight.Startup; +using DysonNetwork.Shared.Http; +using Microsoft.EntityFrameworkCore; + +var builder = WebApplication.CreateBuilder(args); + +builder.AddServiceDefaults(); + +builder.ConfigureAppKestrel(builder.Configuration); + +builder.Services.AddDbContext(); + +builder.AddSwaggerManifest( + "DysonNetwork.Insight", + "The insight service in the Solar Network." +); + +var app = builder.Build(); + +app.MapDefaultEndpoints(); + +using (var scope = app.Services.CreateScope()) +{ + var db = scope.ServiceProvider.GetRequiredService(); + await db.Database.MigrateAsync(); +} + +app.ConfigureAppMiddleware(builder.Configuration); + +app.UseSwaggerManifest("DysonNetwork.Insight"); + +app.Run(); \ No newline at end of file diff --git a/DysonNetwork.Insight/Properties/launchSettings.json b/DysonNetwork.Insight/Properties/launchSettings.json new file mode 100644 index 0000000..69c276c --- /dev/null +++ b/DysonNetwork.Insight/Properties/launchSettings.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "http://localhost:5232", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "https://localhost:7142;http://localhost:5232", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/DysonNetwork.Insight/Startup/ApplicationConfiguration.cs b/DysonNetwork.Insight/Startup/ApplicationConfiguration.cs new file mode 100644 index 0000000..26e7137 --- /dev/null +++ b/DysonNetwork.Insight/Startup/ApplicationConfiguration.cs @@ -0,0 +1,24 @@ +using DysonNetwork.Shared.Http; +using Prometheus; + +namespace DysonNetwork.Insight.Startup; + +public static class ApplicationConfiguration +{ + public static WebApplication ConfigureAppMiddleware(this WebApplication app, IConfiguration configuration) + { + app.MapMetrics(); + app.MapOpenApi(); + + app.UseRequestLocalization(); + + app.ConfigureForwardedHeaders(configuration); + + app.UseAuthentication(); + app.UseAuthorization(); + + app.MapControllers(); + + return app; + } +} diff --git a/DysonNetwork.Insight/appsettings.json b/DysonNetwork.Insight/appsettings.json new file mode 100644 index 0000000..7479841 --- /dev/null +++ b/DysonNetwork.Insight/appsettings.json @@ -0,0 +1,26 @@ +{ + "Debug": true, + "BaseUrl": "http://localhost:5071", + "SiteUrl": "https://solian.app", + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "ConnectionStrings": { + "App": "Host=localhost;Port=5432;Database=dyson_insight;Username=postgres;Password=postgres;Include Error Detail=True;Maximum Pool Size=20;Connection Idle Lifetime=60" + }, + "KnownProxies": ["127.0.0.1", "::1"], + "Swagger": { + "PublicBasePath": "/insight" + }, + "Etcd": { + "Insecure": true + }, + "Service": { + "Name": "DysonNetwork.Insight", + "Url": "https://localhost:7192" + } +} \ No newline at end of file diff --git a/DysonNetwork.Pass/Lotteries/LotteryService.cs b/DysonNetwork.Pass/Lotteries/LotteryService.cs index c0c1cd8..e0e5384 100644 --- a/DysonNetwork.Pass/Lotteries/LotteryService.cs +++ b/DysonNetwork.Pass/Lotteries/LotteryService.cs @@ -21,8 +21,6 @@ public class LotteryService( WalletService walletService, ILogger logger) { - private readonly ILogger _logger = logger; - private static bool ValidateNumbers(List region1, int region2) { if (region1.Count != 5 || region1.Distinct().Count() != 5) @@ -180,7 +178,7 @@ public class LotteryService( { try { - _logger.LogInformation("Starting drawing lotteries..."); + logger.LogInformation("Starting drawing lotteries..."); var now = SystemClock.Instance.GetCurrentInstant(); @@ -191,17 +189,17 @@ public class LotteryService( if (tickets.Count == 0) { - _logger.LogInformation("No pending lottery tickets"); + logger.LogInformation("No pending lottery tickets"); return; } - _logger.LogInformation("Found {Count} pending lottery tickets for draw", tickets.Count); + logger.LogInformation("Found {Count} pending lottery tickets for draw", tickets.Count); // Generate winning numbers var winningRegion1 = GenerateUniqueRandomNumbers(5, 0, 99); var winningRegion2 = GenerateUniqueRandomNumbers(1, 0, 99)[0]; - _logger.LogInformation("Winning numbers generated: Region1 [{Region1}], Region2 [{Region2}]", + logger.LogInformation("Winning numbers generated: Region1 [{Region1}], Region2 [{Region2}]", string.Join(",", winningRegion1), winningRegion2); var drawDate = Instant.FromDateTimeUtc(new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, @@ -233,7 +231,7 @@ public class LotteryService( amount: reward, remarks: $"Lottery prize: {region1Matches} matches{(region2Match ? " + special" : "")}" ); - _logger.LogInformation( + logger.LogInformation( "Awarded {Amount} to account {AccountId} for {Matches} matches{(Special ? \" + special\" : \"\")}", reward, ticket.AccountId, region1Matches, region2Match ? " + special" : ""); totalPrizesAwarded++; @@ -241,7 +239,7 @@ public class LotteryService( } else { - _logger.LogWarning("Wallet not found for account {AccountId}, skipping prize award", + logger.LogWarning("Wallet not found for account {AccountId}, skipping prize award", ticket.AccountId); } } @@ -264,12 +262,12 @@ public class LotteryService( db.LotteryRecords.Add(lotteryRecord); await db.SaveChangesAsync(); - _logger.LogInformation("Daily lottery draw completed: {Prizes} prizes awarded, total amount {Amount}", + logger.LogInformation("Daily lottery draw completed: {Prizes} prizes awarded, total amount {Amount}", totalPrizesAwarded, totalPrizeAmount); } catch (Exception ex) { - _logger.LogError(ex, "An error occurred during the daily lottery draw"); + logger.LogError(ex, "An error occurred during the daily lottery draw"); throw; } } diff --git a/DysonNetwork.sln b/DysonNetwork.sln index ffea2e1..38c2ebe 100644 --- a/DysonNetwork.sln +++ b/DysonNetwork.sln @@ -1,6 +1,5 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DysonNetwork.Sphere", "DysonNetwork.Sphere\DysonNetwork.Sphere.csproj", "{CFF62EFA-F4C2-4FC7-8D97-25570B4DB452}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A444D180-5B51-49C3-A35D-AA55832BBC66}" @@ -22,43 +21,128 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DysonNetwork.Control", "Dys EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DysonNetwork.Gateway", "DysonNetwork.Gateway\DysonNetwork.Gateway.csproj", "{AA4D244C-6C3A-4CD0-9DA4-5CAFFBB55085}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DysonNetwork.Insight", "DysonNetwork.Insight\DysonNetwork.Insight.csproj", "{E603CDF2-8BA0-49AE-A1F9-BD2DA5CB983D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {CFF62EFA-F4C2-4FC7-8D97-25570B4DB452}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CFF62EFA-F4C2-4FC7-8D97-25570B4DB452}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CFF62EFA-F4C2-4FC7-8D97-25570B4DB452}.Debug|x64.ActiveCfg = Debug|Any CPU + {CFF62EFA-F4C2-4FC7-8D97-25570B4DB452}.Debug|x64.Build.0 = Debug|Any CPU + {CFF62EFA-F4C2-4FC7-8D97-25570B4DB452}.Debug|x86.ActiveCfg = Debug|Any CPU + {CFF62EFA-F4C2-4FC7-8D97-25570B4DB452}.Debug|x86.Build.0 = Debug|Any CPU {CFF62EFA-F4C2-4FC7-8D97-25570B4DB452}.Release|Any CPU.ActiveCfg = Release|Any CPU {CFF62EFA-F4C2-4FC7-8D97-25570B4DB452}.Release|Any CPU.Build.0 = Release|Any CPU + {CFF62EFA-F4C2-4FC7-8D97-25570B4DB452}.Release|x64.ActiveCfg = Release|Any CPU + {CFF62EFA-F4C2-4FC7-8D97-25570B4DB452}.Release|x64.Build.0 = Release|Any CPU + {CFF62EFA-F4C2-4FC7-8D97-25570B4DB452}.Release|x86.ActiveCfg = Release|Any CPU + {CFF62EFA-F4C2-4FC7-8D97-25570B4DB452}.Release|x86.Build.0 = Release|Any CPU {A8F37E9E-52A4-4159-8227-F2F65CBA0606}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A8F37E9E-52A4-4159-8227-F2F65CBA0606}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A8F37E9E-52A4-4159-8227-F2F65CBA0606}.Debug|x64.ActiveCfg = Debug|Any CPU + {A8F37E9E-52A4-4159-8227-F2F65CBA0606}.Debug|x64.Build.0 = Debug|Any CPU + {A8F37E9E-52A4-4159-8227-F2F65CBA0606}.Debug|x86.ActiveCfg = Debug|Any CPU + {A8F37E9E-52A4-4159-8227-F2F65CBA0606}.Debug|x86.Build.0 = Debug|Any CPU {A8F37E9E-52A4-4159-8227-F2F65CBA0606}.Release|Any CPU.ActiveCfg = Release|Any CPU {A8F37E9E-52A4-4159-8227-F2F65CBA0606}.Release|Any CPU.Build.0 = Release|Any CPU + {A8F37E9E-52A4-4159-8227-F2F65CBA0606}.Release|x64.ActiveCfg = Release|Any CPU + {A8F37E9E-52A4-4159-8227-F2F65CBA0606}.Release|x64.Build.0 = Release|Any CPU + {A8F37E9E-52A4-4159-8227-F2F65CBA0606}.Release|x86.ActiveCfg = Release|Any CPU + {A8F37E9E-52A4-4159-8227-F2F65CBA0606}.Release|x86.Build.0 = Release|Any CPU {DB46D1A6-79B4-43FC-A9A9-115CDA26947A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {DB46D1A6-79B4-43FC-A9A9-115CDA26947A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DB46D1A6-79B4-43FC-A9A9-115CDA26947A}.Debug|x64.ActiveCfg = Debug|Any CPU + {DB46D1A6-79B4-43FC-A9A9-115CDA26947A}.Debug|x64.Build.0 = Debug|Any CPU + {DB46D1A6-79B4-43FC-A9A9-115CDA26947A}.Debug|x86.ActiveCfg = Debug|Any CPU + {DB46D1A6-79B4-43FC-A9A9-115CDA26947A}.Debug|x86.Build.0 = Debug|Any CPU {DB46D1A6-79B4-43FC-A9A9-115CDA26947A}.Release|Any CPU.ActiveCfg = Release|Any CPU {DB46D1A6-79B4-43FC-A9A9-115CDA26947A}.Release|Any CPU.Build.0 = Release|Any CPU + {DB46D1A6-79B4-43FC-A9A9-115CDA26947A}.Release|x64.ActiveCfg = Release|Any CPU + {DB46D1A6-79B4-43FC-A9A9-115CDA26947A}.Release|x64.Build.0 = Release|Any CPU + {DB46D1A6-79B4-43FC-A9A9-115CDA26947A}.Release|x86.ActiveCfg = Release|Any CPU + {DB46D1A6-79B4-43FC-A9A9-115CDA26947A}.Release|x86.Build.0 = Release|Any CPU {D5DAFB0D-487E-48EF-BA2F-C581C846F63B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D5DAFB0D-487E-48EF-BA2F-C581C846F63B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D5DAFB0D-487E-48EF-BA2F-C581C846F63B}.Debug|x64.ActiveCfg = Debug|Any CPU + {D5DAFB0D-487E-48EF-BA2F-C581C846F63B}.Debug|x64.Build.0 = Debug|Any CPU + {D5DAFB0D-487E-48EF-BA2F-C581C846F63B}.Debug|x86.ActiveCfg = Debug|Any CPU + {D5DAFB0D-487E-48EF-BA2F-C581C846F63B}.Debug|x86.Build.0 = Debug|Any CPU {D5DAFB0D-487E-48EF-BA2F-C581C846F63B}.Release|Any CPU.ActiveCfg = Release|Any CPU {D5DAFB0D-487E-48EF-BA2F-C581C846F63B}.Release|Any CPU.Build.0 = Release|Any CPU + {D5DAFB0D-487E-48EF-BA2F-C581C846F63B}.Release|x64.ActiveCfg = Release|Any CPU + {D5DAFB0D-487E-48EF-BA2F-C581C846F63B}.Release|x64.Build.0 = Release|Any CPU + {D5DAFB0D-487E-48EF-BA2F-C581C846F63B}.Release|x86.ActiveCfg = Release|Any CPU + {D5DAFB0D-487E-48EF-BA2F-C581C846F63B}.Release|x86.Build.0 = Release|Any CPU {8DE0B783-8852-494D-B90A-201ABBB71202}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8DE0B783-8852-494D-B90A-201ABBB71202}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8DE0B783-8852-494D-B90A-201ABBB71202}.Debug|x64.ActiveCfg = Debug|Any CPU + {8DE0B783-8852-494D-B90A-201ABBB71202}.Debug|x64.Build.0 = Debug|Any CPU + {8DE0B783-8852-494D-B90A-201ABBB71202}.Debug|x86.ActiveCfg = Debug|Any CPU + {8DE0B783-8852-494D-B90A-201ABBB71202}.Debug|x86.Build.0 = Debug|Any CPU {8DE0B783-8852-494D-B90A-201ABBB71202}.Release|Any CPU.ActiveCfg = Release|Any CPU {8DE0B783-8852-494D-B90A-201ABBB71202}.Release|Any CPU.Build.0 = Release|Any CPU + {8DE0B783-8852-494D-B90A-201ABBB71202}.Release|x64.ActiveCfg = Release|Any CPU + {8DE0B783-8852-494D-B90A-201ABBB71202}.Release|x64.Build.0 = Release|Any CPU + {8DE0B783-8852-494D-B90A-201ABBB71202}.Release|x86.ActiveCfg = Release|Any CPU + {8DE0B783-8852-494D-B90A-201ABBB71202}.Release|x86.Build.0 = Release|Any CPU {C577AA78-B11D-4076-89A6-1C7F0ECC04E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C577AA78-B11D-4076-89A6-1C7F0ECC04E2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C577AA78-B11D-4076-89A6-1C7F0ECC04E2}.Debug|x64.ActiveCfg = Debug|Any CPU + {C577AA78-B11D-4076-89A6-1C7F0ECC04E2}.Debug|x64.Build.0 = Debug|Any CPU + {C577AA78-B11D-4076-89A6-1C7F0ECC04E2}.Debug|x86.ActiveCfg = Debug|Any CPU + {C577AA78-B11D-4076-89A6-1C7F0ECC04E2}.Debug|x86.Build.0 = Debug|Any CPU {C577AA78-B11D-4076-89A6-1C7F0ECC04E2}.Release|Any CPU.ActiveCfg = Release|Any CPU {C577AA78-B11D-4076-89A6-1C7F0ECC04E2}.Release|Any CPU.Build.0 = Release|Any CPU + {C577AA78-B11D-4076-89A6-1C7F0ECC04E2}.Release|x64.ActiveCfg = Release|Any CPU + {C577AA78-B11D-4076-89A6-1C7F0ECC04E2}.Release|x64.Build.0 = Release|Any CPU + {C577AA78-B11D-4076-89A6-1C7F0ECC04E2}.Release|x86.ActiveCfg = Release|Any CPU + {C577AA78-B11D-4076-89A6-1C7F0ECC04E2}.Release|x86.Build.0 = Release|Any CPU {7FFED190-51C7-4302-A8B5-96C839463458}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7FFED190-51C7-4302-A8B5-96C839463458}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7FFED190-51C7-4302-A8B5-96C839463458}.Debug|x64.ActiveCfg = Debug|Any CPU + {7FFED190-51C7-4302-A8B5-96C839463458}.Debug|x64.Build.0 = Debug|Any CPU + {7FFED190-51C7-4302-A8B5-96C839463458}.Debug|x86.ActiveCfg = Debug|Any CPU + {7FFED190-51C7-4302-A8B5-96C839463458}.Debug|x86.Build.0 = Debug|Any CPU {7FFED190-51C7-4302-A8B5-96C839463458}.Release|Any CPU.ActiveCfg = Release|Any CPU {7FFED190-51C7-4302-A8B5-96C839463458}.Release|Any CPU.Build.0 = Release|Any CPU + {7FFED190-51C7-4302-A8B5-96C839463458}.Release|x64.ActiveCfg = Release|Any CPU + {7FFED190-51C7-4302-A8B5-96C839463458}.Release|x64.Build.0 = Release|Any CPU + {7FFED190-51C7-4302-A8B5-96C839463458}.Release|x86.ActiveCfg = Release|Any CPU + {7FFED190-51C7-4302-A8B5-96C839463458}.Release|x86.Build.0 = Release|Any CPU {AA4D244C-6C3A-4CD0-9DA4-5CAFFBB55085}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AA4D244C-6C3A-4CD0-9DA4-5CAFFBB55085}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AA4D244C-6C3A-4CD0-9DA4-5CAFFBB55085}.Debug|x64.ActiveCfg = Debug|Any CPU + {AA4D244C-6C3A-4CD0-9DA4-5CAFFBB55085}.Debug|x64.Build.0 = Debug|Any CPU + {AA4D244C-6C3A-4CD0-9DA4-5CAFFBB55085}.Debug|x86.ActiveCfg = Debug|Any CPU + {AA4D244C-6C3A-4CD0-9DA4-5CAFFBB55085}.Debug|x86.Build.0 = Debug|Any CPU {AA4D244C-6C3A-4CD0-9DA4-5CAFFBB55085}.Release|Any CPU.ActiveCfg = Release|Any CPU {AA4D244C-6C3A-4CD0-9DA4-5CAFFBB55085}.Release|Any CPU.Build.0 = Release|Any CPU + {AA4D244C-6C3A-4CD0-9DA4-5CAFFBB55085}.Release|x64.ActiveCfg = Release|Any CPU + {AA4D244C-6C3A-4CD0-9DA4-5CAFFBB55085}.Release|x64.Build.0 = Release|Any CPU + {AA4D244C-6C3A-4CD0-9DA4-5CAFFBB55085}.Release|x86.ActiveCfg = Release|Any CPU + {AA4D244C-6C3A-4CD0-9DA4-5CAFFBB55085}.Release|x86.Build.0 = Release|Any CPU + {E603CDF2-8BA0-49AE-A1F9-BD2DA5CB983D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E603CDF2-8BA0-49AE-A1F9-BD2DA5CB983D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E603CDF2-8BA0-49AE-A1F9-BD2DA5CB983D}.Debug|x64.ActiveCfg = Debug|Any CPU + {E603CDF2-8BA0-49AE-A1F9-BD2DA5CB983D}.Debug|x64.Build.0 = Debug|Any CPU + {E603CDF2-8BA0-49AE-A1F9-BD2DA5CB983D}.Debug|x86.ActiveCfg = Debug|Any CPU + {E603CDF2-8BA0-49AE-A1F9-BD2DA5CB983D}.Debug|x86.Build.0 = Debug|Any CPU + {E603CDF2-8BA0-49AE-A1F9-BD2DA5CB983D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E603CDF2-8BA0-49AE-A1F9-BD2DA5CB983D}.Release|Any CPU.Build.0 = Release|Any CPU + {E603CDF2-8BA0-49AE-A1F9-BD2DA5CB983D}.Release|x64.ActiveCfg = Release|Any CPU + {E603CDF2-8BA0-49AE-A1F9-BD2DA5CB983D}.Release|x64.Build.0 = Release|Any CPU + {E603CDF2-8BA0-49AE-A1F9-BD2DA5CB983D}.Release|x86.ActiveCfg = Release|Any CPU + {E603CDF2-8BA0-49AE-A1F9-BD2DA5CB983D}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE EndGlobalSection EndGlobal