Skip to content

Commit b590bf3

Browse files
committed
Rearrange lines in project files
Follow the following rules: ### Project File structuring - SOF (_Start Of File_) Imports, - Core properties, Package properties, build properties, - Build items, Resource items, Content items, Misc. items, - In-place Imports, Choose (_elements within follows outer sort order_) - `ProjectReference` items, `PackageReference` items, - Targets and Properties and Items close to said Targets, - EOF (_End Of File_) Imports. Where there's a condition by target properties, we should group them together under `Choose`. For multiple target values, we should sort them by the order in which they are defined. And the order in which they should be defined is either ascending or descending in terms of compatibility layering. Also, Rename solution, readme and icon files for consistency with the Windows repository.
1 parent 743b93a commit b590bf3

File tree

21 files changed

+139
-169
lines changed

21 files changed

+139
-169
lines changed

CommunityToolkit.Common/CommunityToolkit.Common.csproj

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@
1414
<PackageTags>Incremental;Loading;Collection;IncrementalLoadingCollection;String;Array;Extensions;Helpers</PackageTags>
1515
</PropertyGroup>
1616

17-
<!-- .NET Standard 2.1 and .NET 6 already have [NotNullIfNotNull] and [NotNullWhen].
18-
Additionally, also enable trimming support on .NET 6. -->
17+
<!--
18+
.NET Standard 2.1 and .NET 6 already have [NotNullIfNotNull] and [NotNullWhen].
19+
Additionally, also enable trimming support on .NET 6.
20+
-->
1921
<PropertyGroup Condition="'$(TargetFramework)' == 'net6.0'">
2022
<DefineConstants>NETSTANDARD2_1_OR_GREATER</DefineConstants>
2123
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>

CommunityToolkit.Diagnostics/CommunityToolkit.Diagnostics.csproj

Lines changed: 1 addition & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@
2424
</When>
2525

2626
<When Condition="'$(TargetFramework)' == 'netstandard2.1'">
27-
<PropertyGroup>
28-
<DefineConstants>NETSTANDARD2_1_OR_GREATER</DefineConstants>
29-
</PropertyGroup>
3027

3128
<!-- .NET Standard 2.1 doesn't have the Unsafe type -->
3229
<ItemGroup>
@@ -44,51 +41,6 @@
4441
</When>
4542
</Choose>
4643

47-
<ItemGroup>
48-
<None Update="Generated\Guard.Comparable.Numeric.tt">
49-
<Generator>TextTemplatingFileGenerator</Generator>
50-
<LastGenOutput>Guard.Comparable.Numeric.g.cs</LastGenOutput>
51-
</None>
52-
<None Update="Generated\Guard.Collection.tt">
53-
<Generator>TextTemplatingFileGenerator</Generator>
54-
<LastGenOutput>Guard.Collection.g.cs</LastGenOutput>
55-
</None>
56-
<None Update="Generated\ThrowHelper.Collection.tt">
57-
<Generator>TextTemplatingFileGenerator</Generator>
58-
<LastGenOutput>ThrowHelper.Collection.g.cs</LastGenOutput>
59-
</None>
60-
<None Update="Generated\TypeInfo.ttinclude">
61-
<Generator>TextTemplatingFileGenerator</Generator>
62-
<LastGenOutput>TypeInfo.g.cs</LastGenOutput>
63-
</None>
64-
</ItemGroup>
65-
66-
<!-- T4 service used by the Guard APIs -->
67-
<ItemGroup>
68-
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
69-
</ItemGroup>
70-
71-
<ItemGroup>
72-
<Compile Update="Generated\Guard.Comparable.Numeric.g.cs">
73-
<DesignTime>True</DesignTime>
74-
<AutoGen>True</AutoGen>
75-
<DependentUpon>Guard.Comparable.Numeric.tt</DependentUpon>
76-
</Compile>
77-
<Compile Update="Generated\Guard.Collection.g.cs">
78-
<DesignTime>True</DesignTime>
79-
<AutoGen>True</AutoGen>
80-
<DependentUpon>Guard.Collection.tt</DependentUpon>
81-
</Compile>
82-
<Compile Update="Generated\ThrowHelper.Collection.g.cs">
83-
<DesignTime>True</DesignTime>
84-
<AutoGen>True</AutoGen>
85-
<DependentUpon>ThrowHelper.Collection.tt</DependentUpon>
86-
</Compile>
87-
<Compile Update="Generated\TypeInfo.g.cs">
88-
<DesignTime>True</DesignTime>
89-
<AutoGen>True</AutoGen>
90-
<DependentUpon>TypeInfo.ttinclude</DependentUpon>
91-
</Compile>
92-
</ItemGroup>
44+
<Import Project="$(BuildToolsDirectory)Community.Toolkit.TextTemplates.targets" />
9345

