Decompiled source of BetterCoop v0.7.1

BetterCoop.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using BetterCoop.Core;
using BetterCoop.Features;
using BetterCoop.Net;
using BetterCoop.Ui;
using BetterCoop.Ui.Notices;
using BetterCoop.Ui.Paper;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Peak;
using Peak.Afflictions;
using Photon.Pun;
using Photon.Realtime;
using Steamworks;
using TMPro;
using Unity.VectorGraphics;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.UI;
using Zorro.ControllerSupport;
using Zorro.Core;
using Zorro.Core.Serizalization;
using Zorro.Settings;
using Zorro.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("BetterCoop")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.7.1.0")]
[assembly: AssemblyInformationalVersion("0.7.1+612ae1c91e533cf9a1c8449da2dc5a7dddecdab1")]
[assembly: AssemblyProduct("BetterCoop")]
[assembly: AssemblyTitle("BetterCoop")]
[assembly: InternalsVisibleTo("BetterCoop.Tests")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.7.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BetterCoop
{
	public static class Api
	{
		public enum Role
		{
			None,
			Carrier,
			Rider
		}

		public enum PairChange
		{
			Shuffle,
			RoleSwap,
			LatePairing,
			Assignment
		}

		public const int ApiVersion = 1;

		public static bool Enabled
		{
			get
			{
				if (Plugin.Patched)
				{
					return !RoomProtocol.Resting;
				}
				return false;
			}
		}

		public static event Action? PairsChanged;

		public static event Action<PairChange>? PairChangeStarting;

		public static event Action<PairChange>? PairChangeFinished;

		public static Role RoleOf(Character? character)
		{
			try
			{
				return Enabled ? (PairRoster.RoleOf(character) switch
				{
					PairRole.Carrier => Role.Carrier, 
					PairRole.Rider => Role.Rider, 
					_ => Role.None, 
				}) : Role.None;
			}
			catch (Exception exception)
			{
				Guard.Report("Api.RoleOf", exception);
				return Role.None;
			}
		}

		public static bool TryGetPartner(Character? character, [NotNullWhen(true)] out Character? partner)
		{
			partner = null;
			try
			{
				if (Enabled && PairRoster.TryGetPartner(character, out Character partner2))
				{
					partner = partner2;
					return true;
				}
			}
			catch (Exception exception)
			{
				Guard.Report("Api.TryGetPartner", exception);
			}
			return false;
		}

		public static bool TryGetSharedBody(Character? character, [NotNullWhen(true)] out Character? body)
		{
			body = null;
			if ((Object)(object)character == (Object)null)
			{
				return false;
			}
			if (RoleOf(character) != Role.Rider)
			{
				body = character;
				return true;
			}
			return TryGetPartner(character, out body);
		}

		internal static void RaisePairsChanged()
		{
			Raise(Api.PairsChanged, "PairsChanged");
		}

		internal static void RaisePairChangeStarting(OperationKind kind)
		{
			Raise(Api.PairChangeStarting, ChangeOf(kind), "PairChangeStarting");
		}

		internal static void RaisePairChangeFinished(OperationKind kind)
		{
			Raise(Api.PairChangeFinished, ChangeOf(kind), "PairChangeFinished");
		}

		private static PairChange ChangeOf(OperationKind kind)
		{
			return kind switch
			{
				OperationKind.RoleSwap => PairChange.RoleSwap, 
				OperationKind.LatePairing => PairChange.LatePairing, 
				OperationKind.PairAssignment => PairChange.Assignment, 
				_ => PairChange.Shuffle, 
			};
		}

		private static void Raise(Action? handlers, string name)
		{
			Delegate[] array = handlers?.GetInvocationList() ?? Array.Empty<Delegate>();
			foreach (Delegate obj in array)
			{
				try
				{
					((Action)obj)();
				}
				catch (Exception arg)
				{
					Plugin.Log.LogWarning((object)$"A handler of Api.{name} threw: {arg}");
				}
			}
		}

		private static void Raise(Action<PairChange>? handlers, PairChange change, string name)
		{
			Delegate[] array = handlers?.GetInvocationList() ?? Array.Empty<Delegate>();
			foreach (Delegate obj in array)
			{
				try
				{
					((Action<PairChange>)obj)(change);
				}
				catch (Exception arg)
				{
					Plugin.Log.LogWarning((object)$"A handler of Api.{name} threw: {arg}");
				}
			}
		}
	}
	internal static class CoopConfig
	{
		public static ConfigEntry<bool> AllowOddPlayerCount { get; private set; }

		public static ConfigEntry<RolePreference> RolePreference { get; private set; }

		public static ConfigEntry<bool> RiderPicksFromBackpack { get; private set; }

		public static ConfigEntry<bool> CarryWeight { get; private set; }

		public static ConfigEntry<bool> CampfireShuffle { get; private set; }

		public static ConfigEntry<bool> TimedShuffle { get; private set; }

		public static ConfigEntry<int> TimedShuffleInterval { get; private set; }

		public static ConfigEntry<bool> HandOverPlace { get; private set; }

		public static ConfigEntry<bool> HandOverItems { get; private set; }

		public static ConfigEntry<bool> FollowRolePreferences { get; private set; }

		public static ConfigEntry<bool> AllowSwapRequests { get; private set; }

		public static ConfigEntry<bool> LatePairing { get; private set; }

		public static ConfigEntry<bool> RescueCarry { get; private set; }

		public static ConfigEntry<bool> VerboseLog { get; private set; }

		public static void Bind(ConfigFile config)
		{
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Expected O, but got Unknown
			AllowOddPlayerCount = config.Bind<bool>("Party", "Allow Odd Player Count", false, Strings.English("config.allowOddPlayerCount"));
			RolePreference = config.Bind<RolePreference>("Pair", "Role Preference", BetterCoop.Core.RolePreference.Random, Strings.English("config.rolePreference"));
			FollowRolePreferences = config.Bind<bool>("Pair", "Honour Role Preferences", true, Strings.English("config.followRolePreferences"));
			AllowSwapRequests = config.Bind<bool>("Pair", "Allow Role Swaps", true, Strings.English("config.allowSwapRequests"));
			LatePairing = config.Bind<bool>("Pair", "Late Pairing", true, Strings.English("config.latePairing"));
			RiderPicksFromBackpack = config.Bind<bool>("Pair", "Rider Picks From Backpack", true, Strings.English("config.riderPicksFromBackpack"));
			RescueCarry = config.Bind<bool>("Balance", "Rescue Carry", true, Strings.English("config.rescueCarry"));
			CarryWeight = config.Bind<bool>("Balance", "Carry Weight", false, Strings.English("config.carryWeight"));
			CampfireShuffle = config.Bind<bool>("Shuffle", "Campfire Shuffle", true, Strings.English("config.campfireShuffle"));
			TimedShuffle = config.Bind<bool>("Shuffle", "Timed Shuffle", false, Strings.English("config.timedShuffle"));
			TimedShuffleInterval = config.Bind<int>("Shuffle", "Timed Shuffle Interval", 10, new ConfigDescription(Strings.English("config.timedShuffleInterval", ("min", 1), ("max", 60)), (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 60), Array.Empty<object>()));
			HandOverPlace = config.Bind<bool>("Shuffle", "Hand Over Place", true, Strings.English("config.handOverPlace"));
			HandOverItems = config.Bind<bool>("Shuffle", "Hand Over Items", true, Strings.English("config.handOverItems"));
			VerboseLog = config.Bind<bool>("Debug", "Verbose Log", false, Strings.English("config.verboseLog"));
		}
	}
	internal static class DevHooks
	{
		public static bool ActsUnmodded => false;

		public static void Started(BaseUnityPlugin plugin, GameObject runtime)
		{
		}

		public static void PauseMenu(PauseMenuMainPage menu, UIPageHandler handler, PauseMenuControlsPage controls, Button after, Func<string, Action, Button, Button> add)
		{
		}

		public static void HandPictured(Texture2D picture, string name)
		{
		}

		public static string ScoutId(Player player)
		{
			return player.UserId;
		}
	}
	internal static class Guard
	{
		private const int RepeatNote = 600;

		private static readonly Dictionary<(string Site, Type Type), int> Seen = new Dictionary<(string, Type), int>();

		internal static void Report(string site, Exception exception)
		{
			(string, Type) key = (site, exception.GetType());
			Seen.TryGetValue(key, out var value);
			value = (Seen[key] = value + 1);
			if (value == 1)
			{
				Plugin.Log.LogError((object)$"{site} failed; it keeps running.\n{exception}");
			}
			else if (value % 600 == 0)
			{
				Plugin.Log.LogError((object)$"{site} failed {value} times with {exception.GetType().Name}: {exception.Message}");
			}
		}
	}
	[BepInPlugin("in.kawala.bettercoop", "BetterCoop", "0.7.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		private const string CoopModGuid = "com.peak.coopmod";

		internal static ManualLogSource Log { get; private set; }

		internal static bool Patched { get; private set; }

		internal static void Verbose(string message)
		{
			if (CoopConfig.VerboseLog.Value)
			{
				Log.LogInfo((object)message);
			}
		}

		private void Awake()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			CoopConfig.Bind(((BaseUnityPlugin)this).Config);
			GameObject val = new GameObject("BetterCoop");
			((Object)val).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)val);
			if (DevHooks.ActsUnmodded)
			{
				DevHooks.Started((BaseUnityPlugin)(object)this, val);
				Log.LogWarning((object)"This copy stands in for an Unmodded Player: the mod is not patched and publishes nothing.");
				return;
			}
			if (Chainloader.PluginInfos.ContainsKey("com.peak.coopmod"))
			{
				Log.LogError((object)"Co-op Mod (com.peak.coopmod) is also loaded; the mod is disabled. Remove Co-op Mod to play.");
				val.AddComponent<DisabledNotice>().Message = () => Strings.ModDisabledByCoopMod;
				return;
			}
			Harmony val2 = new Harmony("in.kawala.bettercoop");
			try
			{
				val2.PatchAll(typeof(Plugin).Assembly);
				Patched = true;
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Patching failed; the mod is disabled for this game version.\n{arg}");
				val2.UnpatchSelf();
				val.AddComponent<DisabledNotice>();
				return;
			}
			val.AddComponent<ModPresence>();
			val.AddComponent<RoomWrites>();
			val.AddComponent<RunRules>();
			val.AddComponent<PairingDirector>();
			val.AddComponent<CarryKeeper>();
			val.AddComponent<ControlSplitLink>();
			val.AddComponent<RiderHudRefresher>();
			val.AddComponent<RiderBarsKeeper>();
			val.AddComponent<RiderEffectsKeeper>();
			val.AddComponent<RiderPreviewsKeeper>();
			val.AddComponent<SharedViewSoundsKeeper>();
			val.AddComponent<PairShuffleLink>();
			val.AddComponent<UnmoddedPlayers>();
			val.AddComponent<PhotoDarkroom>();
			val.AddComponent<NoticeBoard>();
			DevHooks.Started((BaseUnityPlugin)(object)this, val);
			Log.LogInfo((object)"BetterCoop 0.7.1 loaded.");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "in.kawala.bettercoop";

		public const string PLUGIN_NAME = "BetterCoop";

		public const string PLUGIN_VERSION = "0.7.1";
	}
}
namespace BetterCoop.Ui
{
	internal static class CoopNotice
	{
		private static PlayerConnectionLog? log;

