Decompiled source of ProfitPercent v1.1.0

ProfitPercent.dll

Decompiled 6 months ago
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ProfitPercent")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ProfitPercent")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("1aa9f185-5e80-46e0-935b-a30791a11860")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ProfitPercent;

[BepInPlugin("pr0skynesis.profitpercent", "Profit Percent", "1.1.0")]
public class ProfitPercentMain : BaseUnityPlugin
{
	public const string pluginGuid = "pr0skynesis.profitpercent";

	public const string pluginName = "Profit Percent";

	public const string pluginVersion = "1.1.0";

	public static ConfigEntry<bool> coloredTextConfig;

	public static ConfigEntry<int> greenThresholdConfig;

	public static ConfigEntry<int> blueThresholdConfig;

	public static ConfigEntry<bool> showBestDealsConfig;

	public void Awake()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Expected O, but got Unknown
		Harmony val = new Harmony("pr0skynesis.profitpercent");
		MethodInfo methodInfo = AccessTools.Method(typeof(EconomyUI), "ShowGoodPage", (Type[])null, (Type[])null);
		MethodInfo methodInfo2 = AccessTools.Method(typeof(ProfitPercentPatches), "ShowGoodPage_Patch", (Type[])null, (Type[])null);
		coloredTextConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("A) Colored text", "coloredText", true, "Enables the coloring of the profit in red (loss), green (profit), yellow (neither) and blue (high profit)");
		greenThresholdConfig = ((BaseUnityPlugin)this).Config.Bind<int>("A) Colored text", "greenThreshold", 0, "Sets the value above which the profit % will be colored in green. E.g.: set to 30 to have the text be displayed as green only above 30% profit.");
		blueThresholdConfig = ((BaseUnityPlugin)this).Config.Bind<int>("A) Colored text", "blueThreshold", 100, "Sets the value above which the profit % will be colored in blue, used to identify high profit margins.");
		showBestDealsConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("B) Best Deals", "showBestDeals", true, "Display the best deals from the current port to the destinations in the currently selected bookmark. Set to false to disable.");
		val.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
	}
}
public class ProfitPercentPatches
{
	private static bool instantiated;