9446
</Project>

CommunityToolkit.HighPerformance/CommunityToolkit.HighPerformance.csproj

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,6 @@
4545
</ItemGroup>
4646
</When>
4747

48-
<When Condition="'$(TargetFramework)' == 'net6.0'">
49-
50-
<!-- NETSTANDARD2_1_OR_GREATER: includes both .NET Standard 2.1, .NET Core 3.1 and .NET 6.
51-
Additionally, also enable trimming support on .NET 6. -->
52-
<PropertyGroup>
53-
<DefineConstants>NETSTANDARD2_1_OR_GREATER</DefineConstants>
54-
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>
55-
<IsTrimmable>true</IsTrimmable>
56-
</PropertyGroup>
57-
</When>
58-
5948
<When Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
6049
<PropertyGroup>
6150
<DefineConstants>NETSTANDARD2_1_OR_GREATER</DefineConstants>
@@ -66,6 +55,18 @@
6655
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
6756
</ItemGroup>
6857
</When>
58+
59+
<!--
60+
NETSTANDARD2_1_OR_GREATER: includes both .NET Standard 2.1, .NET Core 3.1 and .NET 6.
61+
Additionally, also enable trimming support on .NET 6.
62+
-->
63+
<When Condition="'$(TargetFramework)' == 'net6.0'">
64+
<PropertyGroup>
65+
<DefineConstants>NETSTANDARD2_1_OR_GREATER</DefineConstants>
66+
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>
67+
<IsTrimmable>true</IsTrimmable>
68+
</PropertyGroup>
69+
</When>
6970
</Choose>
7071

7172
</Project>
Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,22 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>netstandard2.0</TargetFramework>
54
<IsPackable>false</IsPackable>
5+
<TargetFramework>netstandard2.0</TargetFramework>
66
</PropertyGroup>
77

88
<ItemGroup>
9-
<Compile Remove="EmbeddedResources\INotifyPropertyChanged.cs" />
10-
<Compile Remove="EmbeddedResources\NotNullAttribute.cs" />
11-
<Compile Remove="EmbeddedResources\NotNullIfNotNullAttribute.cs" />
12-
<Compile Remove="EmbeddedResources\ObservableObject.cs" />
13-
<Compile Remove="EmbeddedResources\ObservableRecipient.cs" />
9+
<Compile Remove="EmbeddedResources\*.cs" />
10+
<EmbeddedResource Include="EmbeddedResources\*.cs" CopyToOutputDirectory="PreserveNewest" />
1411
</ItemGroup>
1512

1613
<ItemGroup>
17-
<EmbeddedResource Include="EmbeddedResources\INotifyPropertyChanged.cs">
18-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
19-
</EmbeddedResource>
20-
<EmbeddedResource Include="EmbeddedResources\NotNullAttribute.cs">
21-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
22-
</EmbeddedResource>
23-
<EmbeddedResource Include="EmbeddedResources\NotNullIfNotNullAttribute.cs">
24-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
25-
</EmbeddedResource>
26-
<EmbeddedResource Include="EmbeddedResources\ObservableObject.cs">
27-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
28-
</EmbeddedResource>
29-
<EmbeddedResource Include="EmbeddedResources\ObservableRecipient.cs">
30-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
31-
</EmbeddedResource>
14+
<AdditionalFiles Include="AnalyzerReleases.Shipped.md" />
15+
<AdditionalFiles Include="AnalyzerReleases.Unshipped.md" />
3216
</ItemGroup>
3317

3418
<ItemGroup>
3519
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.0.1" PrivateAssets="all" Pack="false" />
3620
</ItemGroup>
3721

38-
<ItemGroup>
39-
<AdditionalFiles Include="AnalyzerReleases.Shipped.md" />
40-
<AdditionalFiles Include="AnalyzerReleases.Unshipped.md" />
41-
</ItemGroup>
42-
4322
</Project>