		private static readonly NoticeGate Gate = new NoticeGate();

		private static readonly SourceGate FromPlayers = new SourceGate();

		public static void Info(string message)
		{
			Show(NoticeKind.Telegram, message);
		}

		public static void Warning(string message)
		{
			Show(NoticeKind.Caution, message);
		}

		public static void From(int player, NoticeKind kind, string message)
		{
			if (!FromPlayers.Allow(player, Time.unscaledTimeAsDouble))
			{
				Plugin.Verbose("[Notice held back] " + message);
			}
			else
			{
				Put(kind, message);
			}
		}

		public static void Show(NoticeKind kind, string message)
		{
			if (!Gate.Allow(message, Time.unscaledTimeAsDouble))
			{
				Plugin.Verbose("[Notice held back] " + message);
			}
			else
			{
				Put(kind, message);
			}
		}

		private static void Put(NoticeKind kind, string message)
		{
			Plugin.Log.LogInfo((object)("[Notice] " + message));
			if (!NoticeBoard.TryShow(kind, message))
			{
				InGameLog(Strings.Prefixed(message), kind == NoticeKind.Caution);
			}
		}

		public static void InGameLog(string message, bool warning)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)log == (Object)null)
			{
				log = Object.FindAnyObjectByType<PlayerConnectionLog>();
			}
			if (!((Object)(object)log == (Object)null))
			{
				Color val = (warning ? log.leftColor : log.joinedColor);
				log.AddMessage(log.GetColorTag(val) + message + "</color>");
				SFX_Instance val2 = (warning ? log.sfxLeave : log.sfxJoin);
				if ((Object)(object)val2 != (Object)null)
				{
					val2.Play(default(Vector3));
				}
			}
		}
	}
	internal sealed class DisabledNotice : MonoBehaviour
	{
		internal Func<string> Message = () => Strings.ModDisabled;

		private PlayerConnectionLog? shownOn;

		private float nextCheck;

		private void Update()
		{
			if (!(Time.unscaledTime < nextCheck))
			{
				nextCheck = Time.unscaledTime + 2f;
				PlayerConnectionLog val = Object.FindAnyObjectByType<PlayerConnectionLog>();
				if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)shownOn)
				{
					shownOn = val;
					string text = Message();
					Plugin.Log.LogInfo((object)("[Notice] " + text));
					CoopNotice.InGameLog(Strings.Prefixed(text), warning: true);
				}
			}
		}
	}
	internal static class Makers
	{
		private static readonly (string Name, string Profile)[] People = new(string, string)[2]
		{
			("kawalain", "https://steamcommunity.com/profiles/76561198436496102"),
			("Puro", "https://steamcommunity.com/profiles/76561198105109754")
		};

		public static void Add(PaperList list)
		{
			list.Credits(People.Select(((string Name, string Profile) p) => ((string Name, Action))(Name: p.Name, delegate
			{
				Open(p.Profile);
			})).ToList());
		}

		private static void Open(string url)
		{
			try
			{
				if (SteamUtils.IsOverlayEnabled())
				{
					SteamFriends.ActivateGameOverlayToWebPage(url, (EActivateGameOverlayToWebPageMode)0);
					return;
				}
			}
			catch (Exception ex)
			{
				Plugin.Verbose("The Steam overlay could not open " + url + ": " + ex.Message);
			}
			Application.OpenURL(url);
		}
	}
	internal static class Strings
	{
		internal const string Resource = "BetterCoop.strings.json";

		private static TextTable? table;

		private static TextTable Table => table ?? (table = Load());

		internal static string LanguageCode => CodeOf(LocalizedText.CURRENT_LANGUAGE);

		public static string ModDisabled => T("notice.modDisabled");

		public static string ModDisabledByCoopMod => T("notice.modDisabledByCoopMod");

		public static string Roster => T("roster.title");

		public static string MenuRolePreference => T("roster.rolePreference");

		public static string FormTitle => T("roster.form");

		public static string MenuYou => T("roster.yourPair");

		public static string MenuPartner => T("roster.partner");

		public static string MenuYourRole => T("roster.yourRole");

		public static string MenuNoPartner => T("roster.noPartner");

		public static string MenuNextShuffle => T("roster.nextShuffle");

		public static string MenuShuffleNow => T("roster.shuffleUnderway");

		public static string MenuShuffleOff => T("roster.shuffleOff");

		public static string MenuCarryRecord => T("roster.carryRecord");

		public static string AboutCarryRecord => T("roster.aboutCarryRecord");

		public static string CarryRecordEmpty => T("roster.carryRecordEmpty");

		public static string HeadScout => T("head.scout");

		public static string HeadCarried => T("head.carried");

		public static string HeadRidden => T("head.ridden");

		public static string HeadClimbed => T("head.climbed");

		public static string HeadRescuing => T("head.rescuing");

		public static string MenuRunReport => T("roster.runReport");

		public static string ReportFormTitle => T("report.form");

		public static string MenuReadReport => T("roster.readReport");

		public static string StampRead => T("stamp.read");

		public static string AboutRunReport => T("roster.aboutRunReport");

		public static string ReportUnderway => T("report.underway");

		public static string ReportGone => T("report.gone");

		public static string ReportResult => T("report.result");

		public static string ReportEnding => T("report.ending");

		public static string ReportRunTime => T("report.runTime");

		public static string MenuMeritBadges => T("report.meritBadges");

		public static string NoBadges => T("report.noBadges");

		public static string ReportBySegment => T("report.bySegment");

		public static string HeadPair => T("head.pair");

		public static string HeadTogether => T("head.together");

		public static string None => T("symbol.none");

		public static string MenuPairsForm => T("roster.pairsForm");

		public static string MenuPairs => T("roster.pairs");

		public static string MenuPairPlan => T("roster.pairPlan");

		public static string MenuPlanHelp => T("roster.planHelp");

		public static string MenuPlanFromLastRun => T("roster.planFromLastRun");

		public static string MenuPlanNone => T("roster.planNone");

		public static string AboutPlan => T("roster.aboutPlan");

		public static string PlanAnnounced => T("notice.planAnnounced");

		public static string MenuTroopLeader => T("roster.troopLeaderOrders");

		public static string MenuTroopLeaderSign => T("roster.troopLeaderSign");

		public static string MenuShuffleNowLabel => T("roster.shuffleNow");

		public static string MenuShufflePlanLabel => T("roster.shufflePlan");

		public static string AboutShufflePlan => T("roster.aboutShufflePlan");

		public static string MenuRecover => T("roster.recover");

		public static string StampShuffle => T("stamp.shuffle");

		public static string StampRestore => T("stamp.restore");

		public static string StampReally => T("stamp.really");

		public static string ReportArrived => T("notice.reportArrived");

		public static string StampCallOff => T("stamp.callOff");

		public static string MenuCallOffLabel => T("roster.callOff");

		public static string AboutCallOff => T("roster.aboutCallOff");

		public static string CallOffUnavailable => T("notice.callOffUnavailable");

		public static string ShuffleCalledOff => T("notice.shuffleCalledOff");

		public static string LetterCalledOff => T("letter.calledOff");

		public static string LetterStays => T("letter.stays");

		public static string CautionStamp => T("notice.cautionStamp");

		public static string LetterDone => T("letter.done");

		public static string LetterAlone => T("letter.alone");

		public static string LetterArrived => T("letter.arrived");

		public static string LetterUnknown => T("letter.unknown");

		public static string LetterYou => T("letter.you");

		public static string LetterRoleUnknown => T("letter.roleUnknown");

		public static string SlipQuery => T("slip.query");

		public static string StampNotify => T("stamp.notify");

		public static string PostmarkOffice => T("postmark.office");

		public static string StampDiscard => T("stamp.discard");

		public static string StampKeep => T("stamp.keep");

		public static string DiscardDraft => T("roster.discardDraft");

		public static string DiscardDraftNote => T("roster.discardDraftNote");

		public static string MenuDraft => T("roster.draft");

		public static string StampAsk => T("stamp.ask");

		public static string StampAsked => T("stamp.asked");

		public static string StampAgree => T("stamp.agree");

		public static string SealNotary => T("seal.notary");

		public static string SealTroop => T("seal.troop");

		public static string SealOrders => T("seal.orders");

		public static string SealInspected => T("seal.inspected");

		public static string AboutSwapWaiting => T("roster.aboutSwapWaiting");

		public static string StampCancel => T("stamp.cancel");

		public static string MenuTooSoon => T("notice.tooSoon");

		public static string ShuffleQueued => T("notice.shuffleQueued");

		public static string PlanUnavailable => T("notice.planUnavailable");

		public static string MenuBusy => T("notice.busy");

		public static string MenuRunRules => T("roster.runRules");

		public static string MenuRulesRead => T("roster.rulesRead");

		public static string RuleLeaderOnly => T("roster.rulesLeaderOnly");

		public static string RuleCampfireShuffle => T("rule.campfireShuffle");

		public static string RuleTimedShuffle => T("rule.timedShuffle");

		public static string RuleTimedShuffleInterval => T("rule.timedShuffleInterval");

		public static string RuleHandOverPlace => T("rule.handOverPlace");

		public static string RuleHandOverItems => T("rule.handOverItems");

		public static string RuleCarryWeight => T("rule.carryWeight");

		public static string RuleRescueCarry => T("rule.rescueCarry");

		public static string RuleRiderPicksFromBackpack => T("rule.riderPicksFromBackpack");

		public static string RuleAllowOddPlayerCount => T("rule.allowOddPlayerCount");

		public static string RuleFollowRolePreferences => T("rule.followRolePreferences");

		public static string RuleAllowSwapRequests => T("rule.allowSwapRequests");

		public static string RuleLatePairing => T("rule.latePairing");

		public static string RulesPairs => T("rules.group.pairs");

		public static string RulesShuffles => T("rules.group.shuffles");

		public static string RulesHandover => T("rules.group.handover");

		public static string RulesCarrying => T("rules.group.carrying");

		public static string AboutFollowRolePreferences => T("rule.followRolePreferences.about");

		public static string AboutAllowSwapRequests => T("rule.allowSwapRequests.about");

		public static string AboutLatePairing => T("rule.latePairing.about");

		public static string AboutRolePreferenceIgnored => T("roster.aboutRolePreferenceIgnored");

		public static string AboutSwapNotAllowed => T("roster.aboutSwapNotAllowed");

		public static string SwapNotAllowed => T("notice.swapNotAllowed");

		public static string AboutRolePreference => T("roster.aboutRolePreference");

		public static string AboutSwapPlaces => T("roster.aboutSwapPlaces");

		public static string AboutNoPartner => T("roster.aboutNoPartner");

		public static string AboutNextShuffle => T("roster.aboutNextShuffle");

		public static string AboutShuffleNow => T("roster.aboutShuffleNow");

		public static string AboutRecover => T("roster.aboutRecover");

		public static string AboutAssign => T("roster.aboutAnnounce");

		public static string MenuBoardHelp => T("roster.boardHelp");

		public static string MenuNewPair => T("roster.newPair");

		public static string MenuDropHere => T("roster.dropHere");

		public static string MenuEmptyPlace => T("roster.emptyPlace");

		public static string MenuAssignReset => T("roster.startOver");

		public static string AboutCampfireShuffle => T("rule.campfireShuffle.about");

		public static string AboutTimedShuffle => T("rule.timedShuffle.about");

		public static string AboutTimedShuffleInterval => T("rule.timedShuffleInterval.about");

		public static string AboutHandOverPlace => T("rule.handOverPlace.about");

		public static string AboutHandOverItems => T("rule.handOverItems.about");

		public static string AboutCarryWeight => T("rule.carryWeight.about");

		public static string AboutRescueCarry => T("rule.rescueCarry.about");

		public static string AboutRiderPicksFromBackpack => T("rule.riderPicksFromBackpack.about");

		public static string AboutAllowOddPlayerCount => T("rule.allowOddPlayerCount.about");

		public static string MenuUnpaired => T("roster.unpaired");

		public static string MenuUnmodded => T("roster.unmodded");

		public static string AboutUnmodded => T("roster.aboutUnmodded");

		public static string MenuAssign => T("roster.announce");

		public static string MenuAssignUnavailable => T("notice.assignUnavailable");

		public static string SwapPlaces => T("roster.swapPlaces");

		public static string CancelSwap => T("roster.cancelSwap");

		public static string SwapUnavailable => T("notice.swapUnavailable");

		public static string SwapCancelled => T("notice.swapCancelled");

		public static string SwapExpired => T("notice.swapExpired");

		public static string SwapCancelledByShuffle => T("notice.swapCancelledByShuffle");

		public static string RiderHandEmptied => T("notice.riderHandEmptied");

		public static string RiderBackEmptied => T("notice.riderBackEmptied");

		public static string Recovered => T("notice.recovered");

		private static string CodeOf(Language language)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected I4, but got Unknown
			return (language - 1) switch
			{
				0 => "fr", 
				1 => "it", 
				2 => "de", 
				3 => "es-ES", 
				4 => "es-419", 
				5 => "pt-BR", 
				6 => "ru", 
				7 => "uk", 
				8 => "zh-Hans", 
				9 => "zh-Hant", 
				10 => "ja", 
				11 => "ko", 
				12 => "pl", 
				13 => "tr", 
				_ => "en", 
			};
		}

		private static TextTable Load()
		{
			try
			{
				using Stream stream = typeof(Strings).Assembly.GetManifestResourceStream("BetterCoop.strings.json");
				if (stream == null)
				{
					Plugin.Log.LogError((object)"The plugin has no BetterCoop.strings.json; text shows as its keys.");
					return TextTable.Empty;
				}
				using StreamReader streamReader = new StreamReader(stream);
				return TextTable.Parse(streamReader.ReadToEnd());
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Could not read BetterCoop.strings.json; text shows as its keys. " + ex.Message));
				return TextTable.Empty;
			}
		}

		private static string T(string key)
		{
			return Table.Get(key, LanguageCode);
		}

		private static string T(string key, params (string Name, object? Value)[] values)
		{
			return TextTable.Fill(T(key), values);
		}

		internal static string English(string key, params (string Name, object? Value)[] values)
		{
			return TextTable.Fill(Table.Get(key, "en"), values);
		}

		public static string Prefixed(string message)
		{
			return T("notice.prefix") + message;
		}

		public static string PairFormed(string carrier, string rider)
		{
			return T("notice.pairFormed", ("carrier", carrier), ("rider", rider));
		}

		public static string PreferenceOverridden(string player)
		{
			return T("notice.preferenceOverridden", ("player", player));
		}

		public static string Unpaired(string player)
		{
			return T("notice.unpaired", ("player", player));
		}

		public static string PairDissolved(string carrier, string rider)
		{
			return T("notice.pairDissolved", ("carrier", carrier), ("rider", rider));
		}

		public static string ShuffleCountdown(int seconds)
		{
			return T("notice.shuffleCountdown", ("seconds", seconds));
		}

		public static string RoleSwapCountdown(int seconds)
		{
			return T("notice.roleSwapCountdown", ("seconds", seconds));
		}

		public static string LatePairingCountdown(int seconds)
		{
			return T("notice.latePairingCountdown", ("seconds", seconds));
		}

		public static string RoleName(RolePreference preference)
		{
			return preference switch
			{
				RolePreference.Carrier => T("role.carrier"), 
				RolePreference.Rider => T("role.rider"), 
				_ => T("role.either"), 
			};
		}

		public static string FormMembers(int count)
		{
			return T((count == 1) ? "roster.scouts.one" : "roster.scouts.other", ("count", count));
		}

		public static string RoleOf(bool carrying)
		{
			return T(carrying ? "role.carrier" : "role.rider");
		}

		public static string Clock(double seconds)
		{
			int num = (int)Math.Ceiling(seconds);
			return $"{num / 60}:{num % 60:00}";
		}

		public static string Duration(double seconds)
		{
			int num = (int)Math.Floor(Math.Max(0.0, seconds));
			if (num < 3600)
			{
				return $"{num / 60}:{num % 60:00}";
			}
			return $"{num / 3600}:{num / 60 % 60:00}:{num % 60:00}";
		}

		public static string Metres(double metres)
		{
			return T("unit.metres", ("metres", Math.Floor(metres).ToString("0", CultureInfo.InvariantCulture)));
		}

		public static string EndingName(RunEnding ending)
		{
			return ending switch
			{
				RunEnding.Summit => T("ending.summit"), 
				RunEnding.Lost => T("ending.lost"), 
				RunEnding.Underway => T("ending.underway"), 
				_ => T("ending.airport"), 
			};
		}

		public static string BadgeName(MeritBadgeKind kind)
		{
			return kind switch
			{
				MeritBadgeKind.SteadyBack => T("badge.steadyBack"), 
				MeritBadgeKind.ComfyPassenger => T("badge.comfyPassenger"), 
				MeritBadgeKind.RescueRanger => T("badge.rescueRanger"), 
				_ => T("badge.bestBuddies"), 
			};
		}

		public static string BadgeAmount(MeritBadgeKind kind, double amount)
		{
			string item = kind switch
			{
				MeritBadgeKind.SteadyBack => HeadCarried, 
				MeritBadgeKind.ComfyPassenger => HeadRidden, 
				MeritBadgeKind.RescueRanger => HeadRescuing, 
				_ => HeadTogether, 
			};
			return T("badge.amount", ("what", item), ("time", Duration(amount)));
		}

		public static string Left(string name)
		{
			return T("report.left", ("name", name));
		}

		public static string Both(string first, string second)
		{
			return T("symbol.and", ("first", first), ("second", second));
		}

		public static string Carries(string carrier, string rider)
		{
			return T("symbol.carries", ("carrier", carrier), ("rider", rider));
		}

		public static string Then(string first, string second)
		{
			return T("symbol.then", ("first", first), ("second", second));
		}

		public static string Sentences(string first, string second)
		{
			return T("symbol.sentences", ("first", first), ("second", second));
		}

		public static string MenuPairNumber(int number)
		{
			return T("roster.pairNumber", ("number", number));
		}

		public static string CalledOffByRule(OperationKind kind)
		{
			return T((kind == OperationKind.RoleSwap) ? "notice.roleSwapCalledOffByRule" : "notice.latePairingCalledOffByRule");
		}

		public static string ShuffleCalledOffUntil(string clock)
		{
			return T("notice.shuffleCalledOffUntil", ("clock", clock));
		}

		public static string Serial(int number)
		{
			return T("roster.serial", ("number", number.ToString("D7", CultureInfo.InvariantCulture)));
		}

		public static string NoticeHeading(NoticeKind kind)
		{
			return kind switch
			{
				NoticeKind.Memo => T("notice.kind.memo"), 
				NoticeKind.Tag => T("notice.kind.tag"), 
				NoticeKind.Caution => T("notice.kind.caution"), 
				_ => T("notice.kind.telegram"), 
			};
		}

		public static string LetterHeading(OperationKind kind)
		{
			return kind switch
			{
				OperationKind.RoleSwap => T("letter.heading.roleSwap"), 
				OperationKind.LatePairing => T("letter.heading.latePairing"), 
				OperationKind.PairAssignment => T("letter.heading.assignment"), 
				OperationKind.None => T("letter.heading.formation"), 
				_ => T("letter.heading.shuffle"), 
			};
		}

		public static string LetterSoon(PairChangeForMe change, int seconds)
		{
			return T(change switch
			{
				PairChangeForMe.Gains => "letter.soon.gains", 
				PairChangeForMe.Swaps => "letter.soon.swaps", 
				PairChangeForMe.Loses => "letter.soon.loses", 
				PairChangeForMe.Mixed => "letter.soon.mixed", 
				_ => "letter.soon.changes", 
			}, ("seconds", seconds));
		}

		public static string LetterDoneFor(PairChangeForMe change)
		{
			return change switch
			{
				PairChangeForMe.Swaps => T("letter.doneSwapped"), 
				PairChangeForMe.Loses => LetterAlone, 
				_ => LetterDone, 
			};
		}

		public static string LetterTo(string player)
		{
			return T("letter.to", ("player", player));
		}

		public static string PostmarkDate(DateTime day)
		{
			return day.ToString(T("postmark.date"), CultureInfo.InvariantCulture).ToUpperInvariant();
		}

		public static string PostmarkTime(DateTime time)
		{
			return T("postmark.time", ("hour", time.ToString("hh", CultureInfo.InvariantCulture)), ("minute", time.ToString("mm", CultureInfo.InvariantCulture)), ("half", T((time.Hour < 12) ? "postmark.am" : "postmark.pm")));
		}

		public static string AboutSwapOffered(string partner)
		{
			return T("roster.aboutSwapOffered", ("partner", partner));
		}

		public static string RuleName(RunRule rule)
		{
			return rule switch
			{
				RunRule.AllowOddPlayerCount => RuleAllowOddPlayerCount, 
				RunRule.CarryWeight => RuleCarryWeight, 
				RunRule.CampfireShuffle => RuleCampfireShuffle, 
				RunRule.TimedShuffle => RuleTimedShuffle, 
				RunRule.HandOverPlace => RuleHandOverPlace, 
				RunRule.HandOverItems => RuleHandOverItems, 
				RunRule.RiderPicksFromBackpack => RuleRiderPicksFromBackpack, 
				RunRule.FollowRolePreferences => RuleFollowRolePreferences, 
				RunRule.AllowSwapRequests => RuleAllowSwapRequests, 
				RunRule.LatePairing => RuleLatePairing, 
				RunRule.RescueCarry => RuleRescueCarry, 
				_ => rule.ToString(), 
			};
		}

		public static string RuleTurnedOn(string rule)
		{
			return T("notice.ruleOn", ("rule", rule));
		}

		public static string RuleTurnedOff(string rule)
		{
			return T("notice.ruleOff", ("rule", rule));
		}

		public static string RuleSetTo(string rule, string value)
		{
			return T("notice.ruleSetTo", ("rule", rule), ("value", value));
		}

		public static string RulesChanged(string changes)
		{
			return T("notice.rulesChanged", ("changes", changes));
		}

		public static string Minutes(int minutes)
		{
			return T("unit.minutes", ("minutes", minutes));
		}

		public static string UnmoddedVersion(string? version)
		{
			if (version != null)
			{
				return T("roster.modVersion", ("version", version));
			}
			return T("roster.noMod");
		}

		public static string AssignmentCountdown(int seconds)
		{
			return T("notice.assignmentCountdown", ("seconds", seconds));
		}

		public static string SwapAsked(string partner)
		{
			return T("notice.swapAsked", ("partner", partner));
		}

		public static string SwapOffered(string partner)
		{
			return T("notice.swapOffered", ("partner", partner));
		}

		public static string SwapWithdrawn(string partner)
		{
			return T("notice.swapWithdrawn", ("partner", partner));
		}

		public static string OddPlayerCount(int pairable, int unmodded)
		{
			if (unmodded <= 0)
			{
				return T("notice.oddPlayerCount", ("pairable", pairable));
			}
			return T("notice.oddPlayerCountWithUnmodded", ("pairable", pairable), ("unmodded", unmodded));
		}

		public static string Overfull(int seats)
		{
			return T("notice.overfull", ("seats", seats));
		}

		public static string UnmoddedPlayer(string player, string? theirs, string? leaders)
		{
			if (theirs != null)
			{
				return T("notice.unmoddedPlayerVersion", ("player", player), ("theirs", theirs), ("leaders", leaders ?? "?"));
			}
			return T("notice.unmoddedPlayer", ("player", player));
		}

		public static string Resting(string leader, string? leaders, string mine)
		{
			if (leaders != null)
			{
				return T("notice.restingVersion", ("leader", leader), ("leaders", leaders), ("mine", mine));
			}
			return T("notice.resting", ("leader", leader));
		}
	}
}
namespace BetterCoop.Ui.Paper
{
	internal static class Boil
	{
		public const int Frames = 4;

