Decompiled source of AutoCrafter v0.2.0

despr0grammer.AutoCrafter.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 despr0grammer.AutoCrafter
{
	internal static class Actions
	{
		internal static CraftingStation HoveredStation(Player player)
		{
			GameObject hoverObject = ((Humanoid)player).GetHoverObject();
			if (!((Object)(object)hoverObject != (Object)null))
			{
				return null;
			}
			return hoverObject.GetComponentInParent<CraftingStation>();
		}

		internal static void OpenHud()
		{
			Hud.Open(HoveredStation(Player.m_localPlayer));
		}

		internal static string HoverLine(CraftingStation station)
		{
			if ((Object)(object)Player.m_localPlayer == (Object)null || RecipeIndex.ForStation(station.m_name).Count == 0)
			{
				return null;
			}
			StationJob stationJob = StationJobs.Get(station);
			string text = ((stationJob == null || stationJob.Orders.Count == 0) ? Text.HoverIdle : Text.HoverJob(stationJob.Orders.Count, stationJob.Enabled));
			return "\n[<color=yellow><b>" + Plugin.MenuKeyLabel + "</b></color>] " + text;
		}

		internal static void Notify(string message, bool center = false)
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null)
			{
				((Character)localPlayer).Message((MessageType)((!center) ? 1 : 2), message, 0, (Sprite)null, false);
			}
		}
	}
	internal static class ChestAccess
	{
		internal static bool InUse(Container container)
		{
			if (container.IsInUse())
			{
				return true;
			}
			ZNetView val = ChestRegistry.NetViewOf(container);
			if ((Object)(object)val != (Object)null && val.IsValid())
			{
				return val.GetZDO().GetInt(ZDOVars.s_inUse, 0) == 1;
			}
			return false;
		}

		internal static bool TryAdd(Inventory inventory, string prefab, int amount, long crafterId, string crafterName)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			return inventory.AddItem(prefab, amount, 1, 0, crafterId, crafterName, new Vector2i(-1, -1), false, false, false) != null;
		}

		internal static void Own(ZNetView view)
		{
			if ((Object)(object)view != (Object)null && !view.IsOwner())
			{
				view.ClaimOwnership();
			}
		}
	}
	internal sealed class ChangeBatch
	{
		private readonly Dictionary<Inventory, Action> _held = new Dictionary<Inventory, Action>();

		internal void Hold(Inventory inventory)
		{
			if (inventory != null && !_held.ContainsKey(inventory))
			{
				_held[inventory] = inventory.m_onChanged;
				inventory.m_onChanged = null;
			}
		}

		internal void Release()
		{
			foreach (KeyValuePair<Inventory, Action> item in _held)
			{
				item.Key.m_onChanged = item.Value;
			}
			foreach (KeyValuePair<Inventory, Action> item2 in _held)
			{
				try
				{
					item2.Value?.Invoke();
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("An inventory handler failed after crafting: " + ex.Message));
				}
			}
			_held.Clear();
		}
	}
	internal static class ChestLink
	{
		private const float WaitSeconds = 120f;

		private static CraftingStation _station;

		private static float _until;

		internal static bool IsWaitingFor(CraftingStation station)
		{
			if ((Object)(object)station != (Object)null && (Object)(object)_station == (Object)(object)station)
			{
				return Time.unscaledTime < _until;
			}
			return false;
		}

		internal static void Begin(CraftingStation station)
		{
			_station = station;
			_until = Time.unscaledTime + 120f;
			Actions.Notify(Text.LinkHint(StationName(station), Plugin.MenuKeyLabel), center: true);
		}

		internal static void Cancel()
		{
			if ((Object)(object)_station != (Object)null && Time.unscaledTime < _until)
			{
				Actions.Notify(Text.LinkCancelled);
			}
			_station = null;
		}

		internal static void OnChestOpened(Container container)
		{
			if ((Object)(object)_station == (Object)null || (Object)(object)container == (Object)null)
			{
				return;
			}
			CraftingStation station = _station;
			if (Time.unscaledTime >= _until)
			{
				_station = null;
				return;
			}
			if (!ChestRegistry.IsStorage(container) || !ChestRegistry.TryGetNetworkId(container, out var user, out var id))
			{
				Actions.Notify(Text.LinkNotStorage);
				return;
			}
			StationJob stationJob = StationJobs.Get(station) ?? new StationJob();
			stationJob.LinkChest(user, id);
			_station = null;
			if (StationJobs.Save(station, stationJob))
			{
				Actions.Notify(Text.Linked(StationName(station)));
			}
			else
			{
				Actions.Notify(Text.SaveFailed);
			}
		}

		internal static void Unlink(CraftingStation station, StationJob job)
		{
			if (job != null && job.HasChest)
			{
				job.UnlinkChest();
				if (StationJobs.Save(station, job))
				{
					Actions.Notify(Text.Unlinked(StationName(station)));
				}
			}
		}

		private static string StationName(CraftingStation station)
		{
			return Localization.instance.Localize(station.m_name);
		}
	}
	internal static class ChestRegistry
	{
		private sealed class Entry
		{
			internal int Id;

			internal Container Container;

			internal Inventory Inventory;

			internal Transform Transform;

			internal ZNetView NetView;

			internal int Storage = -1;
		}

		private struct Candidate
		{
			internal Container Container;

			internal float SqrDistance;
		}

		private static readonly List<Entry> Entries = new List<Entry>(64);

		private static readonly Dictionary<int, Entry> ById = new Dictionary<int, Entry>();

		private static readonly Dictionary<Inventory, Entry> ByInventory = new Dictionary<Inventory, Entry>();

		private static readonly List<Candidate> Scratch = new List<Candidate>(32);

		private static readonly Comparison<Candidate> ByDistance = (Candidate a, Candidate b) => a.SqrDistance.CompareTo(b.SqrDistance);

		internal static void Register(Container container)
		{
			if (!((Object)(object)container == (Object)null) && !ById.ContainsKey(((Object)container).GetInstanceID()))
			{
				Entry entry = new Entry
				{
					Id = ((Object)container).GetInstanceID(),
					Container = container,
					Inventory = container.GetInventory(),
					Transform = ((Component)container).transform,
					NetView = GameAccess.NetViewOf(container)
				};
				Entries.Add(entry);
				ById[entry.Id] = entry;
				if (entry.Inventory != null)
				{
					ByInventory[entry.Inventory] = entry;
				}
			}
		}

		internal static void SeedFromScene()
		{
			Container[] array = Object.FindObjectsByType<Container>((FindObjectsSortMode)0);
			for (int i = 0; i < array.Length; i++)
			{
				Register(array[i]);
			}
		}

		internal static void Prune()
		{
			for (int num = Entries.Count - 1; num >= 0; num--)
			{
				if ((Object)(object)Entries[num].Container == (Object)null)
				{
					RemoveAt(num);
				}
			}
		}

		internal static bool IsStorage(Container container)
		{
			Entry entry = Ensure(container);
			if (entry == null)
			{
				return false;
			}
			if (entry.Storage < 0)
			{
				entry.Storage = (ComputeStorage(container) ? 1 : 0);
			}
			return entry.Storage == 1;
		}

		internal static ZNetView NetViewOf(Container container)
		{
			return Ensure(container)?.NetView;
		}

		internal static bool TryGetByInventory(Inventory inventory, out Container container)
		{
			if (inventory != null && ByInventory.TryGetValue(inventory, out var value) && (Object)(object)value.Container != (Object)null)
			{
				container = value.Container;
				return true;
			}
			container = null;
			return false;
		}

		internal static bool CanUse(Container container, long playerId)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (!GameAccess.CheckAccess(container, playerId))
			{
				return false;
			}
			if (container.m_checkGuardStone)
			{
				return PrivateArea.CheckAccess(((Component)container).transform.position, 0f, false, false);
			}
			return true;
		}

		internal static void Find(Vector3 center, float radius, long playerId, List<Container> result)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//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)
			result.Clear();
			Scratch.Clear();
			float num = radius * radius;
			for (int num2 = Entries.Count - 1; num2 >= 0; num2--)
			{
				Entry entry = Entries[num2];
				if ((Object)(object)entry.Container == (Object)null)
				{
					RemoveAt(num2);
				}
				else
				{
					Vector3 val = entry.Transform.position - center;
					float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
					if (!(sqrMagnitude > num) && IsUsable(entry, playerId))
					{
						Scratch.Add(new Candidate
						{
							Container = entry.Container,
							SqrDistance = sqrMagnitude
						});
					}
				}
			}
			Scratch.Sort(ByDistance);
			for (int i = 0; i < Scratch.Count; i++)
			{
				result.Add(Scratch[i].Container);
			}
		}

		internal static bool TryGetNetworkId(Container container, out long user, out uint id)
		{
			//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)
			ZNetView val = NetViewOf(container);
			if ((Object)(object)val != (Object)null && val.IsValid())
			{
				ZDOID uid = val.GetZDO().m_uid;
				user = ((ZDOID)(ref uid)).UserID;
				id = ((ZDOID)(ref uid)).ID;
				return id != 0;
			}
			user = 0L;
			id = 0u;
			return false;
		}

		internal static Container FindByNetworkId(long user, uint id, long playerId)
		{
			//IL_0057: 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)
			for (int num = Entries.Count - 1; num >= 0; num--)
			{
				Entry entry = Entries[num];
				if ((Object)(object)entry.Container == (Object)null)
				{
					RemoveAt(num);
				}
				else if (!((Object)(object)entry.NetView == (Object)null) && entry.NetView.IsValid())
				{
					ZDOID uid = entry.NetView.GetZDO().m_uid;
					if (((ZDOID)(ref uid)).ID == id && ((ZDOID)(ref uid)).UserID == user)
					{
						if (!IsUsable(entry, playerId))
						{
							return null;
						}
						return entry.Container;
					}
				}
			}
			return null;
		}

		private static bool IsUsable(Entry entry, long playerId)
		{
			if ((Object)(object)entry.NetView == (Object)null || !entry.NetView.IsValid() || entry.Container.GetInventory() == null)
			{
				return false;
			}
			if (IsStorage(entry.Container))
			{
				return CanUse(entry.Container, playerId);
			}
			return false;
		}

		private static bool ComputeStorage(Container container)
		{
			if ((Object)(object)((Component)container).GetComponentInParent<Piece>() != (Object)null && (Object)(object)container.m_wagon == (Object)null && !container.m_autoDestroyEmpty && (Object)(object)((Component)container).GetComponentInParent<TombStone>() == (Object)null)
			{
				return (Object)(object)((Component)container).GetComponentInParent<Incinerator>() == (Object)null;
			}
			return false;
		}

		private static Entry Ensure(Container container)
		{
			if ((Object)(object)container == (Object)null)
			{
				return null;
			}
			int instanceID = ((Object)container).GetInstanceID();
			if (!ById.TryGetValue(instanceID, out var value))
			{
				Register(container);
				ById.TryGetValue(instanceID, out value);
			}
			return value;
		}

		private static void RemoveAt(int index)
		{
			Entry entry = Entries[index];
			ById.Remove(entry.Id);
			if (entry.Inventory != null)
			{
				ByInventory.Remove(entry.Inventory);
			}
			int index2 = Entries.Count - 1;
			Entries[index] = Entries[index2];
			Entries.RemoveAt(index2);
		}
	}
	internal enum CraftStatus
	{
		Idle,
		Working,
		Paused,
		CountComplete,
		StockReached,
		CapReached,
		MissingRecipe,
		UnknownRecipe,
		NeedLevel,
		NotUsable,
		NoIngredients,
		NoRoom,
		NotOwner,
		Disabled,
		ReserveReached,
		ChestUnavailable
	}
	internal sealed class StationState
	{
		internal readonly CraftStatus[] Orders = new CraftStatus[8];

		internal readonly int[] Stock = new int[8];

		internal readonly string[] Detail = new string[8];

		internal readonly bool[] Making = new bool[8];

		internal float NextCraft;

		internal string LastCrafted;

		internal int Chests;

		internal int Barrels;

		internal bool Remote;

		internal string Runner;

		internal float WatchSince = -1f;

		internal long LastBeat = -1L;

		internal float BeatChangedAt;

		internal float UselessSince = -1f;

		internal string LastPublished;

		internal float LastPublishedAt = -100f;
	}
	internal struct StationSummary
	{
		internal int Orders;

		internal int Working;

		internal int Waiting;

		internal int Finished;

		internal int Paused;
	}
	internal static class Crafter
	{
		private sealed class Pick
		{
			internal CraftingStation Station;

			internal RecipeRow Row;

			internal bool Intermediate;
		}

		private const float TickInterval = 1f;

		private const float PruneInterval = 30f;

		private static readonly Dictionary<int, StationState> States = new Dictionary<int, StationState>();

		private static readonly List<Container> Found = new List<Container>(32);

		private static readonly List<Container> Usable = new List<Container>(32);

		private static readonly List<CraftingStation> Scratch = new List<CraftingStation>(32);

		private static readonly List<CraftingStation> Producers = new List<CraftingStation>(16);

		private static readonly Dictionary<string, Pick> Picks = new Dictionary<string, Pick>(StringComparer.Ordinal);

		private static readonly List<Fermenter> Barrels = new List<Fermenter>(16);

		private static readonly HashSet<int> Live = new HashSet<int>();

		private static Player _player;

		private static Vector3 _center;

		private static Container _linked;

		private static bool _linkUnavailable;

		private static float _nextTick;

		private static float _nextPrune;

		private static bool _reported;

		private const string StateKey = "despr0grammer_autocrafter_state";

		private static readonly IComparer<CraftingStation> DistanceFromCenter = Comparer<CraftingStation>.Create(delegate(CraftingStation a, CraftingStation b)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_0030: 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)
			Vector3 val = ((Component)a).transform.position - _center;
			float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
			val = ((Component)b).transform.position - _center;
			return sqrMagnitude.CompareTo(((Vector3)(ref val)).sqrMagnitude);
		});

		internal static StationState StateOf(CraftingStation station)
		{
			if (!((Object)(object)station != (Object)null) || !States.TryGetValue(((Object)station).GetInstanceID(), out var value))
			{
				return null;
			}
			return value;
		}

		internal static StationSummary Summarize(StationJob job, StationState state)
		{
			StationSummary result = new StationSummary
			{
				Orders = (job?.Orders.Count ?? 0)
			};
			for (int i = 0; i < result.Orders; i++)
			{
				switch ((state != null) ? state.Orders[i] : CraftStatus.Idle)
				{
				case CraftStatus.Idle:
				case CraftStatus.Working:
					result.Working++;
					break;
				case CraftStatus.CountComplete:
				case CraftStatus.StockReached:
				case CraftStatus.CapReached:
					result.Finished++;
					break;
				case CraftStatus.Paused:
				case CraftStatus.Disabled:
					result.Paused++;
					break;
				default:
					result.Waiting++;
					break;
				}
			}
			return result;
		}

		internal static void Tick(Player player)
		{
			if (Time.time < _nextTick)
			{
				return;
			}
			_nextTick = Time.time + 1f;
			List<CraftingStation> stations = GameAccess.Stations;
			if (stations == null)
			{
				return;
			}
			Scratch.Clear();
			Scratch.AddRange(stations);
			foreach (CraftingStation item in Scratch)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				try
				{
					RunStation(player, item);
				}
				catch (Exception arg)
				{
					if (!_reported)
					{
						_reported = true;
						Plugin.Log.LogError((object)$"The crafter failed on a station (further errors are not logged): {arg}");
					}
				}
			}
			if (Time.time >= _nextPrune)
			{
				_nextPrune = Time.time + 30f;
				Prune();
			}
		}

		private static void RunStation(Player player, CraftingStation station)
		{
			StationJob stationJob = StationJobs.Get(station);
			if (stationJob == null)
			{
				return;
			}
			StationState stationState = StateFor(station);
			bool flag = stationJob.Ferment && GameAccess.FermenterReady;
			if (!stationJob.Enabled || (stationJob.Orders.Count == 0 && !flag))
			{
				SetAll(stationState, stationJob.Orders.Count, CraftStatus.Disabled);
				stationState.Barrels = 0;
				StopWatching(stationState);
				return;
			}
			ZNetView val = GameAccess.NetViewOf(station);
			if ((Object)(object)val == (Object)null || !val.IsValid())
			{
				StopWatching(stationState);
				return;
			}
			if (!val.IsOwner())
			{
				if (!FollowOrTakeOver(player, station, val, stationJob, stationState))
				{
					return;
				}
				stationState.LastPublished = null;
				stationState.LastPublishedAt = -100f;
			}
			StopWatching(stationState);
			try
			{
				RunAsOwner(player, station, stationJob, stationState, flag);
			}
			finally
			{
				PublishState(player, val, stationJob, stationState);
			}
		}

		private static void RunAsOwner(Player player, CraftingStation station, StationJob job, StationState state, bool fermenting)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)station).transform.position;
			ChestRegistry.Find(position, Plugin.Radius.Value, player.GetPlayerID(), Found);
			Container val = (job.HasChest ? ChestRegistry.FindByNetworkId(job.ChestUser, job.ChestId, player.GetPlayerID()) : null);
			if ((Object)(object)val != (Object)null && !Found.Contains(val))
			{
				Found.Add(val);
			}
			Usable.Clear();
			foreach (Container item in Found)
			{
				GameAccess.RefreshContainer(item);
				if (!ChestAccess.InUse(item))
				{
					Usable.Add(item);
				}
			}
			state.Chests = Usable.Count;
			_linked = (((Object)(object)val != (Object)null && Usable.Contains(val)) ? val : null);
			_linkUnavailable = job.HasChest && (Object)(object)_linked == (Object)null;
			if (fermenting)
			{
				RunFermenters(position, state);
			}
			else
			{
				state.Barrels = 0;
			}
			if (job.Orders.Count == 0)
			{
				return;
			}
			bool flag = Time.time < state.NextCraft;
			_player = player;
			_center = position;
			if (!flag)
			{
				BuildProducers(station);
			}
			bool flag2 = false;
			bool flag3 = false;
			for (int i = 0; i < job.Orders.Count; i++)
			{
				Order order = job.Orders[i];
				state.Detail[i] = null;
				state.Making[i] = false;
				RecipeRow recipeRow = RecipeIndex.Find(station.m_name, order.Recipe);
				if (recipeRow == null)
				{
					state.Orders[i] = CraftStatus.MissingRecipe;
					continue;
				}
				FermentIndex.Conversion conversion = default(FermentIndex.Conversion);
				bool flag4 = order.CountEnd && FermentIndex.TryGetByShared(recipeRow.Shared, out conversion);
				int unitsPerCraft = OrderRules.UnitsPerCraft(recipeRow.Yield, flag4 ? conversion.Produced : 0, flag4);
				int num = ((order.Mode == OrderMode.Stock) ? StockOf(player, position, recipeRow, flag4, conversion) : 0);
				state.Stock[i] = num;
				OrderVerdict orderVerdict = OrderRules.Evaluate(order, num, unitsPerCraft);
				if (orderVerdict != OrderVerdict.Ready)
				{
					state.Orders[i] = orderVerdict switch
					{
						OrderVerdict.CapReached => CraftStatus.CapReached, 
						OrderVerdict.CountComplete => CraftStatus.CountComplete, 
						OrderVerdict.Paused => CraftStatus.Paused, 
						_ => CraftStatus.StockReached, 
					};
					if (orderVerdict == OrderVerdict.CapReached)
					{
						state.Detail[i] = unitsPerCraft.ToString();
					}
					continue;
				}
				if (flag2 || flag)
				{
					state.Orders[i] = ((flag && order.Recipe == state.LastCrafted) ? CraftStatus.Working : CraftStatus.Idle);
					continue;
				}
				bool intermediate;
				CraftStatus craftStatus = Attempt(player, station, order, recipeRow, state, i, out intermediate);
				state.Orders[i] = craftStatus;
				if (craftStatus != CraftStatus.Working)
				{
					state.Making[i] = false;
					continue;
				}
				flag2 = true;
				state.LastCrafted = order.Recipe;
				if (!intermediate && order.Mode == OrderMode.Count)
				{
					order.Done++;
					flag3 = true;
				}
			}
			if (flag2)
			{
				state.NextCraft = Time.time + Plugin.CraftSeconds.Value;
			}
			if (flag3)
			{
				StationJobs.Save(station, job);
			}
		}

		private static long NowTicks()
		{
			if (!((Object)(object)ZNet.instance != (Object)null))
			{
				return DateTime.UtcNow.Ticks;
			}
			return ZNet.instance.GetTime().Ticks;
		}

		private static void StopWatching(StationState state)
		{
			state.Remote = false;
			state.Runner = null;
			state.WatchSince = -1f;
			state.LastBeat = -1L;
			state.UselessSince = -1f;
		}

		private static bool CanUseChestsAt(Player player, CraftingStation station)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			ChestRegistry.Find(((Component)station).transform.position, Plugin.Radius.Value, player.GetPlayerID(), Found);
			foreach (Container item in Found)
			{
				if (!ChestAccess.InUse(item))
				{
					return true;
				}
			}
			return false;
		}

		private static bool FollowOrTakeOver(Player player, CraftingStation station, ZNetView view, StationJob job, StationState state)
		{
			SharedState sharedState = StateCodec.Parse(view.GetZDO().GetString("despr0grammer_autocrafter_state", string.Empty));
			float time = Time.time;
			long num = sharedState?.Beat ?? (-1);
			if (state.WatchSince < 0f)
			{
				state.WatchSince = time;
				state.LastBeat = num;
				state.BeatChangedAt = time;
			}
			else if (num != state.LastBeat)
			{
				state.LastBeat = num;
				state.BeatChangedAt = time;
			}
			RunnerAction runnerAction = StateCodec.Decide(sharedState, time - state.BeatChangedAt, time - state.WatchSince);
			string text = null;
			switch (runnerAction)
			{
			case RunnerAction.Follow:
			{
				state.WatchSince = time;
				if (sharedState.Chests == 0)
				{
					if (state.UselessSince < 0f)
					{
						state.UselessSince = time;
					}
				}
				else
				{
					state.UselessSince = -1f;
				}
				double num2 = ((state.UselessSince < 0f) ? 0.0 : ((double)(time - state.UselessSince)));
				if (num2 >= 15.0 && StateCodec.ShouldReclaim(sharedState, num2, CanUseChestsAt(player, station)))
				{
					runnerAction = RunnerAction.Takeover;
					text = sharedState.Runner + " could use no chest there";
					break;
				}
				ShowReport(state, sharedState, job.Orders.Count);
				return false;
			}
			case RunnerAction.Takeover:
				text = ((sharedState != null) ? ("the report of " + sharedState.Runner + " stopped") : "nobody reported on it");
				break;
			}
			if (runnerAction == RunnerAction.Takeover && CanUseChestsAt(player, station))
			{
				ChestAccess.Own(view);
				if (view.IsOwner())
				{
					Plugin.Log.LogInfo((object)("Took over a " + station.m_name + ": " + text + "."));
					return true;
				}
			}
			state.Remote = false;
			state.Runner = null;
			SetAll(state, job.Orders.Count, CraftStatus.NotOwner);
			return false;
		}

		private static void ShowReport(StationState state, SharedState reported, int orderCount)
		{
			state.Remote = true;
			state.Runner = reported.Runner;
			state.Chests = reported.Chests;
			state.Barrels = reported.Barrels;
			for (int i = 0; i < state.Orders.Length; i++)
			{
				state.Stock[i] = 0;
				state.Making[i] = false;
				state.Detail[i] = null;
				if (i >= orderCount)
				{
					state.Orders[i] = CraftStatus.Idle;
				}
				else if (i < reported.Orders.Count)
				{
					OrderReport orderReport = reported.Orders[i];
					state.Orders[i] = (Enum.IsDefined(typeof(CraftStatus), orderReport.Status) ? ((CraftStatus)orderReport.Status) : CraftStatus.NotOwner);
					state.Stock[i] = orderReport.Stock;
					state.Making[i] = orderReport.Making;
					state.Detail[i] = orderReport.Detail;
				}
				else
				{
					state.Orders[i] = CraftStatus.NotOwner;
				}
			}
		}

		private static void PublishState(Player player, ZNetView view, StationJob job, StationState state)
		{
			SharedState sharedState = new SharedState
			{
				Runner = player.GetPlayerName(),
				Chests = state.Chests,
				Barrels = state.Barrels
			};
			for (int i = 0; i < job.Orders.Count; i++)
			{
				sharedState.Orders.Add(new OrderReport
				{
					Status = (int)state.Orders[i],
					Stock = state.Stock[i],
					Making = state.Making[i],
					Detail = state.Detail[i]
				});
			}
			string text = StateCodec.ContentKey(sharedState);
			if (StateCodec.ShouldPublish(text != state.LastPublished, Time.time - state.LastPublishedAt))
			{
				sharedState.Beat = NowTicks();
				view.GetZDO().Set("despr0grammer_autocrafter_state", StateCodec.Serialize(sharedState));
				state.LastPublished = text;
				state.LastPublishedAt = Time.time;
			}
		}

		private static CraftStatus Attempt(Player player, CraftingStation station, Order order, RecipeRow row, StationState state, int index, out bool intermediate)
		{
			intermediate = false;
			if (!RecipeAllowed(player, row))
			{
				return CraftStatus.UnknownRecipe;
			}
			CraftStatus? craftStatus = StationProblem(player, station, row);
			if (craftStatus.HasValue)
			{
				return craftStatus.Value;
			}
			Pick pick = Choose(station, row, order.CraftMissing);
			if (pick == null)
			{
				state.Detail[index] = MissingText(row);
				return CraftStatus.NoIngredients;
			}
			string text = OrderRules.UnderReserve(pick.Row.Needs, CountIn, order.Reserve);
			if (text != null)
			{
				state.Detail[index] = Localization.instance.Localize(text) + " (" + CountIn(text) + ")";
				return CraftStatus.ReserveReached;
			}
			intermediate = pick.Intermediate;
			state.Making[index] = pick.Intermediate;
			state.Detail[index] = (pick.Intermediate ? pick.Row.Display : null);
			CraftStatus craftStatus2 = CraftOne(player, pick.Station, pick.Row);
			if (craftStatus2 != CraftStatus.Working)
			{
				state.Detail[index] = ((craftStatus2 == CraftStatus.NoIngredients) ? MissingText(row) : null);
			}
			return craftStatus2;
		}

		private static bool RecipeAllowed(Player player, RecipeRow row)
		{
			if (Plugin.RequireKnownRecipes.Value)
			{
				return player.IsRecipeKnown(row.Shared);
			}
			return true;
		}

		private static CraftStatus? StationProblem(Player player, CraftingStation station, RecipeRow row)
		{
			if (!station.CheckUsable(player, false))
			{
				return CraftStatus.NotUsable;
			}
			if (station.GetLevel(true) < row.Recipe.GetRequiredStationLevel(1))
			{
				return CraftStatus.NeedLevel;
			}
			return null;
		}

		private static Pick Choose(CraftingStation station, RecipeRow mainRow, bool allowSub)
		{
			Picks.Clear();
			string text = KeyOf(station, mainRow);
			Picks[text] = new Pick
			{
				Station = station,
				Row = mainRow,
				Intermediate = false
			};
			string text2 = Planner.Resolve(text, NeedsOf, HaveOf, allowSub ? new Func<string, string>(RecipeFor) : new Func<string, string>(NoRecipe), 3);
			if (text2 == null || !Picks.TryGetValue(text2, out var value))
			{
				return null;
			}
			return value;
		}

		private static string KeyOf(CraftingStation station, RecipeRow row)
		{
			return ((Object)station).GetInstanceID() + "|" + row.Prefab;
		}

		private static IReadOnlyList<IngredientNeed> NeedsOf(string key)
		{
			return Picks[key].Row.Needs;
		}

		private static int HaveOf(string item)
		{
			return CountIn(item);
		}

		private static string NoRecipe(string item)
		{
			return null;
		}

		private static string RecipeFor(string item)
		{
			foreach (CraftingStation producer in Producers)
			{
				RecipeRow recipeRow = RecipeIndex.FindByShared(producer.m_name, item);
				if (recipeRow != null && RecipeAllowed(_player, recipeRow) && !StationProblem(_player, producer, recipeRow).HasValue)
				{
					string text = KeyOf(producer, recipeRow);
					if (!Picks.ContainsKey(text))
					{
						Picks[text] = new Pick
						{
							Station = producer,
							Row = recipeRow,
							Intermediate = true
						};
					}
					return text;
				}
			}
			return null;
		}

		private static void BuildProducers(CraftingStation station)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			Producers.Clear();
			Producers.Add(station);
			float num = Plugin.Radius.Value * Plugin.Radius.Value;
			foreach (CraftingStation item in Scratch)
			{
				if ((Object)(object)item == (Object)null || (Object)(object)item == (Object)(object)station)
				{
					continue;
				}
				Vector3 val = ((Component)item).transform.position - _center;
				if (!(((Vector3)(ref val)).sqrMagnitude > num))
				{
					ZNetView val2 = GameAccess.NetViewOf(item);
					if ((Object)(object)val2 != (Object)null && val2.IsValid())
					{
						Producers.Add(item);
					}
				}
			}
			if (Producers.Count > 2)
			{
				Producers.Sort(1, Producers.Count - 1, DistanceFromCenter);
			}
		}

		private static string MissingText(RecipeRow row)
		{
			string text = null;
			IngredientNeed[] needs = row.Needs;
			for (int i = 0; i < needs.Length; i++)
			{
				IngredientNeed ingredientNeed = needs[i];
				int num = CountIn(ingredientNeed.Item);
				if (num < ingredientNeed.Amount)
				{
					string text2 = ingredientNeed.Amount - num + "x " + Localization.instance.Localize(ingredientNeed.Item);
					text = ((text == null) ? text2 : (text + ", " + text2));
				}
			}
			return text;
		}

		private static CraftStatus CraftOne(Player player, CraftingStation station, RecipeRow row)
		{
			IngredientNeed[] needs = row.Needs;
			for (int i = 0; i < needs.Length; i++)
			{
				IngredientNeed ingredientNeed = needs[i];
				if (CountIn(ingredientNeed.Item) < ingredientNeed.Amount)
				{
					return CraftStatus.NoIngredients;
				}
			}
			GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(row.Prefab) : null);
			Container val2 = (((Object)(object)val != (Object)null) ? PickOutput(val, row.Shared, row.Yield) : null);
			if ((Object)(object)val2 == (Object)null)
			{
				if (!_linkUnavailable)
				{
					return CraftStatus.NoRoom;
				}
				return CraftStatus.ChestUnavailable;
			}
			ChangeBatch changeBatch = new ChangeBatch();
			try
			{
				Inventory inventory = val2.GetInventory();
				ChestAccess.Own(ChestRegistry.NetViewOf(val2));
				changeBatch.Hold(inventory);
				if (!ChestAccess.TryAdd(inventory, row.Prefab, row.Yield, player.GetPlayerID(), player.GetPlayerName()))
				{
					return CraftStatus.NoRoom;
				}
				try
				{
					needs = row.Needs;
					for (int i = 0; i < needs.Length; i++)
					{
						IngredientNeed ingredientNeed2 = needs[i];
						if (Consume(ingredientNeed2.Item, ingredientNeed2.Amount, changeBatch) > 0)
						{
							inventory.RemoveItem(row.Shared, row.Yield, -1, true);
							Plugin.Log.LogError((object)("Crafting " + row.Prefab + ": an ingredient (" + ingredientNeed2.Item + ") vanished between the check and the craft; the craft was undone."));
							return CraftStatus.NoIngredients;
						}
					}
				}
				catch (Exception)
				{
					inventory.RemoveItem(row.Shared, row.Yield, -1, true);
					throw;
				}
			}
			finally
			{
				changeBatch.Release();
			}
			PlayEffect(station);
			return CraftStatus.Working;
		}

		private static void RunFermenters(Vector3 center, StationState state)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			FermentIndex.Nearby(center, Plugin.Radius.Value, Barrels);
			state.Barrels = Barrels.Count;
			foreach (Fermenter barrel in Barrels)
			{
				ZNetView val = GameAccess.NetViewOf(barrel);
				if (!((Object)(object)val == (Object)null) && val.IsValid())
				{
					switch (GameAccess.StatusOf(barrel))
					{
					case 3:
						Tap(barrel, val);
						break;
					case 0:
						Fill(barrel, val);
						break;
					}
				}
			}
		}

		private static void Tap(Fermenter barrel, ZNetView view)
		{
			if (!FermentIndex.TryGetByShared(GameAccess.ContentOf(barrel), out var conversion))
			{
				return;
			}
			GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(conversion.ToPrefab) : null);
			Container val2 = (((Object)(object)val != (Object)null) ? PickOutput(val, conversion.ToShared, conversion.Produced) : null);
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			ChestAccess.Own(view);
			if (!view.IsOwner())
			{
				return;
			}
			ChangeBatch changeBatch = new ChangeBatch();
			try
			{
				Inventory inventory = val2.GetInventory();
				ChestAccess.Own(ChestRegistry.NetViewOf(val2));
				changeBatch.Hold(inventory);
				if (!ChestAccess.TryAdd(inventory, conversion.ToPrefab, conversion.Produced, 0L, string.Empty))
				{
					return;
				}
				try
				{
					GameAccess.EmptyBarrel(barrel);
					if (!string.IsNullOrEmpty(GameAccess.ContentOf(barrel)))
					{
						inventory.RemoveItem(conversion.ToShared, conversion.Produced, -1, true);
						Plugin.Log.LogError((object)("A finished barrel (" + conversion.FromPrefab + ") did not empty after its " + conversion.ToPrefab + " were stored; they were taken back out of the chest."));
					}
				}
				catch (Exception)
				{
					inventory.RemoveItem(conversion.ToShared, conversion.Produced, -1, true);
					throw;
				}
			}
			finally
			{
				changeBatch.Release();
			}
		}

		private static void Fill(Fermenter barrel, ZNetView view)
		{
			foreach (FermentIndex.Conversion item in FermentIndex.All)
			{
				if (CountIn(item.FromShared) <= 0)
				{
					continue;
				}
				ChestAccess.Own(view);
				if (!view.IsOwner())
				{
					break;
				}
				ChangeBatch changeBatch = new ChangeBatch();
				try
				{
					if (Consume(item.FromShared, 1, changeBatch) > 0)
					{
						continue;
					}
					GameAccess.AddToBarrel(barrel, item.FromPrefab);
					if (GameAccess.ContentOf(barrel) != item.FromShared)
					{
						Refund(item, changeBatch);
					}
					break;
				}
				finally
				{
					changeBatch.Release();
				}
			}
		}

		private static void Refund(FermentIndex.Conversion conversion, ChangeBatch batch)
		{
			GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(conversion.FromPrefab) : null);
			Container val2 = (((Object)(object)val != (Object)null) ? PickAnyOutput(val, conversion.FromShared, 1) : null);
			if ((Object)(object)val2 == (Object)null)
			{
				Plugin.Log.LogError((object)("A barrel refused " + conversion.FromPrefab + " and no chest has room to give it back: one was lost."));
				return;
			}
			ChestAccess.Own(ChestRegistry.NetViewOf(val2));
			batch.Hold(val2.GetInventory());
			if (!ChestAccess.TryAdd(val2.GetInventory(), conversion.FromPrefab, 1, 0L, string.Empty))
			{
				Plugin.Log.LogError((object)("A barrel refused " + conversion.FromPrefab + " and the chest could not take it back: one was lost."));
			}
		}

		private static Container PickOutput(GameObject prefab, string sharedName, int amount)
		{
			if (_linkUnavailable)
			{
				return null;
			}
			if ((Object)(object)_linked != (Object)null)
			{
				if (!_linked.GetInventory().CanAddItem(prefab, amount))
				{
					return null;
				}
				return _linked;
			}
			return PickAnyOutput(prefab, sharedName, amount);
		}

		private static Container PickAnyOutput(GameObject prefab, string sharedName, int amount)
		{
			foreach (Container item in Usable)
			{
				Inventory inventory = item.GetInventory();
				if (inventory.ContainsItemByName(sharedName) && inventory.CanAddItem(prefab, amount))
				{
					return item;
				}
			}
			foreach (Container item2 in Usable)
			{
				if (item2.GetInventory().CanAddItem(prefab, amount))
				{
					return item2;
				}
			}
			return null;
		}

		private static int Consume(string sharedName, int amount, ChangeBatch batch)
		{
			int num = amount;
			foreach (Container item in Usable)
			{
				if (num <= 0)
				{
					break;
				}
				Inventory inventory = item.GetInventory();
				int num2 = Math.Min(inventory.CountItems(sharedName, -1, true), num);
				if (num2 > 0)
				{
					ChestAccess.Own(ChestRegistry.NetViewOf(item));
					batch.Hold(inventory);
					inventory.RemoveItem(sharedName, num2, -1, true);
					num -= num2;
				}
			}
			return num;
		}

		private static int CountIn(string sharedName)
		{
			int num = 0;
			foreach (Container item in Usable)
			{
				num += item.GetInventory().CountItems(sharedName, -1, true);
			}
			return num;
		}

		private static int CountAll(string sharedName)
		{
			int num = 0;
			foreach (Container item in Found)
			{
				num += item.GetInventory().CountItems(sharedName, -1, true);
			}
			return num;
		}

		private static int StockOf(Player player, Vector3 center, RecipeRow row, bool useEnd, FermentIndex.Conversion conversion)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			bool value = Plugin.CountPlayerInventory.Value;
			int num = CountAll(row.Shared) + (value ? ((Humanoid)player).GetInventory().CountItems(row.Shared, -1, true) : 0);
			if (!useEnd)
			{
				return num;
			}
			int end = CountAll(conversion.ToShared) + (value ? ((Humanoid)player).GetInventory().CountItems(conversion.ToShared, -1, true) : 0);
			int fermentingBarrels = FermentIndex.CountBarrels(center, Plugin.Radius.Value, row.Shared);
			return OrderRules.StockUnits(num, end, fermentingBarrels, conversion.Produced, countEnd: true);
		}

		private static void PlayEffect(CraftingStation station)
		{
			//IL_0020: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.PlayEffects.Value)
			{
				return;
			}
			try
			{
				EffectList craftItemDoneEffects = station.m_craftItemDoneEffects;
				if (craftItemDoneEffects != null)
				{
					craftItemDoneEffects.Create(((Component)station).transform.position, Quaternion.identity, ((Component)station).transform, 1f, -1, default(ZDOID));
				}
			}
			catch (Exception)
			{
			}
		}

		private static StationState StateFor(CraftingStation station)
		{
			int instanceID = ((Object)station).GetInstanceID();
			if (!States.TryGetValue(instanceID, out var value))
			{
				value = new StationState();
				States[instanceID] = value;
			}
			return value;
		}

		private static void SetAll(StationState state, int count, CraftStatus status)
		{
			for (int i = 0; i < count && i < state.Orders.Length; i++)
			{
				state.Orders[i] = status;
				state.Detail[i] = null;
				state.Making[i] = false;
			}
		}

		private static void Prune()
		{
			Live.Clear();
			foreach (CraftingStation item in Scratch)
			{
				if ((Object)(object)item != (Object)null)
				{
					Live.Add(((Object)item).GetInstanceID());
				}
			}
			List<int> list = null;
			foreach (int key in States.Keys)
			{
				if (!Live.Contains(key))
				{
					(list ?? (list = new List<int>())).Add(key);
				}
			}
			if (list != null)
			{
				foreach (int item2 in list)
				{
					States.Remove(item2);
				}
			}
			StationJobs.Prune(Live);
		}
	}
	internal static class FermentIndex
	{
		internal struct Conversion
		{
			internal string FromPrefab;

			internal string FromShared;

			internal string ToPrefab;

			internal string ToShared;

			internal int Produced;
		}

		private static readonly Dictionary<string, Conversion> ByFromShared = new Dictionary<string, Conversion>(StringComparer.Ordinal);

		private static readonly List<Conversion> Conversions = new List<Conversion>(16);

		private static readonly List<Fermenter> Live = new List<Fermenter>(16);

		private static bool _built;

		internal static IReadOnlyList<Conversion> All
		{
			get
			{
				EnsureBuilt();
				return Conversions;
			}
		}

		internal static void Register(Fermenter fermenter)
		{
			if ((Object)(object)fermenter != (Object)null && !Live.Contains(fermenter))
			{
				Live.Add(fermenter);
			}
		}

		internal static bool TryGetByShared(string sharedName, out Conversion conversion)
		{
			EnsureBuilt();
			conversion = default(Conversion);
			if (!string.IsNullOrEmpty(sharedName))
			{
				return ByFromShared.TryGetValue(sharedName, out conversion);
			}
			return false;
		}

		internal static void Nearby(Vector3 center, float radius, List<Fermenter> result)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			result.Clear();
			float num = radius * radius;
			for (int num2 = Live.Count - 1; num2 >= 0; num2--)
			{
				Fermenter val = Live[num2];
				if ((Object)(object)val == (Object)null)
				{
					Live.RemoveAt(num2);
				}
				else
				{
					Vector3 val2 = ((Component)val).transform.position - center;
					if (((Vector3)(ref val2)).sqrMagnitude <= num)
					{
						result.Add(val);
					}
				}
			}
		}

		internal static int CountBarrels(Vector3 center, float radius, string sharedName)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			float num = radius * radius;
			int num2 = 0;
			for (int num3 = Live.Count - 1; num3 >= 0; num3--)
			{
				Fermenter val = Live[num3];
				if ((Object)(object)val == (Object)null)
				{
					Live.RemoveAt(num3);
				}
				else
				{
					Vector3 val2 = ((Component)val).transform.position - center;
					if (!(((Vector3)(ref val2)).sqrMagnitude > num))
					{
						try
						{
							if (GameAccess.ContentOf(val) == sharedName)
							{
								num2++;
							}
						}
						catch (Exception)
						{
						}
					}
				}
			}
			return num2;
		}

		private static void EnsureBuilt()
		{
			if (_built)
			{
				return;
			}
			List<ItemConversion> list = null;
			foreach (Fermenter item in Live)
			{
				if ((Object)(object)item != (Object)null && item.m_conversion != null && item.m_conversion.Count > 0)
				{
					list = item.m_conversion;
					break;
				}
			}
			if (list == null && (Object)(object)ZNetScene.instance != (Object)null)
			{
				GameObject prefab = ZNetScene.instance.GetPrefab("fermenter");
				list = ((!((Object)(object)prefab != (Object)null)) ? null : prefab.GetComponent<Fermenter>()?.m_conversion);
			}
			if (list == null || list.Count == 0)
			{
				return;
			}
			foreach (ItemConversion item2 in list)
			{
				string text = item2.m_from?.m_itemData?.m_shared?.m_name;
				string text2 = item2.m_to?.m_itemData?.m_shared?.m_name;
				if (!string.IsNullOrEmpty(text) && !string.IsNullOrEmpty(text2) && !ByFromShared.ContainsKey(text))
				{
					Conversion conversion = new Conversion
					{
						FromPrefab = ((Object)item2.m_from).name,
						FromShared = text,
						ToPrefab = ((Object)item2.m_to).name,
						ToShared = text2,
						Produced = item2.m_producedItems
					};
					ByFromShared[text] = conversion;
					Conversions.Add(conversion);
				}
			}
			_built = ByFromShared.Count > 0;
		}
	}
	internal static class GameAccess
	{
		private static readonly Func<Container, long, bool> CheckAccessImpl = Bind<Func<Container, long, bool>>(typeof(Container), "CheckAccess", new Type[1] { typeof(long) });

		private static readonly FieldInfo ContainerView = AccessTools.Field(typeof(Container), "m_nview");

		private static readonly Func<Container, bool> ContainerLoad = Bind<Func<Container, bool>>(typeof(Container), "Load", Array.Empty<Type>());

		private static readonly FieldInfo StationView = AccessTools.Field(typeof(CraftingStation), "m_nview");

		private static readonly FieldInfo StationList = AccessTools.Field(typeof(CraftingStation), "m_allStations");

		private static readonly Func<Fermenter, string> ContentNameImpl = Bind<Func<Fermenter, string>>(typeof(Fermenter), "GetContentName", Array.Empty<Type>());

		private static readonly FieldInfo FermenterView = AccessTools.Field(typeof(Fermenter), "m_nview");

		private static readonly MethodInfo FermenterStatus = AccessTools.Method(typeof(Fermenter), "GetStatus", (Type[])null, (Type[])null);

		private static readonly Action<Fermenter, long, int, bool> AddItemRpc = Bind<Action<Fermenter, long, int, bool>>(typeof(Fermenter), "RPC_AddItem", new Type[3]
		{
			typeof(long),
			typeof(int),
			typeof(bool)
		});

		internal const int BarrelEmpty = 0;

		internal const int BarrelReady = 3;

		internal static bool FermenterReady
		{
			get
			{
				if (ContentNameImpl != null && FermenterView != null && FermenterView.FieldType == typeof(ZNetView) && FermenterStatus != null)
				{
					return AddItemRpc != null;
				}
				return false;
			}
		}

		internal static bool Ready
		{
			get
			{
				if (CheckAccessImpl != null && ContainerView != null && ContainerView.FieldType == typeof(ZNetView) && StationView != null && StationView.FieldType == typeof(ZNetView) && StationList != null)
				{
					return StationList.FieldType == typeof(List<CraftingStation>);
				}
				return false;
			}
		}

		internal static List<CraftingStation> Stations => StationList?.GetValue(null) as List<CraftingStation>;

		internal static bool CheckAccess(Container container, long playerId)
		{
			if (CheckAccessImpl == null)
			{
				return false;
			}
			try
			{
				return CheckAccessImpl(container, playerId);
			}
			catch (Exception)
			{
				return false;
			}
		}

		internal static ZNetView NetViewOf(Container container)
		{
			object? obj = ContainerView?.GetValue(container);
			return (ZNetView)((obj is ZNetView) ? obj : null);
		}

		internal static void RefreshContainer(Container container)
		{
			try
			{
				ContainerLoad?.Invoke(container);
			}
			catch (Exception)
			{
			}
		}

		internal static ZNetView NetViewOf(CraftingStation station)
		{
			object? obj = StationView?.GetValue(station);
			return (ZNetView)((obj is ZNetView) ? obj : null);
		}

		internal static string ContentOf(Fermenter fermenter)
		{
			return ContentNameImpl?.Invoke(fermenter);
		}

		internal static ZNetView NetViewOf(Fermenter fermenter)
		{
			object? obj = FermenterView?.GetValue(fermenter);
			return (ZNetView)((obj is ZNetView) ? obj : null);
		}

		internal static int StatusOf(Fermenter fermenter)
		{
			try
			{
				return (FermenterStatus == null) ? (-1) : Convert.ToInt32(FermenterStatus.Invoke(fermenter, null));
			}
			catch (Exception)
			{
				return -1;
			}
		}

		internal static void AddToBarrel(Fermenter fermenter, string itemPrefab)
		{
			AddItemRpc?.Invoke(fermenter, 0L, StringExtensionMethods.GetStableHashCode(itemPrefab), arg4: false);
		}

		internal static bool EmptyBarrel(Fermenter fermenter)
		{
			ZNetView val = NetViewOf(fermenter);
			if ((Object)(object)val == (Object)null || !val.IsValid())
			{
				return false;
			}
			ZDO zDO = val.GetZDO();
			zDO.Set(ZDOVars.s_content, 0, false);
			zDO.Set(ZDOVars.s_startTime, 0, false);
			zDO.Set(ZDOVars.s_cheatedQueued, false);
			return true;
		}

		private static T Bind<T>(Type owner, string name, params Type[] args) where T : class
		{
			MethodInfo methodInfo = AccessTools.Method(owner, name, args, (Type[])null);
			if (!(methodInfo == null))
			{
				return (T)(object)Delegate.CreateDelegate(typeof(T), methodInfo);
			}
			return null;
		}
	}
	internal static class Hud
	{
		private static int _blockUntilFrame = -1;

		internal static bool Available { get; set; }

		internal static bool IsOpen { get; private set; }

		internal static HudWindow Window { get; set; }

		internal static bool Blocking
		{
			get
			{
				if (!IsOpen)
				{
					return Time.frameCount <= _blockUntilFrame;
				}
				return true;
			}
		}

		internal static void Open(CraftingStation station)
		{
			if (!Available || (Object)(object)Window == (Object)null || IsOpen)
			{
				return;
			}
			IsOpen = true;
			try
			{
				Window.OnOpened(station);
				((Behaviour)Window).enabled = true;
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"The HUD could not open: {arg}");
				Close();
			}
		}

		internal static void Close()
		{
			if (IsOpen)
			{
				IsOpen = false;
				_blockUntilFrame = Time.frameCount + 1;
				if ((Object)(object)Window != (Object)null)
				{
					((Behaviour)Window).enabled = false;
				}
			}
		}
	}
	internal static class HudStyle
	{
		internal static readonly Color Gold = new Color(1f, 0.72f, 0.36f, 1f);

		internal static readonly Color GoldBright = new Color(1f, 0.84f, 0.35f, 1f);

		internal static readonly Color Body = new Color(0.93f, 0.89f, 0.8f, 1f);

		internal static readonly Color Dim = new Color(0.72f, 0.64f, 0.52f, 1f);

		internal static readonly Color Orange = new Color(1f, 0.65f, 0.16f, 1f);

		internal static GUIStyle Label;

		internal static GUIStyle Notice;

		internal static GUIStyle Small;

		internal static GUIStyle Heading;

		internal static GUIStyle Title;

		internal static GUIStyle TitleFallback;

		internal static GUIStyle Center;

		internal static GUIStyle Wrap;

		internal static GUIStyle Plain;

		internal static GUIStyle PlainRight;

		internal static GUIStyle PlainSmall;

		internal static GUIStyle Button;

		internal static GUIStyle TabOn;

		internal static GUIStyle Slot;

		internal static GUIStyle SlotOn;

		internal static GUIStyle Field;

		internal static GUIStyle Row;

		internal static GUISkin Skin;

		private static Texture2D _wood;

		private static Texture2D _stud;

		private static Texture2D _lock;

		private static Font _body;

		private static Font _title;

		private static bool _ready;

		private static readonly Dictionary<Sprite, Rect> IconRects = new Dictionary<Sprite, Rect>();

		private static readonly Dictionary<string, bool> TitleFits = new Dictionary<string, bool>();

		internal static Texture2D LockIcon
		{
			get
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)_lock != (Object)null))
				{
					return _lock = Load("lock", new Color(0.9f, 0.7f, 0.3f, 1f));
				}
				return _lock;
			}
		}

		internal static void Ensure()
		{
			if (!_ready)
			{
				_ready = true;
				try
				{
					Build();
				}
				catch (Exception arg)
				{
					Plugin.Log.LogError((object)$"Could not build the HUD's Valheim look; using plain styles. {arg}");
				}
				FillMissing();
			}
		}

		private static void FillMissing()
		{
			//IL_0013: 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_004d: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			Label = (GUIStyle)(((object)Label) ?? ((object)new GUIStyle(GUI.skin.label)));
			Notice = (GUIStyle)(((object)Notice) ?? ((object)new GUIStyle(GUI.skin.label)));
			Small = (GUIStyle)(((object)Small) ?? ((object)new GUIStyle(GUI.skin.label)));
			Heading = (GUIStyle)(((object)Heading) ?? ((object)new GUIStyle(GUI.skin.label)));
			Title = (GUIStyle)(((object)Title) ?? ((object)new GUIStyle(GUI.skin.label)
			{
				alignment = (TextAnchor)4,
				fontSize = 28
			}));
			TitleFallback = TitleFallback ?? Title;
			Center = (GUIStyle)(((object)Center) ?? ((object)new GUIStyle(GUI.skin.label)
			{
				alignment = (TextAnchor)4
			}));
			Wrap = (GUIStyle)(((object)Wrap) ?? ((object)new GUIStyle(GUI.skin.label)
			{
				wordWrap = true
			}));
			Plain = (GUIStyle)(((object)Plain) ?? ((object)new GUIStyle(GUI.skin.label)));
			PlainRight = (GUIStyle)(((object)PlainRight) ?? ((object)new GUIStyle(GUI.skin.label)
			{
				alignment = (TextAnchor)5
			}));
			PlainSmall = (GUIStyle)(((object)PlainSmall) ?? ((object)new GUIStyle(GUI.skin.label)
			{
				fontSize = 14
			}));
			Button = (GUIStyle)(((object)Button) ?? ((object)new GUIStyle(GUI.skin.button)));
			TabOn = (GUIStyle)(((object)TabOn) ?? ((object)new GUIStyle(GUI.skin.button)
			{
				fontStyle = (FontStyle)1
			}));
			Slot = (GUIStyle)(((object)Slot) ?? ((object)new GUIStyle(GUI.skin.box)));
			SlotOn = (GUIStyle)(((object)SlotOn) ?? ((object)new GUIStyle(GUI.skin.box)));
			Field = (GUIStyle)(((object)Field) ?? ((object)new GUIStyle(GUI.skin.textField)));
			Row = (GUIStyle)(((object)Row) ?? ((object)new GUIStyle(GUI.skin.button)));
			Skin = (((Object)(object)Skin != (Object)null) ? Skin : GUI.skin);
		}

		private static void Build()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Expected O, but got Unknown
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Expected O, but got Unknown
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Expected O, but got Unknown
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Expected O, but got Unknown
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ac: Expected O, but got Unknown
			//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Expected O, but got Unknown
			//IL_03c0: Expected O, but got Unknown
			//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0401: Expected O, but got Unknown
			//IL_0424: Unknown result type (might be due to invalid IL or missing references)
			//IL_0444: Unknown result type (might be due to invalid IL or missing references)
			//IL_0477: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ed: Expected O, but got Unknown
			//IL_04f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0502: Expected O, but got Unknown
			//IL_050c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0511: Unknown result type (might be due to invalid IL or missing references)
			//IL_0516: Unknown result type (might be due to invalid IL or missing references)
			//IL_0520: Expected O, but got Unknown
			//IL_0525: Expected O, but got Unknown
			//IL_0553: Unknown result type (might be due to invalid IL or missing references)
			//IL_0580: Unknown result type (might be due to invalid IL or missing references)
			FindFonts();
			_wood = Load("wood", new Color(0.42f, 0.29f, 0.19f, 1f));
			_stud = Load("stud", new Color(0.5f, 0.36f, 0.24f, 1f));
			Label = Make(GUI.skin.label, _body, 16, Body, (TextAnchor)3);
			Notice = Make(GUI.skin.label, _body, 16, Gold, (TextAnchor)3);
			Small = Make(GUI.skin.label, _body, 13, Dim, (TextAnchor)3);
			Heading = Make(GUI.skin.label, _body, 20, Gold, (TextAnchor)3);
			Title = Make(GUI.skin.label, ((Object)(object)_title != (Object)null) ? _title : _body, 30, Gold, (TextAnchor)4);
			TitleFallback = Make(GUI.skin.label, _body, 28, Gold, (TextAnchor)4);
			Center = Make(GUI.skin.label, _body, 16, Body, (TextAnchor)4);
			Plain = Make(GUI.skin.label, _body, 16, Color.white, (TextAnchor)3);
			PlainRight = Make(GUI.skin.label, _body, 16, Color.white, (TextAnchor)5);
			PlainSmall = Make(GUI.skin.label, _body, 14, Color.white, (TextAnchor)3);
			Wrap = Make(GUI.skin.label, _body, 16, Body, (TextAnchor)0);
			Wrap.wordWrap = true;
			Button = Make(GUI.skin.button, _body, 16, Body, (TextAnchor)4);
			Button.normal.background = Load("button", new Color(0.2f, 0.19f, 0.18f, 1f));
			Button.hover.background = Load("button_hover", new Color(0.3f, 0.28f, 0.24f, 1f));
			Button.active.background = Load("button_active", new Color(0.12f, 0.11f, 0.1f, 1f));
			Button.focused.background = Button.normal.background;
			Button.hover.textColor = GoldBright;
			Button.active.textColor = Gold;
			Button.border = new RectOffset(12, 12, 12, 12);
			Button.padding = new RectOffset(10, 10, 4, 4);
			TabOn = new GUIStyle(Button);
			TabOn.normal.background = Button.hover.background;
			TabOn.normal.textColor = GoldBright;
			TabOn.focused.background = Button.hover.background;
			TabOn.focused.textColor = GoldBright;
			Slot = new GUIStyle(GUI.skin.box)
			{
				border = new RectOffset(14, 14, 14, 14),
				margin = new RectOffset(0, 0, 0, 0),
				padding = new RectOffset(0, 0, 0, 0)
			};
			Slot.normal.background = Load("slot", new Color(0.28f, 0.19f, 0.12f, 0.9f));
			SlotOn = new GUIStyle(Slot);
			SlotOn.normal.background = Load("slot_selected", new Color(0.4f, 0.28f, 0.15f, 0.95f));
			Field = Make(GUI.skin.textField, _body, 16, Body, (TextAnchor)3);
			Field.normal.background = Load("field", new Color(0.13f, 0.09f, 0.07f, 1f));
			Field.focused.background = Field.normal.background;
			Field.hover.background = Field.normal.background;
			Field.focused.textColor = GoldBright;
			Field.border = new RectOffset(14, 14, 14, 14);
			Field.padding = new RectOffset(10, 10, 4, 4);
			Row = new GUIStyle(GUI.skin.button)
			{
				border = new RectOffset(0, 0, 0, 0)
			};
			Row.normal.background = null;
			Row.hover.background = Flat(new Color(1f, 0.85f, 0.5f, 0.1f));
			Row.active.background = Flat(new Color(1f, 0.85f, 0.5f, 0.2f));
			Row.focused.background = null;
			BuildSkin();
		}

		internal static void Fill(Rect rect, Color color)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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)
			if ((int)Event.current.type == 7)
			{
				Color color2 = GUI.color;
				GUI.color = color;
				GUI.DrawTexture(rect, (Texture)(object)Texture2D.whiteTexture);
				GUI.color = color2;
			}
		}

		internal static void Border(Rect rect, Color color, float thickness = 2f)
		{
			//IL_0016: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			Fill(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width, thickness), color);
			Fill(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).yMax - thickness, ((Rect)(ref rect)).width, thickness), color);
			Fill(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, thickness, ((Rect)(ref rect)).height), color);
			Fill(new Rect(((Rect)(ref rect)).xMax - thickness, ((Rect)(ref rect)).y, thickness, ((Rect)(ref rect)).height), color);
		}

		internal static void Frame(Rect rect)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			if ((int)Event.current.type == 7)
			{
				if ((Object)(object)_wood != (Object)null)
				{
					GUI.DrawTexture(rect, (Texture)(object)_wood, (ScaleMode)0);
				}
				else
				{
					Fill(rect, new Color(0.42f, 0.29f, 0.19f, 1f));
				}
				Border(rect, new Color(0.05f, 0.03f, 0.02f, 1f), 3f);
				Border(Inset(rect, 3f), new Color(0.23f, 0.15f, 0.09f, 1f), 7f);
				Border(Inset(rect, 10f), new Color(0.59f, 0.42f, 0.27f, 1f), 1f);
				Border(Inset(rect, 11f), new Color(0.13f, 0.09f, 0.055f, 1f), 1f);
				DrawStud(((Rect)(ref rect)).x + 11f, ((Rect)(ref rect)).y + 11f);
				DrawStud(((Rect)(ref rect)).xMax - 11f, ((Rect)(ref rect)).y + 11f);
				DrawStud(((Rect)(ref rect)).x + 11f, ((Rect)(ref rect)).yMax - 11f);
				DrawStud(((Rect)(ref rect)).xMax - 11f, ((Rect)(ref rect)).yMax - 11f);
			}
		}

		internal static void Divider(float left, float right, float y)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			if ((int)Event.current.type == 7)
			{
				float num = (left + right) / 2f;
				Color color = default(Color);
				((Color)(ref color))..ctor(0.1f, 0.055f, 0.03f, 1f);
				Color color2 = default(Color);
				((Color)(ref color2))..ctor(0.72f, 0.53f, 0.29f, 1f);
				Fill(new Rect(left, y, num - 14f - left, 3f), color);
				Fill(new Rect(left, y - 1f, num - 14f - left, 1f), color2);
				Fill(new Rect(num + 14f, y, right - num - 14f, 3f), color);
				Fill(new Rect(num + 14f, y - 1f, right - num - 14f, 1f), color2);
				Matrix4x4 matrix = GUI.matrix;
				GUIUtility.RotateAroundPivot(45f, new Vector2(num, y + 1f));
				Fill(new Rect(num - 5f, y - 4f, 10f, 10f), color);
				Fill(new Rect(num - 4f, y - 3f, 8f, 8f), color2);
				GUI.matrix = matrix;
			}
		}

		internal static void Shadowed(Rect rect, string text, GUIStyle style)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			Color contentColor = GUI.contentColor;
			GUI.contentColor = new Color(0f, 0f, 0f, 0.75f * contentColor.a);
			GUI.Label(new Rect(((Rect)(ref rect)).x + 1f, ((Rect)(ref rect)).y + 1.5f, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height), text, style);
			GUI.contentColor = contentColor;
			GUI.Label(rect, text, style);
		}

		internal static void DrawTitle(Rect rect, string text)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			if (!TitleFits.TryGetValue(text, out var value))
			{
				value = (Object)(object)_title != (Object)null;
				int num = 0;
				while (value && num < text.Length)
				{
					value = text[num] == ' ' || _title.HasCharacter(text[num]);
					num++;
				}
				TitleFits[text] = value;
			}
			Shadowed(rect, text, value ? Title : TitleFallback);
		}

		internal static void SlotIcon(Rect rect, Sprite sprite)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			GUI.Box(rect, GUIContent.none, Slot);
			Icon(new Rect(((Rect)(ref rect)).x + 3f, ((Rect)(ref rect)).y + 3f, ((Rect)(ref rect)).width - 6f, ((Rect)(ref rect)).height - 6f), sprite);
		}

		internal static void Icon(Rect rect, Sprite sprite)
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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_0022: Invalid comparison between Unknown and I4
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_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)
			if ((Object)(object)sprite == (Object)null || (Object)(object)sprite.texture == (Object)null || (int)Event.current.type != 7)
			{
				return;
			}
			if (!IconRects.TryGetValue(sprite, out var value))
			{
				try
				{
					Rect textureRect = sprite.textureRect;
					Texture2D texture = sprite.texture;
					value = new Rect(((Rect)(ref textureRect)).x / (float)((Texture)texture).width, ((Rect)(ref textureRect)).y / (float)((Texture)texture).height, ((Rect)(ref textureRect)).width / (float)((Texture)texture).width, ((Rect)(ref textureRect)).height / (float)((Texture)texture).height);
				}
				catch (Exception)
				{
					value = Rect.zero;
				}
				IconRects[sprite] = value;
			}
			if (((Rect)(ref value)).width > 0f)
			{
				GUI.DrawTextureWithTexCoords(rect, (Texture)(object)sprite.texture, value);
			}
		}

		internal static Color WithAlpha(Color color, float alpha)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			return new Color(color.r, color.g, color.b, alpha);
		}

		private static Rect Inset(Rect rect, float by)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			return new Rect(((Rect)(ref rect)).x + by, ((Rect)(ref rect)).y + by, ((Rect)(ref rect)).width - 2f * by, ((Rect)(ref rect)).height - 2f * by);
		}

		private static void DrawStud(float x, float y)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_stud != (Object)null)
			{
				GUI.DrawTexture(new Rect(x - 8f, y - 8f, 16f, 16f), (Texture)(object)_stud);
			}
		}

		private static GUIStyle Make(GUIStyle basis, Font font, int size, Color color, TextAnchor anchor)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			GUIStyle val = new GUIStyle(basis)
			{
				font = font,
				fontSize = size,
				alignment = anchor,
				wordWrap = false,
				clipping = (TextClipping)1,
				richText = false
			};
			val.normal.textColor = color;
			val.hover.textColor = color;
			val.active.textColor = color;
			val.focused.textColor = color;
			return val;
		}

		private static void BuildSkin()
		{
			//IL_0034: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Expected O, but got Unknown
			Skin = Object.Instantiate<GUISkin>(GUI.skin);
			((Object)Skin).hideFlags = (HideFlags)61;
			Texture2D texture = Load("scroll_track", new Color(0.1f, 0.07f, 0.05f, 0.8f));
			Texture2D texture2 = Load("scroll_thumb", new Color(0.6f, 0.43f, 0.21f, 1f));
			Skin.verticalScrollbar = Bar(Skin.verticalScrollbar, texture, new RectOffset(5, 5, 5, 5));
			Skin.verticalScrollbarThumb = Bar(Skin.verticalScrollbarThumb, texture2, new RectOffset(5, 5, 6, 6));
			Skin.horizontalScrollbar = Bar(Skin.horizontalScrollbar, texture, new RectOffset(5, 5, 5, 5));
			Skin.horizontalScrollbarThumb = Bar(Skin.horizontalScrollbarThumb, texture2, new RectOffset(6, 6, 5, 5));
			Skin.verticalScrollbarUpButton = Hidden(Skin.verticalScrollbarUpButton);
			Skin.verticalScrollbarDownButton = Hidden(Skin.verticalScrollbarDownButton);
			Skin.horizontalScrollbarLeftButton = Hidden(Skin.horizontalScrollbarLeftButton);
			Skin.horizontalScrollbarRightButton = Hidden(Skin.horizontalScrollbarRightButton);
		}

		private static GUIStyle Bar(GUIStyle basis, Texture2D texture, RectOffset border)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//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_003a: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			GUIStyle val = new GUIStyle(basis)
			{
				border = border,
				margin = new RectOffset(0, 0, 0, 0),
				padding = new RectOffset(0, 0, 0, 0),
				overflow = new RectOffset(0, 0, 0, 0)
			};
			val.normal.background = texture;
			val.hover.background = texture;
			val.active.background = texture;
			val.focused.background = texture;
			return val;
		}

		private static GUIStyle Hidden(GUIStyle basis)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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)
			//IL_001c: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			GUIStyle val = new GUIStyle(basis)
			{
				fixedWidth = 0f,
				fixedHeight = 0f
			};
			val.normal.background = null;
			val.hover.background = null;
			val.active.background = null;
			val.focused.background = null;
			return val;
		}

		private static Texture2D Flat(Color color)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false)
			{
				hideFlags = (HideFlags)61
			};
			val.SetPixel(0, 0, color);
			val.Apply();
			return val;
		}

		private static Texture2D Load(string name, Color fallback)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (HudTextures.Base64.TryGetValue(name, out var value))
				{
					Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false)
					{
						hideFlags = (HideFlags)61
					};
					if (ImageConversion.LoadImage(val, Convert.FromBase64String(value)))
					{
						((Texture)val).filterMode = (FilterMode)1;
						((Texture)val).wrapMode = (TextureWrapMode)1;
						return val;
					}
					Object.Destroy((Object)(object)val);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("HUD texture '" + name + "' could not be decoded (" + ex.Message + "); using a flat colour."));
			}
			return Flat(fallback);
		}

		private static void FindFonts()
		{
			try
			{
				Font[] array = Resources.FindObjectsOfTypeAll<Font>();
				StringBuilder stringBuilder = new StringBuilder();
				Font[] array2 = array;
				foreach (Font val in array2)
				{
					if ((Object)(object)val != (Object)null)
					{
						stringBuilder.Append(((Object)val).name).Append(val.dynamic ? string.Empty : " (static)").Append("; ");
					}
				}
				_body = Pick(array, "AveriaSerif", "Regular", null) ?? Pick(array, "AveriaSerif", null, null);
				_title = Pick(array, null, null, "Norse") ?? Pick(array, "Norse", null, null);
				Plugin.Log.LogInfo((object)string.Format("HUD fonts: text = {0}, title = {1} (fonts in the game: {2})", ((Object)(object)_body != (Object)null) ? ((Object)_body).name : "default", ((Object)(object)_title != (Object)null) ? ((Object)_title).name : "default", stringBuilder));
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Could not look for the game's fonts (" + ex.Message + "); the HUD uses the default font."));
			}
		}

		private static Font Pick(Font[] fonts, string contains, string and, string exact)
		{
			foreach (Font val in fonts)
			{
				if ((Object)(object)val == (Object)null || !val.dynamic)
				{
					continue;
				}
				string name = ((Object)val).name;
				bool num;
				if (exact == null)
				{
					if (name.IndexOf(contains, StringComparison.OrdinalIgnoreCase) < 0)
					{
						continue;
					}
					if (and == null)
					{
						goto IL_0053;
					}
					num = name.IndexOf(and, StringComparison.OrdinalIgnoreCase) >= 0;
				}
				else
				{
					num = string.Equals(name, exact, StringComparison.OrdinalIgnoreCase);
				}
				if (!num)
				{
					continue;
				}
				goto IL_0053;
				IL_0053:
				if (val.HasCharacter('A') && val.HasCharacter('a'))
				{
					return val;
				}
			}
			return null;
		}
	}
	internal static class HudTextures
	{
		internal static readonly Dictionary<string, string> Base64 = new Dictionary<string, string>
		{
			{
				"wood",
				"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAQDAwQDAwQEBAQFBQQFBwsHBwYGBw4KCggLEA4RERAOEA8SFBoWEhMYEw8QFh8XGBsbHR0dERYgIh8cIhocHRz/" + "2wBDAQUFBQcGBw0HBw0cEhASHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBwcHBz/wAARCAGAAgADASIAAhEBAxEB/8QA" + "GwAAAgMBAQEAAAAAAAAAAAAAAQMAAgQFBgf/xABEEAABAwEEBwYDBgMHBQEBAQABAAIRAwQTITESFEFRYXGRIjJCUoGhU2KSBRUjM0NyorHRNFRjgsHw8SRE" + "c6PhwpOy/8QAFwEBAQEBAAAAAAAAAAAAAAAAAAECBf/EAB0RAQEBAQEBAQEBAQAAAAAAAAARARIhAoFhE1H/2gAMAwEAAhEDEQA/APg9247lLp/DotrKzfIm" + "ioyO6FxK7cc66ds/kpcvygLph4HhCEtjuiEpHMuncEbpw3dF0tNow0RCmkzLRCUjmmi4ZgdEBSO4LphzT4BG5AlpBGgnRHNunDd0Quzw6Lp9k+EIQ0+AJ0Ry" + "7ojdCl3xELpaLc9HFAsYY7KdEc00+IQ0IIxGK6RpMnuqtyzyq9JHO0WgDJTRAM4LeaDMOyhq7PKlIwQ3eFOydoW7V2HwKpsrCO7klIydneMUZbvC1arT8vQI" + "apT3K0jMCydiOkzdKfqjBsy4KaoyCYUpCNJm1HSZGWKcbI0bFNVbiYS4QrSZuRDqe73TDZWg4AqCzN/2EuEU0meUKBzJy91cWYQcPZS4H+wgrpM8qmmwDuq5" + "oAbPZDVwN8oRXSp+QKabD4fdW1cTGPRTV/8AcIKabB4FXTZ5PdM1cGf6I6tP/CBJeweEIaTMOx7p+qjbPRTVMcvZLhGfSZnoe6ks8i1CxDjHJWFiE7eiXCMg" + "DPIMFYBnlC2NsTTvjkrixDHPmnSxhAp+UIgM8oW0WJuSOptzgqUjFDPKFOxE6IxWw2MHCOCOpNJyPJKRj7HlCnYwGi1a9TbxnYobG0bMskuEZOx5WqnYGQat" + "psLTiMUt1hAAgFLiRmBZ8uCsHU97YV3WIbilmyBuw+ivgc19LaWprLo7WrCbPByMKwpQMj1SDotZSO1qNzRJzasAp8J9U1rAN/VSK1Gy0jGLVU2Kjh2mqgaM" + "oKu2nIwnnKihqNEzLmqajRMYtVjSGwTv4oikNuKUiuoUfMzoh930cBpNmNyvc4yR7qXIyj0SkUH2fRA7zOih+z6Mg6TFc0x/sqXAlLpFfu6jPeZ0QNgoAd5n" + "JXugAd/NJewY7kukZ212z3nJzbQ2D2ndFzW1jEaLuiY2sfK7otRnNdQV2kd908lL5uem7osLa+zRdOeSYKxIHZdjjEKRqtd6Ce8eiF62J0neoxWc1Tsa7ope" + "k+FwPEKQrQao8zpUNVuek7okXxjuOnkpemO64eiQrQKrZjTcoajZgOd0SBVPld0UvjMlro5JCn3gx7R5wppCO+eiSKpnuu6I3xE9l0ngkDS/Hvn0RkRGkY3Q" + "lCrA7ruiN7hkUFpgYucph5jzjBC9+Uo3pwwd0RRicZKEA5uOKOnsg4I6ZwwKCujvcZ3qaGeJ4Sr6W4FGYGRUIXobST0R0BPe9U6dwUA4GUpCtATmjdjMZJwG" + "xHR/2UpCLps4fyRFNkHKFoDOSN1uI5KVYz3TSpdMOwYrTdDeMOKNyJxI6pSMwpU84CgpU5mAtVwN4KOrjzDqlIy3VOMgEbqkdgPVabgDGR1RFAeYJSMtzTIy" + "CsKNMnAD3WgUB5hjvKlyN46qUhF1TBiAiKNMEGB1Trpo2j0Q0BPeGHFKRQUaY2CEbmnOz0ViABmI5qsgbfdBNBkHJS6YVQuA2+6GmBtQXDGzsgKpYzgqGrsB" + "IVTVBkqhpY3fgpoN2kckm+EQpfAb0DTTaRifVQ0gTmlX43lWFYSM09FzTbv9kTREZ4jgqC0AjEFMFduXa6J6FmgDOMJbrNgTK1Cq0nxyeCuHsw73RLpHMdZf" + "mSXWf5iuwbs5aXRAsYZ73RXpOXDNEjHSVdEgzpGF2jSZE9vnCU6g3MB08lek5crScMNM9FYVSDOmei3us7SfF0VHUWjDt9FaRlvj55UNYjxHonmk3YHRyQum" + "CO/HJCEX5nvn0UNYjxmE+6acBp+gUumYDt9E8IRfHa8oG0EeMwnuYwDJ/RKLGfP0RCXWgz3ykutBx7ZT3Nbie30SXMZj3ui1kQttH5T1TmUTsaeq0Nszoz6J" + "jbM47U3TMIbRPl901tAz3Z9VqbZnb01tkJGfusbrWYyihJ7pjmjq58p6lb22V2U8U0WJ2Pa4rPTXLliz5y048UbiPCeq6epHKZKGovk9r3To5c3V+B6qavjG" + "ieq6OouxGlwQNgdiZTo5YLgEDA9VBRA2Hqt5sD5ifdVNgeT3vdOiMlwNx3ZqXDdx6rVqDzk6UPu+pAMlKRnum7jPNWFJmWM8037vqebih931POOqXP8ApFTR" + "ZxHqiKbMseqJ+z6g8fuq6jVI72SUi13T4o3VPiqahUPizQ1GoPFHqn6GFlPijo0wNvVK1KpPexKGpvB7x6p4HBtLe7qjFPIl3VINkd55Q1V2PbKDR+H5j1UF" + "1vcs+rHzFQ2ePGUGgGmNrlJpx3nQVmNEA4uOCl02e8UGiaQnF0KF9Ke85ZtBmHaKmgzzlINOnS3u9UC+mcy7BZtCnPedkho0stIqwaS5mB0nHahp04Hacs+j" + "SA7xULaU5uSB5fTJ7zlXTZvckaNIeIqFtLzOQOlhHedG9VOjlpOStGmfE5QMp4dpyqGENjvOQhu9ypoUye85TQYBgSgvosM4uKGg3A9pC7Z5ioGN8xQHQbtc" + "5Q0mnzKaLRhpFDQaMZcguKY2aSF005FyqWNHicpojHEoGXYI8Su2mNukklrfMVA0eYiEGlrRGOl1TGtB2ujmsgEeJysIHiKkVtaxsgglNbSbEy6eK57SB4im" + "NcB4jHNZit4otIjtdVY2ZvzdViFQR3imNqt8xgbFJqtOpMJ8SGoNPmlKFZuGJxTBWp4DSMc81PTwfu5p8xHND7sbnj1V7+nvII4qwrMmZKXSYV92NnGYneg7" + "7OYPNKca1MR2j/qlPtFM7TCXTwh32e3YSku+z2b3TzT3WimMyYSH2hmGJ6rWVnYS+wN4pJsLePVOdXYR3j6JD67N7lvKzsUY1uWPVOY1uGLkptWlKeytRj+q" + "amGsY3MF3VObTbO3Hiktq0Yn/RPZVokLOt4a2m0Zl0801rGHMu6qlOrQjEJzatnz2rGtYGi3DEyeKgptIiSmXlCfZS8oyTtUUu7AHi3ZoGm3e5N06GSP4EgZ" + "qhJpjzE+qpoN3u6rVNEkbJ2qaNAnMJSM4pjDtOkcVXQHmd1Wssok58oUuqB24nZKUjHdDES7qgacHAu6rdq9GUdWoSNiUjnmmI7zuGKBpDe7kuibJRwR1WkM" + "56J0RzLoeY4cULob3bl1DY6OJO9TUqWUp0RyrkZaTsOKrdbJdPNdbUqc4GUdSpgZ4c06OXINHaNKVDQx29V19RZGGKGos28k6OXHuMs0NWjzLtakwTxQNkaB" + "kr0cuNq0+FyqbNl2XLtGyNAwI/moLKIMCU6TlxDZcO6VNV+V0rt6ttU1accE6OXENlzlruqmqb2uwwXa1eDkIU1ciZEp0cuLqu9hU1SPAV29XIOWags5iYEl" + "OjlxdUA8J4I6pua5doUDGQUuXCDEp0cuLqg8h6qCyie4V220XSYaI4I3RjZBTo5cXVMO4ZR1YROgV2jSd5UDTIPdU6Xlx9Vx/LhS4GH4ZXY0HbBBCl27Hsp0" + "cuQKA8iGr5yxdi7LY7GKhaZHZkp0cuQbOMRoYqCiB4M119Ez3cFAwk5GeidEcg0YyYDsUu4/TldW7MHA5IimZGDpTojk6I+GOqroCe4MV2DQg4zxUNCd/snR" + "HIhsdwIQNrAV2BZhIzUdZRu2bE6OXI02iOwPRQPG1g6rrmyNOJnFTVGjHH0TrCa5F7B7jfVC/gdxvVdgWJhEy5DUWbyJTrCa5QtGE6DcOKOsZdhs811BYGRm" + "6diBsDJIkp1hNcl1ogdwJbrRI7gC7LrDTzkpL7EzeVc+sTc1xnVx5QlOrgT2BGxdh1jp+Y+yQ6x0wMzC1n1jG5rkOrjytSXV48AXXfY2ARJJSH2VmUkLWbjO" + "5rkso1YyKcylVGw9UG2sGME5trGwLW1MRtGsBkeqc2jVEYHqoy2AnJObbBgYCztayIKNWMiE5tGtE44bZQbbBAwTRawZwwWdrWKGlVAmCeSoDVEE06nRaNcE" + "ZKa2CMk9UgPrAflVOil5WH6dVP1mdg5qGvO7BAk1qvw6sclYV6szd1Y24K96Dl/NA1DESPVQVFpqzjSqSOCItlUfp1IjcrFxIPa90MTtHVU9HXKsTd1cd4RF" + "uqgwKdToqFhOZHVTQcfEFJh6YPtCptp1PpR+8qo/Tqc9FJFF898dULl/nHVJh60D7TqfDqdFB9p1MPw6mHyrPcP8zeqmr1BHaE80mF1qH2pUk/h1YPyo/elW" + "fy6n0rJcPzLh1RNB4HfHVJhdax9qVPh1I/Yp96Pj8t/0LGKL/MOqN2/zjqkxbrYftKoThSqY/Ip951dlOrBw7qyCm8eIGOKga8Rj1Kkwut33k/4VX6FPvCoc" + "bqpP7FiAfvy4ogvG3hmkwutv3hUj8upj8imv1CZuqmPyLEXu3+6mm/DdzSYV0adqqPk6DhwLVe/qQcD9K5oqPnnxUvXf8lTla6YrVP8AXuoivU3fwrmCq4bf" + "dWFZ2OfVOSule1IMDD9qhq1ccNvlXOvnbY6qwru3+6cldEVa20YclLytO8TlC5987hPNXFVwBn+akK26dY5ZzuQD604RzhZRWcTj/NHTceI5pCtGnX5cghp1" + "yCP9EkOdnt5oguAmB1SKaXVwZETyQ0rQTs6JcO3e6JDpzQWD7RGxAvr7hCF27aAf9FWDv90Rc1LRwH+qAqV5GSW4HhPNVcHDOMOKsDr60ZSBsQv68YEQs5mN" + "nOVQzOw4b0hWp1prDaJCGs1hgCFjIPD1KoWuG5WJW02ythiI5quuVYI0gsZpEnYhcE7AfUpMLrYbdWykIa/WwxasmrkjITzVtUJIJA6qzC60feFbeFXX6uA0" + "hHNJFjkDATKLbFOejPqpMPV32+qfE3qkvt1beOqu6xDcPdKdYc8ArkTaU+21Y7zZSXWyrJlw6pz7CDsHVJdYgdg6reRnaS62Vd4SXWyqRi4cMU91iHCOCS6x" + "gDILWRjaU0tH6YTRoYTTBSmip5QmtvB4RCaGsDI/KCc0NJ/LCW0VRk1NZe+ULOtYY0Nw/CATm6OV0IVG3g8ITW3sd0LOtYEMMfhjehDR+mEyKk90I/iT3QOS" + "ilQ34YCEA/piU78WMgjD9rQBuSjOWjE3YULe13BitI0iY0QoA8jFoSjLoHYwIFjj4Frhxw0RCIDgD2cFaRiuz5MkDTdGDVuGljgEZJHd90pHPu3bkLp+7/6u" + "lhu9FYaInDNTojl3NQbEBRqZ7F1ezOSPZ8uKdEcoWeqdhhQWeo44BdaWZaPHBWBZ5U6I4+q1SMFbVKpC7ALJ7phHSp7inWnLjix1DyRFiqGMV2g6nu9EQ+nh" + "gYMKdavOOKLBVO1WFgqj/hdrTo7iSrXlLaDG5OtOccP7uqzngiPs+pv9l2y+kDlhvRFSkZEQU605xwx9nVYOOHJT7vq44ru3tPHsmULylOAyU71eccM/Z9WM" + "DggbDVyK7wdSgYKrqlM4wU71OccLUqoyKBs1YHPku4X0oiD6KjjSB7qvWnOOKaNUb+iOhV2rql1Mz2eOaoXUxgGhXojnTWbwCOnWGWC2ucwDJLL2TMbEqM99" + "V2hEWmsmGo2cuqF43cEFTaqoxRNsrTMKGq2ch1UFRuxreqAG2VjOGKGuVtwjYiajY7oUDwT3W9UCza62WxVNqrnf1WgPB8LVYEEd1qoxmvXOzkqiraCV0WtB" + "8LExrG4S1kc1KRyQ60ETmrAWgjau02m3PRp+pTGMaRg1mHFOl5cMU642pgpVzkSu6GtmdFkDirjRHhZwU7OXCua8ROCuKNcnMruAtAkNp9VA4RlTk8VOl5cW" + "5tEZlG6r4w4rsl43M6oXg2CnjxU6I4xpV8e0Up1KvlK7b6gOOjTHqUh9UQezT5Srn0m44rqdbzJLqdceLHcuy6oJ7rPQpLnjcxbzWdxxn068zpGUlzK0d5dd" + "7xjGhPApD6mGTIC1ms7hDabN5TmUqexxhBhw7g5pzXQe4ME0xanTYIJcU5tOnPeKDDvYMk1j/wDDasa1gspUzm48JT20qUTpGUGOx7jU5p/wxBWdaxW6pHDS" + "J5IXNPa4punjN21C8nwNHooqgpUp7x6qGlSB7xVy+D+WPZAvOxjZCKoKVIjM9UbukR3jzRLyY7AVLwz3GyiL3VPeeqBo0t/qUt1Vwx0BihevAwZwVDbqkMyV" + "LmiYxJCReu8gVXVHRGiOYSFaDRpRtlS7pRmT6rLev2t4IGo8+AeiQrWGUo2zzULKW2Y3TCwmo/ybFDWqR3FYlbNCljBdjvKmhSG0zzWI1XtiGKGq+e6EhWyK" + "YnFw9VPwhlpFYr6ph2MUL1+PZwSFbIptObuqJLB5livX7G9FBWfuw5pCtksz7XVDSbxO9ZDWJGWzepeu3e6QrWXtAyMKabRHZd1WUVThgOqhqnEaPukGq8A2" + "Ox4oCrAMh5nis18ccPdQVSTMe6QrTp5dl3DFTTxGDuqz353ZIi0bI4JCnOMZB2HFEmRgH9UkWiDkjrEDJIL6B3HnKl2cOyT6oC04gkK2tbC1PRU0XHwkc1W4" + "dsaeq0C1cCUdZBAwKXRkNnfHdPVDVqkd04raLVB7p5KwtIjKUukxgNlqHNuKGqVMDo4roG0CcQeSIraQGB6JdJjniyPnu5I6rUmNEYLoC0SO77Kus4TBS6TG" + "QWVwA7IV22aofCPRaTaY2dEDahn2lLq+KMoPEHQCu2i8eBuaqbWJESqm1809PDxTcPC0BEteM2t9VlNqIjEqhtZjMwk0rcQ4ZtbihLvK3HLBYDas+2VU2o4d" + "spNK6Ok8HJu7FV03+Vv9FzTaDj2zjuCqbQ6cajuivKV0y98DsshAVHA90Y4rmX5856IXxMRUdCcldFznZ6Lf6JD3uPhCxurE43h6JTqx85hXPlN1re92OASH" + "Of5W4rK+qTPbPRJdVPxHStZjO60vc7GQ1KcXbmysrqhJ75SXVD5yt5jG6uytV8vROZWqDYszSTHayTWuiIerpjSy0VN0pzK9XLRWZrjPeMFOa456RlZaxpZX" + "q7k1toqg4DNZmvPmyTGuPmWdxrDxaKmGGEIX9QDJL0zPfxQkx3zKim6xVzhC/floiUrSO15QDnGO0kKcK9QRxQvnDYlSR4ih2vMeaQONZ85YKXrjulJx8xUk" + "mDKRDrwlTTx4pOJ8UIhrjGKBmmZzUmZVNEnaiGnHFFWBBiSpI3lDRO9WDThsQDDeUIbGZTBTyM5IinjKBWiB4igGNnvGVoFMbVe6Bk7EpGTQYDi9yGg0jvOW" + "4Um7YhWFBsbFKRz7tnmchdNjF7l0hQYJEDlKuLPT3DqnRHKNFk996F03Eabiuxq7NzYRFnp+UD1To5cW5b8R0lQ0m+d3qu2LNT2BuPFE2amSYATo5cM0m7aj" + "kLtvmcu4LJTGxuPFTVWYdkHkU6OXD0AB33YKaI2Ocu2bK3yt9ShqwmIb1To5cbGRieiMniurqs4w2OaJsxjIYcU6I5V4csfVEVHYgLomzOIyaqmzP2AJcIxC" + "u/dlwKtrD9o9lpNnq45QgaFcHKClwIFpf5Qri1VM9ETyVzQrzGCqaVo3+qeAC1VJ7s81bWn5aI6FQ0bRggado2kp4CbQ87G9ChrDtwjkULq0bzwKN3XxxxQG" + "/JI7LeOal4Scm9Cpd1RvlS7flpEIJpA7Ge6A0TsbjzVm037XHFS7J8R3oquiwjHQ6FHRZlLMeBRFIEd4q123EFxAQLu6WMlseqN1RmS5mJ4qwpsJxc6eCN1T" + "xxdCCppUPMyfVQ0aGWk2eRVzTpCMXRyRuqIM6TlAk0aAHebHIpTqFAT2mdCtL6dAbXJLqdDe6DwVzU1ndQs5k6bPdJdQs+xzOeK0Op0InSclOZR3vWsZ1mfR" + "oeZvukuo0PM2fVaXNoeZ3RJe2jHect4xrmsNP5k1l18y0tpsKaynTwkeyu6kZm3R8ya26+aVqbSp5n+Se2nTkiD0Wd1rMZG3eXanmnMuvm9VrbTp8eie2nTE" + "Yeyzv03mOf8AhRtlGKXzLpXdOcvWFLun5T6BSrHPAo7nIxRnxLoimwf8KwZTGAbipSOc0UNzlYCz7Q70XQ0KUTE+kKwbTGEf/Uqxgihh2SrDV4PYdgt2iye6" + "i27k9nDfClIxRZ5gNKuLjyOWsaGOBjkp2AcBywSkZtKzjDQcrzZ4H4ZT5ZEwY5KBzAe6T6KKUH2YZU3TkVNOznwOTBUblB6KXrSZ0SEFRUs58DpUvLOc6bhj" + "uVr1sTB9FW/A8J4oJe0NlMo3lGT2HYKt8PKZ5Iay2I0TCC97Rgdl0qXtPMtKWbSAMjgNyGtbIKRDb1hnsu6KXrdx6JGt8DjuUNrA8JzSFOvhEQeil8DjB6JJ" + "tvylV1uMgRCsK0CrIAAPRA1SPNPJI1w5QTwQ1uMCCkK0CoY2zmoapO/HbAWd1swxCmt4RjCQrSKrpj/RG8dvPTFZdaO3Sx2qa0TGJhIVrNQzvOWSmmY70LIL" + "QTtKOsHeYUhWsEnaQoHHRJk4LKK5OTkRV+eEi1rkgjE+iGeJPosoqkGdNG8/xM0hWmHT3oUjCQVnmf1FCTP5hSB8Z9rDejEDvJAG0VcskYw/MwQMM+b2Q4zJ" + "2KoafihHROBFX3QAgT3sEDG8RxV9Ez+aFA2QfxRj6oFGNh6KOIHqnill+IPUImmCB+IEpGUwPVQuEY5LXc/4gKNz/iNASkYi4DMIaQOxbrmMnhE0ScdNvKEp" + "HPDxgQDGSF4BhGHuujcAwNNqgs4kEPafRLhHMfUGUJLnjd/Ndd1ngd9vRJfQjxNVzU3HIc9u5IdUbuXXdQ2aTUl1EQe01azWNxyHPGwJTnjGAuq6jj3mpLqM" + "eILeazGdrCdg6prWThA6rmtrlNFd29XcTNdRrCBMDqnNYfKOq5bbQ70Tm2h85LO43mum2mdw6p7GETgOq5QtLzuCcLQ+Fnc1rNdHRdOAHVDRdMQOqw6w8SIC" + "l+/NSaVuAdsA6qEloLoEDisIrvk5I3z3DYkWtBtLeGPNA2oHaJnisxqVDjpADdCk1fP7JMStOtcj1VdagzIlIBrH9QdEQa3n6hJhdPda4Gf81U2wg4H+aVFX" + "Y8RyUArkYVB0VmHq5tbtrlNbcPEq6FfDt4jgoWVvPjylPD1Da3HxD3Q1x2x381a7r/Eyx7qF1XPjH0p4nqutu84wQdaneb2VxSrYfieyN1WIxqR/lTw9L1kg" + "9/DkVNYM9/ZuTbmsf1D9Kl1Xn8zH9qeL6TfST+JnwKN5OdQ9E8Uax/Ux/aiKNf4mH7U8PWfTGP4h6IyPiHotNzXwF6Y/arijWON6Z/apRjww/E9kQGxF6R6F" + "axRrN/Vx/arXVYwL0/SlIxBrDiahjkpoME/inot91WE/i+yl1WEG9MH5UpGDRZsqGeSmgwmDUOHBdC6rY/ix/lUNOrP5v8KUjn6LD+ofpQhnxTMeVdK5q/EP" + "0oXVT4xj9qUjmyyJvTI4IF7fOZ5LqGz1D+p/Cpq9Sfzf4U6wmuUXjzwOSF6B4z9K6urPcfzT9KgsztlT+FLhNcm/E98/ShrE+M/Suvqbs73btbmpqZ+J/CnW" + "E1x9a+b+HJDW/mPRdk2J3xP4UNTOV5/Cr1hNcfXTtd/Cprx838K7BsLviCf2oCxO+J/CnWE1yNfdHe/hU1905/wrrCxOPj/hVTZHfE/hS4TXM+8Xnxfwq33g" + "/h9K6JsrgB+J/Cq6s7D8T10UuJNYR9o1Mv8A8q33lVHL9q2XLsrwejVU03t/UkD5UuL6zj7Sq5Z/5VYfaVX/AIam6FSR+Jj+1Ttjx/wp4eqfeNWcsvlTdatM" + "9z+EKmlUEm8M/tUNSp8T+FQMFpteHYx/aiLXapnQEcQEq9qzjUy+VS9qH9TD9qQpjrRaj4fZKdabUR3MvlQdaKkReH6Ul1ap8TD9quYUXWi1bG9QlPtFq8g9" + "QibS9ubp4wkvtTtpPRXMZ3UfXtEdwY8Eg17QSTojoi+0uM44ckl1pdv9lvMZ3S22WphljwTWWSpIxHRb22owMWpzbUcux0U360zMYGWV85jonNslQbRJ4LoM" + "tR+XonNtZgYMgrO/WtZmOe2yVN7R6JrbHUO0RyXSZa3fJCcy1Ox7mG5Z361rMxyxZKg8Q6KanU2OHRdY2tx2MJU1p3yRxCz1qzHJFkqeYQeCtqbzMPHKF079" + "0eAomu4HDQ3J1pMcwWWoZ7TeGCIszzPbEroGpUjwD0U035w1Lqxh1Z21wHojq5BjTatZfUOHZxULqm5pS6kZxZ3GfxGdFNXMj8Rp9E4h5nuzlKBZUHl5QlUs" + "UDH5reisKGMio1Esf8sBDQqTiEBuYBF6wnkiKEHCqIVdB87DCOg+DMdEFxSw/MZCIok5VGzwSwx4EQIRgwMAgYKWP5rVa6PxG+iTJGzBWDjGQUDbs4dtpCsG" + "GR2m80i9hA2jRwgQhTw0g99sIw7MuaQsmtwMAq66BsmUmlbJcTg5kckL10HtALEbcN2GaXr7Y7vAKwroXj97ZVb585tCwH7QBPdCpr7YPZxKcpXRNd0jFgH8" + "0NYcCZLVztfA8JVTbxhDVeSunrL97TCGtOMYtXNNuHlQNuGHZTkrqa44bW8FNbdvYuUbcT4cEBbScgnJ06+uOBzaprhAzauRr58qmuny48k5OnY13YS1TXSc" + "ZaBOa4+vO8pU150931Tk6drXe14VbXMM24Lha684hpHojrr/AClODp2xbYGJYQiLYIIwXEFueJGjmoLc8+FODp2zaxHhw4I6yI8M8lxRbXx3URbqgOXsFODp" + "2tZGwNnipftIw0ei4+v1IynhgiLdUGzH0TlenXNdrtjZ3QgarT5Fy9eefDj6K4tzx4f5JyV0Lxhnun0QNRkGGtlYhbX+VE21+UcdiQrTpNGxs8lNNuEhs8ln" + "1x58PsEdaqHZ/JJpT9Nkd1pHJVvG7Gt6JetPOOjntwU1moch6YJCi5zQ3ut4JDnMiNFvRMNpfHdSXWh5ybCuYmqOczc04bkh7meVvRMdaHEHCeiS+u/Y3jkF" + "rGdKc9u4dEl7m44NTHV3nZ/JKdWfnC1jGsbXmYkJjXEbQsjbPVBwqhNbZavxR0W9jONrHnHEJ7XnzBYG2Wqf1RHFNbZqszejos7jeOg153jqnMeTk4LnMs1U" + "D84dE0WeqP1Qs7jWa3aZ8zVYVOIWE2esP1R0UuK3xQpMWugahwGk1XFSMnBcy7qg/mDLaEdGof1BCQrqCocILcFcVA4ZgFcgGoP1BiialQAnTB4QpyV2G1I3" + "EK7akZQYwXCFprjwjD5grC21/IPqCcnTuh4zMQraY3gnguELfWEfhj6grt+0awxux9SnOr07emGzkFbSBGzcuJ95VY/LbP7goPtOqCJpAx8ycadO2HNzwUL2" + "7x6rjfelST+EMfmS3fbFVkC4ccJlpTjTrHbNRucCULwYxBPJcL76qARqj0D9sVDJ1WpjxTjTvHbNUCf6Kjqw2ZclxD9rVJP/AEr+qH3pVj+yv6q8aneOuaoG" + "EeyU+qDB/wBFzDb6p/7Wp1Q1yq7/ALWpG3FXlOnRNScCEsuwOE+ix39Ux/0tTqmCpWP/AGtSeaQpxJOxV0Z2eyANUkTZKkc1cXu2yVZ5oVXQwy9kRSnYY5Jg" + "FYYapU6o6Nb+61PqRS7rHunooKOM6Psm6NfPVKk81NGsD/Zap9UCrpuPZw5I3YzDfZX0axOFkqj1VtGt/davVQLNFvln0Uumzi32TNGuP+0qdUNGtP8AZKs8" + "0FbtmHY9lBTZtb7I6Ncz/wBJV9SpFeP7JVnmggp08OypoUx4RKOhXI/slUzxVdCv/dKnVAQynHdBIQ0WYdkYblNGt/dKnVS7r/3Sp1QTRYDg0eoQIYMdEdEb" + "qvlqlXqhc1zP/SVEAhk90dFXSYPCIPBXNG0ThZK2HFC5rkf2SpEb1RQvZlohVNRow0RwV9XtGQslXBVNnr4f9JVTxFRWA8IQvhsDY5I6tX/ulWUNWr6X9kqq" + "+CazuaFNZ26LVXV65yslVV1ev/dKm9PEpmtme6Edc+UJJs9oj+yVEDRrj/tKvskwp+ufKFBa8cgs9zXz1OqUbmv/AHSqkwpzrYdzUp1rO5vRR1nf8Gp9KqLK" + "95Iu3A8Qr4bVHWzg0+iS61mTgE99hdOWKS6xv3K5GdpLrVuhKdajuCc+xOGYSnWR25ayM7W9lkOHeTmWQ7CVlbbHbzimstrhtKztayNjbHjGKa2xxvWRlteY" + "EmE9ttdvKztayNTbFjm4JrbBjm6VlbbXHacU9lteRiSsbW8huoHAyeAU1DAYuVRbXExJ9VYW1284qer4r93zmXQhqHEpmtEkGTjuVha8e8U9PGd32fxKr938" + "XLVrAMSTBRvWwMTmrdSYxGwRm5yBsI8xjkt5qMJgk81UlhxkpdIwCyDOShqrZjSct5NIRiUDcxmQOKXSMOrNHiMoau3GS5bSKW8j1QLaJABmUpGO5bGZUumj" + "xGFs0aAwkqaNE4hx6q0jJct2OKAot8xlbNCjjsVg2lOeSlIx3DCDBKtcsjMrZd0jt98lA1gmEpGcUW5TCY2g2ANJ0hNhsYYneoQNkkqUVFNuj3z6CFcaA8Rl" + "Lcdg2pbnOjA+6DTpN85wUNVvnMbFhe+pujkUpxq7vdWFdE1xA7RCGs498rlk1zv6qhFeMAVeUrra2MJLpVTa4ycVySK4/wCUNG0FOcOnW1wzg48lUW0z3iuW" + "BaN3uqxaMP6q84V1dccMNIygbY6Z0iVzIrxl6SpFfd7pzhXUNrcPEVBan+Y4rmRWx48UQa8hOSukLU84SYRFqqZyVzQ6rHBHTrAwVIV0TaqnmKItFTDtxK54" + "qVY481BUqR/9SFdHWahx0iiLRVjFx6LnX1ScZnmrCtUBwBTkroXtXeSTsVr+qRg49Fzr+pxR1l/mOPFTla6IqVvTkjp1ThOfBc8Wl28zxVha3jaQkK3G9k4m" + "Sob0jPPgsYtj956qwtrozMKQrTo1/wD7CBZWx2wdyRrjozPVHXXE5mVZoYadf/kIXdfeYPBDXXZz7qa4TAxwT0C5rhS5tG/LbCItjt5R1s44nDinoSaNeDiB" + "tySTQr5YLS62OiJOPFKdaiRtVyprK6hWyKS+jW3z6LU60necUl9oJGM9VrKzrI6jWGSU6jWyWp1o2yeqS+0Heea1lZ2OUyvEZYJra/JaW/ZzcpCez7NacMMV" + "rdxnM1kZaOScy0nh6LWPsxp3JrPsxoBwCzcamsjbQRsCc20YZha2/ZrIBGCY37LaMRELPWN5msesngiLV+2Vt+7G7xCn3Y3HEKXCayC05d1WFp5LQfs9s7J5" + "qGwsnMJcWaTrI+Xkri0jbCZqbGjEjHipqrM5HVPD0BXBwMRxVxVB8sICgxsYtlWFNnmbgp4o6bc+yjpNM4D3RF2BGk3qrA0s9JuW1QVgE5NChaIyEBEV6Ajt" + "t6KwtVBoAvBKABgOGGSmi2fCR6q5tNnIweMFDbKHmCnp4rogbB7oQ0YACFbW6Ize3oqm20T4h0V9EMDdHqgXgRgMEDbKWxw6JD7RpExXAG4sTMKaamUxOaq5" + "4djtCTfuI/PH0KGs4/rj6ArEq7nxhOPqq6Uz/Qqt4/4wAnyKzX1PjCR8isKBEnZ7oaB/3KaH1PjCT/hq2nVdje/+tQJFMmMfZEUScZn0T9OqR+b/AOtWva3x" + "v/WlCLkj/ZRNCZE+xWgVa0/nH/8Amia1UgTVx/8AGpVZhZ8P+VNWxIww5rQKlXbW/wDWpeVoi/8A/Wl0I1QxsPVQ2UDbPVOL6w/W/gQLq3x4P/jS6F6pGGCB" + "skbRjzTfxvj4f+PJCK2esH6FaheqAwez7oaphsPVX0auy0fwKpbVOdoP0IBqQnNqAsYjZPqrXdb+8n6FU0qv95OPyIBqbcyRhxQNjE+GETSq4nWT9CIs1d+I" + "tBjfop+ihsYGej7oGx4eH3V9Sryfx/4VU2Suf1zEeUJf6fiuqDPsnkq6tu0equbHWP8A3GH7UNUrDKv/AAhW/wBT8V1bCOyhq4wnRjmrNslVrpNaRuiFfVyA" + "O11ShRobIb1UFD9vUplxliULqcycEqxQURubxxKl0MoafVWuY8SApye9miJdcG9VDRB2N6qXXFQ0+KKDqY3N6pTqUHHR6lXc0b8Ut7RjiriaWWAzg3BJfTzn" + "RjmmOYBPaSXNA3rWMaWWYZN6pTqY3DqmOAjNJc0Y44LWM66zajsOy1ObVO5vVY2sdh2oPNaKdMkd/wDiWNxvGptR3lYPVOY92Wiz3WRlN2A0/daG0356Xus6" + "1jS15EHRZHMpzXuEEtZPNZmU3Ezpe6eyk7zjqsa1hpLjJ0Ge6qS52OiyfVS7dPe2+ZEU3ecdVFV0XRGizjiUCwyBosOzMpopGe8Oql27z/xIQg0SdjDM7UHU" + "CT3WLSKZnv8A8SN38ww4q0jEbMSe62FQ2Y7m710LrGZ90HU8R28tkpSOebKcob1Q1TOdFdA0m759ULsDbhzSkYBYwcipqUE4hbjTaBM481Axp/5V6SMOpZQQ" + "pqIIGIWwtYNme3SVtFs7ct6l0jCLEN45K2pZwVsDW5wTvxVtFk93Hml0jILD8ys2wg+JawG4yD1CMtB7p5kpdWM7bENHvBXbYwIE+ydLMcDM+ZDTYMm5/MFL" + "qxG2VoPeyxTG2drRnklXrfLG7FVNYbj6OT08aW0mjblwVy0ZgyOQWE1wZgGf3KhrjY3+JSFdEOAx0suCgeAe8Vy7/gR6oGtIxafRyvJXWvAJh3sheiILvYLk" + "Xxx7OP7sFW+cPDh+5OTp2b0Zl2XBS+b5s9wC4164xhJ/dipeuAwGyc05OnavBlp+yF8PPMYZLjXzxsP1IGq/IDA8U5Tp2jUGekY5BS8kgaXsFxhVqzz4qadb" + "dlxTlenXvB5vYI6Qgdo9AuNeVpEfzUvazsj7pydOyXjfxyQ0hEaXsFx72uRmIUvK+OOHNOU6djSbh2z0CEtnvEHkFyLyvGfuoKtoPi27CnJXWMGe17BSW4Cc" + "D8oXJvbQBOlCJr2jzc05K6oDNpP0hAtafF7LlttFoz0gI4oi0WjzAztTkroljDtP0hC7bhLvYLnaxaR4xgjrNog9oZqwroGk3eegQNJuwmf2hYdZr+bkprVo" + "8wlJpWwUmgd4xyQuWkEhxx+ULMbTaPOEBaq8d8JNK0Gg0yJOHAKGg07T9ISBaq4M6YVTaq8RpDNJp4c6i3eecBIfQbB7XVoUdaq094FJfaq2elmrmamo6gM5" + "PQJDqDRtPQIutNY4lwSX2it5hgtZWdB1Fp8Rn9oSHURhieis+01se0kur1T4gt5WNjKy0u4EJzbS8bksFm89E0Fm89FrUw1lqdwjami1v2Qlgs8xnknNLJiT" + "0WGsNban7YTW2txzhKa5sYF3RNDmYQ53RZ1rF9cduH9EdccTsPoqSzE6TuiEtAnSd0UmKcLW75URbTl2YWfSblpO5wgXtx7bucJCtgtriIMFXFtOHdnkucHt" + "8zlLxsDtuSFdQWscMERaQQRDei5N4J7zo5KXjfO7DgnJXYFpb8qsLQ2PDC4t83zunejej4jvVTlenbFdkz2TzUvmYwG5ZriCoD4nD0RLwPG5OTp2r5mXZ3wi" + "K1P5ei4emPO5A1Bse5OTp3L2mD4fRS/YB4Z3Lgl2MabkNIz33K8nTuOtDfl5hVNpYQcguGST4iqwTkSnKdO2+1NjwpTrW2Mmrk6BO0oXTthKvOFdV1qx8PRU" + "Nq2YLnXDozKs2zOO9JiXWs2ozgOgVdYP/wBWcWR24pmpmcikw9Xvj6KXxJ2ICxEDIq2pO3Yp4voCs6MlYVTt2oixOBghW1F091PD0sVXYf0R03K4sbiJ0Qpq" + "bjsw5qeHqum4TkiHuwH+iuLIR4c0NXd5UA0idyOmcMlLl3lUuX+UdUEDiRmFbScRntQu3T3UNB24ckVbTIGYgIh54YKmi4T2QVId5QiLaZz0myeCtp4GSMUu" + "HDYJU7cHsjqirF+OYRvYzISyHYfhidykP8g6IL3omZARvgNow2pUPOEDqoA+RDAUQy/AOY9QprDY2JR0zkwIhlQz2AEgYbQ3goLUzbo9EnRecmDFHRqfDakD" + "Ra6Y3dFNcYD4eSToVCO4MEAyrH5YISYH64ychCIttP5eizXdQn8sYqxpVfhiEmFMfbGbhKU62M4blV1Op8MJTqdWIDArmYm6L7aydiS62U4yag6nV8gSnU6u" + "d2AtZmM7uo61sM4NSn2th2BB1OqPAAlOp1PIFrMxndam2Vu2oU5lkaP1SnsY3eME9rGnas79NZjO2xtn81NbY2gY1DPNaWtbwhPbTbwWa1mMrbG2PzDCY2xt" + "ON6VrbSbGMYbk8UmxiQI3FZ36azHPNiECapQNiEgXpXTNFo3QqmkwZkGVOljlmxgfqFVNiHxTG9dQ0mzMid6qaQjCFekjl6nhN4qmxx+rK6ZptG5UcxsYgSn" + "RHNNjIM3hhVNlwJvF0i0TgllsHL2VqRg1UnKocVXVnDC8W4jhCriNnQK0jFcGO+jcO2PWon5UNP5THJKkZrg+YqXLj4iVo0+HVG8AOLTCUjNdHzFWuXbHFag" + "/wCWFYOHlSrGQUTI7SsKJ3m