CommunityToolkit.Mvvm/CommunityToolkit.Mvvm.csproj

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,23 @@
2020
<PackageTags>MVVM;Toolkit;MVVMToolkit;INotifyPropertyChanged;Observable;IOC;DI;Dependency Injection;Object Messaging;Extensions;Helpers</PackageTags>
2121
</PropertyGroup>
2222

23+
<!-- Enable trimming support on .NET 6 -->
24+
<PropertyGroup Condition="'$(TargetFramework)' == 'net6.0'">
25+
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>
26+
<IsTrimmable>true</IsTrimmable>
27+
</PropertyGroup>
28+
29+
<!--
30+
Include the custom .targets file to check the source generator.
31+
.NET 6 is not needed as it guarantees Roslyn 4.x.
32+
-->
33+
<ItemGroup>
34+
<None Include="CommunityToolkit.Mvvm.targets" Pack="True" PackagePath="build\netstandard2.0" />
35+
<None Include="CommunityToolkit.Mvvm.targets" Pack="True" PackagePath="build\netstandard2.1" />
36+
<None Include="CommunityToolkit.Mvvm.targets" Pack="True" PackagePath="buildTransitive\netstandard2.0" />
37+
<None Include="CommunityToolkit.Mvvm.targets" Pack="True" PackagePath="buildTransitive\netstandard2.1" />
38+
</ItemGroup>
39+
2340
<!-- .NET Standard 2.0 doesn't have the Span<T> and IAsyncEnumerable<T> types -->
2441
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
2542
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="6.0.0" />
@@ -34,30 +51,19 @@
3451
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.0.0" />
3552
</ItemGroup>
3653

37-
<!-- Enable trimming support on .NET 6 -->
38-
<PropertyGroup Condition="'$(TargetFramework)' == 'net6.0'">
39-
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>
40-
<IsTrimmable>true</IsTrimmable>
41-
</PropertyGroup>
42-
4354
<!-- Source generator project reference for packing -->
4455
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
45-
<ProjectReference Include="..\CommunityToolkit.Mvvm.SourceGenerators\CommunityToolkit.Mvvm.SourceGenerators.csproj" ReferenceOutputAssembly="false" />
56+
<ProjectReference Include="..\CommunityToolkit.Mvvm.SourceGenerators\CommunityToolkit.Mvvm.SourceGenerators.csproj"
57+
ReferenceOutputAssembly="false" />
4658
</ItemGroup>
4759

48-
<ItemGroup Label="Package">
49-
50-
<!-- Include the custom .targets file to check the source generator (.NET 6 is not needed as it guarantees Roslyn 4.x) -->
51-
<None Include="CommunityToolkit.Mvvm.targets" PackagePath="buildTransitive\netstandard2.0" Pack="true" />
52-
<None Include="CommunityToolkit.Mvvm.targets" PackagePath="buildTransitive\netstandard2.1" Pack="true" />
53-
<None Include="CommunityToolkit.Mvvm.targets" PackagePath="build\netstandard2.0" Pack="true" />
54-
<None Include="CommunityToolkit.Mvvm.targets" PackagePath="build\netstandard2.1" Pack="true" />
55-
56-
<!-- Pack the source generator to the right package folder -->
60+
<!--
61+
Pack the source generator to the right package folder
62+
-->
63+
<ItemGroup>
5764
<None Include="..\CommunityToolkit.Mvvm.SourceGenerators\bin\$(Configuration)\netstandard2.0\CommunityToolkit.Mvvm.SourceGenerators.dll"
5865
PackagePath="analyzers\dotnet\roslyn4.0\cs"
59-
Pack="true"
60-
Visible="false" />
66+
Pack="true" Visible="false" />
6167
</ItemGroup>
6268

6369
</Project>

CommunityToolkit.Mvvm/CommunityToolkit.Mvvm.targets

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,17 @@
1313
AfterTargets="ResolvePackageDependenciesForBuild;ResolveNuGetPackageAssets"
1414
DependsOnTargets="_MVVMToolkitGatherAnalyzers">
1515

