Unit constants was added
This commit is contained in:
1
App.xaml
1
App.xaml
@@ -7,6 +7,7 @@
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="Infrastructure/UI/Styles.xaml"/>
|
||||
<ResourceDictionary Source="Infrastructure/UI/Resources/ShapeEditTemplates.xaml"/>
|
||||
<ResourceDictionary Source="Infrastructure/UI/Resources/Converters.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
|
||||
@@ -160,6 +160,7 @@ namespace FieldVisualizer.ViewModels.FieldViewerViewModels
|
||||
private double crossLineY;
|
||||
private double sumAboveLine;
|
||||
private double sumUnderLine;
|
||||
private Line previosLine;
|
||||
const int RangeNumber = 16;
|
||||
|
||||
public FieldViewerViewModel()
|
||||
@@ -311,16 +312,16 @@ namespace FieldVisualizer.ViewModels.FieldViewerViewModels
|
||||
if (crossLineX == 0d)
|
||||
{
|
||||
line.X1 = - width / 2d - dX;
|
||||
line.Y1 = - crossLineY - dY;
|
||||
line.Y1 = - crossLineY + dY;
|
||||
line.X2 = width / 2d - dX;
|
||||
line.Y2 = - crossLineY - dY;
|
||||
line.Y2 = - crossLineY + dY;
|
||||
}
|
||||
else if (crossLineY == 0d)
|
||||
{
|
||||
line.X1 = crossLineX - dX;
|
||||
line.Y1 = heigth / 2 - dY;
|
||||
line.Y1 = heigth / 2 + dY;
|
||||
line.X2 = crossLineX - dX;
|
||||
line.Y2 = -heigth / 2 - dY;
|
||||
line.Y2 = -heigth / 2 + dY;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -334,6 +335,12 @@ namespace FieldVisualizer.ViewModels.FieldViewerViewModels
|
||||
line.Fill = brush;
|
||||
line.Stroke = brush;
|
||||
line.StrokeThickness = (width + heigth) / 100;
|
||||
if (previosLine != null)
|
||||
{
|
||||
try { WorkPlaneCanvas.Children.Remove(previosLine);}
|
||||
catch (Exception) {}
|
||||
}
|
||||
previosLine = line;
|
||||
WorkPlaneCanvas.Children.Add(line);
|
||||
}
|
||||
private double GetPointOfCrossLine(double x)
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace StructureHelper.Infrastructure.UI.Converters.Units
|
||||
double val;
|
||||
if (value != null) { val = (double)value; }
|
||||
else { throw new Exception($"{unitName} value is null"); }
|
||||
val *= UnitConstatnts.LengthConstant * UnitConstatnts.LengthConstant;
|
||||
val *= UnitConstatnts.Length * UnitConstatnts.Length;
|
||||
return val;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace StructureHelper.Infrastructure.UI.Converters.Units
|
||||
double.TryParse(strVal, out val);
|
||||
}
|
||||
else { throw new Exception($"{unitName} value is null"); }
|
||||
val /= (UnitConstatnts.LengthConstant * UnitConstatnts.LengthConstant);
|
||||
val /= (UnitConstatnts.Length * UnitConstatnts.Length);
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
39
Infrastructure/UI/Converters/Units/Force.cs
Normal file
39
Infrastructure/UI/Converters/Units/Force.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace StructureHelper.Infrastructure.UI.Converters.Units
|
||||
{
|
||||
internal class Force : UnitBase
|
||||
{
|
||||
private double coeffficient = UnitConstatnts.Force;
|
||||
|
||||
public override string unitName { get => "Force"; }
|
||||
|
||||
public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
double val;
|
||||
if (value != null) { val = (double)value; }
|
||||
else { throw new Exception($"{unitName} value is null"); }
|
||||
val *= coeffficient;
|
||||
return val;
|
||||
}
|
||||
|
||||
public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
double val;
|
||||
if (value != null)
|
||||
{
|
||||
var strVal = value as string;
|
||||
double.TryParse(strVal, out val);
|
||||
}
|
||||
else { throw new Exception($"{unitName} value is null"); }
|
||||
val /= coeffficient;
|
||||
return val;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ namespace StructureHelper.Infrastructure.UI.Converters.Units
|
||||
double val;
|
||||
if (value != null) { val = (double)value; }
|
||||
else { throw new Exception($"{unitName} value is null"); }
|
||||
val *= UnitConstatnts.LengthConstant;
|
||||
val *= UnitConstatnts.Length;
|
||||
return val;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace StructureHelper.Infrastructure.UI.Converters.Units
|
||||
double.TryParse(strVal, out val);
|
||||
}
|
||||
else { throw new Exception($"{unitName} value is null"); }
|
||||
val /= UnitConstatnts.LengthConstant;
|
||||
val /= UnitConstatnts.Length;
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
39
Infrastructure/UI/Converters/Units/Stress.cs
Normal file
39
Infrastructure/UI/Converters/Units/Stress.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace StructureHelper.Infrastructure.UI.Converters.Units
|
||||
{
|
||||
internal class Stress : UnitBase
|
||||
{
|
||||
private double coeffficient = UnitConstatnts.Stress;
|
||||
|
||||
public override string unitName { get => "Stress"; }
|
||||
|
||||
public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
double val;
|
||||
if (value != null) { val = (double)value; }
|
||||
else { throw new Exception($"{unitName} value is null"); }
|
||||
val *= coeffficient;
|
||||
return val;
|
||||
}
|
||||
|
||||
public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
double val;
|
||||
if (value != null)
|
||||
{
|
||||
var strVal = value as string;
|
||||
double.TryParse(strVal, out val);
|
||||
}
|
||||
else { throw new Exception($"{unitName} value is null"); }
|
||||
val /= coeffficient;
|
||||
return val;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,8 @@ namespace StructureHelper.Infrastructure.UI.Converters.Units
|
||||
{
|
||||
internal static class UnitConstatnts
|
||||
{
|
||||
public static double LengthConstant = 1000d;
|
||||
public static double Length = 1e3d;
|
||||
public static double Force = 1e-3d;
|
||||
public static double Stress = 1e-6d;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,12 +337,12 @@ namespace StructureHelper.Infrastructure.UI.DataContexts
|
||||
{
|
||||
if (this is Rectangle)
|
||||
{
|
||||
X = showedX + OwnerVm.YX1 / UnitConstatnts.LengthConstant;
|
||||
X = showedX + OwnerVm.YX1 / UnitConstatnts.Length;
|
||||
}
|
||||
else if (this is Point)
|
||||
{
|
||||
Point point = this as Point;
|
||||
X = showedX + OwnerVm.YX1 / UnitConstatnts.LengthConstant;
|
||||
X = showedX + OwnerVm.YX1 / UnitConstatnts.Length;
|
||||
}
|
||||
else { throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknown); }
|
||||
}
|
||||
@@ -350,12 +350,12 @@ namespace StructureHelper.Infrastructure.UI.DataContexts
|
||||
{
|
||||
if (this is Rectangle)
|
||||
{
|
||||
Y = -showedY + OwnerVm.XY1 / UnitConstatnts.LengthConstant - PrimitiveHeight;
|
||||
Y = -showedY + OwnerVm.XY1 / UnitConstatnts.Length - PrimitiveHeight;
|
||||
}
|
||||
else if (this is Point)
|
||||
{
|
||||
Point point = this as Point;
|
||||
Y = -showedY + OwnerVm.XY1 / UnitConstatnts.LengthConstant - point.Diameter;
|
||||
Y = -showedY + OwnerVm.XY1 / UnitConstatnts.Length - point.Diameter;
|
||||
}
|
||||
else { throw new StructureHelperException(ErrorStrings.ObjectTypeIsUnknown); }
|
||||
}
|
||||
|
||||
12
Infrastructure/UI/Resources/Converters.xaml
Normal file
12
Infrastructure/UI/Resources/Converters.xaml
Normal file
@@ -0,0 +1,12 @@
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:convertersCommon ="clr-namespace:StructureHelper.Infrastructure.UI.Converters.Common"
|
||||
xmlns:convertersUnits ="clr-namespace:StructureHelper.Infrastructure.UI.Converters.Units">
|
||||
|
||||
<convertersCommon:InvertBoolConverter x:Key="InvertBoolConverter"/>
|
||||
<convertersUnits:Length x:Key="LengthConverter"/>
|
||||
<convertersUnits:Area x:Key="AreaConverter"/>
|
||||
<convertersUnits:Force x:Key="ForceConverter"/>
|
||||
<convertersUnits:Stress x:Key="StressConverter"/>
|
||||
</ResourceDictionary>
|
||||
@@ -12,5 +12,6 @@ namespace StructureHelper.Services.ResultViewers
|
||||
{
|
||||
string Name { get; }
|
||||
Func<IStrainMatrix, INdm, double> ResultFunction { get; }
|
||||
double UnitFactor { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,5 +12,11 @@ namespace StructureHelper.Services.ResultViewers
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public Func<IStrainMatrix, INdm, double> ResultFunction { get; set; }
|
||||
public double UnitFactor { get; set; }
|
||||
|
||||
public ResultFunc()
|
||||
{
|
||||
UnitFactor = 1d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using LoaderCalculator.Logics;
|
||||
using StructureHelper.Infrastructure.UI.Converters.Units;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -17,12 +18,12 @@ namespace StructureHelper.Services.ResultViewers
|
||||
resultFuncs.Add(new ResultFunc() { Name = "Total Strain with prestrain", ResultFunction = stressLogic.GetTotalStrainWithPresrain });
|
||||
resultFuncs.Add(new ResultFunc() { Name = "Elastic Strain", ResultFunction = stressLogic.GetElasticStrain });
|
||||
resultFuncs.Add(new ResultFunc() { Name = "Plastic Strain", ResultFunction = stressLogic.GetPlasticStrain });
|
||||
resultFuncs.Add(new ResultFunc() { Name = "Stress", ResultFunction = stressLogic.GetStress });
|
||||
resultFuncs.Add(new ResultFunc() { Name = "Secant modulus", ResultFunction = stressLogic.GetSecantModulus });
|
||||
resultFuncs.Add(new ResultFunc() { Name = "Stress", ResultFunction = stressLogic.GetStress, UnitFactor = UnitConstatnts.Stress });
|
||||
resultFuncs.Add(new ResultFunc() { Name = "Secant modulus", ResultFunction = stressLogic.GetSecantModulus, UnitFactor = UnitConstatnts.Stress });
|
||||
resultFuncs.Add(new ResultFunc() { Name = "Modulus degradation", ResultFunction = stressLogic.GetModulusDegradation });
|
||||
resultFuncs.Add(new ResultFunc() { Name = "Force", ResultFunction = stressLogic.GetForce });
|
||||
resultFuncs.Add(new ResultFunc() { Name = "Moment X", ResultFunction = stressLogic.GetMomentX });
|
||||
resultFuncs.Add(new ResultFunc() { Name = "Moment Y", ResultFunction = stressLogic.GetMomentY });
|
||||
resultFuncs.Add(new ResultFunc() { Name = "Force", ResultFunction = stressLogic.GetForce, UnitFactor = UnitConstatnts.Force });
|
||||
resultFuncs.Add(new ResultFunc() { Name = "Moment X", ResultFunction = stressLogic.GetMomentX, UnitFactor = UnitConstatnts.Force });
|
||||
resultFuncs.Add(new ResultFunc() { Name = "Moment Y", ResultFunction = stressLogic.GetMomentY, UnitFactor = UnitConstatnts.Force });
|
||||
return resultFuncs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace StructureHelper.Services.ResultViewers
|
||||
List<IValuePrimitive> primitives = new List<IValuePrimitive>();
|
||||
foreach (INdm ndm in ndms)
|
||||
{
|
||||
double val = valDelegate.ResultFunction.Invoke(strainMatrix, ndm);
|
||||
double val = valDelegate.ResultFunction.Invoke(strainMatrix, ndm) * valDelegate.UnitFactor;
|
||||
IValuePrimitive valuePrimitive;
|
||||
if (ndm is IRectangleNdm)
|
||||
{
|
||||
|
||||
@@ -135,6 +135,8 @@
|
||||
<Compile Include="Infrastructure\Enums\PrimitiveType.cs" />
|
||||
<Compile Include="Infrastructure\UI\Converters\Common\InvertBoolConverter.cs" />
|
||||
<Compile Include="Infrastructure\UI\Converters\Units\Area.cs" />
|
||||
<Compile Include="Infrastructure\UI\Converters\Units\Stress.cs" />
|
||||
<Compile Include="Infrastructure\UI\Converters\Units\Force.cs" />
|
||||
<Compile Include="Infrastructure\UI\Converters\Units\Length.cs" />
|
||||
<Compile Include="Infrastructure\UI\Converters\Units\UnitBase.cs" />
|
||||
<Compile Include="Infrastructure\UI\Converters\Units\UnitConstatnts.cs" />
|
||||
@@ -229,6 +231,10 @@
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="Infrastructure\UI\Resources\Converters.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Infrastructure\UI\Resources\ShapeEditTemplates.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
||||
@@ -35,9 +35,9 @@
|
||||
SelectedItem="{Binding Path=SelectedCombination}">
|
||||
<DataGrid.Columns>
|
||||
<DataGridCheckBoxColumn Header="Active" Binding="{Binding Path=TakeInCalculate}"/>
|
||||
<DataGridTextColumn Header="Moment Mx" Width="90" Binding="{Binding Path=ForceMatrix.Mx}"/>
|
||||
<DataGridTextColumn Header="Moment My" Width="90" Binding="{Binding Path=ForceMatrix.My}"/>
|
||||
<DataGridTextColumn Header="Force Nz" Width="90" Binding="{Binding Path=ForceMatrix.Nz}"/>
|
||||
<DataGridTextColumn Header="Moment Mx" Width="90" Binding="{Binding Path=ForceMatrix.Mx, Converter={StaticResource ForceConverter}}"/>
|
||||
<DataGridTextColumn Header="Moment My" Width="90" Binding="{Binding Path=ForceMatrix.My, Converter={StaticResource ForceConverter}}"/>
|
||||
<DataGridTextColumn Header="Force Nz" Width="90" Binding="{Binding Path=ForceMatrix.Nz, Converter={StaticResource ForceConverter}}"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<StackPanel Grid.Column="1">
|
||||
|
||||
@@ -25,12 +25,15 @@
|
||||
</DataGrid.RowStyle>
|
||||
<DataGrid.Columns>
|
||||
<DataGridCheckBoxColumn Header="Valid" Binding="{Binding Path=IsValid}"/>
|
||||
<DataGridTextColumn Header="Moment Mx" Width="90" Binding="{Binding Path=LoaderResults.ForceStrainPair.ForceMatrix.Mx}"/>
|
||||
<DataGridTextColumn Header="Moment My" Width="90" Binding="{Binding Path=LoaderResults.ForceStrainPair.ForceMatrix.My}"/>
|
||||
<DataGridTextColumn Header="Force Nz" Width="90" Binding="{Binding Path=LoaderResults.ForceStrainPair.ForceMatrix.Nz}"/>
|
||||
<DataGridTextColumn Header="Moment Mx" Width="90" Binding="{Binding Path=LoaderResults.ForceStrainPair.ForceMatrix.Mx, Converter={StaticResource ForceConverter}}"/>
|
||||
<DataGridTextColumn Header="Moment My" Width="90" Binding="{Binding Path=LoaderResults.ForceStrainPair.ForceMatrix.My, Converter={StaticResource ForceConverter}}"/>
|
||||
<DataGridTextColumn Header="Force Nz" Width="90" Binding="{Binding Path=LoaderResults.ForceStrainPair.ForceMatrix.Nz, Converter={StaticResource ForceConverter}}"/>
|
||||
<DataGridTextColumn Header="Accuracy" Width="90" Binding="{Binding Path=LoaderResults.AccuracyRate}"/>
|
||||
<DataGridTextColumn Header="Max Iteration" Width="90" Binding="{Binding Path=LoaderResults.IterationCounter}"/>
|
||||
<DataGridTextColumn Header="Description" Width="300" Binding="{Binding Path=Desctription}"/>
|
||||
<DataGridTextColumn Header="Kx" Width="90" Binding="{Binding LoaderResults.ForceStrainPair.StrainMatrix.Kx}"/>
|
||||
<DataGridTextColumn Header="Ky" Width="90" Binding="{Binding LoaderResults.ForceStrainPair.StrainMatrix.Ky}"/>
|
||||
<DataGridTextColumn Header="EpsZ" Width="90" Binding="{Binding LoaderResults.ForceStrainPair.StrainMatrix.EpsZ}"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<StackPanel Grid.Column="1">
|
||||
|
||||
@@ -287,7 +287,7 @@ namespace StructureHelper.Windows.MainWindow
|
||||
Primitives.Add(primitive);
|
||||
PrimitiveRepository.Add(primitive);
|
||||
}
|
||||
AddCaseLoads(50e3d, 50e3d, 0d);
|
||||
AddCaseLoads(-50e3d, 50e3d, 0d);
|
||||
});
|
||||
|
||||
AddColumnCase = new RelayCommand(o =>
|
||||
@@ -454,11 +454,11 @@ namespace StructureHelper.Windows.MainWindow
|
||||
double[] xs = new double[] { -width / 2 + gap, width / 2 - gap };
|
||||
double[] ys = new double[] { -height / 2 + gap, height / 2 - gap };
|
||||
|
||||
yield return new Rectangle(width, height, 0, 0, this) { HeadMaterial = concrete };
|
||||
yield return new Point(area1, xs[0], ys[0], this) { HeadMaterial = reinforcement };
|
||||
yield return new Point(area1, xs[1], ys[0], this) { HeadMaterial = reinforcement };
|
||||
yield return new Point(area2, xs[0], ys[1], this) { HeadMaterial = reinforcement };
|
||||
yield return new Point(area2, xs[1], ys[1], this) { HeadMaterial = reinforcement };
|
||||
yield return new Rectangle(width, height, 0, 0, this) { HeadMaterial = concrete, Name = "Concrete block" };
|
||||
yield return new Point(area1, xs[0], ys[0], this) { HeadMaterial = reinforcement, Name = "Left bottom point" };
|
||||
yield return new Point(area1, xs[1], ys[0], this) { HeadMaterial = reinforcement, Name = "Right bottom point" };
|
||||
yield return new Point(area2, xs[0], ys[1], this) { HeadMaterial = reinforcement, Name = "Left top point" };
|
||||
yield return new Point(area2, xs[1], ys[1], this) { HeadMaterial = reinforcement, Name = "Right top point" };
|
||||
|
||||
if (template.WidthCount > 2)
|
||||
{
|
||||
@@ -466,8 +466,8 @@ namespace StructureHelper.Windows.MainWindow
|
||||
double dist = (xs[1] - xs[0]) / count;
|
||||
for (int i = 1; i < count; i++)
|
||||
{
|
||||
yield return new Point(area1, xs[0] + dist * i, ys[0], this) { HeadMaterial = reinforcement };
|
||||
yield return new Point(area2, xs[0] + dist * i, ys[1], this) { HeadMaterial = reinforcement };
|
||||
yield return new Point(area1, xs[0] + dist * i, ys[0], this) { HeadMaterial = reinforcement, Name = $"Bottom point {i}" };
|
||||
yield return new Point(area2, xs[0] + dist * i, ys[1], this) { HeadMaterial = reinforcement, Name = $"Top point {i}" };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -477,8 +477,8 @@ namespace StructureHelper.Windows.MainWindow
|
||||
double dist = (ys[1] - ys[0]) / count;
|
||||
for (int i = 1; i < count; i++)
|
||||
{
|
||||
yield return new Point(area1, xs[0], ys[0] + dist * i, this) { HeadMaterial = reinforcement };
|
||||
yield return new Point(area1, xs[1], ys[0] + dist * i, this) { HeadMaterial = reinforcement };
|
||||
yield return new Point(area1, xs[0], ys[0] + dist * i, this) { HeadMaterial = reinforcement, Name = $"Left point {i}" };
|
||||
yield return new Point(area1, xs[1], ys[0] + dist * i, this) { HeadMaterial = reinforcement, Name = $"Right point {i}" };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,15 +5,10 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:StructureHelper.Windows.PrimitiveProperiesWindow"
|
||||
xmlns:vm="clr-namespace:StructureHelper.Windows.ViewModels.PrimitiveProperties"
|
||||
xmlns:convertersCommon ="clr-namespace:StructureHelper.Infrastructure.UI.Converters.Common"
|
||||
xmlns:convertersUnits ="clr-namespace:StructureHelper.Infrastructure.UI.Converters.Units"
|
||||
d:DataContext="{d:DesignInstance vm:PrimitivePropertiesViewModel}"
|
||||
mc:Ignorable="d"
|
||||
Title="PrimitiveProperties" Height="450" Width="300" ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
|
||||
<Window.Resources>
|
||||
<convertersCommon:InvertBoolConverter x:Key="InvertBoolConverter"/>
|
||||
<convertersUnits:Length x:Key="LengthConverter"/>
|
||||
<convertersUnits:Area x:Key="AreaConverter"/>
|
||||
<DataTemplate x:Key="RectangleProperties">
|
||||
<Expander Header="Rectangle" IsExpanded="True">
|
||||
<Grid>
|
||||
|
||||
Reference in New Issue
Block a user