Skip to content

Commit

Permalink
Merge pull request #353 from Particular/net8-servicecomposer
Browse files Browse the repository at this point in the history
.NET 8 and update all exercises to use ServiceComposer
  • Loading branch information
DavidBoike authored Nov 1, 2024
2 parents c1e874a + 39290cd commit 3b1bdad
Show file tree
Hide file tree
Showing 194 changed files with 642 additions and 1,205 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Welcome to the workshop.
## Prerequisites

- Windows
- .NET 7.0 or newer
- .NET 8.0 or newer
- A .NET IDE for the exercises
- Visual Studio 2022 ([version 17.4](https://github.com/dotnet/core/blob/main/release-notes/7.0/7.0.0/7.0.0.md#visual-studio-compatibility)) or later
- [SwitchStartupProject](https://marketplace.visualstudio.com/items?itemName=vs-publisher-141975.SwitchStartupProjectForVS2022)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Exe</OutputType>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="ServiceComposer.AspNetCore" Version="2.0.0" />
<PackageReference Include="ServiceComposer.AspNetCore" Version="2.2.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\ITOps.Data\ITOps.Data.csproj" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="ServiceComposer.AspNetCore" Version="2.0.0" />
<PackageReference Include="ServiceComposer.AspNetCore" Version="2.2.0" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="ServiceComposer.AspNetCore" Version="2.0.0" />
<PackageReference Include="ServiceComposer.AspNetCore" Version="2.2.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
using ITOps.Json;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
using ServiceComposer.AspNetCore;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Net.Http;
Expand Down Expand Up @@ -47,7 +45,7 @@ public async Task Handle(HttpRequest request)
var compositionContext = request.GetCompositionContext();
await compositionContext.RaiseEvent(new OrdersLoaded { OrderViewModelDictionary = orderViewModelDictionary });

// Using dynamic to simplify the demo. The ViewModel can be strongly typed.
// Using dynamic to simplify the demo. The ViewModel can be strongly typed using GetComposedResponseModel<T>()
var vm = request.GetComposedResponseModel();
vm.Orders = orderViewModelDictionary.Values;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\ITOps.Data\ITOps.Data.csproj" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="ServiceComposer.AspNetCore" Version="2.0.0" />
<PackageReference Include="ServiceComposer.AspNetCore" Version="2.2.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
using Divergent.Sales.ViewModelComposition.Events;
using ITOps.Json;
using ServiceComposer.AspNetCore;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using System;
using System.Net.Http;
using Microsoft.AspNetCore.Mvc;

Expand Down
4 changes: 2 additions & 2 deletions demos/asp-net-core/Divergent.Website/Divergent.Website.csproj
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="ServiceComposer.AspNetCore" Version="2.0.0" />
<PackageReference Include="ServiceComposer.AspNetCore" Version="2.2.0" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion demos/asp-net-core/ITOps.Data/ITOps.Data.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion demos/asp-net-core/ITOps.Json/ITOps.Json.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
Expand Down
21 changes: 7 additions & 14 deletions exercises/01-composite-ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,27 +88,20 @@ In the `Divergent.Finance.ViewModelComposition` project, add a new class named `
Add the following code to the class

```csharp
using System.Net.Http;
using Divergent.Sales.ViewModelComposition.Events;
using ITOps.Json;
using ITOps.ViewModelComposition;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using System;
using System.Net.Http;
using Microsoft.AspNetCore.Mvc;
using ServiceComposer.AspNetCore;

namespace Divergent.Finance.ViewModelComposition;

public class OrdersLoadedSubscriber : ISubscribeToCompositionEvents
public class OrdersLoadedSubscriber : ICompositionEventsSubscriber
{
// Very simple matching for the purpose of the exercise.
public bool Matches(RouteData routeData, string httpMethod) =>
HttpMethods.IsGet(httpMethod)
&& string.Equals((string)routeData.Values["controller"], "orders", StringComparison.OrdinalIgnoreCase)
&& !routeData.Values.ContainsKey("id");

public void Subscribe(IPublishCompositionEvents publisher)
[HttpGet("/orders")]
public void Subscribe(ICompositionEventsPublisher publisher)
{
publisher.Subscribe<OrdersLoaded>(async (pageViewModel, ordersLoaded, routeData, query) =>
publisher.Subscribe<OrdersLoaded>(async (ordersLoaded, httpRequest) =>
{
var orderIds = string.Join(",", ordersLoaded.OrderViewModelDictionary.Keys);

Expand Down
32 changes: 9 additions & 23 deletions exercises/01-composite-ui/after/01-composite-ui-after.sln
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2010
# Visual Studio Version 17
VisualStudioVersion = 17.11.35327.3
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Website", "Website", "{120B20F8-E388-4973-8F67-8340EADED83B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Divergent.Customers.Data", "Divergent.Customers.Data\Divergent.Customers.Data.csproj", "{314AA28E-E5A9-40B3-AA9B-C2C0E5BAD059}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Divergent.Customers.Data", "Divergent.Customers.Data\Divergent.Customers.Data.csproj", "{314AA28E-E5A9-40B3-AA9B-C2C0E5BAD059}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Divergent.Finance.Data", "Divergent.Finance.Data\Divergent.Finance.Data.csproj", "{FEE53DC5-B52D-49DB-8F07-A8C835998283}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Divergent.Finance.Data", "Divergent.Finance.Data\Divergent.Finance.Data.csproj", "{FEE53DC5-B52D-49DB-8F07-A8C835998283}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Divergent.Sales.Data", "Divergent.Sales.Data\Divergent.Sales.Data.csproj", "{80F82F7D-3F0A-4316-87CD-49F19DBD5B85}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Divergent.Sales.Data", "Divergent.Sales.Data\Divergent.Sales.Data.csproj", "{80F82F7D-3F0A-4316-87CD-49F19DBD5B85}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Customers", "Customers", "{808B901F-6EF7-49F0-B668-F54EEDB1F3F1}"
EndProject
Expand All @@ -19,20 +19,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sales", "Sales", "{3F113598
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ITOps", "ITOps", "{A9587680-24D6-475A-81E8-8699773B5ED9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Divergent.Customers.API", "Divergent.Customers.API\Divergent.Customers.API.csproj", "{222B8A52-4F51-4140-80B4-8AF531E293E4}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Divergent.Customers.API", "Divergent.Customers.API\Divergent.Customers.API.csproj", "{222B8A52-4F51-4140-80B4-8AF531E293E4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Divergent.Finance.API", "Divergent.Finance.API\Divergent.Finance.API.csproj", "{BF4B517B-DBC4-4107-886F-9E246312E9AF}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Divergent.Finance.API", "Divergent.Finance.API\Divergent.Finance.API.csproj", "{BF4B517B-DBC4-4107-886F-9E246312E9AF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Divergent.Sales.API", "Divergent.Sales.API\Divergent.Sales.API.csproj", "{C2FE4732-EA4E-49CC-BE34-46341FB32E09}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Divergent.Sales.API", "Divergent.Sales.API\Divergent.Sales.API.csproj", "{C2FE4732-EA4E-49CC-BE34-46341FB32E09}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Divergent.Frontend", "Divergent.Frontend\Divergent.Frontend.csproj", "{0EE90477-6D50-49A3-A557-3741F568E2ED}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ITOps.ViewModelComposition", "..\..\shared-api-gateway\ITOps.ViewModelComposition\ITOps.ViewModelComposition.csproj", "{888DB2A9-39D2-4B21-8620-8C2BD67AAF6F}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Divergent.Frontend", "Divergent.Frontend\Divergent.Frontend.csproj", "{0EE90477-6D50-49A3-A557-3741F568E2ED}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ITOps.Json", "..\..\shared-api-gateway\ITOps.Json\ITOps.Json.csproj", "{416C923B-61E5-4182-909C-21651394C05F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ITOps.ViewModelComposition.Gateway", "..\..\shared-api-gateway\ITOps.ViewModelComposition.Gateway\ITOps.ViewModelComposition.Gateway.csproj", "{A99F2A92-EE56-49FB-970C-5EA7935D1316}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Divergent.CompositionGateway", "Divergent.CompositionGateway\Divergent.CompositionGateway.csproj", "{4776CCE0-98E9-4E3A-9DDC-93278D63721E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Divergent.Sales.ViewModelComposition", "Divergent.Sales.ViewModelComposition\Divergent.Sales.ViewModelComposition.csproj", "{A476ADD9-1DA4-46E1-8555-6040C52B76D0}"
Expand Down Expand Up @@ -79,18 +75,10 @@ Global
{0EE90477-6D50-49A3-A557-3741F568E2ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0EE90477-6D50-49A3-A557-3741F568E2ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0EE90477-6D50-49A3-A557-3741F568E2ED}.Release|Any CPU.Build.0 = Release|Any CPU
{888DB2A9-39D2-4B21-8620-8C2BD67AAF6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{888DB2A9-39D2-4B21-8620-8C2BD67AAF6F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{888DB2A9-39D2-4B21-8620-8C2BD67AAF6F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{888DB2A9-39D2-4B21-8620-8C2BD67AAF6F}.Release|Any CPU.Build.0 = Release|Any CPU
{416C923B-61E5-4182-909C-21651394C05F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{416C923B-61E5-4182-909C-21651394C05F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{416C923B-61E5-4182-909C-21651394C05F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{416C923B-61E5-4182-909C-21651394C05F}.Release|Any CPU.Build.0 = Release|Any CPU
{A99F2A92-EE56-49FB-970C-5EA7935D1316}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A99F2A92-EE56-49FB-970C-5EA7935D1316}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A99F2A92-EE56-49FB-970C-5EA7935D1316}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A99F2A92-EE56-49FB-970C-5EA7935D1316}.Release|Any CPU.Build.0 = Release|Any CPU
{4776CCE0-98E9-4E3A-9DDC-93278D63721E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4776CCE0-98E9-4E3A-9DDC-93278D63721E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4776CCE0-98E9-4E3A-9DDC-93278D63721E}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down Expand Up @@ -127,9 +115,7 @@ Global
{BF4B517B-DBC4-4107-886F-9E246312E9AF} = {65F37558-1C29-4247-BD01-4DFAFD452ECB}
{C2FE4732-EA4E-49CC-BE34-46341FB32E09} = {3F113598-B240-4E06-B41A-6C684C208F2A}
{0EE90477-6D50-49A3-A557-3741F568E2ED} = {120B20F8-E388-4973-8F67-8340EADED83B}
{888DB2A9-39D2-4B21-8620-8C2BD67AAF6F} = {A9587680-24D6-475A-81E8-8699773B5ED9}
{416C923B-61E5-4182-909C-21651394C05F} = {A9587680-24D6-475A-81E8-8699773B5ED9}
{A99F2A92-EE56-49FB-970C-5EA7935D1316} = {A9587680-24D6-475A-81E8-8699773B5ED9}
{4776CCE0-98E9-4E3A-9DDC-93278D63721E} = {120B20F8-E388-4973-8F67-8340EADED83B}
{A476ADD9-1DA4-46E1-8555-6040C52B76D0} = {3F113598-B240-4E06-B41A-6C684C208F2A}
{D4B3216E-6072-4B7A-97C5-A6FC4C2ABB05} = {3F113598-B240-4E06-B41A-6C684C208F2A}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

Expand All @@ -10,7 +10,6 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\shared-api-gateway\ITOps.ViewModelComposition.Gateway\ITOps.ViewModelComposition.Gateway.csproj" />
<ProjectReference Include="..\Divergent.Customers.ViewModelComposition\Divergent.Customers.ViewModelComposition.csproj" />
<ProjectReference Include="..\Divergent.Finance.ViewModelComposition\Divergent.Finance.ViewModelComposition.csproj" />
<ProjectReference Include="..\Divergent.Sales.ViewModelComposition.Events\Divergent.Sales.ViewModelComposition.Events.csproj" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using ITOps.ViewModelComposition;
using ITOps.ViewModelComposition.Gateway;
using ServiceComposer.AspNetCore;

namespace Divergent.CompositionGateway;

Expand All @@ -21,6 +20,10 @@ public void Configure(IApplicationBuilder app)
policyBuilder.AllowAnyHeader();
});

app.RunCompositionGatewayWithDefaultRoutes();
app.UseRouting();
app.UseEndpoints(builder =>
{
builder.MapCompositionHandlers();
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<LangVersion>latest</LangVersion>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="ServiceComposer.AspNetCore" Version="2.2.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\shared-api-gateway\ITOps.Json\ITOps.Json.csproj" />
<ProjectReference Include="..\..\..\shared-api-gateway\ITOps.ViewModelComposition\ITOps.ViewModelComposition.csproj" />
<ProjectReference Include="..\Divergent.Sales.ViewModelComposition.Events\Divergent.Sales.ViewModelComposition.Events.csproj" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,17 @@
using Divergent.Sales.ViewModelComposition.Events;
using System.Net.Http;
using Divergent.Sales.ViewModelComposition.Events;
using ITOps.Json;
using ITOps.ViewModelComposition;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using System;
using System.Net.Http;
using Microsoft.AspNetCore.Mvc;
using ServiceComposer.AspNetCore;

namespace Divergent.Customers.ViewModelComposition;

public class OrdersLoadedSubscriber : ISubscribeToCompositionEvents
public class OrdersLoadedSubscriber : ICompositionEventsSubscriber
{
// Very simple matching for the purpose of the exercise.
public bool Matches(RouteData routeData, string httpMethod) =>
HttpMethods.IsGet(httpMethod)
&& string.Equals((string)routeData.Values["controller"], "orders", StringComparison.OrdinalIgnoreCase)
&& !routeData.Values.ContainsKey("id");

public void Subscribe(IPublishCompositionEvents publisher)
[HttpGet("/orders")]
public void Subscribe(ICompositionEventsPublisher publisher)
{
publisher.Subscribe<OrdersLoaded>(async (pageViewModel, ordersLoaded, routeData, query) =>
publisher.Subscribe<OrdersLoaded>(async (ordersLoaded, httpRequest) =>
{
var orderIds = string.Join(",", ordersLoaded.OrderViewModelDictionary.Keys);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<LangVersion>latest</LangVersion>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
Expand Down
Loading

0 comments on commit 3b1bdad

Please sign in to comment.