Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

мини апстримчик <3 #164

Merged
merged 23 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
78c51b6
make some ores more common on lavaland planets (#2441)
deltanedas Dec 17, 2024
7200dfb
Automatic changelog update
DeltaV-Bot Dec 17, 2024
9de9a17
New Blood Based Soda! (#2250)
BlitzTheSquishy Dec 18, 2024
b84986e
Automatic changelog update
DeltaV-Bot Dec 18, 2024
63b9a05
Emag for fugi (#2374)
Stop-Signs Dec 18, 2024
2d96bb3
Automatic changelog update
DeltaV-Bot Dec 18, 2024
85a29fb
add ash storms to lavaland (#2445)
deltanedas Dec 18, 2024
5625428
Automatic changelog update
DeltaV-Bot Dec 18, 2024
6fd816c
Remove justice lockers from upstream files and add DeltaV base locker…
Radezolid Dec 18, 2024
6b83754
Frontier Port: Pretty Money (#2398)
Unkn0wnGh0st333 Dec 18, 2024
2623935
Updates Maintenance Lights (#2465)
IamVelcroboy Dec 18, 2024
f416875
Fix Rodentia Bat snouts to properly mirror left and right face (#2470)
paige404 Dec 18, 2024
7cdc016
Automatic changelog update
DeltaV-Bot Dec 18, 2024
9146ee3
remove constant shuttle spam from survival (#2471)
deltanedas Dec 18, 2024
94b2542
Add error logging for Auto ACO procedure. (#2450)
ewokswagger Dec 18, 2024
ee4fca4
cleanup and carrying refactor (#2466)
deltanedas Dec 18, 2024
8ac8da7
Automatic changelog update
DeltaV-Bot Dec 18, 2024
dce230f
port ore bag magnet toggle from white dream (#2467)
deltanedas Dec 18, 2024
93c13b4
Automatic changelog update
DeltaV-Bot Dec 18, 2024
600ef0e
Add history tab to bounty console (#2473)
BarryNorfolk Dec 18, 2024
f49142c
Automatic changelog update
DeltaV-Bot Dec 18, 2024
9f5e1b4
up
Dec 18, 2024
e74c460
fix
Dec 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ protected override void UpdateState(BoundUserInterfaceState message)
if (message is not CargoBountyConsoleState state)
return;

_menu?.UpdateEntries(state.Bounties, state.UntilNextSkip);
_menu?.UpdateEntries(state.Bounties, state.History, state.UntilNextSkip);
}
}
23 changes: 23 additions & 0 deletions Content.Client/Cargo/UI/BountyHistoryEntry.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<BoxContainer xmlns="https://spacestation14.io"
xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls"
Margin="10 10 10 0"
HorizontalExpand="True"
Visible="True">
<PanelContainer StyleClasses="AngleRect" HorizontalExpand="True">
<BoxContainer Orientation="Vertical"
HorizontalExpand="True">
<BoxContainer Orientation="Horizontal">
<BoxContainer Orientation="Vertical" HorizontalExpand="True">
<RichTextLabel Name="RewardLabel"/>
<RichTextLabel Name="ManifestLabel"/>
<RichTextLabel Name="NoticeLabel"/>
</BoxContainer>
<Control MinWidth="10"/>
<BoxContainer Orientation="Vertical" MinWidth="120">
<RichTextLabel Name="StatusLabel" HorizontalAlignment="Right" Margin="0 0 5 0"/>
<RichTextLabel Name="IdLabel" HorizontalAlignment="Right" Margin="0 0 5 0"/>
</BoxContainer>
</BoxContainer>
</BoxContainer>
</PanelContainer>
</BoxContainer>
54 changes: 54 additions & 0 deletions Content.Client/Cargo/UI/BountyHistoryEntry.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Content.Client.Message;
using Content.Shared.Cargo;
using Content.Shared.Cargo.Prototypes;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;

namespace Content.Client.Cargo.UI;

[GenerateTypedNameReferences]
public sealed partial class BountyHistoryEntry : BoxContainer
{
[Dependency] private readonly IPrototypeManager _prototype = default!;

public BountyHistoryEntry(CargoBountyHistoryData bounty)
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);

if (!_prototype.TryIndex<CargoBountyPrototype>(bounty.Bounty, out var bountyPrototype))
return;
Comment on lines +22 to +23
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling for missing prototypes

The current implementation silently returns if the prototype is not found. Consider logging an error or showing a user-friendly message.

 if (!_prototype.TryIndex<CargoBountyPrototype>(bounty.Bounty, out var bountyPrototype))
-    return;
+{
+    Logger.Error($"Failed to find bounty prototype: {bounty.Bounty}");
+    ManifestLabel.SetMarkup(Loc.GetString("bounty-console-error-invalid-bounty"));
+    return;
+}

Committable suggestion skipped: line range outside the PR's diff.


var items = new List<string>();
foreach (var entry in bountyPrototype.Entries)
{
items.Add(Loc.GetString("bounty-console-manifest-entry",
("amount", entry.Amount),
("item", Loc.GetString(entry.Name))));
}
ManifestLabel.SetMarkup(Loc.GetString("bounty-console-manifest-label", ("item", string.Join(", ", items))));
RewardLabel.SetMarkup(Loc.GetString("bounty-console-reward-label", ("reward", bountyPrototype.Reward)));
IdLabel.SetMarkup(Loc.GetString("bounty-console-id-label", ("id", bounty.Id)));

var stationTime = bounty.Timestamp.ToString("hh\\:mm\\:ss");
if (bounty.ActorName == null)
{
StatusLabel.SetMarkup(Loc.GetString("bounty-console-history-completed-label"));
NoticeLabel.SetMarkup(Loc.GetString("bounty-console-history-notice-completed-label", ("time", stationTime)));
}
else
{
StatusLabel.SetMarkup(Loc.GetString("bounty-console-history-skipped-label"));
NoticeLabel.SetMarkup(Loc.GetString("bounty-console-history-notice-skipped-label",
("id", bounty.ActorName),
("time", stationTime)));
}
}
protected override void FrameUpdate(FrameEventArgs args)
{
base.FrameUpdate(args);
}
Comment on lines +50 to +53
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Remove empty FrameUpdate method

The empty FrameUpdate method can be removed as it only calls the base implementation.

-protected override void FrameUpdate(FrameEventArgs args)
-{
-    base.FrameUpdate(args);
-}

}
29 changes: 20 additions & 9 deletions Content.Client/Cargo/UI/CargoBountyMenu.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,26 @@
<PanelContainer.PanelOverride>
<gfx:StyleBoxFlat BackgroundColor="#1B1B1E" />
</PanelContainer.PanelOverride>
<ScrollContainer HScrollEnabled="False"
HorizontalExpand="True"
VerticalExpand="True">
<BoxContainer Name="BountyEntriesContainer"
Orientation="Vertical"
VerticalExpand="True"
HorizontalExpand="True">
</BoxContainer>
</ScrollContainer>
<TabContainer Name="MasterTabContainer" VerticalExpand="True" HorizontalExpand="True">
<ScrollContainer HScrollEnabled="False"
HorizontalExpand="True"
VerticalExpand="True">
<BoxContainer Name="BountyEntriesContainer"
Orientation="Vertical"
VerticalExpand="True"
HorizontalExpand="True">
</BoxContainer>
</ScrollContainer>
<ScrollContainer HScrollEnabled="False"
HorizontalExpand="True"
VerticalExpand="True">
<BoxContainer Name="BountyHistoryContainer"
Orientation="Vertical"
VerticalExpand="True"
HorizontalExpand="True">
</BoxContainer>
</ScrollContainer>
</TabContainer>
</PanelContainer>
<!-- Footer -->
<BoxContainer Orientation="Vertical">
Expand Down
12 changes: 11 additions & 1 deletion Content.Client/Cargo/UI/CargoBountyMenu.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ public CargoBountyMenu()
RobustXamlLoader.Load(this);
}

public void UpdateEntries(List<CargoBountyData> bounties, TimeSpan untilNextSkip)
public void UpdateEntries(List<CargoBountyData> bounties, List<CargoBountyHistoryData> history, TimeSpan untilNextSkip)
{
MasterTabContainer.SetTabTitle(0, Loc.GetString("bounty-console-tab-available-label"));
MasterTabContainer.SetTabTitle(1, Loc.GetString("bounty-console-tab-history-label"));

Comment on lines +20 to +24
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add parameter validation

The method should validate the input parameters to prevent potential null reference exceptions.

Consider adding parameter validation:

-public void UpdateEntries(List<CargoBountyData> bounties, List<CargoBountyHistoryData> history, TimeSpan untilNextSkip)
+public void UpdateEntries(List<CargoBountyData> bounties, List<CargoBountyHistoryData> history, TimeSpan untilNextSkip)
 {
+    ArgumentNullException.ThrowIfNull(bounties);
+    ArgumentNullException.ThrowIfNull(history);
+
     MasterTabContainer.SetTabTitle(0, Loc.GetString("bounty-console-tab-available-label"));
     MasterTabContainer.SetTabTitle(1, Loc.GetString("bounty-console-tab-history-label"));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public void UpdateEntries(List<CargoBountyData> bounties, List<CargoBountyHistoryData> history, TimeSpan untilNextSkip)
{
MasterTabContainer.SetTabTitle(0, Loc.GetString("bounty-console-tab-available-label"));
MasterTabContainer.SetTabTitle(1, Loc.GetString("bounty-console-tab-history-label"));
public void UpdateEntries(List<CargoBountyData> bounties, List<CargoBountyHistoryData> history, TimeSpan untilNextSkip)
{
ArgumentNullException.ThrowIfNull(bounties);
ArgumentNullException.ThrowIfNull(history);
MasterTabContainer.SetTabTitle(0, Loc.GetString("bounty-console-tab-available-label"));
MasterTabContainer.SetTabTitle(1, Loc.GetString("bounty-console-tab-history-label"));

BountyEntriesContainer.Children.Clear();
foreach (var b in bounties)
{
Expand All @@ -32,5 +35,12 @@ public void UpdateEntries(List<CargoBountyData> bounties, TimeSpan untilNextSkip
{
MinHeight = 10
});

BountyHistoryContainer.Children.Clear();
foreach (var h in history)
{
var entry = new BountyHistoryEntry(h);
BountyHistoryContainer.AddChild(entry);
}
}
}
23 changes: 14 additions & 9 deletions Content.Client/Stack/StackSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace Content.Client.Stack
{
[UsedImplicitly]
public sealed class StackSystem : SharedStackSystem
public sealed partial class StackSystem : SharedStackSystem // Frontier: add partial to class definition
{
[Dependency] private readonly AppearanceSystem _appearanceSystem = default!;
[Dependency] private readonly ItemCounterSystem _counterSystem = default!;
Expand Down Expand Up @@ -44,7 +44,7 @@ public override void SetCount(EntityUid uid, int amount, StackComponent? compone
// TODO PREDICT ENTITY DELETION: This should really just be a normal entity deletion call.
if (component.Count <= 0 && !component.Lingering)
{
Xform.DetachEntity(uid, Transform(uid));
Xform.DetachParentToNull(uid, Transform(uid));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add null check for Transform component

The DetachParentToNull call should include a null check for the Transform component.

-Xform.DetachParentToNull(uid, Transform(uid));
+if (TryComp<TransformComponent>(uid, out var transform))
+    Xform.DetachParentToNull(uid, transform);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Xform.DetachParentToNull(uid, Transform(uid));
if (TryComp<TransformComponent>(uid, out var transform))
Xform.DetachParentToNull(uid, transform);

return;
}

Expand All @@ -56,20 +56,25 @@ private void OnAppearanceChange(EntityUid uid, StackComponent comp, ref Appearan
if (args.Sprite == null || comp.LayerStates.Count < 1)
return;

StackLayerData data = new StackLayerData(); // Frontier: use structure to store StackLayerData

// Skip processing if no actual
if (!_appearanceSystem.TryGetData<int>(uid, StackVisuals.Actual, out var actual, args.Component))
if (!_appearanceSystem.TryGetData<int>(uid, StackVisuals.Actual, out data.Actual, args.Component))
return;

if (!_appearanceSystem.TryGetData<int>(uid, StackVisuals.MaxCount, out var maxCount, args.Component))
maxCount = comp.LayerStates.Count;
if (!_appearanceSystem.TryGetData<int>(uid, StackVisuals.MaxCount, out data.MaxCount, args.Component))
data.MaxCount = comp.LayerStates.Count;

if (!_appearanceSystem.TryGetData<bool>(uid, StackVisuals.Hide, out data.Hidden, args.Component))
data.Hidden = false;

if (!_appearanceSystem.TryGetData<bool>(uid, StackVisuals.Hide, out var hidden, args.Component))
hidden = false;
if (comp.LayerFunction != StackLayerFunction.None) // Frontier: use stack layer function to modify appearance if provided.
ApplyLayerFunction(uid, comp, ref data); // Frontier: definition in _NF/Stack/StackSystem.Layers.cs

if (comp.IsComposite)
_counterSystem.ProcessCompositeSprite(uid, actual, maxCount, comp.LayerStates, hidden, sprite: args.Sprite);
_counterSystem.ProcessCompositeSprite(uid, data.Actual, data.MaxCount, comp.LayerStates, data.Hidden, sprite: args.Sprite);
else
_counterSystem.ProcessOpaqueSprite(uid, comp.BaseLayer, actual, maxCount, comp.LayerStates, hidden, sprite: args.Sprite);
_counterSystem.ProcessOpaqueSprite(uid, comp.BaseLayer, data.Actual, data.MaxCount, comp.LayerStates, data.Hidden, sprite: args.Sprite);
}
}
}
56 changes: 56 additions & 0 deletions Content.Client/_NF/Stack/StackSystem.Layers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using Content.Shared.Stacks.Components;
using Content.Shared.Stacks;

namespace Content.Client.Stack
{
/// <summary>
/// Data used to determine which layers of a stack's sprite are visible.
/// </summary>
public struct StackLayerData
{
public int Actual;
public int MaxCount;
public bool Hidden;
}

public sealed partial class StackSystem : SharedStackSystem
{
// Modifies a given stack component to adjust the layers to display.
private bool ApplyLayerFunction(EntityUid uid, StackComponent comp, ref StackLayerData data)
{
switch (comp.LayerFunction)
{
case StackLayerFunction.Threshold:
if (TryComp<StackLayerThresholdComponent>(uid, out var threshold))
{
ApplyThreshold(threshold, ref data);
return true;
}
break;
}
// No function applied.
return false;
}

/// <summary>
/// Sets Actual to the number of thresholds that Actual exceeds from the beginning of the list.
/// Sets MaxCount to the total number of thresholds plus one (for values under thresholds).
/// </summary>
private static void ApplyThreshold(StackLayerThresholdComponent comp, ref StackLayerData data)
{
// We must stop before we run out of thresholds or layers, whichever's smaller.
data.MaxCount = Math.Min(comp.Thresholds.Count + 1, data.MaxCount);
int newActual = 0;
foreach (var threshold in comp.Thresholds)
{
//If our value exceeds threshold, the next layer should be displayed.
//Note: we must ensure actual <= MaxCount.
if (data.Actual >= threshold && newActual < data.MaxCount)
newActual++;
else
break;
}
data.Actual = newActual;
}
}
}
7 changes: 7 additions & 0 deletions Content.Server/Body/Components/LungComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,11 @@ public sealed partial class LungComponent : Component
/// </summary>
[DataField]
public ProtoId<AlertPrototype> Alert = "LowOxygen";

/// <summary>
/// DeltaV: Multiplier on saturation passively lost.
/// Higher values require more air, lower require less.
/// </summary>
[DataField]
public float SaturationLoss = 1f;
}
17 changes: 9 additions & 8 deletions Content.Server/Body/Systems/RespiratorSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,15 @@ public override void Update(float frameTime)
if (_mobState.IsDead(uid))
continue;

//_bodySystem.GetBodyOrgans<(EntityUid euid, LungComponent lc)>(uid, body);
//_bodySystem.
/* var organs = _bodySystem.GetBodyOrganComponents<LungComponent>(uid, body);
if(organs==null){
continue;
}*/

UpdateSaturation(uid, -(float) respirator.UpdateInterval.TotalSeconds, respirator);
// Begin DeltaV Code: Addition:
var organs = _bodySystem.GetBodyOrganEntityComps<LungComponent>((uid, body));
var multiplier = -1f;
foreach (var (_, lung, _) in organs)
{
multiplier *= lung.SaturationLoss;
}
// End DeltaV Code
UpdateSaturation(uid, multiplier * (float) respirator.UpdateInterval.TotalSeconds, respirator); // DeltaV: use multiplier instead of negating

if (!_mobState.IsIncapacitated(uid)) // cannot breathe in crit.
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ public sealed partial class StationCargoBountyDatabaseComponent : Component
[DataField, ViewVariables(VVAccess.ReadWrite)]
public List<CargoBountyData> Bounties = new();

/// <summary>
/// A list of all the bounties that have been completed or
/// skipped for a station.
/// </summary>
[DataField, ViewVariables(VVAccess.ReadWrite)]
public List<CargoBountyHistoryData> History = new();

/// <summary>
/// Used to determine unique order IDs
/// </summary>
Expand Down
26 changes: 19 additions & 7 deletions Content.Server/Cargo/Systems/CargoSystem.Bounty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Content.Shared.Cargo.Components;
using Content.Shared.Cargo.Prototypes;
using Content.Shared.Database;
using Content.Shared.IdentityManagement;
using Content.Shared.NameIdentifier;
using Content.Shared.Paper;
using Content.Shared.Stacks;
Expand All @@ -16,6 +17,7 @@
using Robust.Server.Containers;
using Robust.Shared.Containers;
using Robust.Shared.Random;
using Robust.Shared.Timing;
using Robust.Shared.Utility;

namespace Content.Server.Cargo.Systems;
Expand All @@ -25,6 +27,7 @@ public sealed partial class CargoSystem
[Dependency] private readonly ContainerSystem _container = default!;
[Dependency] private readonly NameIdentifierSystem _nameIdentifier = default!;
[Dependency] private readonly EntityWhitelistSystem _whitelistSys = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;

[ValidatePrototypeId<NameIdentifierGroupPrototype>]
private const string BountyNameIdentifierGroup = "Bounty";
Expand Down Expand Up @@ -54,7 +57,7 @@ private void OnBountyConsoleOpened(EntityUid uid, CargoBountyConsoleComponent co
return;

var untilNextSkip = bountyDb.NextSkipTime - _timing.CurTime;
_uiSystem.SetUiState(uid, CargoConsoleUiKey.Bounty, new CargoBountyConsoleState(bountyDb.Bounties, untilNextSkip));
_uiSystem.SetUiState(uid, CargoConsoleUiKey.Bounty, new CargoBountyConsoleState(bountyDb.Bounties, bountyDb.History, untilNextSkip));
}

private void OnPrintLabelMessage(EntityUid uid, CargoBountyConsoleComponent component, BountyPrintLabelMessage args)
Expand Down Expand Up @@ -95,13 +98,13 @@ private void OnSkipBountyMessage(EntityUid uid, CargoBountyConsoleComponent comp
return;
}

if (!TryRemoveBounty(station, bounty.Value))
if (!TryRemoveBounty(station, bounty.Value, null, args.Actor))
return;

FillBountyDatabase(station);
db.NextSkipTime = _timing.CurTime + db.SkipDelay;
var untilNextSkip = db.NextSkipTime - _timing.CurTime;
_uiSystem.SetUiState(uid, CargoConsoleUiKey.Bounty, new CargoBountyConsoleState(db.Bounties, untilNextSkip));
_uiSystem.SetUiState(uid, CargoConsoleUiKey.Bounty, new CargoBountyConsoleState(db.Bounties, db.History, untilNextSkip));
_audio.PlayPvs(component.SkipSound, uid);
}

Expand Down Expand Up @@ -434,15 +437,15 @@ public bool TryAddBounty(EntityUid uid, CargoBountyPrototype bounty, StationCarg
}

[PublicAPI]
public bool TryRemoveBounty(EntityUid uid, string dataId, StationCargoBountyDatabaseComponent? component = null)
public bool TryRemoveBounty(EntityUid uid, string dataId, StationCargoBountyDatabaseComponent? component = null, EntityUid? actor = null)
{
if (!TryGetBountyFromId(uid, dataId, out var data, component))
return false;

return TryRemoveBounty(uid, data.Value, component);
return TryRemoveBounty(uid, data.Value, component, actor);
}

public bool TryRemoveBounty(EntityUid uid, CargoBountyData data, StationCargoBountyDatabaseComponent? component = null)
public bool TryRemoveBounty(EntityUid uid, CargoBountyData data, StationCargoBountyDatabaseComponent? component = null, EntityUid? actor = null)
{
if (!Resolve(uid, ref component))
return false;
Expand All @@ -451,6 +454,15 @@ public bool TryRemoveBounty(EntityUid uid, CargoBountyData data, StationCargoBou
{
if (component.Bounties[i].Id == data.Id)
{
string? actorName = default;
if (actor != null)
{
var getIdentityEvent = new TryGetIdentityShortInfoEvent(uid, actor.Value);
RaiseLocalEvent(getIdentityEvent);
actorName = getIdentityEvent.Title;
}

component.History.Add(new CargoBountyHistoryData(data, _gameTiming.CurTime, actorName));
component.Bounties.RemoveAt(i);
return true;
}
Expand Down Expand Up @@ -492,7 +504,7 @@ public void UpdateBountyConsoles()
}

var untilNextSkip = db.NextSkipTime - _timing.CurTime;
_uiSystem.SetUiState((uid, ui), CargoConsoleUiKey.Bounty, new CargoBountyConsoleState(db.Bounties, untilNextSkip));
_uiSystem.SetUiState((uid, ui), CargoConsoleUiKey.Bounty, new CargoBountyConsoleState(db.Bounties, db.History, untilNextSkip));
}
}

Expand Down
Loading
Loading