Decompiled source of Shop Items Spawn in Level v1.7.20

REPO_Shop_Items_in_Level.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
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.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("REPO_Shop_Items_in_Level")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.7.20.0")]
[assembly: AssemblyInformationalVersion("1.7.20+2f095d29308799a97341ec4944d0353f59d39f44")]
[assembly: AssemblyProduct("Shop Items spawn in Level")]
[assembly: AssemblyTitle("REPO_Shop_Items_in_Level")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.7.20.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 REPO_Shop_Items_in_Level
{
	public class UsedVolumeTracker : MonoBehaviour
	{
	}
	public class SpawnedItemTracker : MonoBehaviour
	{
	}
	[BepInPlugin("REPO_Shop_Items_in_Level", "Shop Items spawn in Level", "1.7.20")]
	[BepInProcess("REPO.exe")]
	public class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(EnemyParent), "Despawn")]
		private class DespawnPatch
		{
			private static int GetEnemySpawnValuableCurrent(EnemyParent enemyParent)
			{
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Expected O, but got Unknown
				//IL_007d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0083: Expected O, but got Unknown
				Enemy val = (Enemy)(AccessTools.Field(typeof(EnemyParent), "Enemy")?.GetValue(enemyParent));
				if ((Object)(object)val == (Object)null)
				{
					Logger.LogWarning((object)("Failed to access Enemy from EnemyParent " + ((Object)enemyParent).name + "."));
					return 0;
				}
				EnemyHealth val2 = (EnemyHealth)(AccessTools.Field(typeof(Enemy), "Health")?.GetValue(val));
				if ((Object)(object)val2 == (Object)null)
				{
					Logger.LogWarning((object)("Failed to access Health from Enemy " + ((Object)enemyParent).name + "."));
					return 0;
				}
				FieldInfo fieldInfo = AccessTools.Field(typeof(EnemyHealth), "spawnValuableCurrent");
				if (fieldInfo == null)
				{
					Logger.LogWarning((object)("Field spawnValuableCurrent not found in EnemyHealth for enemy " + ((Object)enemyParent).name + "."));
					return 0;
				}
				return (int)fieldInfo.GetValue(val2);
			}

			private static void Prefix(EnemyParent __instance, out int __state)
			{
				__state = GetEnemySpawnValuableCurrent(__instance);
			}

			private static void Postfix(EnemyParent __instance, int __state)
			{
				//IL_00da: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e1: Expected O, but got Unknown
				//IL_0105: Unknown result type (might be due to invalid IL or missing references)
				//IL_0119: Unknown result type (might be due to invalid IL or missing references)
				//IL_011e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0123: Unknown result type (might be due to invalid IL or missing references)
				//IL_0125: Unknown result type (might be due to invalid IL or missing references)
				//IL_012a: Unknown result type (might be due to invalid IL or missing references)
				//IL_012d: Unknown result type (might be due to invalid IL or missing references)
				//IL_012f: Unknown result type (might be due to invalid IL or missing references)
				if (!SemiFunc.IsMasterClientOrSingleplayer() || !SpawnHealthPacksFromEnemies.Value || GetEnemySpawnValuableCurrent(__instance) <= __state)
				{
					return;
				}
				Logger.LogInfo((object)("Enemy " + ((Object)__instance).name + " spawned a valuable!"));
				Item item;
				if (Random.Range(0f, 100f) >= HealthPackDropChance.Value)
				{
					Logger.LogInfo((object)$"Health pack spawn roll failed (chance: {HealthPackDropChance.Value}%)");
				}
				else if (GetRandomItemOfType((itemType)8, out item))
				{
					Enemy val = (Enemy)(AccessTools.Field(typeof(EnemyParent), "Enemy")?.GetValue(__instance));
					Transform val2 = val.CustomValuableSpawnTransform;
					if (!Object.op_Implicit((Object)(object)val2))
					{
						val2 = val.CenterTransform;
					}
					Vector3 position = val2.position + new Vector3(0f, 1f, 0f);
					Quaternion identity = Quaternion.identity;
					SpawnItem(item, position, identity);
				}
			}
		}

		internal static ManualLogSource Logger;

		internal static ConfigEntry<bool> SpawnUpgradeItems;

		internal static ConfigEntry<bool> MapHideUpgradeItems;

		internal static ConfigEntry<float> UpgradeItemSpawnChance;

		internal static ConfigEntry<bool> UseShopPriceForUpgradeItems;

		internal static ConfigEntry<bool> SpawnDroneItems;

		internal static ConfigEntry<bool> MapHideDroneItems;

		internal static ConfigEntry<float> DroneItemSpawnChance;

		internal static ConfigEntry<bool> UseShopPriceForDroneItems;

		internal static ConfigEntry<bool> SpawnHealthPacksFromEnemies;

		internal static ConfigEntry<float> HealthPackDropChance;

		internal static List<ConfigEntry<bool>> DisallowedItems;

		private Harmony harmony;

		public static Plugin Instance { get; private set; }

		private void Awake()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Expected O, but got Unknown
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Expected O, but got Unknown
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Expected O, but got Unknown
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Expected O, but got Unknown
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Expected O, but got Unknown
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Expected O, but got Unknown
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Expected O, but got Unknown
			Instance = this;
			Logger = ((BaseUnityPlugin)this).Logger;
			Logger.LogInfo((object)"Plugin REPO_Shop_Items_in_Level is loaded!");
			harmony = new Harmony("REPO_Shop_Items_in_Level");
			harmony.PatchAll(typeof(Plugin));
			harmony.PatchAll(typeof(DespawnPatch));
			Logger.LogInfo((object)"Harmony patches applied!");
			SpawnUpgradeItems = ((BaseUnityPlugin)this).Config.Bind<bool>("UpgradeItems", "SpawnUpgradeItems", true, new ConfigDescription("Whether upgrade items can spawn in levels", (AcceptableValueBase)null, Array.Empty<object>()));
			MapHideUpgradeItems = ((BaseUnityPlugin)this).Config.Bind<bool>("UpgradeItems", "MapHideShopUpgradeItems", true, new ConfigDescription("(Client) Whether upgrade items are hidden on the map", (AcceptableValueBase)null, Array.Empty<object>()));
			UpgradeItemSpawnChance = ((BaseUnityPlugin)this).Config.Bind<float>("UpgradeItems", "UpgradeItemSpawnChance", 2.5f, new ConfigDescription("% chance for an upgrade item to spawn", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
			UseShopPriceForUpgradeItems = ((BaseUnityPlugin)this).Config.Bind<bool>("UpgradeItems", "UseShopPriceForItemSelection", true, new ConfigDescription("If ON: Cheaper upgrade items appear more often. If OFF: All upgrade items have equal chance.", (AcceptableValueBase)null, Array.Empty<object>()));
			SpawnDroneItems = ((BaseUnityPlugin)this).Config.Bind<bool>("DroneItems", "SpawnDroneItems", true, new ConfigDescription("Whether drone items can spawn in levels", (AcceptableValueBase)null, Array.Empty<object>()));
			MapHideDroneItems = ((BaseUnityPlugin)this).Config.Bind<bool>("DroneItems", "MapHideDroneItems", true, new ConfigDescription("(Client) Whether drone items are hidden on the map", (AcceptableValueBase)null, Array.Empty<object>()));
			DroneItemSpawnChance = ((BaseUnityPlugin)this).Config.Bind<float>("DroneItems", "DroneItemsSpawnChance", 0.95f, new ConfigDescription("% chance for a drone item to spawn", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
			UseShopPriceForDroneItems = ((BaseUnityPlugin)this).Config.Bind<bool>("DroneItems", "UseShopPriceForItemSelection", true, new ConfigDescription("If ON: Cheaper drone items appear more often. If OFF: All drone items have equal chance.", (AcceptableValueBase)null, Array.Empty<object>()));
			SpawnHealthPacksFromEnemies = ((BaseUnityPlugin)this).Config.Bind<bool>("HealthPacks", "SpawnHealthPacksFromEnemies", true, new ConfigDescription("Whether health packs can spawn when enemies die", (AcceptableValueBase)null, Array.Empty<object>()));
			HealthPackDropChance = ((BaseUnityPlugin)this).Config.Bind<float>("HealthPacks", "HealthPackDropChance", 100f, new ConfigDescription("% chance for a health pack to spawn when an enemy dies", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
		}

		[HarmonyPatch(typeof(MainMenuOpen), "Awake")]
		[HarmonyPostfix]
		public static void MainMenuOpen_Awake_Postfix(StatsManager __instance)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Invalid comparison between Unknown and I4
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			if (DisallowedItems != null)
			{
				return;
			}
			Logger.LogInfo((object)"Initializing disallowed items list");
			DisallowedItems = new List<ConfigEntry<bool>>();
			foreach (Item value in StatsManager.instance.itemDictionary.Values)
			{
				itemType itemType = value.itemType;
				itemType val = itemType;
				ConfigEntry<bool> val2;
				if ((int)val != 0)
				{
					if ((int)val != 3)
					{
						continue;
					}
					val2 = ((BaseUnityPlugin)Instance).Config.Bind<bool>("AllowedItems Upgrades", ((Object)value).name, true, new ConfigDescription("Whether this upgrade item can spawn in levels", (AcceptableValueBase)null, Array.Empty<object>()));
				}
				else
				{
					val2 = ((BaseUnityPlugin)Instance).Config.Bind<bool>("AllowedItems Drones", ((Object)value).name, true, new ConfigDescription("Whether this drone item can spawn in levels", (AcceptableValueBase)null, Array.Empty<object>()));
				}
				if (!val2.Value)
				{
					DisallowedItems.Add(val2);
				}
			}
		}

		private static bool GetRandomItemOfType(itemType itemType, out Item item)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Invalid comparison between Unknown and I4
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Invalid comparison between Unknown and I4
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			item = null;
			List<Item> list = (from i in StatsManager.instance.itemDictionary.Values
				where i.itemType == itemType
				where (Object)(object)i.value != (Object)null && i.value.valueMin > 0f
				where !DisallowedItems.Any((ConfigEntry<bool> cfg) => ((ConfigEntryBase)cfg).Definition.Key == ((Object)i).name && !cfg.Value)
				select i).ToList();
			if (list.Count == 0)
			{
				Logger.LogWarning((object)$"GetRandomItemOfType: No valid items found for type {itemType} after filtering.");
				return false;
			}
			bool flag = false;
			itemType val = itemType;
			itemType val2 = val;
			if ((int)val2 != 0)
			{
				if ((int)val2 != 3)
				{
					if ((int)val2 == 8)
					{
						flag = true;
					}
				}
				else
				{
					flag = UseShopPriceForUpgradeItems.Value;
				}
			}
			else
			{
				flag = UseShopPriceForDroneItems.Value;
			}
			if (flag)
			{
				float num = list.Sum((Item i) => 1f / i.value.valueMin);
				if (num <= 0f || float.IsNaN(num) || float.IsInfinity(num))
				{
					Logger.LogWarning((object)($"GetRandomItemOfType: Invalid total weight {num} for type {itemType}. " + "This may indicate an issue with item values or weights."));
					return false;
				}
				float num2 = Random.Range(0f, num);
				foreach (Item item2 in list)
				{
					float num3 = 1f / item2.value.valueMin;
					num2 -= num3;
					if (num2 <= 0f)
					{
						item = item2;
						break;
					}
				}
				if ((Object)(object)item == (Object)null)
				{
					Logger.LogWarning((object)($"GetRandomItemOfType: Weighted selection loop for type {itemType} completed unexpectedly " + "without selecting an item. This may indicate a precision issue."));
					return false;
				}
				float num4 = 1f / item.value.valueMin / num * 100f;
				Logger.LogInfo((object)$"Selecting {((Object)item).name} at a chance of {num4:F2}% compared to others of type {itemType} (based on shop price)");
			}
			else
			{
				int index = Random.Range(0, list.Count);
				item = list[index];
				Logger.LogInfo((object)$"Selecting {((Object)item).name} at a chance of {100f / (float)list.Count:F2}% compared to others of type {itemType} (equal chance)");
			}
			return true;
		}

		private static bool HasValuablePropSwitch(ValuableVolume volume)
		{
			return (Object)(object)((Component)((Component)volume).transform).GetComponentInParent<ValuablePropSwitch>() != (Object)null;
		}

		private static bool ShouldSpawnItem(ValuableVolume volume, out itemType? itemType, out bool hasSwitch)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			itemType = null;
			hasSwitch = HasValuablePropSwitch(volume);
			if (hasSwitch)
			{
				return false;
			}
			Type volumeType = volume.VolumeType;
			Type val = volumeType;
			if ((int)val != 0)
			{
				if ((int)val == 1)
				{
					if (!SpawnDroneItems.Value)
					{
						return false;
					}
					itemType = (itemType)0;
					return Random.Range(0f, 100f) <= DroneItemSpawnChance.Value;
				}
				return false;
			}
			if (!SpawnUpgradeItems.Value)
			{
				return false;
			}
			itemType = (itemType)3;
			return Random.Range(0f, 100f) <= UpgradeItemSpawnChance.Value;
		}

		private static GameObject SpawnItem(Item item, Vector3 position, Quaternion rotation)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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)
			GameObject val = ((!SemiFunc.IsMultiplayer()) ? Object.Instantiate<GameObject>(item.prefab.Prefab, position, rotation) : PhotonNetwork.Instantiate("Items/" + ((Object)item).name, position, rotation, (byte)0, (object[])null));
			val.AddComponent<SpawnedItemTracker>();
			return val;
		}

		private static bool RandomItemSpawn(ValuableVolume volume)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if (!ShouldSpawnItem(volume, out var itemType, out var _))
			{
				return false;
			}
			if (!itemType.HasValue)
			{
				return false;
			}
			if (!GetRandomItemOfType(itemType.Value, out var item))
			{
				return false;
			}
			SpawnItem(item, ((Component)volume).transform.position, ((Component)volume).transform.rotation);
			return true;
		}

		[HarmonyPatch(typeof(ValuableDirector), "Spawn")]
		[HarmonyPrefix]
		public static void ValuableDirector_Spawn_Prefix(GameObject _valuable, ValuableVolume _volume, string _path)
		{
			((Component)_volume).gameObject.AddComponent<UsedVolumeTracker>();
		}

		[HarmonyPatch(typeof(ValuableDirector), "VolumesAndSwitchSetup")]
		[HarmonyPostfix]
		public static void ValuableDirector_VolumesAndSwitchSetup_Postfix(ValuableDirector __instance)
		{
			if (!SemiFunc.RunIsLevel())
			{
				return;
			}
			IEnumerable<ValuableVolume> enumerable = from volume in Object.FindObjectsOfType<ValuableVolume>(false).ToList()
				where (Object)(object)((Component)volume).gameObject.GetComponent<UsedVolumeTracker>() == (Object)null
				where !HasValuablePropSwitch(volume)
				select volume;
			Logger.LogInfo((object)$"Found {enumerable.Count()} potential volumes to spawn items in");
			Logger.LogInfo((object)$"Upgrade item spawn chance: {UpgradeItemSpawnChance.Value}% on {enumerable.Where((ValuableVolume volume) => (int)volume.VolumeType == 0).Count()} tiny volumes");
			Logger.LogInfo((object)$"Drone item spawn chance: {DroneItemSpawnChance.Value}% on {enumerable.Where((ValuableVolume volume) => (int)volume.VolumeType == 1).Count()} small volumes");
			int num = 0;
			foreach (ValuableVolume item in enumerable)
			{
				if (RandomItemSpawn(item))
				{
					num++;
				}
			}
			Logger.LogInfo((object)$"Spawned {num} items in total");
		}

		[HarmonyPatch(typeof(Map), "AddCustom")]
		[HarmonyPostfix]
		public static void Map_AddCustom_Postfix(MapCustom mapCustom)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Invalid comparison between Unknown and I4
			ItemAttributes val = default(ItemAttributes);
			if (!SemiFunc.RunIsLevel() || !((Component)mapCustom).gameObject.TryGetComponent<ItemAttributes>(ref val))
			{
				return;
			}
			itemType itemType = val.item.itemType;
			itemType val2 = itemType;
			if ((int)val2 != 0)
			{
				if ((int)val2 != 3 || !MapHideUpgradeItems.Value)
				{
					return;
				}
			}
			else if (!MapHideDroneItems.Value)
			{
				return;
			}
			((Component)mapCustom.mapCustomEntity).gameObject.SetActive(false);
		}

		[HarmonyPatch(typeof(ExtractionPoint), "DestroyAllPhysObjectsInHaulList")]
		[HarmonyPostfix]
		public static void ExtractionPoint_DestroyAllPhysObjectsInHaulList_Postfix(ExtractionPoint __instance)
		{
			if (!SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			List<GameObject> list = (from tracker in Object.FindObjectsOfType<SpawnedItemTracker>(false)
				select ((Component)tracker).gameObject).ToList();
			foreach (GameObject item in list)
			{
				RoomVolumeCheck component = item.GetComponent<RoomVolumeCheck>();
				if (!((Object)(object)component == (Object)null) && component.CurrentRooms.Any((RoomVolume room) => room.Extraction))
				{
					ItemAttributes component2 = item.GetComponent<ItemAttributes>();
					Logger.LogInfo((object)("Adding item " + component2.itemAssetName + " to purchased items"));
					StatsManager.instance.ItemPurchase(component2.itemAssetName);
					Logger.LogInfo((object)("Destroying spawned item " + ((Object)item).name + " in extraction point " + ((Object)__instance).name));
					item.GetComponent<PhysGrabObject>().DestroyPhysGrabObject();
				}
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "REPO_Shop_Items_in_Level";

		public const string PLUGIN_NAME = "Shop Items spawn in Level";

		public const string PLUGIN_VERSION = "1.7.20";
	}
}