Decompiled source of MarkLoans v1.0.5

plugins/MarkLoans/MarkLoans.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Extensions;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("MarkLoans.Tests")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MarkLoans")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.5.0")]
[assembly: AssemblyInformationalVersion("1.0.5")]
[assembly: AssemblyProduct("MarkLoans")]
[assembly: AssemblyTitle("MarkLoans")]
[assembly: AssemblyVersion("1.0.5.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 MarkLoans
{
	public static class AtomicFile
	{
		public static void Write(string path, string contents)
		{
			string text = path + ".markloans.tmp";
			using (FileStream fileStream = new FileStream(text, FileMode.Create, FileAccess.Write, FileShare.None))
			{
				using StreamWriter streamWriter = new StreamWriter(fileStream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
				streamWriter.Write(contents);
				streamWriter.Flush();
				fileStream.Flush(flushToDisk: true);
			}
			if (File.Exists(path))
			{
				File.Replace(text, path, path + ".markloans.bak");
			}
			else
			{
				File.Move(text, path);
			}
		}
	}
	internal sealed class LoanMenu : MonoBehaviour, IUIManager
	{
		internal View View;

		private GameObject canvasRoot;

		private GameObject panel;

		private GameObject toast;

		private GameObject voteBadge;

		private GameObject goldRule;

		private TMP_FontAsset font;

		private TextMeshProUGUI title;

		private TextMeshProUGUI summary;

		private TextMeshProUGUI amount;

		private TextMeshProUGUI terms;

		private TextMeshProUGUI debt;

		private TextMeshProUGUI voteText;

		private TextMeshProUGUI toastText;

		private TextMeshProUGUI badgeText;

		private Slider slider;

		private Button startVote;

		private Button approve;

		private Button reject;

		private Button repay;

		private Button close;

		private Quote quote;

		private string mode = "Loans";

		private string shownVote;

		private string toastMessage;

		private string selectedLoan;

		private float toastUntil;

		private InputLayer oldLayer;

		private bool oldLocked;

		private bool oldHeadLocked;

		private CursorLockMode oldCursor;

		private bool oldVisible;

		private PlayerController lockedPlayer;

		private GameObject oldSelection;

		private bool registered;

		private float desiredPercent = 25f;

		private double serverNow;

		private float receivedAt;

		private bool pendingAuto;

		private float nextVoteRefresh;

		private float nextBadgeRefresh;

		private bool settingSlider;

		private bool requestingQuote;

		private float quoteRequestTime;

		private PlayerInteract lockedInteraction;

		private bool oldInteractionEnabled;

		private GameObject interactionPanel;

		private bool oldPanelActive;

		private static SFXGenericUIButtonComponent clickSound;

		private int lastClosedFrame = -1;

		private static readonly Color Gold = new Color(1f, 0.79f, 0.22f);

		private static readonly Color Ink = new Color(0.055f, 0.11f, 0.14f, 0.98f);

		public bool IsActive { get; private set; }

		public int Priority => 90;

		internal bool BlocksEscape
		{
			get
			{
				if (!IsActive)
				{
					return lastClosedFrame == Time.frameCount;
				}
				return true;
			}
		}

		private static string Cash(BigNumber value)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return MoneyFormatter.FormatWithDollar(value, false);
		}

		internal void Receive(View view)
		{
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			View = view;
			serverNow = view.Now;
			receivedAt = Time.unscaledTime;
			if (!string.IsNullOrEmpty(view.Notice))
			{
				ShowNotice(view.Notice);
			}
			bool flag = requestingQuote && IsActive;
			if (!string.IsNullOrEmpty(view.Notice) || view.Quote != null)
			{
				requestingQuote = false;
			}
			if (view.Quote != null && flag)
			{
				quote = view.Quote;
				mode = "Confirm";
				if (!IsActive)
				{
					OpenUI();
				}
			}
			if (view.Proposal != null && view.Proposal.Eligible.Contains(view.Session) && !view.Proposal.Approved.Contains(view.Session) && !view.Proposal.Rejected.Contains(view.Session) && shownVote != view.Proposal.Id)
			{
				shownVote = view.Proposal.Id;
				EnsureUI();
				pendingAuto = true;
				if ((int)InputEvents.ActiveLayer == 0 || IsActive)
				{
					mode = "Vote";
					OpenUI();
					pendingAuto = false;
				}
			}
			if (view.Proposal == null && mode == "Vote")
			{
				CloseUI();
			}
			Refresh();
		}

		private void Update()
		{
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Invalid comparison between Unknown and I4
			if (!registered && (Object)(object)UIManager.Instance != (Object)null)
			{
				UIManager.Instance.RegisterUI((IUIManager)(object)this);
				registered = true;
			}
			if ((Object)(object)canvasRoot == (Object)null)
			{
				return;
			}
			toast.SetActive(Time.unscaledTime < toastUntil);
			bool flag = View?.Proposal != null && View.Proposal.Eligible.Contains(View.Session) && !View.Proposal.Approved.Contains(View.Session) && !View.Proposal.Rejected.Contains(View.Session);
			if (flag && !IsActive && (int)InputEvents.ActiveLayer == 0)
			{
				if (!pendingAuto)
				{
					Keyboard current = Keyboard.current;
					if (current == null || !((ButtonControl)current.f6Key).wasPressedThisFrame)
					{
						goto IL_0117;
					}
				}
				mode = "Vote";
				OpenUI();
				pendingAuto = false;
			}
			goto IL_0117;
			IL_0117:
			voteBadge.SetActive(flag && !IsActive);
			if (flag && !IsActive && Time.unscaledTime >= nextBadgeRefresh)
			{
				nextBadgeRefresh = Time.unscaledTime + 0.2f;
				((TMP_Text)badgeText).text = "MARK'S TEAM LOAN VOTE\n" + Remaining().ToString("0") + "s remaining • F6 to reopen";
			}
			if (IsActive)
			{
				if (requestingQuote && Time.unscaledTime - quoteRequestTime > 10f)
				{
					requestingQuote = false;
					ShowNotice("Mark is taking his time. Try Start Vote again.");
					Refresh();
				}
				if (!NetworkClient.isConnected || (Object)(object)lockedPlayer == (Object)null || (int)InputEvents.ActiveLayer != 3)
				{
					CloseUI();
				}
				else if (mode == "Vote" && Time.unscaledTime >= nextVoteRefresh)
				{
					nextVoteRefresh = Time.unscaledTime + 0.2f;
					Refresh();
				}
			}
		}

		private double Remaining()
		{
			if (View?.Proposal != null)
			{
				return Math.Max(0.0, View.Proposal.Deadline - (serverNow + (double)Time.unscaledTime - (double)receivedAt));
			}
			return 0.0;
		}

		public void OpenUI()
		{
			//IL_001c: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			if (IsActive)
			{
				Refresh();
			}
			else
			{
				if ((Object)(object)NetworkClient.localPlayer == (Object)null || (int)InputEvents.ActiveLayer != 0)
				{
					return;
				}
				EnsureUI();
				lockedPlayer = ((Component)NetworkClient.localPlayer).GetComponent<PlayerController>();
				if ((Object)(object)lockedPlayer == (Object)null)
				{
					return;
				}
				UIManager instance = UIManager.Instance;
				if (instance != null)
				{
					instance.SetActiveUI((IUIManager)(object)this);
				}
				oldLayer = InputEvents.ActiveLayer;
				oldLocked = lockedPlayer.IsLocked;
				oldHeadLocked = (Object)(object)lockedPlayer.head != (Object)null && lockedPlayer.head.isLocked;
				oldCursor = Cursor.lockState;
				oldVisible = Cursor.visible;
				EventSystem current = EventSystem.current;
				oldSelection = ((current != null) ? current.currentSelectedGameObject : null);
				lockedInteraction = ((Component)lockedPlayer).GetComponent<PlayerInteract>();
				oldInteractionEnabled = (Object)(object)lockedInteraction != (Object)null && ((Behaviour)lockedInteraction).enabled;
				if ((Object)(object)lockedInteraction != (Object)null)
				{
					((Behaviour)lockedInteraction).enabled = false;
				}
				LocalManager instance2 = MonoSingleton<LocalManager>.Instance;
				object obj;
				if (instance2 == null)
				{
					obj = null;
				}
				else
				{
					InteractionUIPanel interactionUIPanel = instance2.interactionUIPanel;
					obj = ((interactionUIPanel != null) ? ((Component)interactionUIPanel).gameObject : null);
				}
				interactionPanel = (GameObject)obj;
				oldPanelActive = (Object)(object)interactionPanel != (Object)null && interactionPanel.activeSelf;
				if ((Object)(object)interactionPanel != (Object)null)
				{
					interactionPanel.SetActive(false);
				}
				if ((Object)(object)Plugin.Instance.Visual.Mark != (Object)null)
				{
					TextMeshPro componentInChildren = Plugin.Instance.Visual.Mark.GetComponentInChildren<TextMeshPro>(true);
					if (componentInChildren != null)
					{
						((Component)componentInChildren).gameObject.SetActive(false);
					}
				}
				InputEvents.OnMoveEvent?.Invoke(Vector2.zero);
				InputEvents.OnAimEvent?.Invoke(Vector2.zero);
				InputEvents.UpdateInteract(false);
				InputEvents.UpdateJump(false);
				InputEvents.UpdateCrouch(false);
				InputEvents.UpdateSprint(false);
				InputEvents.UpdateUseItem(false);
				InputEvents.UpdateThrowItem(false);
				InputEvents.ActiveLayer = (InputLayer)3;
				lockedPlayer.IsLocked = true;
				if ((Object)(object)lockedPlayer.head != (Object)null)
				{
					lockedPlayer.head.isLocked = true;
				}
				IsActive = true;
				panel.SetActive(true);
				UICursorSimple instance3 = UICursorSimple.Instance;
				if (instance3 != null)
				{
					instance3.ShowCursor();
				}
				Refresh();
				EventSystem current2 = EventSystem.current;
				if (current2 != null)
				{
					current2.SetSelectedGameObject((mode == "Vote") ? ((Component)approve).gameObject : ((Component)slider).gameObject);
				}
				PlayClick();
			}
		}

		public void CloseUI()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Invalid comparison between Unknown and I4
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			if (!IsActive)
			{
				return;
			}
			lastClosedFrame = Time.frameCount;
			IsActive = false;
			GameObject obj = panel;
			if (obj != null)
			{
				obj.SetActive(false);
			}
			pendingAuto = false;
			bool num = (int)InputEvents.ActiveLayer == 3;
			if (num)
			{
				InputEvents.ActiveLayer = oldLayer;
			}
			if (num && (Object)(object)lockedPlayer != (Object)null)
			{
				lockedPlayer.IsLocked = oldLocked;
				if ((Object)(object)lockedPlayer.head != (Object)null)
				{
					lockedPlayer.head.isLocked = oldHeadLocked;
				}
			}
			if ((Object)(object)lockedInteraction != (Object)null)
			{
				((Behaviour)lockedInteraction).enabled = oldInteractionEnabled;
			}
			if ((Object)(object)interactionPanel != (Object)null)
			{
				interactionPanel.SetActive(oldPanelActive);
			}
			if ((Object)(object)Plugin.Instance.Visual.Mark != (Object)null)
			{
				TextMeshPro componentInChildren = Plugin.Instance.Visual.Mark.GetComponentInChildren<TextMeshPro>(true);
				if (componentInChildren != null)
				{
					((Component)componentInChildren).gameObject.SetActive(true);
				}
			}
			lockedInteraction = null;
			interactionPanel = null;
			if (num)
			{
				UICursorSimple instance = UICursorSimple.Instance;
				if (instance != null)
				{
					instance.HideCursor();
				}
				Cursor.lockState = oldCursor;
				Cursor.visible = oldVisible;
				EventSystem current = EventSystem.current;
				if (current != null)
				{
					current.SetSelectedGameObject(oldSelection);
				}
			}
			UIManager instance2 = UIManager.Instance;
			if (instance2 != null)
			{
				instance2.ClearActiveUI((IUIManager)(object)this);
			}
			lockedPlayer = null;
			quote = null;
			mode = "Loans";
			requestingQuote = false;
		}

		internal void ShowNotice(string text)
		{
			EnsureUI();
			toastMessage = text;
			((TMP_Text)toastText).text = text;
			toastUntil = Time.unscaledTime + 9f;
			PlayClick();
		}

		private void EnsureUI()
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			//IL_00f0: 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_0124: 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_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_0382: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0403: Unknown result type (might be due to invalid IL or missing references)
			//IL_0412: Unknown result type (might be due to invalid IL or missing references)
			//IL_0442: Unknown result type (might be due to invalid IL or missing references)
			//IL_045d: Unknown result type (might be due to invalid IL or missing references)
			//IL_048d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04eb: 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_0545: Unknown result type (might be due to invalid IL or missing references)
			//IL_0554: Unknown result type (might be due to invalid IL or missing references)
			//IL_0559: Unknown result type (might be due to invalid IL or missing references)
			//IL_057f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0584: Unknown result type (might be due to invalid IL or missing references)
			//IL_05af: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b9: Expected O, but got Unknown
			if ((Object)(object)canvasRoot != (Object)null)
			{
				return;
			}
			font = ((IEnumerable<TMP_FontAsset>)Resources.FindObjectsOfTypeAll<TMP_FontAsset>()).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => (Object)(object)f != (Object)null && ((Object)f).name.Contains("Liberation"))) ?? Resources.FindObjectsOfTypeAll<TMP_FontAsset>().FirstOrDefault();
			canvasRoot = new GameObject("Mark Loans UI", new Type[4]
			{
				typeof(RectTransform),
				typeof(Canvas),
				typeof(CanvasScaler),
				typeof(GraphicRaycaster)
			});
			canvasRoot.transform.SetParent(((Component)this).transform, false);
			canvasRoot.GetComponent<Canvas>().renderMode = (RenderMode)0;
			canvasRoot.GetComponent<Canvas>().sortingOrder = 500;
			CanvasScaler component = canvasRoot.GetComponent<CanvasScaler>();
			component.uiScaleMode = (ScaleMode)1;
			component.referenceResolution = new Vector2(1920f, 1080f);
			component.matchWidthOrHeight = 0.5f;
			panel = Box("Mark's desk", canvasRoot.transform, new Vector2(650f, 640f), Vector2.zero, Ink);
			goldRule = Box("Gold rule", panel.transform, new Vector2(650f, 5f), new Vector2(0f, 315f), Gold);
			title = Label(panel.transform, new Vector2(510f, 42f), new Vector2(-16f, 270f), 32f);
			((TMP_Text)title).text = "MARK THE SHARK";
			((Graphic)title).color = Gold;
			summary = Label(panel.transform, new Vector2(580f, 42f), new Vector2(0f, 220f), 20f);
			slider = MakeSlider(panel.transform, new Vector2(0f, 174f));
			((UnityEvent<float>)(object)slider.onValueChanged).AddListener((UnityAction<float>)delegate(float v)
			{
				if (!settingSlider)
				{
					desiredPercent = ((View == null) ? v : ((float)View.Rules.Snap(v)));
					Refresh();
				}
			});
			amount = Label(panel.transform, new Vector2(580f, 142f), new Vector2(0f, 74f), 58f);
			((Graphic)amount).color = Gold;
			terms = Label(panel.transform, new Vector2(580f, 58f), new Vector2(0f, -33f), 22f);
			startVote = Button(panel.transform, "START VOTE", new Vector2(0f, -112f), (Action)StartLoan, (Vector2?)new Vector2(550f, 54f));
			repay = Button(panel.transform, "REPAY", new Vector2(0f, -178f), (Action)delegate
			{
				if (selectedLoan != null)
				{
					Wire.Send("Repay", selectedLoan);
					((Selectable)repay).interactable = false;
				}
			}, (Vector2?)new Vector2(550f, 48f));
			close = Button(panel.transform, "X", new Vector2(280f, 270f), (Action)CloseUI, (Vector2?)new Vector2(38f, 38f));
			debt = Label(panel.transform, new Vector2(580f, 88f), new Vector2(0f, -260f), 17f);
			voteText = Label(panel.transform, new Vector2(580f, 40f), new Vector2(0f, 117f), 22f);
			approve = Button(panel.transform, "APPROVE", new Vector2(-142f, -166f), (Action)delegate
			{
				Vote(yes: true);
			}, (Vector2?)new Vector2(265f, 54f));
			reject = Button(panel.transform, "REJECT", new Vector2(142f, -166f), (Action)delegate
			{
				Vote(yes: false);
			}, (Vector2?)new Vector2(265f, 54f));
			toast = Box("Team notification", canvasRoot.transform, new Vector2(760f, 105f), new Vector2(0f, 430f), Ink);
			toastText = Label(toast.transform, new Vector2(720f, 95f), Vector2.zero, 21f);
			voteBadge = Box("Vote notification", canvasRoot.transform, new Vector2(360f, 92f), new Vector2(710f, 390f), Ink);
			badgeText = Label(voteBadge.transform, new Vector2(330f, 80f), Vector2.zero, 20f);
			((UnityEvent)voteBadge.AddComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				mode = "Vote";
				OpenUI();
			});
			panel.SetActive(false);
			toast.SetActive(false);
			voteBadge.SetActive(false);
		}

		private void StartLoan()
		{
			if (View == null || requestingQuote)
			{
				return;
			}
			if (View.Proposal != null)
			{
				mode = "Vote";
				Refresh();
				return;
			}
			if (mode == "Confirm" && quote != null)
			{
				Wire.Send("Propose", quote.Id);
				quote = null;
				mode = "Loans";
			}
			else
			{
				requestingQuote = true;
				quoteRequestTime = Time.unscaledTime;
				Wire.Send("Quote", null, desiredPercent);
			}
			Refresh();
		}

		private void Vote(bool yes)
		{
			if (View?.Proposal != null)
			{
				Wire.Send("Vote", View.Proposal.Id, 0.0, yes);
				CloseUI();
			}
		}

		private void Refresh()
		{
			//IL_0636: Unknown result type (might be due to invalid IL or missing references)
			//IL_063b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0650: Unknown result type (might be due to invalid IL or missing references)
			//IL_0681: Unknown result type (might be due to invalid IL or missing references)
			//IL_066c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0673: Unknown result type (might be due to invalid IL or missing references)
			//IL_0678: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0686: Unknown result type (might be due to invalid IL or missing references)
			//IL_068b: Unknown result type (might be due to invalid IL or missing references)
			//IL_070c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_07df: Unknown result type (might be due to invalid IL or missing references)
			//IL_07e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_076f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0887: Unknown result type (might be due to invalid IL or missing references)
			//IL_088d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0892: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0531: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)canvasRoot == (Object)null || !IsActive)
			{
				return;
			}
			if (View == null)
			{
				((TMP_Text)amount).text = "<size=26>WAITING FOR MARK</size>";
				((TMP_Text)terms).text = "Everyone needs Mark Loans 1.0.5";
				Button obj = startVote;
				bool interactable = (((Selectable)repay).interactable = false);
				((Selectable)obj).interactable = interactable;
				((Component)approve).gameObject.SetActive(false);
				((Component)reject).gameObject.SetActive(false);
				((Component)voteText).gameObject.SetActive(false);
				return;
			}
			bool flag2 = mode == "Vote" && View.Proposal != null;
			bool flag3 = mode == "Confirm" && this.quote != null;
			((RectTransform)panel.transform).sizeDelta = new Vector2(650f, (float)(flag2 ? 450 : 640));
			((RectTransform)goldRule.transform).anchoredPosition = new Vector2(0f, (float)(flag2 ? 220 : 315));
			((TMP_Text)title).rectTransform.anchoredPosition = new Vector2(-16f, (float)(flag2 ? 175 : 270));
			((Component)summary).gameObject.SetActive(!flag2);
			((Component)debt).gameObject.SetActive(!flag2);
			((Component)repay).gameObject.SetActive(!flag2);
			((RectTransform)((Component)close).transform).anchoredPosition = new Vector2(280f, (float)(flag2 ? 175 : 270));
			((TMP_Text)amount).rectTransform.anchoredPosition = new Vector2(0f, (float)(flag2 ? 25 : 74));
			((TMP_Text)terms).rectTransform.anchoredPosition = new Vector2(0f, (float)(flag2 ? (-83) : (-33)));
			((TMP_Text)title).text = (flag2 ? "MARK'S TEAM LOAN VOTE" : "MARK THE SHARK");
			((Component)slider).gameObject.SetActive(!flag2);
			((Component)voteText).gameObject.SetActive(flag2);
			((Component)startVote).gameObject.SetActive(!flag2);
			((Component)approve).gameObject.SetActive(flag2);
			((Component)reject).gameObject.SetActive(flag2);
			settingSlider = true;
			slider.minValue = (float)View.Rules.MinPercent;
			slider.maxValue = (float)View.Rules.MaxPercent;
			desiredPercent = (float)View.Rules.Snap(desiredPercent);
			slider.SetValueWithoutNotify(desiredPercent);
			settingSlider = false;
			((Selectable)slider).interactable = !flag3 && View.Proposal == null && View.Ready;
			((Selectable)startVote).interactable = !requestingQuote && (View.Ready || View.Proposal != null);
			((TMP_Text)((Component)startVote).GetComponentInChildren<TextMeshProUGUI>()).text = (requestingQuote ? "GETTING TERMS..." : ((View.Proposal != null) ? "VIEW VOTE" : (View.Ledger.HasUnsettledDebt ? "REPAY EXISTING DEBT FIRST" : (flag3 ? "CONFIRM START VOTE" : "START VOTE"))));
			if (flag2)
			{
				Proposal proposal = View.Proposal;
				ShowTerms(proposal.Terms);
				((TMP_Text)voteText).text = proposal.Approved.Count + "/" + proposal.Required + " approvals needed • " + Remaining().ToString("0") + "s";
				bool flag4 = proposal.Eligible.Contains(View.Session) && !proposal.Approved.Contains(View.Session) && !proposal.Rejected.Contains(View.Session) && Remaining() > 0.0;
				Button obj2 = approve;
				bool interactable = (((Selectable)reject).interactable = flag4);
				((Selectable)obj2).interactable = interactable;
			}
			else
			{
				try
				{
					Quote quote = (flag3 ? this.quote : Quote.Create(View.Day, View.BaseQuota, desiredPercent, View.Rules));
					ShowTerms(quote);
					((TMP_Text)summary).text = quote.Percent.ToString("0.##") + "% OF QUOTA " + Cash(View.BaseQuota) + " • DAY " + (View.Day + 1);
				}
				catch (Exception ex)
				{
					((TMP_Text)amount).text = "<size=26>NO BORROWING QUOTE</size>";
					((TMP_Text)terms).text = ex.Message;
					((Selectable)startVote).interactable = false;
				}
			}
			List<Loan> list = View.Ledger.Loans.Where((Loan l) => l.Status == "Outstanding" || l.Status == "Defaulted" || (l.Status == "Transferred" && !l.QuotaCleared)).ToList();
			Loan loan = (from l in list
				where l.Status == "Outstanding"
				orderby l.Terms.DueDay
				select l).FirstOrDefault();
			selectedLoan = loan?.Id;
			BigNumber val = BigNumber.Zero;
			foreach (Loan item in list)
			{
				val += ((item.Status == "Transferred") ? item.Transferred : (item.Terms.Total - item.Paid));
			}
			((TMP_Text)debt).text = (View.Ledger.HasUnsettledDebt ? "BORROWING LOCKED UNTIL DEBT IS SETTLED" : (View.Ledger.UsedDays.Contains(View.Day) ? "TODAY'S LOAN: USED" : (View.Ready ? "TODAY'S LOAN: AVAILABLE" : "BORROWING CLOSED"))) + " • TEAM DEBT " + Cash(val) + "\n";
			foreach (Loan item2 in list)
			{
				TextMeshProUGUI obj3 = debt;
				((TMP_Text)obj3).text = ((TMP_Text)obj3).text + ((item2.Status == "Defaulted") ? "UNPAID AT DEADLINE — LOSING PIT\n" : ((item2.Status == "Outstanding") ? ("Day " + (item2.Terms.Day + 1) + ": " + Cash(item2.Terms.Total - item2.Paid) + " due end of day " + (item2.Terms.DueDay + 1) + "\n") : (Cash(item2.Transferred) + " quota debt on day " + (item2.TransferDay + 1) + "\n")));
			}
			if (list.Count == 0)
			{
				TextMeshProUGUI obj4 = debt;
				((TMP_Text)obj4).text = ((TMP_Text)obj4).text + "No debt. Mark is trying to look happy for you.";
			}
			((TMP_Text)((Component)repay).GetComponentInChildren<TextMeshProUGUI>()).text = ((loan == null) ? "REPAY" : ("REPAY " + Cash(loan.Terms.Total - loan.Paid)));
			((Selectable)repay).interactable = loan?.Status == "Outstanding";
		}

		private void ShowTerms(Quote q)
		{
			//IL_0017: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			((TMP_Text)amount).text = "<size=20>YOU BORROW</size>\n" + Cash(q.Principal) + "\n<size=28>INTEREST " + q.Rate.ToString("0.##") + "% • " + Cash(q.Interest) + "</size>";
			((TMP_Text)terms).text = "TOTAL REPAYMENT " + Cash(q.Total) + " • DUE END OF DAY " + (q.DueDay + 1) + "\nMISS THE DEADLINE: THE TEAM LOSES";
		}

		private static GameObject Box(string name, Transform parent, Vector2 size, Vector2 pos, Color color)
		{
			//IL_0021: 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_0033: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_0059: Expected O, but got Unknown
			GameObject val = new GameObject(name, new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent(parent, false);
			RectTransform val2 = (RectTransform)val.transform;
			val2.sizeDelta = size;
			val2.anchoredPosition = pos;
			((Graphic)val.GetComponent<Image>()).color = color;
			return val;
		}

		private TextMeshProUGUI Label(Transform parent, Vector2 size, Vector2 pos, float fontSize)
		{
			//IL_0025: 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_0043: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Label", new Type[2]
			{
				typeof(RectTransform),
				typeof(TextMeshProUGUI)
			});
			val.transform.SetParent(parent, false);
			TextMeshProUGUI component = val.GetComponent<TextMeshProUGUI>();
			((TMP_Text)component).rectTransform.sizeDelta = size;
			((TMP_Text)component).rectTransform.anchoredPosition = pos;
			if ((Object)(object)font != (Object)null)
			{
				((TMP_Text)component).font = font;
			}
			((TMP_Text)component).fontSize = fontSize;
			((Graphic)component).color = new Color(0.94f, 0.96f, 0.93f);
			((TMP_Text)component).alignment = (TextAlignmentOptions)514;
			((TMP_Text)component).textWrappingMode = (TextWrappingModes)1;
			((Graphic)component).raycastTarget = false;
			return component;
		}

		private Button Button(Transform parent, string text, Vector2 pos, Action action, Vector2? size = null)
		{
			//IL_002e: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Expected O, but got Unknown
			Vector2 val = (Vector2)(((??)size) ?? new Vector2(275f, 42f));
			GameObject val2 = Box(text, parent, val, pos, Gold);
			Button obj = val2.AddComponent<Button>();
			ColorBlock colors = ((Selectable)obj).colors;
			((ColorBlock)(ref colors)).highlightedColor = new Color(1f, 0.92f, 0.6f);
			((ColorBlock)(ref colors)).disabledColor = new Color(0.35f, 0.35f, 0.35f);
			((Selectable)obj).colors = colors;
			TextMeshProUGUI obj2 = Label(val2.transform, val - new Vector2(16f, 4f), Vector2.zero, 23f);
			((TMP_Text)obj2).text = text;
			((Graphic)obj2).color = Ink;
			((UnityEvent)obj.onClick).AddListener((UnityAction)delegate
			{
				PlayClick();
				action();
			});
			return obj;
		}

		private Slider MakeSlider(Transform parent, Vector2 pos)
		{
			//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_0025: 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: Expected O, but got Unknown
			//IL_006d: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Expected O, but got Unknown
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Expected O, but got Unknown
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Expected O, but got Unknown
			GameObject val = Box("Hi Lo inspired percentage slider", parent, new Vector2(550f, 18f), pos, new Color(0.26f, 0.43f, 0.45f));
			Slider val2 = val.AddComponent<Slider>();
			GameObject val3 = new GameObject("Fill area", new Type[1] { typeof(RectTransform) });
			val3.transform.SetParent(val.transform, false);
			Stretch((RectTransform)val3.transform, Vector2.zero, Vector2.zero);
			GameObject val4 = Box("Fill", val3.transform, Vector2.zero, Vector2.zero, Gold);
			Stretch((RectTransform)val4.transform, Vector2.zero, Vector2.zero);
			val2.fillRect = (RectTransform)val4.transform;
			GameObject val5 = new GameObject("Handle area", new Type[1] { typeof(RectTransform) });
			val5.transform.SetParent(val.transform, false);
			Stretch((RectTransform)val5.transform, new Vector2(12f, 0f), new Vector2(-12f, 0f));
			GameObject val6 = Box("Knob", val5.transform, new Vector2(24f, 32f), Vector2.zero, new Color(1f, 0.94f, 0.72f));
			val2.handleRect = (RectTransform)val6.transform;
			((Selectable)val2).targetGraphic = (Graphic)(object)val6.GetComponent<Image>();
			val2.direction = (Direction)0;
			return val2;
		}

		private static void Stretch(RectTransform rect, Vector2 min, Vector2 max)
		{
			//IL_0001: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			rect.anchorMin = Vector2.zero;
			rect.anchorMax = Vector2.one;
			rect.offsetMin = min;
			rect.offsetMax = max;
		}

		private static void PlayClick()
		{
			if ((Object)(object)clickSound == (Object)null)
			{
				clickSound = Object.FindAnyObjectByType<SFXGenericUIButtonComponent>((FindObjectsInactive)1);
			}
			if ((Object)(object)clickSound != (Object)null)
			{
				clickSound.PlayClick();
			}
		}

		private void OnDestroy()
		{
			CloseUI();
			if (registered)
			{
				UIManager instance = UIManager.Instance;
				if (instance != null)
				{
					instance.UnregisterUI((IUIManager)(object)this);
				}
			}
			if ((Object)(object)canvasRoot != (Object)null)
			{
				Object.Destroy((Object)(object)canvasRoot);
			}
		}
	}
	public sealed class LoanRules
	{
		public double MinPercent = 25.0;

		public double MaxPercent = 50.0;

		public double StepPercent = 5.0;

		public double MinInterest = 10.0;

		public double MaxInterest = 50.0;

		public double OverduePenalty;

		public double VoteSeconds = 30.0;

		public void Validate()
		{
			if (!new double[7] { MinPercent, MaxPercent, StepPercent, MinInterest, MaxInterest, OverduePenalty, VoteSeconds }.All((double x) => !double.IsNaN(x) && !double.IsInfinity(x)) || MinPercent <= 0.0 || MaxPercent <= MinPercent || MaxPercent > 10000.0 || StepPercent <= 0.0 || StepPercent > MaxPercent - MinPercent || MinInterest < 0.0 || MaxInterest < MinInterest || MaxInterest > 1000.0 || OverduePenalty < 0.0 || OverduePenalty > 1000.0 || VoteSeconds < 1.0 || VoteSeconds > 600.0)
			{
				throw new ArgumentException("Invalid loan configuration. See CONFIGURATION.md.");
			}
		}

		public double Snap(double percent)
		{
			if (double.IsNaN(percent) || double.IsInfinity(percent))
			{
				throw new ArgumentException("Invalid percentage.");
			}
			percent = Math.Max(MinPercent, Math.Min(MaxPercent, percent));
			if (percent >= MaxPercent)
			{
				return MaxPercent;
			}
			return Math.Min(MaxPercent, MinPercent + Math.Round((percent - MinPercent) / StepPercent, MidpointRounding.AwayFromZero) * StepPercent);
		}
	}
	public sealed class Quote
	{
		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public string Id;

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public int Day;

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public int DueDay;

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public BigNumber BaseQuota;

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public BigNumber Principal;

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public BigNumber Interest;

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public BigNumber Total;

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public double Percent;

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public double Rate;

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public double Penalty;

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public double VoteSeconds;

		public static Quote Create(int day, BigNumber quota, double percent, LoanRules rules)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			rules.Validate();
			if (quota <= BigNumber.Zero)
			{
				throw new InvalidOperationException("Mark needs a positive quota to lend against.");
			}
			percent = rules.Snap(percent);
			double num = rules.MinInterest + (percent - rules.MinPercent) / (rules.MaxPercent - rules.MinPercent) * (rules.MaxInterest - rules.MinInterest);
			BigNumber val = Whole(quota * (percent / 100.0));
			BigNumber val2 = Whole(val * (num / 100.0));
			if (val <= BigNumber.Zero || val + val2 > BigNumber.MaxValue)
			{
				throw new InvalidOperationException("This loan exceeds the game's money range.");
			}
			return new Quote
			{
				Id = Guid.NewGuid().ToString("N"),
				Day = day,
				DueDay = checked(day + 1),
				BaseQuota = quota,
				Percent = percent,
				Principal = val,
				Rate = num,
				Interest = val2,
				Total = val + val2,
				Penalty = rules.OverduePenalty,
				VoteSeconds = rules.VoteSeconds
			};
		}

		public static BigNumber Whole(BigNumber value)
		{
			//IL_0000: 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_000b: Unknown result type (might be due to invalid IL or missing references)
			if (value.Exponent >= 15)
			{
				return value;
			}
			return BigNumber.FromDouble(Math.Round(((BigNumber)(ref value)).ToDouble(), MidpointRounding.AwayFromZero));
		}
	}
	public sealed class Loan
	{
		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public string Id;

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public Quote Terms;

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public BigNumber Paid;

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public BigNumber Transferred;

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public string Status = "Outstanding";

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public int TransferDay = -1;

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public bool QuotaApplied;

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public bool QuotaCleared;
	}
	public sealed class Ledger
	{
		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public int Schema = 1;

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public string RunId = Guid.NewGuid().ToString("N");

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public List<int> UsedDays = new List<int>();

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public List<int> EndedDays = new List<int>();

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public List<Loan> Loans = new List<Loan>();

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public BigNumber AppliedQuotaDebt;

		[JsonProperty(/*Could not decode attribute arguments.*/)]
		public int AppliedDay = -1;

		[JsonIgnore]
		public bool HasUnsettledDebt => Loans.Any((Loan l) => l.Status == "Outstanding" || l.Status == "Defaulted" || (l.Status == "Transferred" && !l.QuotaCleared));

		[JsonIgnore]
		public bool HasDefaultedLoan => Loans.Any((Loan l) => l.Status == "Defaulted" || (l.Status == "Transferred" && !l.QuotaCleared));

		public void Validate()
		{
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: 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_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: 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_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			if (Schema != 1 || string.IsNullOrEmpty(RunId) || UsedDays == null || EndedDays == null || Loans == null || Loans.Any((Loan x) => x == null || x.Terms == null || string.IsNullOrEmpty(x.Id) || x.Terms.DueDay != x.Terms.Day + 1 || x.Terms.Principal <= BigNumber.Zero || x.Terms.Day < 0 || x.Terms.Interest < BigNumber.Zero || x.Terms.Total != x.Terms.Principal + x.Terms.Interest || x.Paid < BigNumber.Zero || x.Paid > x.Terms.Total || (x.Status != "Outstanding" && x.Status != "Repaid" && x.Status != "Transferred" && x.Status != "Defaulted")) || Loans.Select((Loan x) => x.Id).Distinct().Count() != Loans.Count)
			{
				throw new InvalidOperationException("Unsupported or damaged Mark Loans ledger. Restore the save backup.");
			}
			BigNumber val = BigNumber.Zero;
			foreach (Loan loan in Loans)
			{
				if ((loan.Status == "Repaid" && loan.Paid != loan.Terms.Total) || (loan.Status == "Transferred" && (loan.Paid >= loan.Terms.Total || loan.Transferred <= BigNumber.Zero || loan.TransferDay <= loan.Terms.DueDay)) || (loan.Status == "Defaulted" && (loan.Paid >= loan.Terms.Total || loan.Transferred != BigNumber.Zero || loan.QuotaApplied)) || (loan.QuotaCleared && !loan.QuotaApplied) || (loan.QuotaApplied && loan.Status != "Transferred"))
				{
					throw new InvalidOperationException("Inconsistent Mark Loans settlement record. Restore the save backup.");
				}
				if (loan.QuotaApplied && !loan.QuotaCleared)
				{
					val += loan.Transferred;
				}
			}
			if (val != AppliedQuotaDebt)
			{
				throw new InvalidOperationException("Inconsistent quota debt. Restore the save backup.");
			}
		}

		public bool Accept(string proposalId, Quote terms)
		{
			if (HasUnsettledDebt || UsedDays.Contains(terms.Day) || EndedDays.Contains(terms.Day) || Loans.Any((Loan x) => x.Id == proposalId))
			{
				return false;
			}
			Loans.Add(new Loan
			{
				Id = proposalId,
				Terms = terms
			});
			UsedDays.Add(terms.Day);
			return true;
		}

		public BigNumber Repay(string id, BigNumber balance)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			Loan loan = Loans.FirstOrDefault((Loan x) => x.Id == id && x.Status == "Outstanding");
			if (loan == null)
			{
				throw new InvalidOperationException("That loan has already been settled.");
			}
			BigNumber val = loan.Terms.Total - loan.Paid;
			if (balance < val)
			{
				throw new InvalidOperationException("Team funds cannot cover this repayment yet.");
			}
			loan.Paid += val;
			loan.Status = "Repaid";
			return val;
		}

		public BigNumber EndDay(int day, BigNumber balance)
		{
			//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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: 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_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: 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_0154: Unknown result type (might be due to invalid IL or missing references)
			if (EndedDays.Contains(day))
			{
				return BigNumber.Zero;
			}
			BigNumber val = BigNumber.Zero;
			foreach (Loan item in from x in Loans
				where x.Status == "Outstanding" && x.Terms.DueDay <= day
				orderby x.Terms.DueDay, x.Terms.Day
				select x)
			{
				BigNumber val2 = item.Terms.Total - item.Paid;
				BigNumber val3 = BigNumber.Min(val2, BigNumber.Max(BigNumber.Zero, balance - val));
				item.Paid += val3;
				val += val3;
				if (val2 - val3 > BigNumber.Zero)
				{
					item.Status = "Defaulted";
				}
				else
				{
					item.Status = "Repaid";
				}
			}
			EndedDays.Add(day);
			return val;
		}

		public BigNumber ApplyQuota(int day)
		{
			//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_004d: 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_0055: 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_0079: 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_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_0095: Unknown result type (might be due to invalid IL or missing references)
			BigNumber val = BigNumber.Zero;
			foreach (Loan item in Loans.Where((Loan x) => x.Status == "Transferred" && !x.QuotaApplied && x.TransferDay <= day))
			{
				val += item.Transferred;
				item.QuotaApplied = true;
			}
			AppliedQuotaDebt += val;
			AppliedDay = day;
			return val;
		}

		public BigNumber ClearQuota()
		{
			//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_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_0064: Unknown result type (might be due to invalid IL or missing references)
			BigNumber appliedQuotaDebt = AppliedQuotaDebt;
			foreach (Loan item in Loans.Where((Loan x) => x.QuotaApplied))
			{
				item.QuotaCleared = true;
			}
			AppliedQuotaDebt = BigNumber.Zero;
			return appliedQuotaDebt;
		}

		public Ledger Copy()
		{
			return Codec.Read<Ledger>(Codec.Write(this));
		}

		public Ledger ViewForDay(int day)
		{
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			return new Ledger
			{
				RunId = RunId,
				Schema = Schema,
				UsedDays = UsedDays.Where((int d) => d == day).ToList(),
				EndedDays = EndedDays.Where((int d) => d == day).ToList(),
				Loans = Loans.Where((Loan l) => l.Status == "Outstanding" || l.Status == "Defaulted" || (l.Status == "Transferred" && !l.QuotaCleared)).ToList(),
				AppliedQuotaDebt = AppliedQuotaDebt,
				AppliedDay = AppliedDay
			};
		}
	}
	public sealed class Proposal
	{
		public string Id = Guid.NewGuid().ToString("N");

		public Quote Terms;

		public string Borrower;

		public List<string> Eligible;

		public List<string> Approved = new List<string>();

		public List<string> Rejected = new List<string>();

		public int Required;

		public double Deadline;

		public static Proposal Start(Quote quote, string borrower, IEnumerable<string> players, double now)
		{
			List<string> list = players.Distinct().ToList();
			if (!list.Contains(borrower) || list.Count == 0)
			{
				throw new InvalidOperationException("Borrower is not connected.");
			}
			return new Proposal
			{
				Terms = quote,
				Borrower = borrower,
				Eligible = list,
				Required = (list.Count + 1) / 2,
				Approved = new List<string> { borrower },
				Deadline = now + quote.VoteSeconds
			};
		}

		public bool Vote(string player, bool approve, double now)
		{
			if (now >= Deadline || !Eligible.Contains(player) || Approved.Contains(player) || Rejected.Contains(player))
			{
				return false;
			}
			(approve ? Approved : Rejected).Add(player);
			return true;
		}

		public bool Passed(double now)
		{
			if (now < Deadline)
			{
				return Approved.Count >= Required;
			}
			return false;
		}

		public bool Failed(double now)
		{
			if (!(now >= Deadline))
			{
				return Eligible.Count - Rejected.Count < Required;
			}
			return true;
		}
	}
	internal sealed class MarkVisual : IDisposable
	{
		private readonly Plugin plugin;

		private readonly ConfigEntry<float> x;

		private readonly ConfigEntry<float> y;

		private readonly ConfigEntry<float> z;

		private readonly ConfigEntry<float> height;

		private GameObject cacheRoot;

		private GameObject template;

		private GameObject mark;

		private ElevatorManager elevator;

		private float nextScan;

		private bool warned;

		private readonly RaycastHit[] floorHits = (RaycastHit[])(object)new RaycastHit[16];

		private Vector3 placedOffset;

		private float placedHeight;

		private static readonly FieldRef<ElevatorManager, Collider> ElevatorBounds = AccessTools.FieldRefAccess<ElevatorManager, Collider>("checkCollider");

		internal GameObject Mark => mark;

		internal float[] Offset => new float[3] { x.Value, y.Value, z.Value };

		internal float Height => height.Value;

		internal MarkVisual(Plugin owner, ConfigFile config)
		{
			plugin = owner;
			x = config.Bind<float>("Mark", "CornerOffsetX", -5.2f, "Local elevator X position. All peers should use the same values.");
			y = config.Bind<float>("Mark", "CornerOffsetY", 0f, "Local elevator floor height offset.");
			z = config.Bind<float>("Mark", "CornerOffsetZ", 3.4f, "Local elevator Z position.");
			height = config.Bind<float>("Mark", "ModelHeight", 2.4f, "Loan shark visual height, in Unity units.");
		}

		internal void Capture()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_00e9: 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)
			if ((Object)(object)template != (Object)null)
			{
				return;
			}
			cacheRoot = new GameObject("Mark Loans Visual Cache");
			Object.DontDestroyOnLoad((Object)(object)cacheRoot);
			cacheRoot.SetActive(false);
			string text = Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location), "shark");
			if (!File.Exists(Path.Combine(text, "model.json")))
			{
				Object.Destroy((Object)(object)cacheRoot);
				cacheRoot = null;
				return;
			}
			try
			{
				template = SharkModel.Load(text, cacheRoot.transform);
			}
			catch (Exception ex)
			{
				plugin.Logger.LogError((object)("Cannot load extracted game's shark model: " + ex.Message));
				Object.Destroy((Object)(object)cacheRoot);
				cacheRoot = null;
				return;
			}
			((Object)template).name = "Mark LoanShark Template";
			template.transform.localPosition = Vector3.zero;
			template.transform.localRotation = Quaternion.identity;
			plugin.Logger.LogInfo((object)"Cached original loan shark pose using static meshes.");
		}

		internal void Tick()
		{
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: 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_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Expected O, but got Unknown
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: 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_03b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0481: Unknown result type (might be due to invalid IL or missing references)
			//IL_0486: Unknown result type (might be due to invalid IL or missing references)
			//IL_0497: Unknown result type (might be due to invalid IL or missing references)
			//IL_049c: Unknown result type (might be due to invalid IL or missing references)
			//IL_04aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_04af: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0522: Unknown result type (might be due to invalid IL or missing references)
			//IL_0530: Unknown result type (might be due to invalid IL or missing references)
			//IL_0535: Unknown result type (might be due to invalid IL or missing references)
			//IL_053f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0544: Unknown result type (might be due to invalid IL or missing references)
			//IL_056b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0570: Unknown result type (might be due to invalid IL or missing references)
			//IL_0590: Unknown result type (might be due to invalid IL or missing references)
			//IL_0595: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0615: Unknown result type (might be due to invalid IL or missing references)
			//IL_061d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0629: Unknown result type (might be due to invalid IL or missing references)
			//IL_063b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0645: Unknown result type (might be due to invalid IL or missing references)
			//IL_0685: Unknown result type (might be due to invalid IL or missing references)
			//IL_069e: Unknown result type (might be due to invalid IL or missing references)
			//IL_043a: Unknown result type (might be due to invalid IL or missing references)
			//IL_043f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0445: Unknown result type (might be due to invalid IL or missing references)
			//IL_0469: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0504: Unknown result type (might be due to invalid IL or missing references)
			//IL_0509: Unknown result type (might be due to invalid IL or missing references)
			if (Time.unscaledTime < nextScan)
			{
				return;
			}
			nextScan = Time.unscaledTime + 1f;
			Capture();
			ElevatorManager val = ((!NetworkClient.active) ? null : (((Object)(object)elevator != (Object)null) ? elevator : Object.FindAnyObjectByType<ElevatorManager>()));
			if ((Object)(object)val == (Object)null || !NetworkClient.active)
			{
				if ((Object)(object)mark != (Object)null)
				{
					Object.Destroy((Object)(object)mark);
				}
				mark = null;
				elevator = null;
				return;
			}
			float[] array = plugin.Menu.View?.MarkOffset ?? Offset;
			float num = Mathf.Clamp(plugin.Menu.View?.MarkHeight ?? Height, 0.5f, 5f);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(array[0], array[1], array[2]);
			if ((Object)(object)mark != (Object)null && (Object)(object)val == (Object)(object)elevator && val2 == placedOffset && num == placedHeight)
			{
				return;
			}
			if ((Object)(object)template == (Object)null)
			{
				if (!warned)
				{
					plugin.Logger.LogWarning((object)"LoanShark_Body is unavailable. Install the shark folder next to MarkLoans.dll; no substitute model will be used.");
					warned = true;
				}
				return;
			}
			if ((Object)(object)mark != (Object)null)
			{
				Object.Destroy((Object)(object)mark);
			}
			elevator = val;
			placedOffset = val2;
			placedHeight = num;
			mark = new GameObject("Mark The Shark", new Type[2]
			{
				typeof(BoxCollider),
				typeof(MarkInteractable)
			});
			mark.transform.SetParent(((Component)elevator).transform, false);
			mark.transform.localPosition = new Vector3(array[0], array[1], array[2]);
			BoxCollider component = mark.GetComponent<BoxCollider>();
			GameObject val3 = Object.Instantiate<GameObject>(template, mark.transform);
			val3.transform.localPosition = Vector3.zero;
			val3.transform.localRotation = Quaternion.Euler(0f, 135f, 0f);
			val3.SetActive(true);
			Renderer[] componentsInChildren = val3.GetComponentsInChildren<Renderer>(true);
			if (componentsInChildren.Length != 0)
			{
				Bounds val4 = VisibleBounds(componentsInChildren);
				if (((Bounds)(ref val4)).size.y > 0.01f)
				{
					Transform transform = val3.transform;
					transform.localScale *= num / ((Bounds)(ref val4)).size.y;
					val4 = VisibleBounds(componentsInChildren);
					Vector3 val5 = default(Vector3);
					((Vector3)(ref val5))..ctor(mark.transform.position.x - ((Bounds)(ref val4)).center.x, mark.transform.position.y - ((Bounds)(ref val4)).min.y, mark.transform.position.z - ((Bounds)(ref val4)).center.z);
					Transform transform2 = val3.transform;
					transform2.position += val5;
				}
			}
			Vector3 position = mark.transform.position;
			position.y = (((Object)(object)elevator.playerSpawnPosition != (Object)null) ? (elevator.playerSpawnPosition.position.y + 1f) : (position.y + 4f));
			int num2 = Physics.RaycastNonAlloc(position, Vector3.down, floorHits, 12f, -1, (QueryTriggerInteraction)1);
			float num3 = float.MaxValue;
			for (int i = 0; i < num2; i++)
			{
				RaycastHit val6 = floorHits[i];
				if (!(((RaycastHit)(ref val6)).normal.y < 0.7f) && !(((RaycastHit)(ref val6)).distance >= num3) && !((Component)((RaycastHit)(ref val6)).collider).transform.IsChildOf(mark.transform) && !((Object)(object)((Component)((RaycastHit)(ref val6)).collider).GetComponentInParent<PlayerController>() != (Object)null) && !((Object)(object)((Component)((RaycastHit)(ref val6)).collider).GetComponentInParent<InteractableBase>() != (Object)null))
				{
					num3 = ((RaycastHit)(ref val6)).distance;
					Vector3 position2 = mark.transform.position;
					position2.y = ((RaycastHit)(ref val6)).point.y + 0.03f + array[1];
					mark.transform.position = position2;
				}
			}
			Bounds val7 = VisibleBounds(componentsInChildren);
			component.center = mark.transform.InverseTransformPoint(((Bounds)(ref val7)).center);
			Bounds val8 = default(Bounds);
			((Bounds)(ref val8))..ctor(component.center, Vector3.zero);
			for (int j = 0; j < 8; j++)
			{
				((Bounds)(ref val8)).Encapsulate(mark.transform.InverseTransformPoint(((Bounds)(ref val7)).center + Vector3.Scale(((Bounds)(ref val7)).extents, new Vector3((float)(((j & 1) != 0) ? 1 : (-1)), (float)(((j & 2) != 0) ? 1 : (-1)), (float)(((j & 4) != 0) ? 1 : (-1))))));
			}
			component.center = ((Bounds)(ref val8)).center;
			component.size = ((Bounds)(ref val8)).size + Vector3.one * 0.2f;
			plugin.Logger.LogInfo((object)("Mark placed: visible bottom=" + ((Bounds)(ref val7)).min.y.ToString("0.00") + ", visible height=" + ((Bounds)(ref val7)).size.y.ToString("0.00") + ", full-body collider=" + ((object)component.size/*cast due to .constrained prefix*/).ToString()));
			GameObject val9 = new GameObject("Mark name", new Type[2]
			{
				typeof(TextMeshPro),
				typeof(MarkNameFacing)
			});
			val9.transform.SetParent(mark.transform, false);
			val9.transform.position = new Vector3(((Bounds)(ref val7)).center.x, ((Bounds)(ref val7)).max.y + 0.35f, ((Bounds)(ref val7)).center.z);
			TextMeshPro component2 = val9.GetComponent<TextMeshPro>();
			((TMP_Text)component2).text = "MARK THE SHARK\n<size=65%>Loans • Debts • Questionable advice</size>";
			((TMP_Text)component2).fontSize = 2f;
			((TMP_Text)component2).alignment = (TextAlignmentOptions)514;
			((Graphic)component2).color = new Color(1f, 0.81f, 0.25f);
			((TMP_Text)component2).rectTransform.sizeDelta = new Vector2(5f, 1f);
		}

		private static Bounds VisibleBounds(Renderer[] renderers)
		{
			//IL_0004: 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_0018: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			bool flag = true;
			Bounds result = default(Bounds);
			for (int i = 0; i < renderers.Length; i++)
			{
				Bounds bounds = renderers[i].bounds;
				if (flag)
				{
					result = bounds;
					flag = false;
				}
				else
				{
					((Bounds)(ref result)).Encapsulate(bounds);
				}
			}
			return result;
		}

		internal bool Near(Vector3 player)
		{
			//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)
			//IL_004f: 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_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_006b: 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)
			if ((Object)(object)mark == (Object)null || (Object)(object)elevator == (Object)null || !mark.activeInHierarchy)
			{
				return false;
			}
			Collider val = ElevatorBounds.Invoke(elevator);
			if ((Object)(object)val != (Object)null)
			{
				Bounds bounds = val.bounds;
				if (((Bounds)(ref bounds)).Contains(player + Vector3.up * 0.5f))
				{
					return Vector3.Distance(player, mark.transform.position) <= 4.5f;
				}
			}
			return false;
		}

		public void Dispose()
		{
			if ((Object)(object)mark != (Object)null)
			{
				Object.Destroy((Object)(object)mark);
			}
			if ((Object)(object)cacheRoot != (Object)null)
			{
				Object.Destroy((Object)(object)cacheRoot);
			}
		}
	}
	internal sealed class MarkNameFacing : MonoBehaviour
	{
		private void LateUpdate()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			Camera main = Camera.main;
			if ((Object)(object)main != (Object)null)
			{
				((Component)this).transform.rotation = ((Component)main).transform.rotation;
			}
		}
	}
	internal sealed class MarkInteractable : MonoBehaviour, IInteractable
	{
		public float HoldDuration { get; set; } = 0.25f;

		public bool HoldInteract { get; set; }

		public bool IsInteractable { get; set; } = true;

		public bool MeetRequirements { get; set; } = true;

		public bool IsBeingHovered { get; set; }

		public bool IsBeingHold { get; set; }

		public float HoldProgress { get; set; }

		public string TooltipMessage { get; set; } = "Press [E] to talk loans";

		public string InteractableName { get; set; } = "Mark The Shark";

		public CursorType CursorType { get; set; } = (CursorType)1;

		public event Action<IInteractable> OnInteractableChanged
		{
			add
			{
			}
			remove
			{
			}
		}

		public void OnHover(PlayerInteract p)
		{
			IsBeingHovered = true;
		}

		public void OnHoverExit(PlayerInteract p)
		{
			IsBeingHovered = false;
		}

		public void OnHold(PlayerInteract p)
		{
		}

		public void OnHoldExit(PlayerInteract p)
		{
		}

		public void OnInteract(PlayerInteract p)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (((NetworkBehaviour)p).isLocalPlayer && (int)InputEvents.ActiveLayer == 0 && Plugin.Instance.Visual.Near(((Component)p).transform.position))
			{
				Plugin.Instance.Menu.OpenUI();
			}
		}

		public void ServerOnHover(PlayerInteract p)
		{
		}

		public void ServerOnHoverExit(PlayerInteract p)
		{
		}

		public void ServerOnHold(PlayerInteract p)
		{
		}

		public void ServerOnHoldExit(PlayerInteract p)
		{
		}

		public void ServerOnInteract(PlayerInteract p)
		{
		}

		public void RpcOnInteract(PlayerInteract p)
		{
		}
	}
	public struct MarkLoanRequest : NetworkMessage
	{
		public string Kind;

		public string Id;

		public string Version;

		public double Percent;

		public bool Approve;
	}
	public struct MarkLoanReply : NetworkMessage
	{
		public string Json;
	}
	public sealed class View
	{
		public string Session;

		public string Notice;

		public Ledger Ledger;

		public Proposal Proposal;

		public Quote Quote;

		public LoanRules Rules;

		public BigNumber BaseQuota;

		public int Day;

		public bool Ready;

		public double Now;

		public float[] MarkOffset;

		public float MarkHeight;
	}
	internal static class Wire
	{
		internal static void Init()
		{
			Writer<MarkLoanRequest>.write = delegate(NetworkWriter w, MarkLoanRequest m)
			{
				NetworkWriterExtensions.WriteString(w, m.Kind);
				NetworkWriterExtensions.WriteString(w, m.Id);
				NetworkWriterExtensions.WriteString(w, m.Version);
				NetworkWriterExtensions.WriteDouble(w, m.Percent);
				NetworkWriterExtensions.WriteBool(w, m.Approve);
			};
			Reader<MarkLoanRequest>.read = (NetworkReader r) => new MarkLoanRequest
			{
				Kind = NetworkReaderExtensions.ReadString(r),
				Id = NetworkReaderExtensions.ReadString(r),
				Version = NetworkReaderExtensions.ReadString(r),
				Percent = NetworkReaderExtensions.ReadDouble(r),
				Approve = NetworkReaderExtensions.ReadBool(r)
			};
			Writer<MarkLoanReply>.write = delegate(NetworkWriter w, MarkLoanReply m)
			{
				NetworkWriterExtensions.WriteString(w, m.Json);
			};
			Reader<MarkLoanReply>.read = (NetworkReader r) => new MarkLoanReply
			{
				Json = NetworkReaderExtensions.ReadString(r)
			};
		}

		internal static void RegisterServer()
		{
			NetworkServer.ReplaceHandler<MarkLoanRequest>((Action<NetworkConnectionToClient, MarkLoanRequest>)Plugin.Instance.Request, true);
		}

		internal static void RegisterClient()
		{
			NetworkClient.ReplaceHandler<MarkLoanReply>((Action<MarkLoanReply>)delegate(MarkLoanReply m)
			{
				try
				{
					Plugin.Instance.Receive(Codec.Read<View>(m.Json));
				}
				catch (Exception ex)
				{
					Plugin.Instance.Logger.LogError((object)("Invalid Mark Loans host reply: " + ex.Message));
				}
			}, true);
		}

		internal static void Send(string kind, string id = null, double percent = 0.0, bool approve = false)
		{
			if (NetworkClient.isConnected)
			{
				NetworkClient.Send<MarkLoanRequest>(new MarkLoanRequest
				{
					Kind = kind,
					Id = id,
					Percent = percent,
					Approve = approve,
					Version = "1.0.5"
				}, 0);
			}
		}
	}
	public static class Codec
	{
		private sealed class NumberConverter : JsonConverter
		{
			public override bool CanConvert(Type t)
			{
				return t == typeof(BigNumber);
			}

			public override void WriteJson(JsonWriter w, object value, JsonSerializer s)
			{
				//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_0019: 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)
				BigNumber val = (BigNumber)value;
				w.WriteStartObject();
				w.WritePropertyName("m");
				w.WriteValue(val.Mantissa);
				w.WritePropertyName("e");
				w.WriteValue(val.Exponent);
				w.WriteEndObject();
			}

			public override object ReadJson(JsonReader r, Type t, object existing, JsonSerializer s)
			{
				//IL_0044: 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)
				JObject obj = JObject.Load(r);
				double num = ((JToken)obj).Value<double>((object)"m");
				long num2 = ((JToken)obj).Value<long>((object)"e");
				if (double.IsNaN(num) || double.IsInfinity(num) || num2 < -1000000000 || num2 > 1000000000)
				{
					throw new JsonSerializationException("Invalid money value.");
				}
				return (object)new BigNumber(num, num2);
			}
		}

		private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
		{
			Converters = new List<JsonConverter> { (JsonConverter)(object)new NumberConverter() },
			MaxDepth = 24,
			TypeNameHandling = (TypeNameHandling)0
		};

		public static string Write(object value)
		{
			return JsonConvert.SerializeObject(value, Settings);
		}

		public static T Read<T>(string json)
		{
			return JsonConvert.DeserializeObject<T>(json, Settings);
		}
	}
	internal static class Persistence
	{
		private sealed class Attached
		{
			public Ledger Ledger;

			public bool Invalid;
		}

		internal const string Key = "markLoans";

		private static readonly ConditionalWeakTable<SaveData, Attached> Loaded = new ConditionalWeakTable<SaveData, Attached>();

		internal static bool LastWriteSucceeded;

		internal static bool Resetting;

		internal static SaveData ResetOriginal;

		internal static readonly FieldRef<SaveManager, SaveData> Current = AccessTools.FieldRefAccess<SaveManager, SaveData>("currentSaveData");

		internal static readonly FieldRef<SaveManager, bool> HasLoaded = AccessTools.FieldRefAccess<SaveManager, bool>("hasLoadedGame");

		internal static void AttachRead(string json, object result)
		{
			SaveData val = (SaveData)((result is SaveData) ? result : null);
			if (val == null)
			{
				return;
			}
			Attached orCreateValue = Loaded.GetOrCreateValue(val);
			try
			{
				JToken val2 = JObject.Parse(json)["markLoans"];
				orCreateValue.Ledger = ((val2 == null) ? new Ledger() : Codec.Read<Ledger>(((object)val2).ToString()));
				orCreateValue.Ledger.Validate();
			}
			catch (Exception ex)
			{
				orCreateValue.Invalid = true;
				Plugin.Instance.Logger.LogError((object)("Mark Loans save data could not be read: " + ex.Message));
			}
		}

		internal static void AttachWrite(object obj, ref string json)
		{
			SaveData val = (SaveData)((obj is SaveData) ? obj : null);
			if (val != null)
			{
				Attached orCreateValue = Loaded.GetOrCreateValue(val);
				if (NetworkServer.active && (Object)(object)NetworkSingleton<SaveManager>.Instance != (Object)null && val == Current.Invoke(NetworkSingleton<SaveManager>.Instance) && Plugin.Instance.Loaded)
				{
					orCreateValue.Ledger = Plugin.Instance.State;
				}
				if (orCreateValue.Invalid)
				{
					throw new InvalidOperationException("Refusing to overwrite an unreadable Mark Loans ledger.");
				}
				if (orCreateValue.Ledger != null)
				{
					JObject val2 = JObject.Parse(json);
					val2["markLoans"] = JToken.Parse(Codec.Write(orCreateValue.Ledger));
					json = ((JToken)val2).ToString((Formatting)1, Array.Empty<JsonConverter>());
				}
			}
		}

		internal static void OnLoad(SaveManager manager, bool wasLoaded)
		{
			if (!(!NetworkServer.active || wasLoaded) && HasLoaded.Invoke(manager) && Current.Invoke(manager) != null)
			{
				Attached orCreateValue = Loaded.GetOrCreateValue(Current.Invoke(manager));
				Plugin.Instance.State = orCreateValue.Ledger ?? new Ledger();
				Plugin.Instance.Loaded = !orCreateValue.Invalid;
				Plugin.Instance.Faulted = !Plugin.Instance.StartupHealthy || orCreateValue.Invalid;
				Plugin.Instance.CancelProposal();
				Plugin.Instance.ResetLossRequest();
				if (orCreateValue.Invalid)
				{
					Plugin.Instance.Logger.LogError((object)"Financial actions disabled because the save ledger is damaged.");
				}
			}
		}

		internal static void NewRun()
		{
			if (NetworkServer.active)
			{
				Plugin.Instance.State = new Ledger();
				Plugin.Instance.ResetLossRequest();
				Plugin.Instance.Loaded = true;
				Plugin.Instance.Faulted = !Plugin.Instance.StartupHealthy;
				Plugin.Instance.CancelProposal();
			}
		}

		internal static void WriteAtomic(string path, string contents)
		{
			LastWriteSucceeded = false;
			AtomicFile.Write(path, contents);
			LastWriteSucceeded = true;
		}
	}
	[HarmonyPatch(typeof(JsonUtility), "FromJson", new Type[]
	{
		typeof(string),
		typeof(Type)
	})]
	internal static class ReadSavePatch
	{
		private static void Postfix(string json, object __result)
		{
			Persistence.AttachRead(json, __result);
		}
	}
	[HarmonyPatch(typeof(JsonUtility), "ToJson", new Type[]
	{
		typeof(object),
		typeof(bool)
	})]
	internal static class WriteSavePatch
	{
		private static void Postfix(object obj, ref string __result)
		{
			Persistence.AttachWrite(obj, ref __result);
		}
	}
	[HarmonyPatch(typeof(SaveManager), "LoadGame")]
	internal static class LoadPatch
	{
		private static void Prefix(SaveManager __instance, out bool __state)
		{
			__state = Persistence.HasLoaded.Invoke(__instance);
		}

		private static void Postfix(SaveManager __instance, bool __state)
		{
			Persistence.OnLoad(__instance, __state);
		}
	}
	[HarmonyPatch(typeof(SaveManager), "ResetCurrentSaveToDefaults")]
	internal static class ResetPatch
	{
		private static void Prefix(SaveManager __instance)
		{
			Persistence.Resetting = NetworkServer.active;
			Persistence.ResetOriginal = Persistence.Current.Invoke(__instance);
		}

		private static Exception Finalizer(Exception __exception)
		{
			Persistence.Resetting = false;
			Persistence.ResetOriginal = null;
			return __exception;
		}
	}
	[HarmonyPatch(typeof(SaveManager), "SaveGameDataToFile")]
	internal static class AtomicSavePatch
	{
		private static void Prefix(SaveData saveData)
		{
			if (Persistence.Resetting && saveData != Persistence.ResetOriginal && (Object)(object)NetworkSingleton<SaveManager>.Instance != (Object)null && saveData == Persistence.Current.Invoke(NetworkSingleton<SaveManager>.Instance))
			{
				Persistence.NewRun();
				Persistence.ResetOriginal = saveData;
			}
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			MethodInfo original = AccessTools.Method(typeof(File), "WriteAllText", new Type[2]
			{
				typeof(string),
				typeof(string)
			}, (Type[])null);
			MethodInfo replacement = AccessTools.Method(typeof(Persistence), "WriteAtomic", (Type[])null, (Type[])null);
			bool found = false;
			foreach (CodeInstruction instruction in instructions)
			{
				if (CodeInstructionExtensions.Calls(instruction, original))
				{
					instruction.operand = replacement;
					found = true;
				}
				yield return instruction;
			}
			if (!found)
			{
				throw new MissingMethodException("The game's save writer changed; Mark Loans cannot ensure atomic saves.");
			}
		}
	}
	[HarmonyPatch(typeof(GameManager), "OnTimerEnd")]
	internal static class TimerEndPatch
	{
		private static bool Prefix(GameManager __instance, ref IEnumerator __result)
		{
			if (!Plugin.Instance.EndDay(__instance.daysPassed))
			{
				return true;
			}
			Plugin.Instance.BeginLoanLoss();
			__result = Enumerable.Empty<object>().GetEnumerator();
			return false;
		}
	}
	[HarmonyPatch(typeof(GameManager), "ProgressGame")]
	internal static class ProgressLoanDeadlinePatch
	{
		private static bool Prefix(GameManager __instance)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Invalid comparison between Unknown and I4
			if (!NetworkServer.active || !Plugin.Instance.Loaded || (int)__instance.state == 2)
			{
				return true;
			}
			bool flag = Plugin.Instance.State.HasDefaultedLoan;
			if ((int)__instance.state == 1)
			{
				flag = Plugin.Instance.EndDay(__instance.daysPassed);
			}
			if (!flag)
			{
				return true;
			}
			Plugin.Instance.BeginLoanLoss();
			return false;
		}
	}
	[HarmonyPatch(typeof(NetworkManager), "ServerChangeScene")]
	internal static class DefaultLossRedirectPatch
	{
		private static void Prefix(ref string __0)
		{
			if (NetworkServer.active && Plugin.Instance.Loaded && Plugin.Instance.State.HasDefaultedLoan && (__0 == "HomeScene" || __0 == "CasinoScene"))
			{
				__0 = "LoseStateScene";
			}
		}
	}
	[HarmonyPatch(typeof(GameManager), "ServerPayDebt")]
	internal static class FailedLoanQuotaRewardPatch
	{
		private static bool Prefix()
		{
			if (NetworkServer.active && Plugin.Instance.Loaded)
			{
				return !Plugin.Instance.State.HasDefaultedLoan;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(GameManager), "set_NetworkdaysPassed")]
	internal static class DayPatch
	{
		private static void Prefix(GameManager __instance, int value)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			if (NetworkServer.active && (int)__instance.state == 1 && value == __instance.daysPassed + 1)
			{
				Plugin.Instance.EndDay(__instance.daysPassed);
			}
		}
	}
	[HarmonyPatch(typeof(GameManager), "ProgressNextQuota")]
	internal static class QuotaPatch
	{
		private static void Prefix(GameManager __instance)
		{
			//IL_0015: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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)
			if (NetworkServer.active && Plugin.Instance.Loaded)
			{
				__instance.currentQuota = BigNumber.Max(BigNumber.Zero, __instance.currentQuota - Plugin.Instance.State.ClearQuota());
			}
		}

		private static void Postfix(GameManager __instance)
		{
			//IL_0016: 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)
			if (NetworkServer.active && Plugin.Instance.Loaded)
			{
				__instance.currentQuota += Plugin.Instance.State.ApplyQuota(__instance.daysPassed);
			}
		}
	}
	[HarmonyPatch(typeof(CustomNetworkManager), "OnStartServer")]
	internal static class ServerStartPatch
	{
		private static void Postfix()
		{
			Wire.RegisterServer();
		}
	}
	[HarmonyPatch(typeof(CustomNetworkManager), "OnClientConnect")]
	internal static class ClientStartPatch
	{
		private static void Prefix()
		{
			Wire.RegisterClient();
		}
	}
	[HarmonyPatch(typeof(CustomNetworkManager), "OnStopClient")]
	internal static class ClientStopPatch
	{
		private static void Postfix()
		{
			Plugin.Instance.StopSession();
		}
	}
	[HarmonyPatch(typeof(EscapeMenu), "ToggleEscapeMenu")]
	internal static class EscapePatch
	{
		private static bool Prefix()
		{
			return !Plugin.Instance.Menu.BlocksEscape;
		}
	}
	[BepInPlugin("local.markloans", "Mark Loans", "1.0.5")]
	public sealed class Plugin : BaseUnityPlugin
	{
		private sealed class Peer
		{
			public string Session = Guid.NewGuid().ToString("N");

			public Quote Quote;

			public double QuoteExpiry;

			public double LastRequest;
		}

		public const string Version = "1.0.5";

		internal static Plugin Instance;

		internal Ledger State = new Ledger();

		internal bool Loaded;

		internal bool Faulted;

		internal bool StartupHealthy;

		internal LoanMenu Menu;

		internal MarkVisual Visual;

		private Harmony harmony;

		private Proposal proposal;

		private readonly Dictionary<NetworkConnectionToClient, Peer> peers = new Dictionary<NetworkConnectionToClient, Peer>();

		private ConfigEntry<double> min;

		private ConfigEntry<double> max;

		private ConfigEntry<double> step;

		private ConfigEntry<double> minRate;

		private ConfigEntry<double> maxRate;

		private ConfigEntry<double> duration;

		private float nextHello;

		private float nextBroadcast;

		private bool busy;

		private bool snapshotSent;

		private bool lastReady;

		private int lastDay;

		private string lastRun;

		private BigNumber lastQuota;

		private bool lossRequested;

		private static readonly FieldRef<GameManager, bool> Transitioning = AccessTools.FieldRefAccess<GameManager, bool>("_isTransitioning");

		internal ManualLogSource Logger => ((BaseUnityPlugin)this).Logger;

		internal LoanRules Rules => new LoanRules
		{
			MinPercent = min.Value,
			MaxPercent = max.Value,
			StepPercent = step.Value,
			MinInterest = minRate.Value,
			MaxInterest = maxRate.Value,
			OverduePenalty = 0.0,
			VoteSeconds = duration.Value
		};

		internal BigNumber BaseQuota
		{
			get
			{
				//IL_0032: 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_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)NetworkSingleton<GameManager>.Instance == (Object)null))
				{
					return BigNumber.Max(BigNumber.Zero, NetworkSingleton<GameManager>.Instance.currentQuota - State.AppliedQuotaDebt);
				}
				return BigNumber.Zero;
			}
		}

		private bool CanBorrow
		{
			get
			{
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Invalid comparison between Unknown and I4
				if (Loaded && !Faulted && (Object)(object)NetworkSingleton<GameManager>.Instance != (Object)null && (int)NetworkSingleton<GameManager>.Instance.state == 1 && !State.HasUnsettledDebt && !State.UsedDays.Contains(NetworkSingleton<GameManager>.Instance.daysPassed))
				{
					return !State.EndedDays.Contains(NetworkSingleton<GameManager>.Instance.daysPassed);
				}
				return false;
			}
		}

		private void Awake()
		{
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Expected O, but got Unknown
			Instance = this;
			min = ((BaseUnityPlugin)this).Config.Bind<double>("Loans", "MinimumQuotaPercent", 25.0, "Minimum borrowing percentage of base quota.");
			max = ((BaseUnityPlugin)this).Config.Bind<double>("Loans", "MaximumQuotaPercent", 50.0, "Maximum borrowing percentage of base quota.");
			step = ((BaseUnityPlugin)this).Config.Bind<double>("Loans", "SliderStepPercent", 5.0, "Percentage point increment; maximum is always selectable.");
			minRate = ((BaseUnityPlugin)this).Config.Bind<double>("Interest", "MinimumPercent", 10.0, "One-time interest at minimum borrowing.");
			maxRate = ((BaseUnityPlugin)this).Config.Bind<double>("Interest", "MaximumPercent", 50.0, "One-time interest at maximum borrowing.");
			duration = ((BaseUnityPlugin)this).Config.Bind<double>("Voting", "DurationSeconds", 30.0, "Vote timeout in real seconds.");
			Visual = new MarkVisual(this, ((BaseUnityPlugin)this).Config);
			Menu = ((Component)this).gameObject.AddComponent<LoanMenu>();
			Wire.Init();
			harmony = new Harmony("local.markloans");
			try
			{
				Rules.Validate();
				harmony.PatchAll(typeof(Plugin).Assembly);
				StartupHealthy = true;
			}
			catch (Exception ex)
			{
				Faulted = true;
				Logger.LogError((object)("Mark Loans disabled: " + ex));
			}
			SceneManager.sceneLoaded += SceneLoaded;
			Logger.LogInfo((object)"Mark Loans 1.0.5 loaded. All players must install this version. Multiplayer validation pending.");
		}

		private void SceneLoaded(Scene scene, LoadSceneMode mode)
		{
			Menu.CloseUI();
			Visual.Capture();
			if (NetworkServer.active)
			{
				CancelProposal();
			}
		}

		private void Update()
		{
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			if (Faulted)
			{
				return;
			}
			Visual.Tick();
			if (NetworkClient.isConnected && Time.unscaledTime >= nextHello)
			{
				nextHello = Time.unscaledTime + 2f;
				if (Menu.View == null)
				{
					Wire.Send("Hello");
				}
			}
			if (!NetworkServer.active)
			{
				return;
			}
			if (Loaded && State.HasDefaultedLoan)
			{
				BeginLoanLoss();
				return;
			}
			foreach (NetworkConnectionToClient item in peers.Keys.Where((NetworkConnectionToClient x) => !NetworkServer.connections.Values.Contains(x)).ToList())
			{
				peers.Remove(item);
			}
			if (proposal != null)
			{
				if ((Object)(object)NetworkSingleton<GameManager>.Instance == (Object)null || proposal.Terms.Day != NetworkSingleton<GameManager>.Instance.daysPassed || !CanBorrow || proposal.Failed(NetworkTime.time))
				{
					CancelProposal("Vote expired or failed. Mark's patience has left the building.");
				}
				else if (proposal.Passed(NetworkTime.time))
				{
					Accept();
				}
			}
			if (Time.unscaledTime >= nextBroadcast)
			{
				nextBroadcast = Time.unscaledTime + 1f;
				if (proposal != null || !snapshotSent || lastQuota != BaseQuota || lastDay != (NetworkSingleton<GameManager>.Instance?.daysPassed ?? 0) || lastReady != CanBorrow || lastRun != State.RunId)
				{
					Broadcast();
				}
			}
		}

		internal void Request(NetworkConnectionToClient conn, MarkLoanRequest request)
		{
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Invalid comparison between Unknown and I4
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_031d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			if (Faulted || !((NetworkConnection)conn).isAuthenticated || request.Version != "1.0.5")
			{
				return;
			}
			if (request.Kind == "Hello")
			{
				if (!peers.ContainsKey(conn))
				{
					peers.Add(conn, new Peer());
				}
				Reply(conn);
			}
			else
			{
				if (!peers.TryGetValue(conn, out var value) || (Object)(object)((NetworkConnection)conn).identity == (Object)null || NetworkTime.time - value.LastRequest < 0.15)
				{
					return;
				}
				value.LastRequest = NetworkTime.time;
				try
				{
					if (request.Kind == "Vote")
					{
						if (proposal != null && !(request.Id != proposal.Id) && proposal.Vote(value.Session, request.Approve, NetworkTime.time))
						{
							if (proposal.Passed(NetworkTime.time))
							{
								Accept();
							}
							else if (proposal.Failed(NetworkTime.time))
							{
								CancelProposal("The team said no. Mark will survive. Probably.");
							}
							else
							{
								Broadcast();
							}
						}
						return;
					}
					if (!Loaded || busy)
					{
						throw new InvalidOperationException("The save is not ready for financial changes.");
					}
					if (request.Kind == "Repay")
					{
						if ((Object)(object)NetworkSingleton<GameManager>.Instance == (Object)null || (int)NetworkSingleton<GameManager>.Instance.state != 1)
						{
							throw new InvalidOperationException("Repayment is available during the casino day.");
						}
						Commit(() => -State.Repay(request.Id, NetworkSingleton<MoneyManager>.Instance.balance));
						Broadcast("Loan repaid! Mark's accountant just did a little fin dance.");
						return;
					}
					if (State.HasUnsettledDebt)
					{
						throw new InvalidOperationException("Settle your existing loan or quota debt first. Mark remembers.");
					}
					if (!CanBorrow)
					{
						throw new InvalidOperationException("No more loans today. My wallet needs a nap. You can still repay me.");
					}
					if (!Visual.Near(((Component)((NetworkConnection)conn).identity).transform.position))
					{
						throw new InvalidOperationException("Talk to Mark inside the elevator.");
					}
					if (proposal != null)
					{
						throw new InvalidOperationException("A team vote is already in progress.");
					}
					if (request.Kind == "Quote")
					{
						value.Quote = Quote.Create(NetworkSingleton<GameManager>.Instance.daysPassed, BaseQuota, request.Percent, Rules);
						value.QuoteExpiry = NetworkTime.time + 60.0;
						Reply(conn, null, value.Quote);
					}
					else
					{
						if (!(request.Kind == "Propose"))
						{
							return;
						}
						if (value.Quote == null || request.Id != value.Quote.Id || NetworkTime.time >= value.QuoteExpiry || value.Quote.Day != NetworkSingleton<GameManager>.Instance.daysPassed || value.Quote.BaseQuota != BaseQuota)
						{
							throw new InvalidOperationException("That quote has expired or the quota changed. Review a fresh quote.");
						}
						List<NetworkConnection