16-
<!-- Use the CSharpCoreTargetsPath property to find the version of the compiler we are using. This is the same mechanism
17-
MSBuild uses to find the compiler. We could check the assembly version for any compiler assembly (since they all have
18-
the same version) but Microsoft.Build.Tasks.CodeAnalysis.dll is where MSBuild loads the compiler tasks from so if
19-
someone is getting creative with msbuild tasks/targets this is the "most correct" assembly to check. -->
16+
<!--
17+
Use the CSharpCoreTargetsPath property to find the version of the compiler we are using. This is the same mechanism
18+
MSBuild uses to find the compiler. We could check the assembly version for any compiler assembly (since they all have
19+
the same version) but Microsoft.Build.Tasks.CodeAnalysis.dll is where MSBuild loads the compiler tasks from so if
20+
someone is getting creative with msbuild tasks/targets this is the "most correct" assembly to check.
21+
-->
2022
<GetAssemblyIdentity AssemblyFiles="$([System.IO.Path]::Combine(`$([System.IO.Path]::GetDirectoryName($(CSharpCoreTargetsPath)))`,`Microsoft.Build.Tasks.CodeAnalysis.dll`))">
2123
<Output TaskParameter="Assemblies" ItemName="CurrentCompilerAssemblyIdentity"/>
2224
</GetAssemblyIdentity>
2325

2426
<PropertyGroup>
25-
2627
<!-- Transform the resulting item from GetAssemblyIdentity into a property representing its assembly version -->
2728
<CurrentCompilerVersion>@(CurrentCompilerAssemblyIdentity->'%(Version)')</CurrentCompilerVersion>
2829

@@ -35,9 +36,11 @@
3536
<Analyzer Remove="@(_MVVMToolkitAnalyzer)"/>
3637
</ItemGroup>
3738

38-
<!-- If the source generators are disabled, also emit a warning. This would've been produced by MSBuild itself as well, but
39-
emitting this manually lets us customize the message to inform developers as to why exactly the generators have been
40-
disabled, and that the rest of the MVVM Toolkit will still keep working as intended, just without additional features. -->
39+
<!--
40+
If the source generators are disabled, also emit a warning. This would've been produced by MSBuild itself as well, but
41+
emitting this manually lets us customize the message to inform developers as to why exactly the generators have been
42+
disabled, and that the rest of the MVVM Toolkit will still keep working as intended, just without additional features.
43+
-->
4144
<Warning Condition ="'$(CurrentCompilerVersionIsNotNewEnough)' == 'true'" Text="The MVVM Toolkit source generators have been disabled on the current configuration, as they need Roslyn 4.x in order to work. The MVVM Toolkit will work just fine, but features relying on the source generators will not be available."/>
4245
</Target>
4346