		public static int Frame => (int)((long)Mathf.Round(Time.timeSinceLevelLoad * PaperSheet.WiggleTime) % 4);
	}
	internal sealed class CorrectionTape : MonoBehaviour
	{
		private const float DrawSeconds = 0.3f;

		private const float HoldSeconds = 0.35f;

		private const float FadeSeconds = 0.25f;

		private RectTransform line;

		private RectTransform drawn;

		private RectTransform strip;

		private CanvasGroup faint;

		private readonly List<GameObject> covered = new List<GameObject>();

		private readonly List<CanvasGroup> under = new List<CanvasGroup>();

		private float startedAt;

		private float alpha = 1f;

		public bool Striking => ((Behaviour)this).enabled;

		public static CorrectionTape Add(RectTransform target, CanvasGroup fade, int seed)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: 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_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = PaperList.NewRect("Tape", (Transform)(object)target);
			((Component)val).gameObject.AddComponent<LayoutElement>().ignoreLayout = true;
			val.anchorMin = Vector2.zero;
			val.anchorMax = new Vector2(0f, 1f);
			val.pivot = new Vector2(0f, 0.5f);
			val.offsetMin = new Vector2(-4f, -3f);
			val.offsetMax = new Vector2(0f, 3f);
			((Component)val).gameObject.AddComponent<RectMask2D>();
			RectTransform val2 = PaperList.NewRect("Strip", (Transform)(object)val);
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = new Vector2(0f, 1f);
			val2.pivot = new Vector2(0f, 0.5f);
			Vector2 offsetMin = (val2.offsetMax = Vector2.zero);
			val2.offsetMin = offsetMin;
			VectorView.Add(val2, (Vector2 size) => FormDrawing.CorrectionTape(size.x, size.y, seed), Color.clear);
			((Component)val).gameObject.SetActive(false);
			CorrectionTape correctionTape = ((Component)target).gameObject.AddComponent<CorrectionTape>();
			correctionTape.line = target;
			correctionTape.drawn = val;
			correctionTape.strip = val2;
			correctionTape.faint = fade;
			((Behaviour)correctionTape).enabled = false;
			return correctionTape;
		}