	[HarmonyPostfix]
	public static void ShowGoodPage_Patch(int goodIndex, IslandMarket ___currentIsland, int[][] ___bookmarkIslands, int ___currentBookmark)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Expected O, but got Unknown
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Expected O, but got Unknown
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Expected O, but got Unknown
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Expected O, but got Unknown
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Expected O, but got Unknown
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Expected O, but got Unknown
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Expected O, but got Unknown
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Expected O, but got Unknown
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Expected O, but got Unknown
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Expected O, but got Unknown
		//IL_0c11: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c99: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ca0: Expected O, but got Unknown
		TextMesh val = new TextMesh();
		TextMesh val2 = new TextMesh();
		TextMesh val3 = new TextMesh();
		TextMesh val4 = new TextMesh();
		TextMesh val5 = new TextMesh();
		TextMesh val6 = new TextMesh();
		TextMesh val7 = new TextMesh();
		TextMesh val8 = new TextMesh();
		TextMesh val9 = new TextMesh();
		TextMesh val10 = new TextMesh();
		TextMesh val11 = new TextMesh();
		MethodInfo methodInfo = AccessTools.Method(typeof(EconomyUI), "GetBuyPrice", (Type[])null, (Type[])null);
		MethodInfo methodInfo2 = AccessTools.Method(typeof(EconomyUI), "GetSellPrice", (Type[])null, (Type[])null);
		ShipItem good = PrefabsDirectory.instance.GetGood(goodIndex);
		Good component = ((Component)good).GetComponent<Good>();
		EconomyUI instance = EconomyUI.instance;
		TextMesh[] componentsInChildren = ((Component)instance).GetComponentsInChildren<TextMesh>();
		TextMesh val12 = componentsInChildren[2];
		TextMesh val13 = componentsInChildren[3];
		TextMesh val14 = componentsInChildren[6];
		TextMesh val15 = componentsInChildren[7];
		TextMesh val16 = componentsInChildren[8];
		TextMesh val17 = componentsInChildren[9];
		TextMesh val18 = componentsInChildren[11];
		TextMesh val19 = componentsInChildren[13];
		TextMesh val20 = componentsInChildren[14];
		TextMesh val21 = componentsInChildren[16];
		if (!instantiated)
		{
			val = Object.Instantiate<TextMesh>(val12, ((Component)val12).transform.parent);
			((Object)val).name = "modIslandNames";
			val2 = Object.Instantiate<TextMesh>(val17, ((Component)val17).transform.parent);
			((Object)val2).name = "modProfitColumn";
			val3 = Object.Instantiate<TextMesh>(val14, ((Component)val14).transform.parent);
			((Object)val3).name = "modGoodName";
			val4 = Object.Instantiate<TextMesh>(val13, ((Component)val13).transform.parent);
			((Object)val4).name = "productionText";
			val5 = Object.Instantiate<TextMesh>(val13, ((Component)val13).transform.parent);
			((Object)val5).name = "percentText";
			val6 = Object.Instantiate<TextMesh>(val13, ((Component)val13).transform.parent);
			((Object)val6).name = "perPoundText";
			val8 = Object.Instantiate<TextMesh>(val13, ((Component)val13).transform.parent);
			((Object)val8).name = "bdBestDeals";
			((Component)val8).transform.Rotate(0f, 0f, 15f);
			val8.anchor = (TextAnchor)3;
			val9 = Object.Instantiate<TextMesh>(val13, ((Component)val13).transform.parent);
			((Object)val9).name = "bdPercent";
			val9.anchor = (TextAnchor)3;
			val10 = Object.Instantiate<TextMesh>(val13, ((Component)val13).transform.parent);
			((Object)val10).name = "bdPerPound";
			val10.anchor = (TextAnchor)3;
			val11 = Object.Instantiate<TextMesh>(val13, ((Component)val13).transform.parent);
			((Object)val11).name = "bdAbsolute";
			val11.anchor = (TextAnchor)3;
			val7 = Object.Instantiate<TextMesh>(val13, ((Component)val13).transform.parent);
			((Object)val7).name = "highlightBar";
			val7.anchor = (TextAnchor)3;
			instantiated = true;
		}
		else
		{
			val = componentsInChildren[18];
			val2 = componentsInChildren[19];
			val3 = componentsInChildren[20];
			val4 = componentsInChildren[21];
			val5 = componentsInChildren[22];
			val6 = componentsInChildren[23];
			val8 = componentsInChildren[24];
			val9 = componentsInChildren[25];
			val10 = componentsInChildren[26];
			val11 = componentsInChildren[27];
			val7 = componentsInChildren[28];
		}
		if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val4 == (Object)null || (Object)(object)val5 == (Object)null || (Object)(object)val6 == (Object)null || (Object)(object)val8 == (Object)null || (Object)(object)val9 == (Object)null || (Object)(object)val10 == (Object)null || (Object)(object)val11 == (Object)null)
		{
			Debug.LogError((object)"ProfitPercent: Some of the new TextMeshes are null!");
			return;
		}
		val.text = "";
		val2.text = "";
		val3.text = char.ToUpper(good.name[0]) + good.name.Substring(1);
		val4.text = "";
		val5.text = "";
		val6.text = "";
		val8.text = "<color=#4D0000>★ Best Deals! ★</color>";
		val9.text = BestDeals(instance, ___currentIsland, ___bookmarkIslands, ___currentBookmark, 0);
		val10.text = BestDeals(instance, ___currentIsland, ___bookmarkIslands, ___currentBookmark, 1);
		val11.text = BestDeals(instance, ___currentIsland, ___bookmarkIslands, ___currentBookmark, 2);
		val7.text = "┌───────────────────────────────────┐\n└───────────────────────────────────┘";
		for (int i = 0; i < ___bookmarkIslands[___currentBookmark].Length; i++)
		{
			int num = ___bookmarkIslands[___currentBookmark][i];
			object[] parameters = new object[2]
			{
				___currentIsland.GetPortIndex(),
				goodIndex
			};
			object[] parameters2 = new object[2] { num, goodIndex };
			FieldInfo fieldInfo = AccessTools.Field(typeof(Port), "producedGoodPrefabs");
			GameObject[] source = (GameObject[])fieldInfo.GetValue(Port.ports[num]);
			int[] source2 = source.Select((GameObject go) => go.GetComponent<SaveablePrefab>().prefabIndex).ToArray();
			int value = PrefabsDirectory.GoodToItemIndex(goodIndex);
			if (source2.Contains(value))
			{
				TextMesh obj = val4;
				obj.text += "✓\n";
			}
			else
			{
				TextMesh obj2 = val4;
				obj2.text += "- \n";
			}
			int num2 = (int)methodInfo.Invoke(instance, parameters);
			int num3 = (int)methodInfo2.Invoke(instance, parameters2);
			float num4 = Mathf.Round((float)(num3 - num2) / (float)num2 * 100f);
			float cargoWeight = component.GetCargoWeight();
			float num5 = (float)Math.Round((float)(num3 - num2) / cargoWeight, 2);
			if (ProfitPercentMain.coloredTextConfig.Value)
			{
				int value2 = ProfitPercentMain.blueThresholdConfig.Value;
				int value3 = ProfitPercentMain.greenThresholdConfig.Value;
				if (ProfitPercentMain.blueThresholdConfig.Value < ProfitPercentMain.greenThresholdConfig.Value)
				{
					value2 = ProfitPercentMain.greenThresholdConfig.Value;
					value3 = ProfitPercentMain.blueThresholdConfig.Value;
				}
				if (float.IsInfinity(num4))
				{
					TextMesh obj3 = val2;
					obj3.text += "<color=#CC7F00>- </color>\n";
					TextMesh obj4 = val5;
					obj4.text += "<color=#CC7F00>- </color>\n";
					TextMesh obj5 = val6;
					obj5.text += "<color=#CC7F00>- </color>\n";
				}
				else if (num4 > (float)value2)
				{
					TextMesh obj6 = val2;
					obj6.text += $"<color=#051139>{num3 - num2}</color>\n";
					TextMesh obj7 = val5;
					obj7.text += $"<color=#051139>{num4}<size=40%>%</size></color>\n";
					TextMesh obj8 = val6;
					obj8.text += $"<color=#051139>{num5}</color>\n";
				}
				else if (num4 > (float)value3)
				{
					TextMesh obj9 = val2;
					obj9.text += $"<color=#003300>{num3 - num2}</color>\n";
					TextMesh obj10 = val5;
					obj10.text += $"<color=#003300>{num4}<size=40%>%</size></color>\n";
					TextMesh obj11 = val6;
					obj11.text += $"<color=#003300>{num5}</color>\n";
				}
				else if (num4 < 0f)
				{
					TextMesh obj12 = val2;
					obj12.text += $"<color=#4D0000>{num3 - num2}</color>\n";
					TextMesh obj13 = val5;
					obj13.text += $"<color=#4D0000>{num4}<size=40%>%</size></color>\n";
					TextMesh obj14 = val6;
					obj14.text += $"<color=#4D0000>{num5}</color>\n";
				}
				else
				{
					TextMesh obj15 = val2;
					obj15.text += $"<color=#CC7F00>{num3 - num2}</color>\n";
					TextMesh obj16 = val5;
					obj16.text += $"<color=#CC7F00>{num4}<size=40%>%</size></color>\n";
					TextMesh obj17 = val6;
					obj17.text += $"<color=#CC7F00>{num5}</color>\n";
				}
				if (num == ___currentIsland.GetPortIndex())
				{
					TextMesh obj18 = val;
					obj18.text = obj18.text + "<color=#4D0000>• " + Port.ports[num].GetPortName() + "</color>\n";
				}
				else
				{
					TextMesh obj19 = val;
					obj19.text = obj19.text + Port.ports[num].GetPortName() + "\n";
				}
			}
			else
			{
				if (num == ___currentIsland.GetPortIndex())
				{
					TextMesh obj20 = val;
					obj20.text = obj20.text + "• " + Port.ports[num].GetPortName() + "\n";
				}
				else
				{
					TextMesh obj21 = val;
					obj21.text = obj21.text + Port.ports[num].GetPortName() + "\n";
				}
				TextMesh obj22 = val2;
				obj22.text += $"{num3 - num2}\n";
				TextMesh obj23 = val5;
				obj23.text += $"{num4}<size=40%>%</size>\n";
				TextMesh obj24 = val6;
				obj24.text += $"{num5}\n";
			}
		}
		val16.characterSize = 0.85f;
		val16.text = "days ago  P.    buy     sell     profit      %    p. pound";
		val19.text = "        |   |       |       |        |       |";
		float characterSize = (val6.characterSize = (val5.characterSize = (val17.characterSize = (val15.characterSize = (val13.characterSize = (val4.characterSize = (val18.characterSize = (val12.characterSize = (val2.characterSize = (val.characterSize = 0.8f))))))))));
		val21.characterSize = characterSize;
		MoveX(((Component)val).transform, 0.23f);
		MoveX(((Component)val2).transform, -0.45f);
		MoveX(((Component)val14).transform, 100f);
		MoveX(((Component)val12).transform, 100f);
		MoveX(((Component)val18).transform, 0.133f);
		MoveX(((Component)val4).transform, 0.05f);
		MoveX(((Component)val13).transform, -0.11f);
		MoveX(((Component)val15).transform, -0.27f);
		MoveX(((Component)val17).transform, 100f);
		MoveX(((Component)val5).transform, -0.61f);
		MoveX(((Component)val6).transform, -0.78f);
		MoveX(((Component)val20).transform, -0.94f);
		MoveXY(((Component)val21).transform, 0.64f, -0.8f);
		val8.characterSize = 1.1f;
		val9.characterSize = 0.7f;
		val10.characterSize = 0.7f;
		val11.characterSize = 0.7f;
		MoveXY(((Component)val8).transform, 0.74f, -0.15f);
		MoveXY(((Component)val9).transform, 0.64f, -0.2f);
		MoveXY(((Component)val10).transform, 0.64f, -0.25f);
		MoveXY(((Component)val11).transform, 0.64f, -0.3f);
		if (!ProfitPercentMain.showBestDealsConfig.Value)
		{
			MoveX(((Component)val8).transform, 100f);
			MoveX(((Component)val9).transform, 100f);
			MoveX(((Component)val10).transform, 100f);
			MoveX(((Component)val11).transform, 100f);
		}
		val7.lineSpacing = 0.9f;
		val7.color = new Color(0.25f, 0f, 0f);
		float[] array = new float[7] { 0.622f, 0.549f, 0.476f, 0.401f, 0.328f, 0.255f, 0.182f };
		MoveXY(((Component)val7).transform, 0.64f, array[GetUIPortIndex(___currentIsland.GetPortIndex())]);
		if (BookmarkCheck(___currentIsland.GetPortIndex()) != ___currentBookmark)
		{
			MoveX(((Component)val7).transform, 100f);
		}
		FieldInfo fieldInfo2 = AccessTools.Field(typeof(EconomyUI), "islandHighlightBar");
		Transform val22 = (Transform)fieldInfo2.GetValue(instance);
		MoveX(((Component)val22).transform, 100f);
	}

	private static void MoveX(Transform transform, float x)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		Vector3 localPosition = transform.localPosition;
		localPosition.x = x;
		transform.localPosition = localPosition;
	}

	private static void MoveXY(Transform transform, float x, float y)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		Vector3 localPosition = transform.localPosition;
		localPosition.x = x;
		localPosition.y = y;
		transform.localPosition = localPosition;
	}

	private static string BestDeals(EconomyUI eco, IslandMarket currentIsland, int[][] bookmarkIslands, int currentBookmark, int selector)
	{
		if (!ProfitPercentMain.showBestDealsConfig.Value)
		{
			return "";
		}
		MethodInfo methodInfo = AccessTools.Method(typeof(EconomyUI), "GetBuyPrice", (Type[])null, (Type[])null);
		MethodInfo methodInfo2 = AccessTools.Method(typeof(EconomyUI), "GetSellPrice", (Type[])null, (Type[])null);
		GameObject[] directory = PrefabsDirectory.instance.directory;
		TransactionCategory[] array = new TransactionCategory[4];
		RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
		TransactionCategory[] validCategories = (TransactionCategory[])(object)array;
		ShipItem[] array2 = (from go in directory
			where (Object)(object)go != (Object)null
			select go.GetComponent<ShipItem>() into shipItem
			where (Object)(object)shipItem != (Object)null && validCategories.Contains(shipItem.category)
			select shipItem).ToArray();
		int[] array3 = new int[array2.Length];
		int[] array4 = new int[array2.Length];
		int index = 0;
		int index2 = 0;
		int index3 = 0;
		int num = 0;
		int num2 = 0;
		int num3 = 0;
		float num4 = -1000f;
		float num5 = -1000f;
		int num6 = -1000;
		for (int i = 0; i < array3.Length; i++)
		{
			int num7 = i + 1;
			if (i >= 44)
			{
				num7++;
			}
			object[] parameters = new object[2]
			{
				currentIsland.GetPortIndex(),
				num7
			};
			array3[i] = (int)methodInfo.Invoke(eco, parameters);
			for (int j = 0; j < bookmarkIslands[currentBookmark].Length; j++)
			{
				int num8 = bookmarkIslands[currentBookmark][j];
				for (int k = 0; k < array4.Length; k++)
				{
					int num9 = k + 1;
					if (k >= 44)
					{
						num9++;
					}
					float cargoWeight = ((Component)array2[k]).GetComponent<Good>().GetCargoWeight();
					object[] parameters2 = new object[2] { num8, num9 };
					int num10 = (int)methodInfo2.Invoke(eco, parameters2);
					float num11;
					float num12;
					if (array3[k] == 0)
					{
						num11 = -10000f;
						num12 = -10000f;
						array4[k] = -10000;
					}
					else
					{
						num11 = Mathf.Round((float)(num10 - array3[k]) / (float)array3[k] * 100f);
						num12 = (float)Math.Round((float)(num10 - array3[k]) / cargoWeight, 2);
						array4[k] = num10 - array3[k];
					}
					if (num11 > num4)
					{
						num = k;
						num4 = num11;
						index = j;
					}
					if (num12 > num5)
					{
						num2 = k;
						num5 = num12;
						index2 = j;
					}
					if (array4[k] > num6)
					{
						num3 = k;
						num6 = array4[k];
						index3 = j;
					}
				}
			}
		}
		switch (selector)
		{
		case 0:
		{
			string name3 = array2[num].name;
			string portName3 = Port.ports[FixPortIndex(index, currentBookmark)].GetPortName();
			string text3 = $"{num4}%";
			name3 = char.ToUpper(name3[0]) + name3.Substring(1);
			return "• " + name3 + " to " + portName3 + " will return a profit of " + text3 + "!";
		}
		case 1:
		{
			string name2 = array2[num2].name;
			string portName2 = Port.ports[FixPortIndex(index2, currentBookmark)].GetPortName();
			string text2 = $"{num5} per pound";
			name2 = char.ToUpper(name2[0]) + name2.Substring(1);
			return "• " + name2 + " to " + portName2 + " will return a profit of " + text2 + "!";
		}
		case 2:
		{
			string name = array2[num3].name;
			string portName = Port.ports[FixPortIndex(index3, currentBookmark)].GetPortName();
			string text = $"{num6} per unit";
			name = char.ToUpper(name[0]) + name.Substring(1);
			return "• " + name + " to " + portName + " will return a profit of " + text + "!";
		}
		default:
			return "Something is wrong in this place...";
		}
	}

	private static int FixPortIndex(int index, int currentBookmark)
	{
		switch (currentBookmark)
		{
		case 0:
		{
			int[] array4 = new int[7] { 0, 1, 2, 3, 4, 5, 6 };
			return array4[index];
		}
		case 1:
		{
			int[] array3 = new int[6] { 9, 10, 11, 12, 13, 14 };
			return array3[index];
		}
		case 2:
		{
			int[] array2 = new int[6] { 15, 16, 17, 18, 19, 20 };
			return array2[index];
		}
		default:
		{
			int[] array = new int[4] { 22, 23, 24, 25 };
			return array[index];
		}
		}
	}

	private static int GetUIPortIndex(int portIndex)
	{
		if (portIndex <= 6)
		{
			return portIndex;
		}
		if (portIndex >= 9 && portIndex <= 14)
		{
			return portIndex - 9;
		}
		if (portIndex >= 15 && portIndex <= 20)
		{
			return portIndex - 15;
		}
		if (portIndex >= 22 && portIndex <= 25)
		{
			return portIndex - 22;
		}
		if (portIndex == 21)
		{
			return 0;
		}
		return 0;
	}

	private static int BookmarkCheck(int portIndex)
	{
		int[] source = new int[7] { 0, 1, 2, 3, 4, 5, 6 };
		int[] source2 = new int[6] { 9, 10, 11, 12, 13, 14 };
		int[] source3 = new int[6] { 15, 16, 17, 18, 19, 20 };
		int[] source4 = new int[4] { 22, 23, 24, 25 };
		if (source.Contains(portIndex))
		{
			return 0;
		}
		if (source2.Contains(portIndex))
		{
			return 1;
		}
		if (source3.Contains(portIndex))
		{
			return 2;
		}
		if (source4.Contains(portIndex))
		{
			return 3;
		}
		return 0;
	}
}