dotnet Community Toolkit.sln renamed to CommunityToolkit.sln

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{88C6FFBE-3
3030
CODE_OF_CONDUCT.md = CODE_OF_CONDUCT.md
3131
Contributing.md = Contributing.md
3232
License.md = License.md
33-
README.md = README.md
33+
ReadMe.md = ReadMe.md
3434
ThirdPartyNotices.txt = ThirdPartyNotices.txt
3535
EndProjectSection
3636
EndProject

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
<!-- Embed source files that are not tracked by the source control manager to the PDB -->
3737
<EmbedUntrackedSources>true</EmbedUntrackedSources>
3838
<!-- Include PDB in the built .nupkg -->
39-
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
39+
<AllowedOutputExtensionsInPackageBuildOutputFolder>.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
4040
</PropertyGroup>
4141
<ItemGroup>
4242
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />

README.md renamed to ReadMe.md

File renamed without changes.

build/Community.Toolkit.Common.props

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,5 @@
11
<Project>
22

3-
<PropertyGroup>
4-
<Company>Microsoft</Company>
5-
<Authors>Microsoft</Authors>
6-
<Product>.NET Community Toolkit</Product>
7-
<CommonTags>dotnet;Community;Toolkit</CommonTags>
8-
<PackageLicenseExpression>MIT</PackageLicenseExpression>
9-
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
10-
<Copyright>(c) .NET Foundation and Contributors. All rights reserved.</Copyright>
11-
<PackageProjectUrl>https://github.com/CommunityToolkit/dotnet</PackageProjectUrl>
12-
<PackageReleaseNotes>https://github.com/CommunityToolkit/dotnet/releases</PackageReleaseNotes>
13-
<PackageIcon>Icon.png</PackageIcon>
14-
<PackageIconUrl>https://raw.githubusercontent.com/CommunityToolkit/dotnet/main/build/nuget.png</PackageIconUrl>
15-
</PropertyGroup>
16-
173
<PropertyGroup>
184
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
195
<LangVersion>10.0</LangVersion>
Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,31 @@
11
<Project>
22

3+
<PropertyGroup Condition="$(IsPackable)">
4+
<Company>Microsoft</Company>
5+
<Authors>Microsoft</Authors>
6+
<Product>.NET Community Toolkit</Product>
7+
<CommonTags>.NET;Community;Toolkit;dotnet</CommonTags>
8+
<PackageLicenseExpression>MIT</PackageLicenseExpression>
9+
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
10+
<Copyright>(c) .NET Foundation and Contributors. All rights reserved.</Copyright>
11+
<PackageProjectUrl>https://github.com/CommunityToolkit/dotnet</PackageProjectUrl>
12+
<PackageReleaseNotes>https://github.com/CommunityToolkit/dotnet/releases</PackageReleaseNotes>
13+
<PackageIcon>Icon.png</PackageIcon>
14+
</PropertyGroup>
15+
316
<PropertyGroup>
4-
<!-- TODO: Dynamically generate Title if one wasn't set -->
517
<Title Condition="'$(Title)' == ''">$(Product) Asset</Title>
618
</PropertyGroup>
719

820
<PropertyGroup>
9-
<CommonTags Condition="$(IsCoreProject)">$(CommonTags);.NET</CommonTags>
1021
<PackageTags Condition="'$(PackageTags)' != ''">$(CommonTags);$(PackageTags)</PackageTags>
1122
<PackageTags Condition="'$(PackageTags)' == ''">$(CommonTags)</PackageTags>
1223
</PropertyGroup>
1324

1425
<ItemGroup Condition="$(IsPackable)">
15-
<None Include="$(BuildToolsDirectory)nuget.png" Pack="true" PackagePath="\Icon.png" Visible="False" />
16-
<None Include="$(RepositoryDirectory)License.md" Pack="true" PackagePath="\" Visible="False" />
17-
<None Include="$(RepositoryDirectory)ThirdPartyNotices.txt" Pack="true" PackagePath="\" Visible="False" />
26+
<None Pack="true" PackagePath="\" Visible="False" Include="$(BuildToolsDirectory)Icon.png" />
27+
<None Pack="true" PackagePath="\" Visible="False" Include="$(RepositoryDirectory)License.md" />
28+
<None Pack="true" PackagePath="\" Visible="False" Include="$(RepositoryDirectory)ThirdPartyNotices.txt" />
1829
</ItemGroup>
1930

2031
</Project>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<Project>
2+
3+
<!-- T4 text template service used by the Visual Studio project system -->
4+
<ItemGroup>
5+
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
6+
</ItemGroup>
7+
8+
<!-- Using T4 text templates to generate sources -->
9+
<ItemGroup>
10+
<None Update="**\*.tt">
11+
<Generator>TextTemplatingFileGenerator</Generator>
12+
<LastGenOutput>%(Filename).g.cs</LastGenOutput>
13+
</None>
14+
</ItemGroup>
15+
16+
<!-- Sources generated based on the above text templates -->
17+
<ItemGroup>
18+
<Compile Update="**\*.g.cs">
19+
<AutoGen>True</AutoGen>
20+
<DesignTime>True</DesignTime>
21+
<DependentUpon>$([System.IO.Path]::ChangeExtension(%(Filename), '.tt'))</DependentUpon>
22+
</Compile>
23+
</ItemGroup>
24+
25+
</Project>
File renamed without changes.

tests/CommunityToolkit.Common.UnitTests/CommunityToolkit.Common.UnitTests.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
</PropertyGroup>
66

77
<ItemGroup>
8-
<PackageReference Include="MSTest.TestAdapter" Version="2.2.8" />
9-
<PackageReference Include="MSTest.TestFramework" Version="2.2.8" />
10-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
8+
<ProjectReference Include="..\..\CommunityToolkit.Common\CommunityToolkit.Common.csproj" />
119
</ItemGroup>
1210

1311
<ItemGroup>
14-
<ProjectReference Include="..\..\CommunityToolkit.Common\CommunityToolkit.Common.csproj" />
12+
<PackageReference Include="MSTest.TestAdapter" Version="2.2.8" />
13+
<PackageReference Include="MSTest.TestFramework" Version="2.2.8" />
14+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
1515
</ItemGroup>
1616

1717
</Project>

0 commit comments

Comments
 (0)