using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ArceDev.ArmedToTheGills")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("ArceDev.ArmedToTheGills")]
[assembly: AssemblyTitle("ArmedToTheGills")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace BepInEx
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
[Embedded]
internal sealed class BepInAutoPluginAttribute : Attribute
{
public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace BepInEx.Preloader.Core.Patching
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
[Embedded]
internal sealed class PatcherAutoPluginAttribute : Attribute
{
public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace Microsoft.CodeAnalysis
{
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace ArmedToTheGills
{
[BepInPlugin("ArceDev.ArmedToTheGills", "ArmedToTheGills", "0.1.0")]
public class Plugin : BaseUnityPlugin
{
[HarmonyPatch(typeof(Player), "OnStartClient")]
private static class PlayerStartPatch
{
private static void Postfix(Player __instance)
{
WeaponDisplayController.Attach(__instance);
}
}
public const string Id = "ArceDev.ArmedToTheGills";
internal static ManualLogSource Log { get; private set; }
public static string Name => "ArmedToTheGills";
public static string Version => "0.1.0";
private void Awake()
{
Log = ((BaseUnityPlugin)this).Logger;
WeaponDisplayController.ValidatePlacements();
Harmony.CreateAndPatchAll(typeof(Plugin).Assembly, "ArceDev.ArmedToTheGills");
Log.LogInfo((object)("Plugin " + Name + " is loaded."));
}
}
internal sealed class WeaponDisplayController : MonoBehaviour
{
private static readonly Placement[] Placements = new Placement[7]
{
new Placement(WeaponKind.Sniper, BodyAnchor.Torso, new Vector3(0.0854f, 0.7968f, -0.163f), new Vector3(63.7386f, -87.8408f, 2f)),
new Placement(WeaponKind.Shotgun, BodyAnchor.Torso, new Vector3(-0.0771f, 0.9268f, -0.0225f), new Vector3(60.6132f, 85.7557f, -2f)),
new Placement(WeaponKind.AssaultRifle, BodyAnchor.Torso, new Vector3(-0.273f, 0.4143f, -0.0093f), new Vector3(-0.001f, 90f, 0f)),
new Placement(WeaponKind.Smg, BodyAnchor.Pelvis, new Vector3(-0.1851f, 0.4842f, 0.0274f), new Vector3(74.7447f, -11.7091f, -12f)),
new Placement(WeaponKind.Pistol, BodyAnchor.Pelvis, new Vector3(0.0614f, 0.5366f, -0.0272f), new Vector3(75.4994f, -12.3929f, 12.0023f)),
new Placement(WeaponKind.Knife, BodyAnchor.LeftThigh, new Vector3(0.2022f, 0.1581f, -0.2302f), new Vector3(-15.6668f, -32.5703f, -56.472f)),
new Placement(WeaponKind.Knuckles, BodyAnchor.Pelvis, new Vector3(0.0375f, 0.1078f, 0.0502f), new Vector3(-97.8997f, 0f, -174.3403f))
};
private static readonly IReadOnlyDictionary<BodyAnchor, string> AnchorNames = new Dictionary<BodyAnchor, string>
{
[BodyAnchor.Pelvis] = string.Empty,
[BodyAnchor.Torso] = "Body",
[BodyAnchor.LeftThigh] = "LegUpper_L"
};
private Player _player;
private WeaponProxy[] _proxies;
private Item?[] _desired;
internal static void Attach(Player player)
{
WeaponDisplayController weaponDisplayController = ((Component)player).GetComponent<WeaponDisplayController>() ?? ((Component)player).gameObject.AddComponent<WeaponDisplayController>();
weaponDisplayController.Initialize(player);
}
internal static void ValidatePlacements()
{
int length = Enum.GetValues(typeof(WeaponKind)).Length;
if (Placements.Length != length || Placements.Where((Placement placement, int index) => placement.Kind != (WeaponKind)index).Any())
{
throw new InvalidOperationException("Every supported weapon needs exactly one body placement.");
}
}
private void Initialize(Player player)
{
_player = player;
if (_proxies == null)
{
int layer = FindBodyLayer(player);
_proxies = Placements.Select((Placement placement) => new WeaponProxy(ResolveAnchor(player, placement), placement, layer)).ToArray();
_desired = (Item?[])(object)new Item[Placements.Length];
}
}
private void LateUpdate()
{
if (!Object.op_Implicit((Object)(object)_player) || _proxies == null)
{
return;
}
if (_player.Body._isOldModel)
{
HideAllWeapons();
return;
}
CollectDesiredWeapons();
for (int i = 0; i < _proxies.Length; i++)
{
_proxies[i].Show(_desired[i]);
}
}
private void HideAllWeapons()
{
WeaponProxy[] proxies = _proxies;
foreach (WeaponProxy weaponProxy in proxies)
{
weaponProxy.Show(null);
}
}
private void CollectDesiredWeapons()
{
Array.Clear(_desired, 0, _desired.Length);
Item heldItem = _player.Holding.HeldItem;
Item syncedCurItem = _player.Inventory.SyncedCurItem;
foreach (KeyValuePair<byte, Item> item in _player.Inventory._items)
{
Item value = item.Value;
if (Object.op_Implicit((Object)(object)value) && !((Object)(object)value == (Object)(object)heldItem) && !((Object)(object)value == (Object)(object)syncedCurItem))
{
WeaponKind? weaponKind = WeaponClassifier.Classify(value);
if (weaponKind.HasValue && !Object.op_Implicit((Object)(object)_desired[(int)weaponKind.Value]))
{
_desired[(int)weaponKind.Value] = value;
}
}
}
}
private static int FindBodyLayer(Player player)
{
SkinnedMeshRenderer? obj = ((Component)player).GetComponentsInChildren<SkinnedMeshRenderer>(true).FirstOrDefault();
if (obj == null)
{
return ((Component)player).gameObject.layer;
}
return ((Component)obj).gameObject.layer;
}
private static Transform ResolveAnchor(Player player, Placement placement)
{
string anchorName = AnchorNames[placement.Anchor];
if (anchorName.Length == 0)
{
return player.Body.LowerBody;
}
Transform val = ((IEnumerable<Transform>)((Component)player.Body.LowerBody).GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform transform) => ((Object)transform).name == anchorName));
if (Object.op_Implicit((Object)(object)val))
{
return val;
}
Plugin.Log.LogWarning((object)$"Body anchor '{anchorName}' was not found for {placement.Kind}; using LowerBody.");
return player.Body.LowerBody;
}
}
internal sealed class WeaponProxy
{
private readonly GameObject _root;
private readonly Transform _visual;
private readonly int _layer;
private Item? _item;
private byte _skin;
internal WeaponProxy(Transform parent, Placement placement, int layer)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Expected O, but got Unknown
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Expected O, but got Unknown
_layer = layer;
_root = new GameObject(placement.Kind.ToString())
{
layer = layer
};
_root.transform.SetParent(parent, false);
_root.transform.localPosition = placement.Position;
_root.transform.localRotation = Quaternion.Euler(placement.Rotation);
GameObject val = new GameObject("Visual")
{
layer = layer
};
_visual = val.transform;
_visual.SetParent(_root.transform, false);
_root.SetActive(false);
}
internal void Show(Item? item)
{
if (!Object.op_Implicit((Object)(object)item))
{
_root.SetActive(false);
return;
}
if ((Object)(object)item != (Object)(object)_item)
{
RebuildVisuals(item);
}
else if (item.CurSkin != _skin)
{
RefreshMaterials(item);
}
_item = item;
_skin = item.CurSkin;
if (!_root.activeSelf)
{
_root.SetActive(true);
}
}
private void RefreshMaterials(Item item)
{
Renderer[] componentsInChildren = ((Component)item).GetComponentsInChildren<Renderer>(true);
Renderer[] componentsInChildren2 = ((Component)_visual).GetComponentsInChildren<Renderer>(true);
int num = Math.Min(componentsInChildren.Length, componentsInChildren2.Length);
for (int i = 0; i < num; i++)
{
componentsInChildren2[i].sharedMaterials = componentsInChildren[i].sharedMaterials;
}
}
private void RebuildVisuals(Item item)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
ClearVisuals();
_visual.localRotation = Quaternion.identity;
_visual.localScale = Vector3.one;
_visual.localPosition = Vector3.zero;
((Component)_visual).gameObject.SetActive(false);
GameObject val = Object.Instantiate<GameObject>(((Component)item).gameObject, _visual, false);
((Object)val).name = ((Object)((Component)item).gameObject).name + " Body Display";
val.transform.localPosition = Vector3.zero;
val.transform.localRotation = Quaternion.identity;
Sanitize(val);
val.SetActive(true);
((Component)_visual).gameObject.SetActive(true);
if (!val.GetComponentsInChildren<Renderer>(true).Any(IsMeshRenderer))
{
Plugin.Log.LogWarning((object)("No visible mesh renderers were copied for '" + ((Object)((Component)item).gameObject).name + "'."));
}
}
private void ClearVisuals()
{
for (int num = _visual.childCount - 1; num >= 0; num--)
{
Object.Destroy((Object)(object)((Component)_visual.GetChild(num)).gameObject);
}
}
private void Sanitize(GameObject clone)
{
for (int i = 0; i < 3; i++)
{
if (!RemoveNonVisualComponents(clone))
{
break;
}
}
Transform[] componentsInChildren = clone.GetComponentsInChildren<Transform>(true);
foreach (Transform val in componentsInChildren)
{
((Component)val).gameObject.layer = _layer;
}
Component[] array = (from component in clone.GetComponentsInChildren<Component>(true)
where !IsVisualComponent(component)
select component).ToArray();
if (array.Length != 0)
{
Plugin.Log.LogWarning((object)("Visual clone '" + ((Object)clone).name + "' retained components: " + string.Join(", ", array.Select((Component component) => ((object)component).GetType().Name).Distinct())));
}
}
private static bool RemoveNonVisualComponents(GameObject clone)
{
Component[] array = (from component in clone.GetComponentsInChildren<Component>(true)
where !IsVisualComponent(component)
select component).ToArray();
for (int num = array.Length - 1; num >= 0; num--)
{
Object.DestroyImmediate((Object)(object)array[num]);
}
return array.Length != 0;
}
private static bool IsVisualComponent(Component component)
{
if (component is Transform || component is Renderer || component is MeshFilter || component is Animator || component is LODGroup)
{
return true;
}
return false;
}
private static bool IsMeshRenderer(Renderer renderer)
{
if (renderer is MeshRenderer || renderer is SkinnedMeshRenderer)
{
return true;
}
return false;
}
}
internal static class WeaponClassifier
{
private static readonly (string Token, WeaponKind Kind)[] RangedNames = new(string, WeaponKind)[6]
{
("assaultrifle", WeaponKind.AssaultRifle),
("sniper", WeaponKind.Sniper),
("shotgun", WeaponKind.Shotgun),
("submachinegun", WeaponKind.Smg),
("smg", WeaponKind.Smg),
("pistol", WeaponKind.Pistol)
};
private static readonly HashSet<byte> ReportedUnknownIds = new HashSet<byte>();
internal static WeaponKind? Classify(Item item)
{
Melee val = (Melee)(object)((item is Melee) ? item : null);
if (val != null)
{
return val.UsePunchSoundOnHit ? WeaponKind.Knuckles : WeaponKind.Knife;
}
if (!(item is Weapon))
{
return null;
}
string text = Normalize(((Object)((Component)item).gameObject).name);
(string, WeaponKind)[] rangedNames = RangedNames;
for (int i = 0; i < rangedNames.Length; i++)
{
var (value, value2) = rangedNames[i];
if (text.Contains(value))
{
return value2;
}
}
if (ReportedUnknownIds.Add(item.ID))
{
Plugin.Log.LogWarning((object)$"No body placement is defined for ranged weapon '{((Object)((Component)item).gameObject).name}' (ID {item.ID}).");
}
return null;
}
private static string Normalize(string value)
{
return value.Replace("(Clone)", string.Empty).Replace(" ", string.Empty).Replace("_", string.Empty)
.Replace("-", string.Empty)
.ToLowerInvariant();
}
}
internal readonly record struct Placement(WeaponKind Kind, BodyAnchor Anchor, Vector3 Position, Vector3 Rotation);
internal enum BodyAnchor
{
Pelvis,
Torso,
LeftThigh
}
internal enum WeaponKind
{
Sniper,
Shotgun,
AssaultRifle,
Smg,
Pistol,
Knife,
Knuckles
}
}
namespace System.Diagnostics.CodeAnalysis
{
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class ConstantExpectedAttribute : Attribute
{
public object? Min { get; set; }
public object? Max { get; set; }
}
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class ExperimentalAttribute : Attribute
{
public string DiagnosticId { get; }
public string? UrlFormat { get; set; }
public ExperimentalAttribute(string diagnosticId)
{
DiagnosticId = diagnosticId;
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
[ExcludeFromCodeCoverage]
internal sealed class MemberNotNullAttribute : Attribute
{
public string[] Members { get; }
public MemberNotNullAttribute(string member)
{
Members = new string[1] { member };
}
public MemberNotNullAttribute(params string[] members)
{
Members = members;
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
[ExcludeFromCodeCoverage]
internal sealed class MemberNotNullWhenAttribute : Attribute
{
public bool ReturnValue { get; }
public string[] Members { get; }
public MemberNotNullWhenAttribute(bool returnValue, string member)
{
ReturnValue = returnValue;
Members = new string[1] { member };
}
public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
{
ReturnValue = returnValue;
Members = members;
}
}
[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class SetsRequiredMembersAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class StringSyntaxAttribute : Attribute
{
public const string CompositeFormat = "CompositeFormat";
public const string DateOnlyFormat = "DateOnlyFormat";
public const string DateTimeFormat = "DateTimeFormat";
public const string EnumFormat = "EnumFormat";
public const string GuidFormat = "GuidFormat";
public const string Json = "Json";
public const string NumericFormat = "NumericFormat";
public const string Regex = "Regex";
public const string TimeOnlyFormat = "TimeOnlyFormat";
public const string TimeSpanFormat = "TimeSpanFormat";
public const string Uri = "Uri";
public const string Xml = "Xml";
public string Syntax { get; }
public object?[] Arguments { get; }
public StringSyntaxAttribute(string syntax)
{
Syntax = syntax;
Arguments = new object[0];
}
public StringSyntaxAttribute(string syntax, params object?[] arguments)
{
Syntax = syntax;
Arguments = arguments;
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class UnscopedRefAttribute : Attribute
{
}
}
namespace System.Runtime.Versioning
{
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class RequiresPreviewFeaturesAttribute : Attribute
{
public string? Message { get; }
public string? Url { get; set; }
public RequiresPreviewFeaturesAttribute()
{
}
public RequiresPreviewFeaturesAttribute(string? message)
{
Message = message;
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class CallerArgumentExpressionAttribute : Attribute
{
public string ParameterName { get; }
public CallerArgumentExpressionAttribute(string parameterName)
{
ParameterName = parameterName;
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class CollectionBuilderAttribute : Attribute
{
public Type BuilderType { get; }
public string MethodName { get; }
public CollectionBuilderAttribute(Type builderType, string methodName)
{
BuilderType = builderType;
MethodName = methodName;
}
}
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class CompilerFeatureRequiredAttribute : Attribute
{
public const string RefStructs = "RefStructs";
public const string RequiredMembers = "RequiredMembers";
public string FeatureName { get; }
public bool IsOptional { get; set; }
public CompilerFeatureRequiredAttribute(string featureName)
{
FeatureName = featureName;
}
}
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute
{
public string[] Arguments { get; }
public InterpolatedStringHandlerArgumentAttribute(string argument)
{
Arguments = new string[1] { argument };
}
public InterpolatedStringHandlerArgumentAttribute(params string[] arguments)
{
Arguments = arguments;
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class InterpolatedStringHandlerAttribute : Attribute
{
}
[EditorBrowsable(EditorBrowsableState.Never)]
[ExcludeFromCodeCoverage]
internal static class IsExternalInit
{
}
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class ModuleInitializerAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class OverloadResolutionPriorityAttribute : Attribute
{
public int Priority { get; }
public OverloadResolutionPriorityAttribute(int priority)
{
Priority = priority;
}
}
[AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)]
[ExcludeFromCodeCoverage]
internal sealed class ParamCollectionAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class RequiredMemberAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[ExcludeFromCodeCoverage]
internal sealed class RequiresLocationAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class SkipLocalsInitAttribute : Attribute
{
}
}