		public void Strike()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			if (((Behaviour)this).enabled)
			{
				return;
			}
			alpha = faint.alpha;
			foreach (Transform item in (Transform)line)
			{
				Transform val = item;
				if ((Object)(object)val != (Object)(object)drawn)
				{
					CanvasGroup val2 = ((Component)val).GetComponent<CanvasGroup>() ?? ((Component)val).gameObject.AddComponent<CanvasGroup>();
					val2.alpha = alpha;
					under.Add(val2);
				}
			}
			startedAt = Time.unscaledTime;
			((Transform)drawn).SetAsLastSibling();
			((Component)drawn).gameObject.SetActive(true);
			((Behaviour)this).enabled = true;
			Pose();
		}

		public void Lift()
		{
			foreach (GameObject item in covered)
			{
				item.SetActive(true);
			}
			covered.Clear();
			foreach (CanvasGroup item2 in under)
			{
				item2.alpha = 1f;
			}
			under.Clear();
			((Behaviour)this).enabled = false;
			((Component)drawn).gameObject.SetActive(false);
			faint.alpha = alpha;
		}

		private void LateUpdate()
		{
			Pose();
		}

		private void Pose()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			Rect rect = line.rect;
			float num = ((Rect)(ref rect)).width + 8f;
			float num2 = Time.unscaledTime - startedAt;
			strip.sizeDelta = new Vector2(num, 0f);
			drawn.sizeDelta = new Vector2(num * Easing.InOut(num2 / 0.3f), drawn.sizeDelta.y);
			if (num2 >= 0.3f && covered.Count == 0)
			{
				foreach (Transform item in (Transform)line)
				{
					Transform val = item;
					if ((Object)(object)val != (Object)(object)drawn && ((Object)val).name != "Ruled" && ((Component)val).gameObject.activeSelf)
					{
						covered.Add(((Component)val).gameObject);
						((Component)val).gameObject.SetActive(false);
					}
				}
			}
			float num3 = (num2 - 0.3f - 0.35f) / 0.25f;
			faint.alpha = 1f - Easing.Out(num3);
			if (num3 >= 1f)
			{
				Lift();
				((Component)line).gameObject.SetActive(false);
			}
		}
	}
	internal sealed class DittoCopy : MonoBehaviour
	{
		private readonly List<TMP_Text> texts = new List<TMP_Text>();

		private RectTransform sheet;

		private float startedAt;

		private bool done;

		public static DittoCopy Add(RectTransform sheet, IEnumerable<TMP_Text> texts, float delay)
		{
			DittoCopy dittoCopy = ((Component)sheet).gameObject.AddComponent<DittoCopy>();
			dittoCopy.sheet = sheet;
			dittoCopy.texts.AddRange(texts);
			dittoCopy.startedAt = Time.unscaledTime + delay;
			dittoCopy.Print();
			return dittoCopy;
		}

		private void LateUpdate()
		{
			if (!done)
			{
				Print();
			}
		}

		private void Print()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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_0099: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: 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_010c: 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_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: 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_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: 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_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			float elapsed = Time.unscaledTime - startedAt;
			done = Ditto.Done(elapsed);
			Color val = PaperText.ToColor(Ditto.Violet);
			Rect rect = sheet.rect;
			foreach (TMP_Text text in texts)
			{
				text.ForceMeshUpdate(false, false);
				if (done)
				{
					continue;
				}
				TMP_TextInfo textInfo = text.textInfo;
				for (int i = 0; i < textInfo.characterCount; i++)
				{
					TMP_CharacterInfo val2 = textInfo.characterInfo[i];
					if (val2.isVisible)
					{
						Vector3 val3 = (val2.bottomLeft + val2.topRight) * 0.5f;
						Vector2 val4 = Vector2.op_Implicit(((Transform)sheet).InverseTransformPoint(text.transform.TransformPoint(val3)));
						(float Printed, float Violet) tuple = Ditto.At(Mathf.Clamp01((((Rect)(ref rect)).yMax - val4.y) / Mathf.Max(1f, ((Rect)(ref rect)).height)), elapsed);
						float item = tuple.Printed;
						float item2 = tuple.Violet;
						Color32[] colors = textInfo.meshInfo[val2.materialReferenceIndex].colors32;
						for (int j = 0; j < 4; j++)
						{
							Color val5 = Color32.op_Implicit(colors[val2.vertexIndex + j]);
							Color val6 = Color.Lerp(val5, new Color(val.r, val.g, val.b, val5.a), item2);
							val6.a *= item;
							colors[val2.vertexIndex + j] = Color32.op_Implicit(val6);
						}
					}
				}
				text.UpdateVertexData((TMP_VertexDataUpdateFlags)16);
			}
		}
	}
	[RequireComponent(typeof(Graphic))]
	internal sealed class InkDry : BaseMeshEffect
	{
		private const float Cell = 2.5f;

		private readonly List<UIVertex> quad = new List<UIVertex>();

		private float dried;

		private int seed = 1;

		public float Dried
		{
			get
			{
				return dried;
			}
			set
			{
				value = Mathf.Clamp01(value);
				if (!Mathf.Approximately(value, dried))
				{
					dried = value;
					((BaseMeshEffect)this).graphic.SetVerticesDirty();
				}
			}
		}

		public int Seed
		{
			get
			{
				return seed;
			}
			set
			{
				if (value != seed)
				{
					seed = value;
					((BaseMeshEffect)this).graphic.SetVerticesDirty();
				}
			}
		}

		public static float LeftAt(Rect area, Vector2 local, float dried, int seed)
		{
			//IL_0011: 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)
			if (!(dried <= 0f))
			{
				if (!(dried >= 1f))
				{
					return InkDrying.Left(dried, InkDrying.Wetness(local.x - ((Rect)(ref area)).xMin, ((Rect)(ref area)).yMax - local.y, ((Rect)(ref area)).width, ((Rect)(ref area)).height, seed));
				}
				return 0f;
			}
			return 1f;
		}

		public override void ModifyMesh(VertexHelper mesh)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0110: 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_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: 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_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			if (!((UIBehaviour)this).IsActive() || dried <= 0f || mesh.currentVertCount != 4)
			{
				return;
			}
			quad.Clear();
			mesh.GetUIVertexStream(quad);
			UIVertex val = quad[0];
			UIVertex val2 = quad[2];
			mesh.Clear();
			if (dried >= 1f)
			{
				return;
			}
			Rect rect = ((BaseMeshEffect)this).graphic.rectTransform.rect;
			Vector2 val3 = Vector2.op_Implicit(val.position);
			Vector2 val4 = Vector2.op_Implicit(val2.position);
			int num = Mathf.Clamp(Mathf.CeilToInt(Mathf.Abs(val4.x - val3.x) / 2.5f), 1, 240);
			int num2 = Mathf.Clamp(Mathf.CeilToInt(Mathf.Abs(val4.y - val3.y) / 2.5f), 1, 240);
			Color32 color = val.color;
			Vector2 val5 = default(Vector2);
			for (int i = 0; i <= num2; i++)
			{
				float num3 = (float)i / (float)num2;
				for (int j = 0; j <= num; j++)
				{
					float num4 = (float)j / (float)num;
					((Vector2)(ref val5))..ctor(Mathf.Lerp(val3.x, val4.x, num4), Mathf.Lerp(val3.y, val4.y, num3));
					Color32 val6 = color;
					val6.a = (byte)Mathf.RoundToInt((float)(int)color.a * LeftAt(rect, val5, dried, seed));
					mesh.AddVert(Vector2.op_Implicit(val5), val6, new Vector4(Mathf.Lerp(val.uv0.x, val2.uv0.x, num4), Mathf.Lerp(val.uv0.y, val2.uv0.y, num3)));
				}
			}
			int num5 = num + 1;
			for (int k = 0; k < num2; k++)
			{
				for (int l = 0; l < num; l++)
				{
					int num6 = k * num5 + l;
					mesh.AddTriangle(num6, num6 + num5, num6 + num5 + 1);
					mesh.AddTriangle(num6, num6 + num5 + 1, num6 + 1);
				}
			}
		}
	}
	[RequireComponent(typeof(RawImage))]
	internal sealed class LeaderDots : MonoBehaviour
	{
		private const float Step = 7f;

		private const int TileWidth = 14;

		private const int TileHeight = 20;

		private static Texture2D? tile;

		private RawImage image;

		public static void Add(RectTransform rect)
		{
			RawImage val = ((Component)rect).gameObject.AddComponent<RawImage>();
			((Graphic)val).raycastTarget = false;
			val.texture = (Texture)(object)Tile();
			((Component)rect).gameObject.AddComponent<LeaderDots>().image = val;
		}

		private void OnRectTransformDimensionsChange()
		{
			//IL_0015: 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_001f: 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)
			if (!((Object)(object)image == (Object)null))
			{
				Rect rect = ((RectTransform)((Component)this).transform).rect;
				float num = ((Rect)(ref rect)).width / 7f;
				image.uvRect = new Rect(0f - (num - Mathf.Floor(num)), 0f, num, 1f);
			}
		}

		private void Start()
		{
			OnRectTransformDimensionsChange();
		}

		private static Texture2D Tile()
		{
			//IL_0019: 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)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)tile != (Object)null)
			{
				return tile;
			}
			tile = new Texture2D(14, 20, (TextureFormat)4, false)
			{
				name = "BetterCoop.LeaderDot",
				wrapMode = (TextureWrapMode)0,
				filterMode = (FilterMode)1,
				hideFlags = (HideFlags)61
			};
			Ink ink = PaperDrawing.Paper.Mix(PaperDrawing.InkBlack, 0.45f);
			float num = 7f;
			float num2 = 3.6f;
			Color[] array = (Color[])(object)new Color[280];
			for (int i = 0; i < 20; i++)
			{
				for (int j = 0; j < 14; j++)
				{
					float num3 = Mathf.Sqrt(((float)j + 0.5f - num) * ((float)j + 0.5f - num) + ((float)i + 0.5f - num2) * ((float)i + 0.5f - num2));
					float num4 = Mathf.Clamp01(2.9f - num3);
					array[i * 14 + j] = new Color(ink.R * num4, ink.G * num4, ink.B * num4, num4);
				}
			}
			tile.SetPixels(array);
			tile.Apply(false, true);
			return tile;
		}
	}
	internal sealed class LinkControl : PaperControl
	{
		private TMP_Text? text;

		public TMP_Text? Text
		{
			get
			{
				return text;
			}
			set
			{
				text = value;
				Underline(on: false);
			}
		}

		protected override void DoStateTransition(SelectionState state, bool instant)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			base.DoStateTransition(state, instant);
			bool flag = (((int)state == 1 || (int)state == 3) ? true : false);
			Underline(flag);
		}

		private void Underline(bool on)
		{
			//IL_002d: 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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)text != (Object)null)
			{
				text.fontStyle = (FontStyles)(on ? (text.fontStyle | 4) : (text.fontStyle & -5));
			}
		}
	}
	internal static class ModelStage
	{
		public readonly struct Shot
		{
			public Vector3 Eye { get; }

			public Quaternion Turn { get; }

			public float HalfHeight { get; }

			public float Near { get; }

			public float Far { get; }

			public Color Ground { get; }

			public Vector3 Light { get; }

			public Shot(Vector3 eye, Quaternion turn, float halfHeight, float near, float far, Color ground, Vector3 light)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: 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_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: 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)
				Eye = eye;
				Turn = turn;
				HalfHeight = halfHeight;
				Near = near;
				Far = far;
				Ground = ground;
				Light = light;
			}
		}

		private const int Samples = 8;

		private const float LampStrength = 1.4f;

		private static readonly Vector3 Place = new Vector3(0f, -6000f, 0f);

		private static readonly int FogEnabled = Shader.PropertyToID("FogEnabled");

		private static readonly int FogSphereSize = Shader.PropertyToID("_FogSphereSize");

		private const float NoFogSphere = 9999999f;

		private static GameObject? root;

		private static Camera? camera;

		private static Light? lamp;

		public static Transform Root
		{
			get
			{
				Ensure();
				return root.transform;
			}
		}

		public static RenderTexture Draw(GameObject subject, in Shot shot, int width, int height)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			RenderTexture val = new RenderTexture(width, height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)0)
			{
				name = "BetterCoop.Drawn",
				useMipMap = true,
				autoGenerateMips = true,
				filterMode = (FilterMode)2,
				wrapMode = (TextureWrapMode)1,
				hideFlags = (HideFlags)61
			};
			val.Create();
			Render(subject, in shot, val);
			return val;
		}

		public static Texture2D Read(GameObject subject, in Shot shot, int width, int height)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_004b: Expected O, but got Unknown
			RenderTexture temporary = RenderTexture.GetTemporary(width, height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)0);
			RenderTexture active = RenderTexture.active;
			try
			{
				Render(subject, in shot, temporary);
				RenderTexture.active = temporary;
				Texture2D val = new Texture2D(width, height, (TextureFormat)4, false);
				val.ReadPixels(new Rect(0f, 0f, (float)width, (float)height), 0, 0);
				val.Apply(false);
				return val;
			}
			finally
			{
				RenderTexture.active = active;
				RenderTexture.ReleaseTemporary(temporary);
			}
		}

		private static void Render(GameObject subject, in Shot shot, RenderTexture target)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Invalid comparison between Unknown and I4
			//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_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			Ensure();
			int num = 0;
			Renderer[] componentsInChildren = subject.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				num |= 1 << ((Component)val).gameObject.layer;
			}
			Camera val2 = camera;
			Light val3 = lamp;
			val2.cullingMask = num;
			val3.cullingMask = num;
			((Component)val2).transform.SetPositionAndRotation(shot.Eye, shot.Turn);
			val2.orthographicSize = shot.HalfHeight;
			val2.nearClipPlane = shot.Near;
			val2.farClipPlane = shot.Far;
			val2.backgroundColor = shot.Ground;
			val2.aspect = (float)((Texture)target).width / (float)((Texture)target).height;
			((Component)val3).transform.rotation = Quaternion.LookRotation(shot.Light);
			RenderTextureDescriptor val4 = default(RenderTextureDescriptor);
			((RenderTextureDescriptor)(ref val4))..ctor(((Texture)target).width, ((Texture)target).height, (RenderTextureFormat)0, 24);
			((RenderTextureDescriptor)(ref val4)).sRGB = (int)QualitySettings.activeColorSpace == 1;
			((RenderTextureDescriptor)(ref val4)).useMipMap = false;
			((RenderTextureDescriptor)(ref val4)).autoGenerateMips = false;
			((RenderTextureDescriptor)(ref val4)).msaaSamples = 8;
			RenderTextureDescriptor val5 = val4;
			((RenderTextureDescriptor)(ref val5)).msaaSamples = Mathf.Clamp(SystemInfo.GetRenderTextureSupportedMSAASampleCount(val5), 1, 8);
			RenderTexture temporary = RenderTexture.GetTemporary(val5);
			Light sun = RenderSettings.sun;
			float globalFloat = Shader.GetGlobalFloat(FogEnabled);
			float globalFloat2 = Shader.GetGlobalFloat(FogSphereSize);
			try
			{
				val2.targetTexture = temporary;
				((Behaviour)val3).enabled = true;
				RenderSettings.sun = val3;
				Shader.SetGlobalFloat(FogEnabled, 0f);
				Shader.SetGlobalFloat(FogSphereSize, 9999999f);
				val2.Render();
				Graphics.Blit((Texture)(object)temporary, target);
			}
			finally
			{
				Shader.SetGlobalFloat(FogEnabled, globalFloat);
				Shader.SetGlobalFloat(FogSphereSize, globalFloat2);
				RenderSettings.sun = sun;
				((Behaviour)val3).enabled = false;
				val2.targetTexture = null;
				RenderTexture.ReleaseTemporary(temporary);
			}
		}

		private static void Ensure()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: 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)
			if (!((Object)(object)root != (Object)null) || !((Object)(object)camera != (Object)null) || !((Object)(object)lamp != (Object)null))
			{
				if ((Object)(object)root != (Object)null)
				{
					Object.Destroy((Object)(object)root);
				}
				root = new GameObject("BetterCoop.ModelStage");
				Object.DontDestroyOnLoad((Object)(object)root);
				root.transform.position = Place;
				camera = new GameObject("Camera").AddComponent<Camera>();
				((Component)camera).transform.SetParent(root.transform, false);
				((Behaviour)camera).enabled = false;
				camera.orthographic = true;
				camera.clearFlags = (CameraClearFlags)2;
				camera.allowHDR = false;
				camera.allowMSAA = true;
				camera.useOcclusionCulling = false;
				lamp = new GameObject("Lamp").AddComponent<Light>();
				((Component)lamp).transform.SetParent(root.transform, false);
				lamp.type = (LightType)1;
				lamp.intensity = 1.4f;
				lamp.color = Color.white;
				lamp.shadows = (LightShadows)0;
				((Behaviour)lamp).enabled = false;
			}
		}
	}
	[RequireComponent(typeof(TMP_Text))]
	internal sealed class NumberWheels : MonoBehaviour
	{
		private static readonly char[] Figures = "0123456789".ToCharArray();

		private TMP_Text text;

		private string from = string.Empty;

		private string to = string.Empty;

		private bool fullTurn;

		private float setAt = float.NegativeInfinity;

		private float restsIn;

		private bool resting = true;

		private bool rollNext;

		private float rollDelay;

		private string open = string.Empty;

		public static NumberWheels Add(TMP_Text text, float advance)
		{
			NumberWheels numberWheels = ((Component)text).gameObject.AddComponent<NumberWheels>();
			numberWheels.text = text;
			numberWheels.open = FormattableString.Invariant($"<mspace={advance}em>");
			return numberWheels;
		}

		public void Set(string figures)
		{
			if (!(figures == to))
			{
				bool flag = to.Length == 0 && !rollNext;
				Turn(rollNext ? NumberingMachine.Noughts(figures) : (flag ? figures : Now()), figures, rollNext, rollNext ? rollDelay : 0f);
				rollNext = false;
			}
		}

		public void Roll(float delay = 0f)
		{
			if (to.Length == 0)
			{
				rollNext = true;
				rollDelay = delay;
			}
			else
			{
				Turn(NumberingMachine.Noughts(to), to, full: true, delay);
			}
		}

		private void Turn(string start, string figures, bool full, float delay = 0f)
		{
			from = start;
			to = figures;
			fullTurn = full;
			setAt = Time.unscaledTime + delay;
			restsIn = NumberingMachine.Seconds(from, to, fullTurn);
			resting = restsIn <= 0f;
			Show();
		}

		private string Now()
		{
			return NumberingMachine.Shown(from, to, Time.unscaledTime - setAt, fullTurn);
		}

		private void LateUpdate()
		{
			if (resting)
			{
				return;
			}
			Show();
			if (Time.unscaledTime - setAt >= restsIn)
			{
				resting = true;
				if (((Behaviour)text).isActiveAndEnabled)
				{
					PaperSounds.Play(PaperSounds.Kind.Clunk);
				}
			}
		}

		private void Show()
		{
			string text = Now();
			int num = text.IndexOfAny(Figures);
			PaperText.Set(this.text, (num < 0) ? text : (text.Substring(0, num) + open + text.Substring(num)));
		}
	}
	internal sealed class PairBoard : MonoBehaviour
	{
		public const float PhotoWidth = 124f;

		public const float PhotoHeight = 155f;

		private const float CaptionHeight = 56f;

		private const float CellHeight = 211f;

		private const float PairLabelHeight = 40f;

		private const float PartnerGap = 8f;

		private const float PairWidth = 256f;

		private const int PairsPerRow = 4;

		private const int UnpairedPerRow = 8;

		private readonly List<SlotView> slots = new List<SlotView>();

		private PairDraft draft;

		private IPortraits portraits;

		private Func<int, string> nameOf;

		private Action<int> moved;

		private TMP_Text template;

		private bool editable;

		private Slot? held;

		private RectTransform? ghost;

		private SlotView? marked;

		private (int Actor, Vector3 At)? released;

		public Selectable? First => (Selectable?)(object)slots.Select((SlotView s) => s.Control).FirstOrDefault((PaperControl c) => (Object)(object)c != (Object)null);

		public static PairBoard Build(RectTransform root, TMP_Text template, PairDraft draft, IPortraits portraits, Func<int, string> nameOf, bool editable, Action<int> moved)
		{
			PairBoard pairBoard = ((Component)root).gameObject.AddComponent<PairBoard>();
			pairBoard.template = template;
			pairBoard.draft = draft;
			pairBoard.portraits = portraits;
			pairBoard.nameOf = nameOf;
			pairBoard.editable = editable;
			pairBoard.moved = moved;
			pairBoard.LayOut(root);
			return pairBoard;
		}

		public void Redraw()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			IReadOnlyDictionary<int, Vector3> before = Places();
			released = null;
			Drop();
			slots.Clear();
			foreach (Transform item in ((Component)this).transform)
			{
				((Component)item).gameObject.SetActive(false);
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
			RectTransform val2 = (RectTransform)((Component)this).transform;
			LayOut(val2);
			RectTransform val3 = val2;
			while (true)
			{
				Transform parent = ((Transform)val3).parent;
				RectTransform val4 = (RectTransform)(object)((parent is RectTransform) ? parent : null);
				if (val4 == null || !((Object)(object)((Component)val4).GetComponent<LayoutGroup>() != (Object)null))
				{
					break;
				}
				val3 = val4;
			}
			LayoutRebuilder.ForceRebuildLayoutImmediate(val3);
			VectorView.DrawAll((Transform)(object)val2);
			GlideFrom(before);
		}

		public bool PutBack()
		{
			if (!held.HasValue)
			{
				return false;
			}
			Drop();
			return true;
		}

		public void Select(int actor)
		{
			Slot? slot = draft.Find(actor);
			if (slot.HasValue)
			{
				Slot slot2 = slot.GetValueOrDefault();
				PaperControl paperControl = slots.FirstOrDefault((SlotView s) => s.Slot == slot2)?.Control;
				if (paperControl != null && (Object)(object)EventSystem.current != (Object)null)
				{
					EventSystem.current.SetSelectedGameObject(((Component)paperControl).gameObject);
				}
			}
		}

		internal void Press(SlotView view)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			Slot? slot = held;
			if (slot.HasValue)
			{
				Slot valueOrDefault = slot.GetValueOrDefault();
				if (valueOrDefault == view.Slot)
				{
					Drop();
					return;
				}
				int value = draft.At(valueOrDefault).Value;
				if ((Object)(object)ghost != (Object)null)
				{
					released = (value, ((Transform)ghost).position);
				}
				Drop();
				if (draft.Move(valueOrDefault, view.Slot))
				{
					Plugin.Verbose($"Moved {value} on the Pair Assignment board to {view.Slot}.");
					moved(value);
				}
			}
			else if (draft.At(view.Slot).HasValue)
			{
				PickUp(view);
			}
		}

		public IReadOnlyDictionary<int, Vector3> Places()
		{
			//IL_0061: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<int, Vector3> dictionary = new Dictionary<int, Vector3>();
			foreach (SlotView slot in slots)
			{
				int? num = draft.At(slot.Slot);
				if (num.HasValue)
				{
					int valueOrDefault = num.GetValueOrDefault();
					if ((Object)(object)slot.Content != (Object)null)
					{
						dictionary[valueOrDefault] = ((Component)slot.Content).transform.position;
					}
				}
			}
			(int, Vector3)? tuple = released;
			if (tuple.HasValue)
			{
				(int, Vector3) valueOrDefault2 = tuple.GetValueOrDefault();
				int item = valueOrDefault2.Item1;
				Vector3 item2 = valueOrDefault2.Item2;
				dictionary[item] = item2;
			}
			return dictionary;
		}

		public void GlideFrom(IReadOnlyDictionary<int, Vector3> before)
		{
			//IL_0050: 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_0070: Expected O, but got Unknown
			foreach (SlotView slot in slots)
			{
				int? num = draft.At(slot.Slot);
				if (num.HasValue)
				{
					int valueOrDefault = num.GetValueOrDefault();
					Vector3 value;
					Vector3? val = (before.TryGetValue(valueOrDefault, out value) ? new Vector3?(value) : ((Vector3?)null));
					Glide.Start((RectTransform)((Component)slot.Content).transform, val);
					if ((Object)(object)slot.Mount != (Object)null)
					{
						Glide.Start(slot.Mount, val);
					}
				}
			}
		}

		internal void BeginDrag(SlotView view)
		{
			if (!held.HasValue && draft.At(view.Slot).HasValue)
			{
				PickUp(view);
			}
		}

		internal void EndDrag(PointerEventData eventData)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (held.HasValue)
			{
				RaycastResult pointerCurrentRaycast = eventData.pointerCurrentRaycast;
				GameObject under = ((RaycastResult)(ref pointerCurrentRaycast)).gameObject;
				SlotView slotView = (((Object)(object)under != (Object)null) ? slots.FirstOrDefault((SlotView s) => under.transform.IsChildOf((Transform)(object)s.Rect)) : null);
				if (slotView == null)
				{
					Drop();
				}
				else
				{
					Press(slotView);
				}
			}
		}

		private void PickUp(SlotView view)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			held = view.Slot;
			view.Faded = true;
			ghost = PaperList.NewRect("Held", ((Component)this).transform);
			((Component)ghost).gameObject.AddComponent<LayoutElement>().ignoreLayout = true;
			RectTransform? obj = ghost;
			RectTransform? obj2 = ghost;
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0.5f, 0.5f);
			obj2.anchorMax = val;
			obj.anchorMin = val;
			ghost.pivot = new Vector2(0.5f, 0.5f);
			ghost.sizeDelta = new Vector2(140f, 223f);
			((Transform)ghost).localRotation = Quaternion.Euler(0f, 0f, 3f);
			VectorView.Add(ghost, (Vector2 s) => FormDrawing.Card(s.x, s.y, lifted: true), Color.clear);
			RectTransform val2 = PaperList.NewRect("Print", (Transform)(object)ghost);
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = new Vector2(6f, 8f);
			val2.offsetMax = new Vector2(-10f, -4f);
			Portrait(val2, draft.At(view.Slot).Value, view.Slot.Kind);
			CanvasGroup obj3 = ((Component)ghost).gameObject.AddComponent<CanvasGroup>();
			obj3.blocksRaycasts = false;
			obj3.interactable = false;
			((Transform)ghost).SetAsLastSibling();
			VectorView.DrawAll((Transform)(object)ghost);
			Follow();
		}

		private void Drop()
		{
			Slot? slot = held;
			if (slot.HasValue)
			{
				Slot slot2 = slot.GetValueOrDefault();
				SlotView slotView = slots.FirstOrDefault((SlotView s) => s.Slot == slot2);
				if (slotView != null)
				{
					slotView.Faded = false;
				}
			}
			held = null;
			Mark(null);
			if ((Object)(object)ghost != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)ghost).gameObject);
				ghost = null;
			}
		}

		private void LateUpdate()
		{
			try
			{
				if (held.HasValue)
				{
					Follow();
				}
			}
			catch (Exception exception)
			{
				Guard.Report("PairBoard.LateUpdate", exception);
			}
		}

		private void OnDisable()
		{
			if (held.HasValue)
			{
				Drop();
			}
		}

		private void Follow()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Invalid comparison between Unknown and I4
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ghost == (Object)null)
			{
				return;
			}
			RectTransform val = (RectTransform)((Component)this).transform;
			SlotView slotView = null;
			GameObject selected = (((Object)(object)EventSystem.current != (Object)null) ? EventSystem.current.currentSelectedGameObject : null);
			if ((int)InputHandler.GetCurrentUsedInputScheme() == 1 && (Object)(object)selected != (Object)null)
			{
				slotView = slots.FirstOrDefault((SlotView s) => (Object)(object)s.Control != (Object)null && (Object)(object)((Component)s.Control).gameObject == (Object)(object)selected);
			}
			if (slotView != null)
			{
				RectTransform rect = slotView.Rect;
				Rect rect2 = slotView.Rect.rect;
				Vector3 val2 = ((Transform)rect).TransformPoint(Vector2.op_Implicit(((Rect)(ref rect2)).center));
				((Transform)ghost).localPosition = Vector2.op_Implicit(Vector2.op_Implicit(((Transform)val).InverseTransformPoint(val2)) + new Vector2(18f, -18f));
			}
			else
			{
				Mouse current = Mouse.current;
				if (current != null)
				{
					Canvas rootCanvas = ((Component)val).GetComponentInParent<Canvas>().rootCanvas;
					Camera eye = (((int)rootCanvas.renderMode == 0) ? null : rootCanvas.worldCamera);
					Vector2 screen = ((InputControl<Vector2>)(object)((Pointer)current).position).ReadValue();
					Vector2 val3 = default(Vector2);
					if (RectTransformUtility.ScreenPointToLocalPointInRectangle(val, screen, eye, ref val3))
					{
						((Transform)ghost).localPosition = Vector2.op_Implicit(val3);
					}
					slotView = slots.FirstOrDefault((SlotView s) => RectTransformUtility.RectangleContainsScreenPoint(s.Rect, screen, eye));
				}
			}
			Mark(slotView);
		}

		private void Mark(SlotView? view)
		{
			if (marked != view)
			{
				if (marked != null)
				{
					marked.Marked = false;
				}
				marked = view;
				if (marked != null)
				{
					marked.Marked = true;
				}
			}
		}

		private void LayOut(RectTransform root)
		{
			//IL_0010: 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_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: 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_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			GridLayoutGroup val = Grid((Transform)(object)root, "Pairs", new Vector2(256f, 251f), 4, new Vector2(22f, 12f));
			int num = 0;
			for (int i = 0; i < draft.Rows.Count; i++)
			{
				(int? Carrier, int? Rider) tuple = draft.Rows[i];
				int? item = tuple.Carrier;
				int? item2 = tuple.Rider;
				bool flag = !item.HasValue && !item2.HasValue;
				if (!flag || editable)
				{
					RectTransform val2 = PaperList.NewRect("Pair", ((Component)val).transform);
					RectTransform val3 = PaperList.NewRect("Number", (Transform)(object)val2);
					val3.anchorMin = new Vector2(0f, 1f);
					val3.anchorMax = Vector2.one;
					val3.pivot = new Vector2(0.5f, 1f);
					val3.sizeDelta = new Vector2(0f, 40f);
					TMP_Text obj = Text(val3, flag ? Strings.MenuNewPair : Strings.MenuPairNumber(++num), 24f, (TextAlignmentOptions)258);
					obj.fontStyle = (FontStyles)1;
					((Graphic)obj).color = (flag ? PaperList.Faded(PaperText.Blue, 0.5f) : PaperText.Blue);
					AddSlot(Cell(val2, 0f), new Slot(SlotKind.Carrier, i));
					AddSlot(Cell(val2, 132f), new Slot(SlotKind.Rider, i));
					((Transform)val3).SetAsLastSibling();
				}
			}
			if (draft.Unpaired.Count != 0 || editable)
			{
				RectTransform val4 = PaperList.NewRect("UnpairedTitle", (Transform)(object)root);
				LayoutElement obj2 = ((Component)val4).gameObject.AddComponent<LayoutElement>();
				float minHeight = (obj2.preferredHeight = 44f);
				obj2.minHeight = minHeight;
				Text(val4, Strings.MenuUnpaired, 24f, (TextAlignmentOptions)1026).fontStyle = (FontStyles)1;
				GridLayoutGroup val5 = Grid((Transform)(object)root, "Unpaired", new Vector2(124f, 211f), 8, new Vector2(10f, 12f));
				int num3 = draft.Unpaired.Count + (editable ? 1 : 0);
				for (int j = 0; j < num3; j++)
				{
					AddSlot(PaperList.NewRect("Cell", ((Component)val5).transform), new Slot(SlotKind.Unpaired, j));
				}
			}
		}

		private static RectTransform Cell(RectTransform pair, float x)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			RectTransform obj = PaperList.NewRect("Cell", (Transform)(object)pair);
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0f, 1f);
			obj.anchorMax = val;
			obj.anchorMin = val;
			obj.pivot = new Vector2(0f, 1f);
			obj.sizeDelta = new Vector2(124f, 211f);
			obj.anchoredPosition = new Vector2(x, -40f);
			return obj;
		}

		private static GridLayoutGroup Grid(Transform root, string name, Vector2 cell, int columns, Vector2 spacing)
		{
			//IL_0012: 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)
			GridLayoutGroup obj = ((Component)PaperList.NewRect(name, root)).gameObject.AddComponent<GridLayoutGroup>();
			obj.cellSize = cell;
			obj.spacing = spacing;
			obj.constraint = (Constraint)1;
			obj.constraintCount = columns;
			((LayoutGroup)obj).childAlignment = (TextAnchor)1;
			return obj;
		}

		private void AddSlot(RectTransform rect, Slot slot)
		{
			//IL_0034: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: 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_01c5: Unknown result type (might be due to invalid IL or missing references)
			SlotView view = new SlotView(slot, rect);
			int? num = draft.At(slot);
			RectTransform val = PaperList.NewRect("Content", (Transform)(object)rect);
			val.anchorMin = Vector2.zero;
			val.anchorMax = Vector2.one;
			Vector2 offsetMin = (val.offsetMax = Vector2.zero);
			val.offsetMin = offsetMin;
			view.Content = ((Component)val).gameObject.AddComponent<CanvasGroup>();
			if (num.HasValue)
			{
				int valueOrDefault = num.GetValueOrDefault();
				Portrait(val, valueOrDefault, slot.Kind);
				RectTransform val2 = PaperList.NewRect("Mount", (Transform)(object)rect);
				val2.anchorMin = Vector2.zero;
				val2.anchorMax = Vector2.one;
				offsetMin = (val2.offsetMax = Vector2.zero);
				val2.offsetMin = offsetMin;
				ScoutPhoto.Corners(val2, valueOrDefault);
				view.Mount = val2;
			}
			else
			{
				VectorView.Add(ScoutPhoto.PhotoArea(val), (Vector2 s) => FormDrawing.Slot(s.x, s.y, marked: false), Color.clear);
				((Graphic)Text(ScoutPhoto.Caption(val), (slot.Kind == SlotKind.Unpaired) ? Strings.MenuDropHere : Strings.MenuEmptyPlace, 20f, (TextAlignmentOptions)258)).color = PaperList.Faded(PaperText.Ink, 0.45f);
			}
			RectTransform rect2 = ScoutPhoto.PhotoArea(rect);
			view.Mark = ((Component)VectorView.Add(rect2, (Vector2 s) => FormDrawing.Slot(s.x, s.y, marked: true), Color.clear)).GetComponent<RawImage>();
			((Behaviour)view.Mark).enabled = false;
			if (editable)
			{
				((Graphic)((Component)rect).gameObject.AddComponent<Image>()).color = Color.clear;
				SlotControl slotControl = PaperControl.Add<SlotControl>(((Component)rect).gameObject);
				slotControl.Board = this;
				slotControl.View = view;
				slotControl.Visual = (Transform?)(object)val;
				slotControl.Companion = (Transform?)(object)view.Mount;
				slotControl.Pressed = delegate
				{
					Press(view);
				};
				slotControl.Back = delegate
				{
					PutBack();
				};
				view.Control = slotControl;
			}
			slots.Add(view);
		}

		private void Portrait(RectTransform parent, int actor, SlotKind kind)
		{
			ScoutPhoto.Add(parent, template, portraits, actor, nameOf(actor), (kind == SlotKind.Unpaired) ? null : Strings.RoleOf(kind == SlotKind.Carrier));
		}

		private TMP_Text Text(RectTransform rect, string value, float size, TextAlignmentOptions alignment)
		{
			//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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			RectTransform obj = PaperList.NewRect("Text", (Transform)(object)rect);
			obj.anchorMin = Vector2.zero;
			obj.anchorMax = Vector2.one;
			Vector2 offsetMin = (obj.offsetMax = Vector2.zero);
			obj.offsetMin = offsetMin;
			TMP_Text obj2 = PaperText.Make(((Component)obj).gameObject, template, size, alignment);
			obj2.text = value;
			return obj2;
		}
	}
	internal sealed class SlotView
	{
		private bool marked;

		public Slot Slot { get; }

		public RectTransform Rect { get; }

		public CanvasGroup Content { get; set; }

		public RectTransform? Mount { get; set; }

		public RawImage Mark { get; set; }

		public PaperControl? Control { get; set; }

		public bool Marked
		{
			get
			{
				return marked;
			}
			set
			{
				marked = value;
				((Behaviour)Mark).enabled = value;
			}
		}

		public bool Faded
		{
			set
			{
				Content.alpha = (value ? 0f : 1f);
			}
		}

		public SlotView(Slot slot, RectTransform rect)
		{
			Slot = slot;
			Rect = rect;
		}
	}
	internal sealed class SlotControl : PaperControl, IBeginDragHandler, IEventSystemHandler, IDragHandler, IEndDragHandler
	{
		public PairBoard Board { get; set; }

		public SlotView View { get; set; }

		public void OnBeginDrag(PointerEventData eventData)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if ((int)eventData.button == 0 && ((Selectable)this).IsInteractable())
			{
				Board.BeginDrag(View);
			}
		}

		public void OnDrag(PointerEventData eventData)
		{
		}

		public void OnEndDrag(PointerEventData eventData)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if ((int)eventData.button == 0)
			{
				Board.EndDrag(eventData);
			}
		}
	}
	internal class PaperControl : Selectable, IPointerClickHandler, IEventSystemHandler, ISubmitHandler
	{
		private const float Lift = 1.08f;

		private const float Sink = 0.94f;

		private static NicksButtonSFX? sounds;

		private float scale = 1f;

		private float target = 1f;

		public static int Uses { get; private set; }

		public Action? Pressed { get; set; }

		public Action? Back { get; set; }

		public Action<int>? Step { get; set; }

		public Transform? Visual { get; set; }

		public Transform? Companion { get; set; }

		public static void UseSoundsOf(Button template)
		{
			if ((Object)(object)sounds == (Object)null)
			{
				sounds = ((Component)template).GetComponentInChildren<NicksButtonSFX>(true);
			}
		}

		public static T Add<T>(GameObject holder, Action? pressed = null) where T : PaperControl
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			T val = holder.AddComponent<T>();
			((Selectable)val).transition = (Transition)0;
			Navigation navigation = default(Navigation);
			((Navigation)(ref navigation)).mode = (Mode)3;
			((Selectable)val).navigation = navigation;
			val.Pressed = pressed;
			return val;
		}

		public virtual void OnPointerClick(PointerEventData eventData)
		{
			//IL_000a: 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_0020: Invalid comparison between Unknown and I4
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Invalid comparison between Unknown and I4
			if (((Selectable)this).IsInteractable())
			{
				if ((int)eventData.button == 0)
				{
					Press();
				}
				else if ((int)eventData.button == 1 && Back != null)
				{
					Uses++;
					Play(click: true);
					Run(Back);
				}
				if ((int)eventData.button != 2 && (Object)(object)EventSystem.current != (Object)null && (Object)(object)EventSystem.current.currentSelectedGameObject == (Object)(object)((Component)this).gameObject)
				{
					EventSystem.current.SetSelectedGameObject((GameObject)null);
				}
			}
		}

		public virtual void OnSubmit(BaseEventData eventData)
		{
			if (((Selectable)this).IsInteractable())
			{
				Press();
			}
		}

		public override void OnMove(AxisEventData eventData)
		{
			//IL_0022: 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_0035: Invalid comparison between Unknown and I4
			if (Step != null && ((int)eventData.moveDir == 0 || (int)eventData.moveDir == 2))
			{
				Uses++;
				Play(click: true);
				Run(delegate
				{
					//IL_0011: Unknown result type (might be due to invalid IL or missing references)
					Step(((int)eventData.moveDir != 0) ? 1 : (-1));
				});
				((AbstractEventData)eventData).Use();
			}
			else
			{
				((Selectable)this).OnMove(eventData);
			}
		}

		public override void OnSelect(BaseEventData eventData)
		{
			((Selectable)this).OnSelect(eventData);
			Play(click: false);
		}

		public override void OnPointerEnter(PointerEventData eventData)
		{
			((Selectable)this).OnPointerEnter(eventData);
			if (((Selectable)this).IsInteractable())
			{
				Play(click: false);
			}
		}

		public void Thump(float depth = 0.85f)
		{
			scale = depth;
		}

		protected virtual void Press()
		{
			Uses++;
			Play(click: true);
			Thump(0.94f);
			if (Pressed != null)
			{
				Run(Pressed);
			}
		}

		protected override void DoStateTransition(SelectionState state, bool instant)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected I4, but got Unknown
			float num;
			switch (state - 1)
			{
			case 0:
			case 2:
				num = 1.08f;
				break;
			case 1:
				num = 0.94f;
				break;
			default:
				num = 1f;
				break;
			}
			target = num;
			if (instant)
			{
				scale = target;
				Apply();
			}
		}

		protected virtual void LateUpdate()
		{
			if (!(Mathf.Abs(scale - target) < 0.001f))
			{
				scale = Mathf.Lerp(scale, target, 1f - Mathf.Exp(-18f * Time.unscaledDeltaTime));
				Apply();
			}
		}

		private void Apply()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			(Visual ?? ((Component)this).transform).localScale = Vector3.one * scale;
			if ((Object)(object)Companion != (Object)null)
			{
				Companion.localScale = Vector3.one * scale;
			}
		}

		private void Play(bool click)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)sounds != (Object)null && (Object)(object)SFX_Player.instance != (Object)null)
				{
					SFX_Player.instance.PlaySFX(click ? sounds.sfxClick : sounds.sfxHover, ((Component)this).transform.position, (Transform)null, (SFX_Settings)null, 1f, false);
				}
			}
			catch (Exception exception)
			{
				Guard.Report("PaperControl.Sound", exception);
			}
		}

		private void Run(Action action)
		{
			try
			{
				action();
			}
			catch (Exception exception)
			{
				Guard.Report(((Object)this).name, exception);
			}
		}
	}
	internal sealed class PaperList
	{
		public const float FieldHeight = 56f;

		public const float HeaderHeight = 84f;

		private const float RuleHeight = 5f;

		private const float TypeInDelay = 0.25f;

		private const float TypeInStep = 0.05f;

		private const float TypeInLongest = 0.9f;

		private const float TableGap = 12f;

		private const float TableLineStep = 0.09f;

		private const float TableTyping = 1.2f;

		private const float LeaderHeight = 10f;

		private const float CheckSize = 46f;

		private const float SignatureWidth = 400f;

		private static readonly Vector2 CreditsSize = new Vector2(236f, 96f);

		private static readonly (Vector2 Spot, float Slant)[] CreditSpots = new(Vector2, float)[2]
		{
			(new Vector2(50f, 38f), 13f),
			(new Vector2(138f, 13f), -19f)
		};

		private static readonly Vector3[] NameWobble = (Vector3[])(object)new Vector3[4]
		{
			new Vector3(0f, 0f, 0f),
			new Vector3(0.6f, -0.4f, 0.7f),
			new Vector3(-0.5f, 0.3f, -0.5f),
			new Vector3(0.3f, 0.5f, 0.4f)
		};

		private const float SignatureInset = 16f;

		private const float StampHeight = 56f;

		private const float RingPadding = 10f;

		private const float RingStroke = 2.8f;

		private const float StepperWidth = 140f;

		private const float StepperWidest = 460f;

		private const float StepperPadding = 24f;

		private static readonly Vector2 BadgeCell = new Vector2(250f, 290f);

		private const float BadgePatch = 150f;

		private static readonly float[] BadgeTilts = new float[4] { -6f, 4f, -3f, 7f };

		private const float TableColumnWidth = 170f;

		private readonly List<PaperRow> rows = new List<PaperRow>();

		private readonly List<Func<bool>> backs = new List<Func<bool>>();

		private readonly RectTransform content;

		private readonly TMP_Text template;

		private int section;

		private int fills;

		public IReadOnlyList<PaperRow> Rows => rows;

		public TMP_Text Template => template;

		public static Color Pen => ToColor(FormDrawing.Pen);

		public static Color StampRed => ToColor(FormDrawing.StampRed);

		public PaperList(RectTransform content, Button buttonTemplate)
		{
			this.content = content;
			template = ((Component)buttonTemplate).GetComponentInChildren<TMP_Text>(true);
			PaperControl.UseSoundsOf(buttonTemplate);
		}

		public static Button CloneButton(Button template, Transform parent, string name, Action onClick)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, parent);
			((Object)val).name = name;
			LocalizedText[] componentsInChildren = val.GetComponentsInChildren<LocalizedText>(true);
			foreach (LocalizedText obj in componentsInChildren)
			{
				obj.autoSet = false;
				((Behaviour)obj).enabled = false;
			}
			Button component = val.GetComponent<Button>();
			component.onClick = new ButtonClickedEvent();
			((UnityEvent)component.onClick).AddListener((UnityAction)delegate
			{
				//IL_001c: Unknown result type (might be due to invalid I