Decompiled source of EquipmentTimers v1.0.8

BepInEx/plugins/EquipmentTimers/EquipmentTimers.dll

Decompiled 16 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using AK;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using GameData;
using Gear;
using HarmonyLib;
using HawChow.EquipmentTimers.Diagnostics;
using HawChow.EquipmentTimers.Game;
using HawChow.EquipmentTimers.Timers;
using HawChow.EquipmentTimers.Ui;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("EquipmentTimers")]
[assembly: AssemblyProduct("EquipmentTimers")]
[assembly: AssemblyCompany("HawChow")]
[assembly: AssemblyFileVersion("1.0.8.0")]
[assembly: AssemblyInformationalVersion("1.0.8")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyVersion("1.0.8.0")]
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;
		}
	}
}
namespace HawChow.EquipmentTimers
{
	[BepInPlugin("HawChow.EquipmentTimers", "EquipmentTimers", "1.0.8")]
	public sealed class Plugin : BasePlugin
	{
		internal static Plugin Instance;

		internal static bool Ready;

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<bool> ShowMeleeCharge;

		internal static ConfigEntry<bool> ShowReload;

		internal static ConfigEntry<bool> ShowScanner;

		internal static ConfigEntry<bool> PlayReadySound;

		internal static ConfigEntry<bool> ShowGlueGun;

		internal static ConfigEntry<string> ReadySoundEvent;

		internal static ConfigEntry<float> ReadyHoldSeconds;

		internal static ConfigEntry<float> OverrunGraceSeconds;

		internal static ConfigEntry<float> GapRatio;

		internal static ConfigEntry<float> MinGap;

		internal static ConfigEntry<float> MaxGap;

		internal static ConfigEntry<float> LabelWidthRatio;

		internal static ConfigEntry<float> MinLabelWidth;

		internal static ConfigEntry<string> ReadyColor;

		internal static ConfigEntry<float> NeutralAlpha;

		internal static ConfigEntry<bool> VerboseLog;

		private static TimerPolicy _policy = TimerPolicy.Default();

		private static TimerStyle _style = TimerStyle.Default;

		internal static int LogLineBudget
		{
			get
			{
				if (VerboseLog == null || !VerboseLog.Value)
				{
					return 40;
				}
				return 400;
			}
		}

		internal static TimerPolicy Policy => _policy;

		internal static TimerStyle Style => _style;

		internal static uint ReadySoundId => ResolveEvent((ReadySoundEvent == null) ? "IMPLANTREADY" : ReadySoundEvent.Value);

		public override void Load()
		{
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Expected O, but got Unknown
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Expected O, but got Unknown
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Expected O, but got Unknown
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Expected O, but got Unknown
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Expected O, but got Unknown
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Expected O, but got Unknown
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Expected O, but got Unknown
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Expected O, but got Unknown
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0336: Expected O, but got Unknown
			//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fe: Expected O, but got Unknown
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			Enabled = ((BasePlugin)this).Config.Bind<bool>("General", "Enabled", true, "Draw the equipment timers. Turning this off hides every label immediately; nothing else changes.");
			ShowMeleeCharge = ((BasePlugin)this).Config.Bind<bool>("General", "ShowMeleeCharge", true, "Show the remaining time until the melee charge-up reaches full damage.");
			ShowReload = ((BasePlugin)this).Config.Bind<bool>("General", "ShowReload", true, "Show the remaining reload time for primary and secondary weapons.");
			ShowScanner = ((BasePlugin)this).Config.Bind<bool>("General", "ShowScanner", true, "Show the BioTracker (enemy scanner) recharge countdown.");
			ShowGlueGun = ((BasePlugin)this).Config.Bind<bool>("General", "ShowGlueGun", true, "Show the GlueGun charge read-out: the native burst shot count and the charge time already accumulated, on one line, only while the charge is being held.");
			PlayReadySound = ((BasePlugin)this).Config.Bind<bool>("General", "PlayReadySound", true, "Play one vanilla Wwise UI event when a timer really completes. Cancels, the first observation and weapon switches never play it.");
			ReadySoundEvent = ((BasePlugin)this).Config.Bind<string>("General", "ReadySoundEvent", "IMPLANTREADY", new ConfigDescription("Vanilla Wwise event used for the one-shot ready cue. 'None' disables the sound without touching the green READY label.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[6] { "IMPLANTREADY", "IMPLANTREADYSMALL", "HUD_SCAN_COMPLETE_INDICATION", "BUTTONGENERICBLIPACTIVATED", "BUTTONGENERICBLIPONE", "None" }), Array.Empty<object>()));
			ReadyHoldSeconds = ((BasePlugin)this).Config.Bind<float>("General", "ReadyHoldSeconds", 0.6f, new ConfigDescription("How long the green READY label stays after a real completion. Clamped to 0.2-3 seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 3f), Array.Empty<object>()));
			OverrunGraceSeconds = ((BasePlugin)this).Config.Bind<float>("General", "OverrunGraceSeconds", 2.5f, new ConfigDescription("If the native action is still running this long after the countdown hit zero, the label is dropped silently instead of claiming success. Clamped to 0.5-10 seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 10f), Array.Empty<object>()));
			GapRatio = ((BasePlugin)this).Config.Bind<float>("Layout", "GapRatio", 0.22f, new ConfigDescription("Gap between the timer and the native equipment name, as a fraction of the native font size. Clamped to 0.02-1.5.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.02f, 1.5f), Array.Empty<object>()));
			MinGap = ((BasePlugin)this).Config.Bind<float>("Layout", "MinGap", 2f, new ConfigDescription("Lower clamp for that gap, in canvas units.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 40f), Array.Empty<object>()));
			MaxGap = ((BasePlugin)this).Config.Bind<float>("Layout", "MaxGap", 40f, new ConfigDescription("Upper clamp for that gap, in canvas units.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 200f), Array.Empty<object>()));
			LabelWidthRatio = ((BasePlugin)this).Config.Bind<float>("Layout", "LabelWidthRatio", 4f, new ConfigDescription("Width of the timer box, as a multiple of the native font size. The text is left-aligned on the shared column, and the whole column (widest label + this gap) stays left of every native name. Clamped to 1.5-12.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1.5f, 12f), Array.Empty<object>()));
			MinLabelWidth = ((BasePlugin)this).Config.Bind<float>("Layout", "MinLabelWidth", 24f, new ConfigDescription("Lower clamp for that width, in canvas units.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(8f, 200f), Array.Empty<object>()));
			ReadyColor = ((BasePlugin)this).Config.Bind<string>("Layout", "ReadyColor", "#6BF25A", "Colour of the READY label. Accepts #RRGGBB or 'r,g,b' (0-1 or 0-255).");
			NeutralAlpha = ((BasePlugin)this).Config.Bind<float>("Layout", "NeutralAlpha", 0.92f, new ConfigDescription("Opacity of the neutral countdown; it always inherits the native name colour.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 1f), Array.Empty<object>()));
			VerboseLog = ((BasePlugin)this).Config.Bind<bool>("Debug", "VerboseLog", false, "Raise the bounded log budget from 40 to 400 lines. The plugin still never logs per frame.");
			((BasePlugin)this).Config.SettingChanged += delegate
			{
				Refresh();
			};
			Refresh();
			ClassInjector.RegisterTypeInIl2Cpp<EquipmentTimerOverlay>();
			((BasePlugin)this).AddComponent<EquipmentTimerOverlay>();
			Ready = true;
			int num = 0;
			try
			{
				Harmony val = new Harmony("HawChow.EquipmentTimers");
				val.PatchAll(typeof(Plugin).Assembly);
				num = ((val.GetPatchedMethods() != null) ? 1 : 0);
			}
			catch (Exception ex)
			{
				((BasePlugin)this).Log.LogWarning((object)("Harmony patching failed; timers stay disabled this session: " + ex.Message));
			}
			ManualLogSource log = ((BasePlugin)this).Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(134, 9, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("EquipmentTimers");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("1.0.8");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" loaded; read-only HUD labels left of the native equipment names; ");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("enabled=");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<bool>(Enabled.Value);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; melee=");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<bool>(ShowMeleeCharge.Value);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; reload=");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<bool>(ShowReload.Value);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; scanner=");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<bool>(ShowScanner.Value);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; ");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("readySound=");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ReadySoundEvent.Value);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; hold=");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(ReadyHoldSeconds.Value, "0.00");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("s; patches=");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>((num > 0) ? "applied" : "FAILED");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(".");
			}
			log.LogInfo(val2);
		}

		internal static void Refresh()
		{
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			_policy = TimerPolicy.Sanitized((ReadyHoldSeconds == null) ? 0.6f : ReadyHoldSeconds.Value, (OverrunGraceSeconds == null) ? 2.5f : OverrunGraceSeconds.Value, unitSuffix: true, "READY", 1);
			if (ReadyColor == null || !TimerColor.TryParse(ReadyColor.Value, out var color))
			{
				color = TimerColor.DefaultReady;
			}
			_style = new TimerStyle((GapRatio == null) ? 0.22f : GapRatio.Value, (MinGap == null) ? 2f : MinGap.Value, (MaxGap == null) ? 40f : MaxGap.Value, (LabelWidthRatio == null) ? 4f : LabelWidthRatio.Value, (MinLabelWidth == null) ? 24f : MinLabelWidth.Value, new Color(color.R, color.G, color.B, 1f), (NeutralAlpha == null) ? 0.92f : NeutralAlpha.Value);
		}

		internal static bool KindEnabled(TimerKind kind)
		{
			switch (kind)
			{
			case TimerKind.MeleeCharge:
				if (ShowMeleeCharge != null)
				{
					return ShowMeleeCharge.Value;
				}
				return true;
			case TimerKind.Reload:
				if (ShowReload != null)
				{
					return ShowReload.Value;
				}
				return true;
			case TimerKind.ScannerRecharge:
				if (ShowScanner != null)
				{
					return ShowScanner.Value;
				}
				return true;
			case TimerKind.GlueGunCharge:
				if (ShowGlueGun != null)
				{
					return ShowGlueGun.Value;
				}
				return true;
			default:
				return false;
			}
		}

		internal static uint ResolveEvent(string name)
		{
			return name switch
			{
				"IMPLANTREADYSMALL" => EVENTS.IMPLANTREADYSMALL, 
				"HUD_SCAN_COMPLETE_INDICATION" => EVENTS.HUD_SCAN_COMPLETE_INDICATION, 
				"BUTTONGENERICBLIPACTIVATED" => EVENTS.BUTTONGENERICBLIPACTIVATED, 
				"BUTTONGENERICBLIPONE" => EVENTS.BUTTONGENERICBLIPONE, 
				"None" => 0u, 
				_ => EVENTS.IMPLANTREADY, 
			};
		}
	}
	internal static class PluginInfo
	{
		public const string Guid = "HawChow.EquipmentTimers";

		public const string Name = "EquipmentTimers";

		public const string Version = "1.0.8";
	}
}
namespace HawChow.EquipmentTimers.Ui
{
	public sealed class EquipmentTimerOverlay : MonoBehaviour
	{
		public EquipmentTimerOverlay(IntPtr pointer)
			: base(pointer)
		{
		}

		private void Awake()
		{
			try
			{
				TimerController.Initialize();
			}
			catch (Exception ex)
			{
				Plugin instance = Plugin.Instance;
				if (instance != null)
				{
					((BasePlugin)instance).Log.LogWarning((object)("[hud] controller init failed: " + ex.GetType().Name));
				}
			}
		}

		private void Update()
		{
			try
			{
				TimerController.Tick(Time.time);
			}
			catch (Exception ex)
			{
				Plugin instance = Plugin.Instance;
				if (instance != null)
				{
					((BasePlugin)instance).Log.LogWarning((object)("[hud] pump failed: " + ex.GetType().Name));
				}
			}
		}

		private void OnDestroy()
		{
			try
			{
				TimerController.Shutdown();
			}
			catch (Exception ex)
			{
				Plugin instance = Plugin.Instance;
				if (instance != null)
				{
					((BasePlugin)instance).Log.LogWarning((object)("[hud] shutdown failed: " + ex.GetType().Name));
				}
			}
		}
	}
	public readonly struct TimerColor
	{
		public float R { get; }

		public float G { get; }

		public float B { get; }

		public static TimerColor DefaultReady => new TimerColor(0.42f, 0.95f, 0.35f);

		private TimerColor(float r, float g, float b)
		{
			R = r;
			G = g;
			B = b;
		}

		public static bool TryParse(string text, out TimerColor color)
		{
			color = DefaultReady;
			if (string.IsNullOrWhiteSpace(text))
			{
				return false;
			}
			string text2 = text.Trim();
			if (text2.StartsWith("#", StringComparison.Ordinal))
			{
				text2 = text2.Substring(1);
				if (text2.Length != 6)
				{
					return false;
				}
				if (!TryHex(text2, 0, out var channel) || !TryHex(text2, 2, out var channel2) || !TryHex(text2, 4, out var channel3))
				{
					return false;
				}
				color = new TimerColor(channel, channel2, channel3);
				return true;
			}
			string[] array = text2.Split(',');
			if (array.Length != 3)
			{
				return false;
			}
			if (!float.TryParse(array[0], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) || !float.TryParse(array[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) || !float.TryParse(array[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result3))
			{
				return false;
			}
			float num = ((result > 1f || result2 > 1f || result3 > 1f) ? 0.003921569f : 1f);
			color = new TimerColor(Clamp01(result * num), Clamp01(result2 * num), Clamp01(result3 * num));
			return true;
		}

		private static bool TryHex(string value, int offset, out float channel)
		{
			channel = 0f;
			if (!byte.TryParse(value.Substring(offset, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var result))
			{
				return false;
			}
			channel = (float)(int)result / 255f;
			return true;
		}

		private static float Clamp01(float value)
		{
			if (value < 0f)
			{
				return 0f;
			}
			if (value > 1f)
			{
				return 1f;
			}
			return value;
		}
	}
	internal static class TimerController
	{
		private struct SlotProbe
		{
			public bool TryGetSucceeded;

			public bool BackpackLoaded;

			public bool InstanceAlive;

			public bool InstanceIsGear;

			public bool SlotMatches;

			public ItemEquippable Item;
		}

		private const float ProbeSeconds = 0.5f;

		private static readonly InventorySlot[] Slots;

		private static readonly List<TimerSlotRow> Rows;

		private static readonly Dictionary<InventorySlot, ItemEquippable> Items;

		private static BoundedLog _log;

		private static PlayerAgent _localPlayer;

		private static PlayerAgent _player;

		private static PlayerInventoryBase _inventory;

		private static PUI_Inventory _hud;

		private static float _nextHudProbe;

		private static float _nextInventoryProbe;

		private static float _nextSlotScan;

		private static bool _slotsDirty;

		private static bool _initialised;

		private static int _budget;

		private static readonly RepeatGate ResetLogGate;

		private static readonly SlotReadDiagnostics SlotDiagnostics;

		private static bool _slotReadFellBack;

		private static readonly bool[] ItemProbeWarned;

		private static readonly float[] ColumnEdges;

		private static readonly float[] ColumnWidths;

		private static readonly float[] ColumnGaps;

		private static readonly bool[] RowReady;

		internal static int LiveLabelCount
		{
			get
			{
				int num = 0;
				for (int i = 0; i < Rows.Count; i++)
				{
					if (Rows[i].HasLabel)
					{
						num++;
					}
				}
				return num;
			}
		}

		internal static void Initialize()
		{
			if (_initialised)
			{
				return;
			}
			_initialised = true;
			_budget = Plugin.LogLineBudget;
			_log = new BoundedLog(delegate(string message)
			{
				Plugin instance = Plugin.Instance;
				if (instance != null)
				{
					((BasePlugin)instance).Log.LogInfo((object)message);
				}
			}, delegate(string message)
			{
				Plugin instance = Plugin.Instance;
				if (instance != null)
				{
					((BasePlugin)instance).Log.LogWarning((object)message);
				}
			}, _budget);
			_slotsDirty = true;
			_nextHudProbe = 0f;
			_nextInventoryProbe = 0f;
			_nextSlotScan = 0f;
			SlotDiagnostics.Reset();
			_slotReadFellBack = false;
			Array.Clear(ItemProbeWarned, 0, ItemProbeWarned.Length);
			_log.Info("[hud] controller initialised; budget=" + _budget + " lines.");
		}

		internal static void Shutdown()
		{
			DestroyRows();
			Items.Clear();
			_hud = null;
			_inventory = null;
			_player = null;
			_localPlayer = null;
			_slotsDirty = true;
			_initialised = false;
			ResetLogGate.Reset();
			Array.Clear(ItemProbeWarned, 0, ItemProbeWarned.Length);
			_log = null;
		}

		internal static void AttachLocalPlayer(PlayerAgent player)
		{
			_localPlayer = player;
			_player = null;
			_inventory = null;
			_nextInventoryProbe = 0f;
			if (_initialised)
			{
				BindPlayer();
			}
		}

		internal static void NotifyHudRebuilt(PUI_Inventory hud)
		{
			if (!((Object)(object)hud == (Object)null))
			{
				_slotsDirty = true;
			}
		}

		internal static void NotifyLevelCleanup()
		{
			if (_initialised)
			{
				ResetRows("level-cleanup");
				_hud = null;
				_inventory = null;
				_player = null;
				_nextHudProbe = 0f;
				_nextInventoryProbe = 0f;
				_slotsDirty = true;
				if (!TimerSlotRow.IsAlive((Object)(object)_localPlayer))
				{
					_localPlayer = null;
				}
			}
		}

		internal static void Tick(float now)
		{
			try
			{
				if (!_initialised)
				{
					Initialize();
				}
				if (Plugin.Ready)
				{
					int logLineBudget = Plugin.LogLineBudget;
					if (logLineBudget != _budget)
					{
						_budget = logLineBudget;
						_log.SetBudget(logLineBudget);
					}
					if (!Plugin.Enabled.Value)
					{
						HideRows();
						return;
					}
					if (!EnsureHud(now) || !EnsureInventory(now))
					{
						HideRows();
						return;
					}
					ScanSlots(now);
					SyncSlotItems();
					UpdateRows(now);
				}
			}
			catch (Exception ex)
			{
				if (_log != null && _log.HasWarnBudget)
				{
					_log.Warn("[hud] update failed: " + ex.GetType().Name + ": " + ex.Message);
				}
				HideRows();
			}
		}

		private static void BindPlayer()
		{
			PlayerAgent localPlayer = _localPlayer;
			if (!TimerSlotRow.IsAlive((Object)(object)localPlayer))
			{
				_localPlayer = null;
			}
			else if (!((Object)(object)_player != (Object)null) || !(((Il2CppObjectBase)_player).Pointer == ((Il2CppObjectBase)localPlayer).Pointer) || !((Object)(object)_inventory != (Object)null))
			{
				_player = localPlayer;
				_inventory = SafeInventory(localPlayer);
				_slotsDirty = true;
				if (_log.HasInfoBudget)
				{
					_log.Info("[hud] local player bound; inventory=" + (((Object)(object)_inventory != (Object)null) ? "ready" : "pending") + ".");
				}
			}
		}

		private static bool EnsureHud(float now)
		{
			if ((Object)(object)_hud != (Object)null)
			{
				return true;
			}
			HideRows();
			if (now < _nextHudProbe)
			{
				return false;
			}
			_nextHudProbe = now + 0.5f;
			PUI_Inventory inventory;
			try
			{
				PlayerGuiLayer playerLayer = GuiManager.PlayerLayer;
				if (playerLayer == null)
				{
					return false;
				}
				inventory = playerLayer.Inventory;
			}
			catch (Exception ex)
			{
				_hud = null;
				if (_log.HasWarnBudget)
				{
					_log.Warn("[hud] player layer unavailable: " + ex.GetType().Name);
				}
				return false;
			}
			if ((Object)(object)inventory == (Object)null)
			{
				return false;
			}
			_hud = inventory;
			_slotsDirty = true;
			if (_log.HasInfoBudget)
			{
				_log.Info("[hud] player inventory HUD acquired.");
			}
			return true;
		}

		private static bool EnsureInventory(float now)
		{
			if ((Object)(object)_inventory != (Object)null)
			{
				return true;
			}
			_player = null;
			if (now < _nextInventoryProbe)
			{
				return false;
			}
			_nextInventoryProbe = now + 0.5f;
			PlayerInventoryBase val;
			try
			{
				PlayerAgent localPlayer = _localPlayer;
				if (!TimerSlotRow.IsAlive((Object)(object)localPlayer))
				{
					_localPlayer = null;
					return false;
				}
				_player = localPlayer;
				val = SafeInventory(localPlayer);
			}
			catch (Exception ex)
			{
				_player = null;
				_inventory = null;
				if (_log.HasWarnBudget)
				{
					_log.Warn("[hud] local inventory unavailable: " + ex.GetType().Name);
				}
				return false;
			}
			if ((Object)(object)val == (Object)null)
			{
				_player = null;
				return false;
			}
			_inventory = val;
			_slotsDirty = true;
			return true;
		}

		private static PlayerInventoryBase SafeInventory(PlayerAgent player)
		{
			try
			{
				return ((Object)(object)player == (Object)null) ? null : player.Inventory;
			}
			catch
			{
				return null;
			}
		}

		private unsafe static void ScanSlots(float now)
		{
			//IL_015c: 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_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			if (!_slotsDirty && now < _nextSlotScan && RowsBound())
			{
				return;
			}
			_nextSlotScan = now + 0.5f;
			_slotsDirty = false;
			Dictionary<InventorySlot, PUI_InventoryItem> inventorySlots;
			try
			{
				inventorySlots = _hud.m_inventorySlots;
			}
			catch (Exception ex)
			{
				_hud = null;
				DestroyRows();
				if (_log.HasWarnBudget)
				{
					_log.Warn("[hud] slot table unavailable: " + ex.GetType().Name);
				}
				return;
			}
			if (inventorySlots == null)
			{
				DestroyRows();
				return;
			}
			for (int i = 0; i < Slots.Length; i++)
			{
				InventorySlot val = Slots[i];
				try
				{
					if (!TryResolveSlot(inventorySlots, val, i, out var item))
					{
						RemoveRow(val);
						continue;
					}
					if ((Object)(object)item == (Object)null || (int)item.CurrentState == 0)
					{
						RemoveRow(val);
						continue;
					}
					TimerSlotRow timerSlotRow = FindRow(val);
					if (timerSlotRow == null)
					{
						timerSlotRow = new TimerSlotRow(val);
						Rows.Add(timerSlotRow);
						if (_log.HasInfoBudget)
						{
							_log.Info("[hud] row added for slot " + ((object)(*(InventorySlot*)(&val))/*cast due to .constrained prefix*/).ToString() + ".");
						}
					}
					else if ((Object)(object)timerSlotRow.UiItem != (Object)null && ((Il2CppObjectBase)timerSlotRow.UiItem).Pointer != ((Il2CppObjectBase)item).Pointer)
					{
						timerSlotRow.Invalidate();
						Items.Remove(val);
					}
					timerSlotRow.UiItem = item;
				}
				catch (Exception ex2)
				{
					RemoveRow(val);
					if (_log.HasWarnBudget)
					{
						_log.Warn("[hud] slot " + ((object)(*(InventorySlot*)(&val))/*cast due to .constrained prefix*/).ToString() + " unavailable: " + ex2.GetType().Name + ": " + ex2.Message);
					}
				}
			}
		}

		private static bool TryResolveSlot(Dictionary<InventorySlot, PUI_InventoryItem> slots, InventorySlot slot, int slotIndex, out PUI_InventoryItem item)
		{
			//IL_002c: 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_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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)
			item = null;
			if (!_slotReadFellBack)
			{
				try
				{
					if (!slots.ContainsKey(slot))
					{
						return true;
					}
					item = slots[slot];
					return true;
				}
				catch (Exception error)
				{
					_slotReadFellBack = true;
					ReportSlotFailure(slotIndex, slot, "ContainsKey/indexer", error);
				}
			}
			try
			{
				PUI_InventoryItem val = default(PUI_InventoryItem);
				bool flag = slots.TryGetValue(slot, ref val);
				item = (flag ? val : null);
				return true;
			}
			catch (Exception error2)
			{
				ReportSlotFailure(slotIndex, slot, "TryGetValue", error2);
				return false;
			}
		}

		private unsafe static void ReportSlotFailure(int slotIndex, InventorySlot slot, string member, Exception error)
		{
			if (_log != null && _log.HasWarnBudget && SlotDiagnostics.ShouldReport(slotIndex))
			{
				_log.Warn(SlotReadDiagnostics.Describe(((object)(*(InventorySlot*)(&slot))/*cast due to .constrained prefix*/).ToString(), member, error));
			}
		}

		private static bool RowsBound()
		{
			for (int i = 0; i < Rows.Count; i++)
			{
				if ((Object)(object)Rows[i].UiItem == (Object)null)
				{
					return false;
				}
			}
			return true;
		}

		private static void SyncSlotItems()
		{
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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_00a7: Invalid comparison between Unknown and I4
			SNet_Player val = null;
			try
			{
				PlayerAgent player = _player;
				if (TimerSlotRow.IsAlive((Object)(object)player))
				{
					val = player.Owner;
				}
			}
			catch (Exception error)
			{
				val = null;
				WarnItemProbe(0, "owner", error);
			}
			ItemEquippable val2 = null;
			try
			{
				PlayerAgent player2 = _player;
				if (TimerSlotRow.IsAlive((Object)(object)player2) && (Object)(object)player2.FPItemHolder != (Object)null)
				{
					val2 = player2.FPItemHolder.m_meleeWeapon;
				}
			}
			catch (Exception error2)
			{
				val2 = null;
				WarnItemProbe(3, "holder", error2);
			}
			if (!TimerSlotRow.IsAlive((Object)(object)val2))
			{
				val2 = null;
			}
			for (int i = 0; i < Rows.Count; i++)
			{
				TimerSlotRow timerSlotRow = Rows[i];
				try
				{
					SlotProbe slotProbe = ProbeSlot(timerSlotRow.Slot, val, i);
					ItemEquippable val3 = (ItemEquippable)(SlotItemRules.Decide((int)timerSlotRow.Slot == 10, (Object)(object)val != (Object)null, slotProbe.TryGetSucceeded, slotProbe.BackpackLoaded, slotProbe.InstanceAlive, slotProbe.InstanceIsGear, slotProbe.SlotMatches, (Object)(object)val2 != (Object)null) switch
					{
						SlotItemVerdict.BindHolderMelee => val2, 
						SlotItemVerdict.BindBackpack => slotProbe.Item, 
						_ => null, 
					});
					if (!TimerSlotRow.IsAlive((Object)(object)val3))
					{
						DetachItem(timerSlotRow);
					}
					else
					{
						BindItem(timerSlotRow, val3);
					}
				}
				catch (Exception error3)
				{
					DetachItem(timerSlotRow);
					WarnItemProbe(i, "slot " + ((object)timerSlotRow.Slot/*cast due to .constrained prefix*/).ToString(), error3);
				}
			}
		}

		private unsafe static SlotProbe ProbeSlot(InventorySlot slot, SNet_Player owner, int rowIndex)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			SlotProbe result = default(SlotProbe);
			if ((Object)(object)owner == (Object)null)
			{
				return result;
			}
			try
			{
				BackpackItem val = default(BackpackItem);
				if (!PlayerBackpackManager.TryGetItem(owner, slot, ref val) || val == null)
				{
					return result;
				}
				result.TryGetSucceeded = true;
				if (!val.IsLoaded)
				{
					return result;
				}
				result.BackpackLoaded = true;
				Item instance = val.Instance;
				if ((Object)(object)instance == (Object)null || ((Il2CppObjectBase)instance).Pointer == IntPtr.Zero || !TimerSlotRow.IsAlive((Object)(object)instance))
				{
					return result;
				}
				result.InstanceAlive = true;
				ItemEquippable val2 = ((Il2CppObjectBase)instance).TryCast<ItemEquippable>();
				if ((Object)(object)val2 == (Object)null)
				{
					return result;
				}
				result.InstanceIsGear = true;
				ItemDataBlock itemDataBlock = ((Item)val2).ItemDataBlock;
				if (itemDataBlock == null || itemDataBlock.inventorySlot != slot)
				{
					return result;
				}
				result.SlotMatches = true;
				result.Item = val2;
			}
			catch (Exception error)
			{
				result.Item = null;
				WarnItemProbe(rowIndex, "backpack " + ((object)(*(InventorySlot*)(&slot))/*cast due to .constrained prefix*/).ToString(), error);
			}
			return result;
		}

		private static void WarnItemProbe(int rowIndex, string what, Exception error)
		{
			if (_log == null || !_log.HasWarnBudget)
			{
				return;
			}
			if (rowIndex >= 0 && rowIndex < ItemProbeWarned.Length)
			{
				if (ItemProbeWarned[rowIndex])
				{
					return;
				}
				ItemProbeWarned[rowIndex] = true;
			}
			_log.Warn("[hud] item probe failed (" + what + "): " + error.GetType().Name);
		}

		private static void DetachItem(TimerSlotRow row)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)row.Item == (Object)null) || row.Kind != TimerKind.None || row.Tracker != null)
			{
				row.DetachItem();
				Items.Remove(row.Slot);
			}
		}

		private static void BindItem(TimerSlotRow row, ItemEquippable item)
		{
			//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_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: 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)
			TimerKind timerKind;
			try
			{
				timerKind = GearSampler.KindOf(item);
			}
			catch (Exception ex)
			{
				timerKind = TimerKind.None;
				if (_log.HasWarnBudget)
				{
					_log.Warn("[hud] slot " + ((object)row.Slot/*cast due to .constrained prefix*/).ToString() + " type probe failed: " + ex.GetType().Name);
				}
			}
			bool flag = timerKind != TimerKind.None && timerKind != TimerKind.GlueGunCharge;
			if (!((Object)(object)row.Item != (Object)null) || !(((Il2CppObjectBase)row.Item).Pointer == ((Il2CppObjectBase)item).Pointer) || row.Kind != timerKind || (flag && row.Tracker == null))
			{
				row.Item = item;
				Items[row.Slot] = item;
				if (row.Kind != timerKind || (flag && row.Tracker == null))
				{
					row.Kind = timerKind;
					row.Tracker = (flag ? new TimerTracker(timerKind, Plugin.Policy) : null);
					row.Clock = ((timerKind == TimerKind.Reload) ? new ReloadClock() : null);
				}
				else
				{
					row.ResetTimer();
				}
				if (_log.HasInfoBudget)
				{
					_log.Info("[hud] slot " + ((object)row.Slot/*cast due to .constrained prefix*/).ToString() + " bound; kind=" + timerKind.ToString() + ".");
				}
			}
		}

		private static void UpdateRows(float now)
		{
			TimerStyle style = Plugin.Style;
			TimerPolicy policy = Plugin.Policy;
			for (int i = 0; i < Rows.Count; i++)
			{
				TimerSlotRow timerSlotRow = Rows[i];
				RowReady[i] = false;
				try
				{
					if (!PrepareRow(timerSlotRow, now, style))
					{
						timerSlotRow.Hide();
						continue;
					}
					RowReady[i] = true;
					timerSlotRow.SyncLayout(style);
				}
				catch (Exception error)
				{
					DropRow(timerSlotRow, error);
				}
			}
			for (int j = 0; j < Rows.Count; j++)
			{
				if (!RowReady[j])
				{
					continue;
				}
				TimerSlotRow timerSlotRow2 = Rows[j];
				try
				{
					if (!PaintRow(timerSlotRow2, now, style, policy))
					{
						timerSlotRow2.Hide();
					}
				}
				catch (Exception error2)
				{
					DropRow(timerSlotRow2, error2);
				}
			}
			int num = 0;
			for (int k = 0; k < Rows.Count; k++)
			{
				if (!RowReady[k] || num >= ColumnEdges.Length)
				{
					continue;
				}
				TimerSlotRow timerSlotRow3 = Rows[k];
				try
				{
					if (timerSlotRow3.TryMeasureColumnVote(style, out var nameLeftEdge, out var labelWidth, out var gap))
					{
						ColumnEdges[num] = nameLeftEdge;
						ColumnWidths[num] = labelWidth;
						ColumnGaps[num] = gap;
						num++;
					}
				}
				catch (Exception error3)
				{
					DropRow(timerSlotRow3, error3);
				}
			}
			float leftEdge;
			float columnWorldX = (TimerLayout.TryColumnLeftEdge(ColumnEdges, ColumnWidths, ColumnGaps, num, out leftEdge) ? leftEdge : float.NaN);
			for (int l = 0; l < Rows.Count; l++)
			{
				if (RowReady[l])
				{
					TimerSlotRow timerSlotRow4 = Rows[l];
					try
					{
						timerSlotRow4.PlaceOnColumn(style, columnWorldX);
					}
					catch (Exception error4)
					{
						DropRow(timerSlotRow4, error4);
					}
				}
			}
		}

		private static void DropRow(TimerSlotRow row, Exception error)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			row.Invalidate();
			Items.Remove(row.Slot);
			_slotsDirty = true;
			if (_log.HasWarnBudget)
			{
				_log.Warn("[hud] slot " + ((object)row.Slot/*cast due to .constrained prefix*/).ToString() + " read failed: " + error.GetType().Name);
			}
		}

		private static bool PrepareRow(TimerSlotRow row, float now, TimerStyle style)
		{
			PUI_InventoryItem uiItem = row.UiItem;
			if ((Object)(object)uiItem == (Object)null || !TimerSlotRow.IsAlive((Object)(object)((Component)uiItem).gameObject))
			{
				return false;
			}
			TextMeshPro val = ResolveName(uiItem);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			return row.EnsureLabel(val, style, now);
		}

		private static bool PaintRow(TimerSlotRow row, float now, TimerStyle style, TimerPolicy policy)
		{
			if (row.Kind == TimerKind.None || !Plugin.KindEnabled(row.Kind))
			{
				return false;
			}
			if (row.Kind == TimerKind.GlueGunCharge)
			{
				if ((Object)(object)row.Item == (Object)null)
				{
					return false;
				}
				TimerSample timerSample = GearSampler.Sample(row.Kind, row.Item, row.Clock, now);
				TimerRowView view = TimerDisplayPolicy.ForGlueGun(policy, timerSample.Active, timerSample.ShotsKnown, timerSample.Shots, timerSample.ChargeElapsedKnown, timerSample.ChargeElapsed);
				row.Apply(view, style, now);
				ReportRowDiagnostics(row, now);
				return true;
			}
			if ((Object)(object)row.Item == (Object)null || row.Tracker == null)
			{
				return false;
			}
			if (policy != null)
			{
				row.Tracker.Policy = policy;
			}
			TimerSample sample = GearSampler.Sample(row.Kind, row.Item, row.Clock, now);
			if (row.Kind == TimerKind.MeleeCharge && !sample.InChargeState)
			{
				sample.Cancelled = true;
			}
			int completions = row.Tracker.Completions;
			int suppressedCompletions = row.Tracker.SuppressedCompletions;
			TimerRowView view2 = row.Tracker.Observe(in sample);
			bool sessionSuppressed = row.Tracker.SuppressedCompletions > suppressedCompletions;
			if (row.Tracker.Completions > completions)
			{
				PlayReadySound(row, now);
			}
			TimerRowView view3 = ForKind(row, view2, sample, sessionSuppressed, policy);
			row.Apply(view3, style, now);
			ReportRowDiagnostics(row, now);
			return true;
		}

		private static TimerRowView ForKind(TimerSlotRow row, TimerRowView view, TimerSample sample, bool sessionSuppressed, TimerPolicy policy)
		{
			string readyText = policy?.ReadyText;
			bool overrunHidden = row.Tracker != null && row.Tracker.OverrunHidden;
			return row.Kind switch
			{
				TimerKind.Reload => TimerDisplayPolicy.ForWeapon(view, sample.Active, sample.ClipKnown, sample.Clip, sample.MaxClip, sample.Cancelled, overrunHidden, sessionSuppressed, readyText), 
				TimerKind.ScannerRecharge => TimerDisplayPolicy.ForScanner(view, sample.Active, sample.Cancelled, overrunHidden, sessionSuppressed, readyText), 
				TimerKind.MeleeCharge => TimerDisplayPolicy.ForMelee(view, sample.InChargeState, sample.Done, sample.MeleeReleaseWarning, sample.Cancelled, readyText), 
				_ => view, 
			};
		}

		private static void ReportRowDiagnostics(TimerSlotRow row, float now)
		{
			string text = row.TakeInvalidMeshNote();
			if (text != null && _log.HasInfoBudget)
			{
				_log.Info(text + ".");
			}
			string text2 = row.TakeVisibleSample(now);
			if (text2 != null && _log.HasInfoBudget)
			{
				_log.Info(text2 + "; " + SafeGeometry(row) + ".");
			}
		}

		private static void PlayReadySound(TimerSlotRow row, float now)
		{
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			uint readySoundId = Plugin.ReadySoundId;
			if (!NativeRules.ShouldPostReadyCue(Plugin.PlayReadySound != null && Plugin.PlayReadySound.Value, readySoundId))
			{
				if (_log.HasInfoBudget)
				{
					_log.Info("[hud] slot " + ((object)row.Slot/*cast due to .constrained prefix*/).ToString() + " completed; ready cue disabled.");
				}
				return;
			}
			bool flag = false;
			try
			{
				CellSoundPlayer val = (((Object)(object)_player == (Object)null) ? null : _player.Sound);
				if (val != null)
				{
					val.Post(readySoundId, true);
					flag = true;
				}
			}
			catch (Exception ex)
			{
				if (_log.HasWarnBudget)
				{
					_log.Warn("[sound] player 2D post failed: " + ex.GetType().Name);
				}
			}
			if (!flag)
			{
				try
				{
					if ((Object)(object)CellSound.Current != (Object)null)
					{
						CellSound.Post(readySoundId);
						flag = true;
					}
				}
				catch (Exception ex2)
				{
					if (_log.HasWarnBudget)
					{
						_log.Warn("[sound] global post failed: " + ex2.GetType().Name);
					}
				}
			}
			if (_log.HasInfoBudget)
			{
				_log.Info("[hud] slot " + ((object)row.Slot/*cast due to .constrained prefix*/).ToString() + " completed; ready cue " + (flag ? "posted" : "unavailable") + " at " + now.ToString("0.00") + ".");
			}
		}

		private static string SafeName(Object native)
		{
			try
			{
				return (native == (Object)null) ? "-" : native.name;
			}
			catch
			{
				return "?";
			}
		}

		private static string SafeGeometry(TimerSlotRow row)
		{
			try
			{
				return row.DescribeGeometry();
			}
			catch (Exception ex)
			{
				return "geometry=?(" + ex.GetType().Name + ")";
			}
		}

		private static TextMeshPro ResolveName(PUI_InventoryItem item)
		{
			//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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected I4, but got Unknown
			try
			{
				TextMeshPro selected_archetypeName = item.m_selected_archetypeName;
				TextMeshPro slim_archetypeName = item.m_slim_archetypeName;
				bool flag = TimerSlotRow.IsAlive((Object)(object)selected_archetypeName) && ((Component)selected_archetypeName).gameObject.activeInHierarchy;
				bool flag2 = TimerSlotRow.IsAlive((Object)(object)slim_archetypeName) && ((Component)slim_archetypeName).gameObject.activeInHierarchy;
				ePUI_InventortyItemState currentState = item.CurrentState;
				switch ((int)currentState)
				{
				case 2:
					if (flag)
					{
						return selected_archetypeName;
					}
					return flag2 ? slim_archetypeName : null;
				case 1:
					if (flag2)
					{
						return slim_archetypeName;
					}
					return flag ? selected_archetypeName : null;
				case 0:
					return null;
				default:
					if (flag)
					{
						return selected_archetypeName;
					}
					return flag2 ? slim_archetypeName : null;
				}
			}
			catch
			{
				return null;
			}
		}

		private static TimerSlotRow FindRow(InventorySlot slot)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < Rows.Count; i++)
			{
				if (Rows[i].Slot == slot)
				{
					return Rows[i];
				}
			}
			return null;
		}

		private static void RemoveRow(InventorySlot slot)
		{
			//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_004a: Unknown result type (might be due to invalid IL or missing references)
			for (int num = Rows.Count - 1; num >= 0; num--)
			{
				if (Rows[num].Slot == slot)
				{
					Rows[num].DestroyLabel();
					Rows.RemoveAt(num);
				}
			}
			Items.Remove(slot);
		}

		private static void HideRows()
		{
			for (int i = 0; i < Rows.Count; i++)
			{
				try
				{
					Rows[i].Hide();
				}
				catch (Exception ex)
				{
					if (_log != null && _log.HasWarnBudget)
					{
						_log.Warn("[hud] hide failed: " + ex.GetType().Name);
					}
				}
			}
		}

		private static void ResetRows(string reason)
		{
			_slotsDirty = true;
			if (Rows.Count == 0 && Items.Count == 0)
			{
				return;
			}
			int count = Rows.Count;
			for (int i = 0; i < count; i++)
			{
				try
				{
					Rows[i].Invalidate();
				}
				catch (Exception ex)
				{
					if (_log != null && _log.HasWarnBudget)
					{
						_log.Warn("[hud] reset failed: " + ex.GetType().Name);
					}
				}
			}
			Items.Clear();
			if (ResetLogGate.ShouldLog(count, reason) && _log != null && _log.HasInfoBudget)
			{
				_log.Info("[hud] rows reset (" + reason + "), rows=" + count + ".");
			}
		}

		private static void DestroyRows()
		{
			for (int i = 0; i < Rows.Count; i++)
			{
				try
				{
					Rows[i].DestroyLabel();
				}
				catch (Exception ex)
				{
					if (_log != null && _log.HasWarnBudget)
					{
						_log.Warn("[hud] destroy failed: " + ex.GetType().Name);
					}
				}
			}
			Rows.Clear();
			Items.Clear();
			_slotsDirty = true;
			ResetLogGate.Reset();
		}

		static TimerController()
		{
			InventorySlot[] array = new InventorySlot[4];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			Slots = (InventorySlot[])(object)array;
			Rows = new List<TimerSlotRow>(Slots.Length);
			Items = new Dictionary<InventorySlot, ItemEquippable>();
			_slotsDirty = true;
			ResetLogGate = new RepeatGate();
			SlotDiagnostics = new SlotReadDiagnostics(Slots.Length);
			ItemProbeWarned = new bool[4];
			ColumnEdges = new float[4];
			ColumnWidths = new float[4];
			ColumnGaps = new float[4];
			RowReady = new bool[4];
		}
	}
	public static class TimerLayout
	{
		public const float DefaultGapRatio = 0.22f;

		public const float DefaultMinGap = 2f;

		public const float DefaultMaxGap = 40f;

		public const float DefaultWidthRatio = 4f;

		public const float DefaultMinWidth = 24f;

		public const int MaxColumnSlots = 4;

		public static float Gap(float fontSize, float gapRatio, float minGap, float maxGap)
		{
			float num = Sanitize(gapRatio, 0.22f, 0.02f, 1.5f);
			float min = Sanitize(minGap, 2f, 0f, 40f);
			float max = Sanitize(maxGap, 40f, min, 200f);
			return Clamp(((fontSize > 0f) ? fontSize : 12f) * num, min, max);
		}

		public static float LabelAnchoredX(float nativeAnchoredX, float nativeWidth, float nativePivotX, float gap)
		{
			float num = ((nativeWidth > 0f) ? nativeWidth : 0f);
			return nativeAnchoredX - num * nativePivotX - gap;
		}

		public static float LabelWidth(float fontSize, float widthRatio, float minWidth)
		{
			float num = Sanitize(widthRatio, 4f, 1.5f, 12f);
			float val = Sanitize(minWidth, 24f, 8f, 200f);
			float num2 = ((fontSize > 0f) ? fontSize : 12f);
			return Math.Max(val, num2 * num);
		}

		public static float LabelAnchoredY(float nativeAnchoredY, float nativeHeight, float nativePivotY)
		{
			float num = ((nativeHeight > 0f) ? nativeHeight : 0f);
			return nativeAnchoredY + num * (0.5f - nativePivotY);
		}

		public static float LabelAnchoredXFromGlyph(float nativeAnchoredX, float glyphLeftDelta, float gap)
		{
			return nativeAnchoredX + glyphLeftDelta - gap;
		}

		public static float PointAnchorX(float anchorMinX, float anchorMaxX, float pivotX)
		{
			float num = Clean(anchorMinX);
			float num2 = Clean(anchorMaxX);
			float num3 = Clean(pivotX);
			return num + (num2 - num) * num3;
		}

		public static float PointAnchorY(float anchorMinY, float anchorMaxY, float pivotY)
		{
			float num = Clean(anchorMinY);
			float num2 = Clean(anchorMaxY);
			float num3 = Clean(pivotY);
			return num + (num2 - num) * num3;
		}

		public static bool SameAnchor(float left, float right)
		{
			if (float.IsNaN(left) || float.IsNaN(right) || float.IsInfinity(left) || float.IsInfinity(right))
			{
				return false;
			}
			return Math.Abs(left - right) <= 0.0005f;
		}

		public static bool TryLeftmostEdge(float[] edges, int count, out float leftmost)
		{
			leftmost = 0f;
			if (edges == null)
			{
				return false;
			}
			bool flag = false;
			int num = ((count < edges.Length) ? count : edges.Length);
			for (int i = 0; i < num; i++)
			{
				float num2 = edges[i];
				if (!float.IsNaN(num2) && !float.IsInfinity(num2) && (!flag || num2 < leftmost))
				{
					leftmost = num2;
					flag = true;
				}
			}
			return flag;
		}

		public static bool TryParentLocalX(float worldX, float parentWorldX, float parentLossyScaleX, out float localX)
		{
			localX = 0f;
			if (float.IsNaN(worldX) || float.IsInfinity(worldX))
			{
				return false;
			}
			if (float.IsNaN(parentWorldX) || float.IsInfinity(parentWorldX))
			{
				return false;
			}
			if (float.IsNaN(parentLossyScaleX) || float.IsInfinity(parentLossyScaleX))
			{
				return false;
			}
			if (Math.Abs(parentLossyScaleX) <= 1E-06f)
			{
				return false;
			}
			float num = (worldX - parentWorldX) / parentLossyScaleX;
			if (float.IsNaN(num) || float.IsInfinity(num))
			{
				return false;
			}
			localX = num;
			return true;
		}

		public static float ColumnLimit(float nameLeftEdge, float labelWidth, float gap)
		{
			if (!Finite(nameLeftEdge) || !Finite(labelWidth))
			{
				return float.NaN;
			}
			float num = ((labelWidth > 0f) ? labelWidth : 0f);
			float num2 = ((Finite(gap) && gap > 0f) ? gap : 0f);
			float num3 = nameLeftEdge - num - num2;
			if (!Finite(num3))
			{
				return float.NaN;
			}
			return num3;
		}

		public static bool TryColumnLeftEdge(float[] nameLeftEdges, float[] labelWidths, float[] gaps, int count, out float leftEdge)
		{
			leftEdge = 0f;
			if (nameLeftEdges == null || labelWidths == null || gaps == null)
			{
				return false;
			}
			int num = Math.Min(count, Math.Min(nameLeftEdges.Length, Math.Min(labelWidths.Length, gaps.Length)));
			bool flag = false;
			for (int i = 0; i < num; i++)
			{
				float num2 = ColumnLimit(nameLeftEdges[i], labelWidths[i], gaps[i]);
				if (Finite(num2) && (!flag || num2 < leftEdge))
				{
					leftEdge = num2;
					flag = true;
				}
			}
			return flag;
		}

		public static float AnchorReferenceLocalX(float parentRectXMin, float parentRectWidth, float anchorX)
		{
			return Clean(parentRectXMin) + Clean(parentRectWidth) * Clean(anchorX);
		}

		public static bool TryPlaceLeftEdge(float columnWorldX, float parentWorldX, float parentLossyScaleX, float parentRectXMin, float parentRectWidth, float anchorX, out float anchoredPositionX)
		{
			anchoredPositionX = 0f;
			if (!Finite(parentRectXMin) || !Finite(parentRectWidth) || !Finite(anchorX))
			{
				return false;
			}
			if (!TryParentLocalX(columnWorldX, parentWorldX, parentLossyScaleX, out var localX))
			{
				return false;
			}
			float num = localX - AnchorReferenceLocalX(parentRectXMin, parentRectWidth, anchorX);
			if (!Finite(num))
			{
				return false;
			}
			anchoredPositionX = num;
			return true;
		}

		public static float PlacedLeftEdge(float anchoredPositionX, float parentRectXMin, float parentRectWidth, float anchorX)
		{
			return Clean(anchoredPositionX) + AnchorReferenceLocalX(parentRectXMin, parentRectWidth, anchorX);
		}

		private static bool Finite(float value)
		{
			if (!float.IsNaN(value))
			{
				return !float.IsInfinity(value);
			}
			return false;
		}

		public static float FontScaleToMatchGlyphHeight(float nativeHeight, float labelHeight)
		{
			if (float.IsNaN(nativeHeight) || float.IsInfinity(nativeHeight) || nativeHeight <= 0f)
			{
				return 1f;
			}
			if (float.IsNaN(labelHeight) || float.IsInfinity(labelHeight) || labelHeight <= 0f)
			{
				return 1f;
			}
			float num = nativeHeight / labelHeight;
			if (float.IsNaN(num) || float.IsInfinity(num) || num <= 1f)
			{
				return 1f;
			}
			float num2 = num * 1.1f;
			if (!float.IsNaN(num2) && !float.IsInfinity(num2))
			{
				return num2;
			}
			return num;
		}

		private static float Clean(float value)
		{
			if (float.IsNaN(value) || float.IsInfinity(value))
			{
				return 0f;
			}
			return value;
		}

		private static float Sanitize(float value, float fallback, float min, float max)
		{
			if (float.IsNaN(value) || float.IsInfinity(value))
			{
				return fallback;
			}
			return Clamp(value, min, max);
		}

		private static float Clamp(float value, float min, float max)
		{
			if (value < min)
			{
				return min;
			}
			if (value > max)
			{
				return max;
			}
			return value;
		}
	}
	internal sealed class TimerSlotRow
	{
		private const string LabelObjectName = "EquipmentTimersLabel";

		private const int MeshRetryLimit = 3;

		private const int SurfaceCompareInterval = 15;

		private const float FontScaleEpsilon = 0.001f;

		private const float FontSizeEpsilon = 0.01f;

		private const float MaxFontScale = 8f;

		private const float MinGlyphHeight = 0.0001f;

		private readonly AnchorLatch _latch = new AnchorLatch();

		private bool _visibleSampleArmed;

		private float _shownAt = float.NegativeInfinity;

		private int _invalidMeshReports;

		private string _pendingInvalidNote;

		private RectTransform _anchorRect;

		private RectTransform _labelRect;

		private string _text;

		private TimerRowTone _tone;

		private bool _dirtyColor = true;

		private int _meshRetries = 3;

		private bool _surfaceDirty = true;

		private int _surfaceTicks;

		private float _fontScale = 1f;

		private float _fontSize;

		private float _nativeGlyphHeight;

		private float _labelGlyphHeight;

		public InventorySlot Slot { get; }

		public PUI_InventoryItem UiItem { get; set; }

		public ItemEquippable Item { get; set; }

		public TimerKind Kind { get; set; }

		public TimerTracker Tracker { get; set; }

		public ReloadClock Clock { get; set; }

		public TextMeshPro Anchor { get; private set; }

		public TextMeshPro Label { get; private set; }

		public bool SampleLogged { get; set; }

		public int MeshLogged { get; set; } = -1;

		public bool HasLabel => (Object)(object)Label != (Object)null;

		public bool Alive
		{
			get
			{
				if ((Object)(object)Label != (Object)null)
				{
					return (Object)(object)Anchor != (Object)null;
				}
				return false;
			}
		}

		public TimerSlotRow(InventorySlot slot)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			Slot = slot;
		}

		internal static bool IsAlive(Object value)
		{
			if (value == (Object)null)
			{
				return false;
			}
			try
			{
				return value != (Object)null;
			}
			catch
			{
				return false;
			}
		}

		public static bool IsUsable(TextMeshPro value)
		{
			if (!IsAlive((Object)(object)value))
			{
				return false;
			}
			try
			{
				return ((Component)value).gameObject.activeInHierarchy && ((Behaviour)value).enabled;
			}
			catch
			{
				return false;
			}
		}

		public bool EnsureLabel(TextMeshPro candidate, TimerStyle style, float now)
		{
			bool flag = IsUsable(candidate);
			bool flag2 = IsUsable(Anchor);
			if ((Object)(object)Label == (Object)null)
			{
				if (!flag)
				{
					return false;
				}
				return CreateLabel(candidate, style);
			}
			try
			{
				if (flag && HasParent(candidate))
				{
					long num = ((Il2CppObjectBase)candidate).Pointer.ToInt64();
					if (_latch.ShouldAdopt(num, flag2, now) && RebindAnchor(candidate, style))
					{
						_latch.Commit(num);
					}
				}
				else
				{
					_latch.CancelPending();
				}
				if (!flag && !flag2)
				{
					return false;
				}
				EnsureSurface(style);
				return true;
			}
			catch
			{
				DestroyLabel();
				return false;
			}
		}

		private bool CreateLabel(TextMeshPro anchor, TimerStyle style)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			GameObject val = null;
			try
			{
				RectTransform val2 = ((Il2CppObjectBase)anchor.transform).TryCast<RectTransform>();
				if ((Object)(object)val2 == (Object)null)
				{
					return false;
				}
				val = new GameObject("EquipmentTimersLabel");
				try
				{
					val.SetActive(false);
				}
				catch
				{
				}
				val.transform.SetParent(anchor.transform.parent, false);
				TextMeshPro val3 = val.AddComponent<TextMeshPro>();
				if ((Object)(object)val3 == (Object)null)
				{
					Object.Destroy((Object)(object)val);
					return false;
				}
				try
				{
					Renderer renderer = val3.renderer;
					if ((Object)(object)renderer != (Object)null)
					{
						renderer.enabled = false;
					}
				}
				catch
				{
				}
				_anchorRect = val2;
				Anchor = anchor;
				Label = val3;
				CopyFontFrom(anchor, style);
				((TMP_Text)val3).text = string.Empty;
				HideRenderer();
				ClearMeshSafe();
				try
				{
					Renderer renderer2 = val3.renderer;
					Renderer renderer3 = anchor.renderer;
					if ((Object)(object)renderer2 != (Object)null && (Object)(object)renderer3 != (Object)null)
					{
						renderer2.sortingLayerID = renderer3.sortingLayerID;
						renderer2.sortingOrder = renderer3.sortingOrder;
					}
				}
				catch
				{
				}
				_labelRect = ((Il2CppObjectBase)val3.transform).TryCast<RectTransform>();
				if (!SurfaceSync.CanApplyLayout((Object)(object)_labelRect != (Object)null))
				{
					DestroyLabel();
					return false;
				}
				ApplyRectStyle(anchor, val2, style);
				_surfaceDirty = true;
				_text = null;
				_tone = TimerRowTone.Neutral;
				_dirtyColor = true;
				_meshRetries = 3;
				_latch.Hold(((Il2CppObjectBase)anchor).Pointer.ToInt64());
				try
				{
					((Component)val3).gameObject.layer = ((Component)anchor).gameObject.layer;
				}
				catch
				{
				}
				try
				{
					((Component)val3).gameObject.SetActive(false);
				}
				catch
				{
				}
				_visibleSampleArmed = false;
				SyncTransform(style);
				return true;
			}
			catch
			{
				if ((Object)(object)val != (Object)null)
				{
					try
					{
						Object.Destroy((Object)(object)val);
					}
					catch
					{
					}
				}
				Label = null;
				Anchor = null;
				_labelRect = null;
				_anchorRect = null;
				return false;
			}
		}

		private bool RebindAnchor(TextMeshPro anchor, TimerStyle style)
		{
			if ((Object)(object)Label == (Object)null)
			{
				return false;
			}
			RectTransform val;
			try
			{
				val = ((Il2CppObjectBase)anchor.transform).TryCast<RectTransform>();
			}
			catch
			{
				return false;
			}
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			Transform parent;
			try
			{
				parent = anchor.transform.parent;
			}
			catch
			{
				return false;
			}
			if ((Object)(object)parent == (Object)null)
			{
				return false;
			}
			try
			{
				Transform parent2 = Label.transform.parent;
				if ((Object)(object)parent2 == (Object)null || ((Il2CppObjectBase)parent2).Pointer != ((Il2CppObjectBase)parent).Pointer)
				{
					Label.transform.SetParent(parent, false);
				}
			}
			catch
			{
				return false;
			}
			try
			{
				((Component)Label).gameObject.layer = ((Component)anchor).gameObject.layer;
			}
			catch
			{
			}
			HideRenderer();
			ClearMeshSafe();
			Anchor = anchor;
			_anchorRect = val;
			CopyFontFrom(anchor, style);
			ApplyRectStyle(anchor, val, style);
			_surfaceDirty = true;
			_text = null;
			_dirtyColor = true;
			_meshRetries = 0;
			SyncTransform(style);
			ForceMeshUpdate();
			return true;
		}

		private static bool HasParent(TextMeshPro value)
		{
			if (!IsAlive((Object)(object)value))
			{
				return false;
			}
			try
			{
				return (Object)(object)value.transform.parent != (Object)null;
			}
			catch
			{
				return false;
			}
		}

		private void EnsureSurface(TimerStyle style)
		{
			if ((Object)(object)Label == (Object)null)
			{
				return;
			}
			try
			{
				if (!((Behaviour)Label).enabled)
				{
					((Behaviour)Label).enabled = true;
				}
			}
			catch
			{
			}
			try
			{
				Renderer renderer = Label.renderer;
				if ((Object)(object)renderer != (Object)null && !renderer.enabled)
				{
					renderer.enabled = true;
				}
			}
			catch
			{
			}
			try
			{
				if (IsAlive((Object)(object)Anchor) && ((Component)Label).gameObject.layer != ((Component)Anchor).gameObject.layer)
				{
					((Component)Label).gameObject.layer = ((Component)Anchor).gameObject.layer;
				}
			}
			catch
			{
			}
			if (_surfaceDirty || _surfaceTicks++ % 15 == 0)
			{
				_surfaceDirty = false;
				bool fontChanged = SyncFont();
				SyncMaterial(out var materialChanged, out var shaderChanged);
				if (SurfaceSync.RequiresMeshRebuild(fontChanged, materialChanged, shaderChanged))
				{
					ForceMeshUpdate();
				}
			}
			EnsureMesh();
		}

		private bool SyncFont()
		{
			try
			{
				TMP_FontAsset val = (IsAlive((Object)(object)Anchor) ? ((TMP_Text)Anchor).font : null);
				long nativePointer = (((Object)(object)val == (Object)null) ? 0 : ((Il2CppObjectBase)val).Pointer.ToInt64());
				TMP_FontAsset val2 = (((Object)(object)Label == (Object)null) ? null : ((TMP_Text)Label).font);
				if (!SurfaceSync.NeedsSync(((Object)(object)val2 == (Object)null) ? 0 : ((Il2CppObjectBase)val2).Pointer.ToInt64(), nativePointer))
				{
					return false;
				}
				((TMP_Text)Label).font = val;
				ResetFontFit();
				return true;
			}
			catch
			{
				return false;
			}
		}

		private void SyncMaterial(out bool materialChanged, out bool shaderChanged)
		{
			materialChanged = false;
			shaderChanged = false;
			try
			{
				Material val = (IsAlive((Object)(object)Anchor) ? ((TMP_Text)Anchor).fontSharedMaterial : null);
				long nativePointer = (((Object)(object)val == (Object)null) ? 0 : ((Il2CppObjectBase)val).Pointer.ToInt64());
				if ((Object)(object)val == (Object)null && (Object)(object)Label != (Object)null && (Object)(object)((TMP_Text)Label).font != (Object)null)
				{
					try
					{
						val = ((TMP_Asset)((TMP_Text)Label).font).material;
						nativePointer = (((Object)(object)val == (Object)null) ? 0 : ((Il2CppObjectBase)val).Pointer.ToInt64());
					}
					catch
					{
						val = null;
						nativePointer = 0L;
					}
				}
				Material val2 = (((Object)(object)Label == (Object)null) ? null : ((TMP_Text)Label).fontSharedMaterial);
				if (SurfaceSync.NeedsSync(((Object)(object)val2 == (Object)null) ? 0 : ((Il2CppObjectBase)val2).Pointer.ToInt64(), nativePointer))
				{
					((TMP_Text)Label).fontSharedMaterial = val;
					materialChanged = true;
					val2 = val;
				}
				if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val == (Object)null))
				{
					long num = 0L;
					long num2 = 0L;
					try
					{
						num = (((Object)(object)val2.shader == (Object)null) ? 0 : ((Il2CppObjectBase)val2.shader).Pointer.ToInt64());
					}
					catch
					{
						num = 0L;
					}
					try
					{
						num2 = (((Object)(object)val.shader == (Object)null) ? 0 : ((Il2CppObjectBase)val.shader).Pointer.ToInt64());
					}
					catch
					{
						num2 = 0L;
					}
					if (SurfaceSync.NeedsShaderSync(num, num2))
					{
						((TMP_Text)Label).fontSharedMaterial = val;
						shaderChanged = true;
					}
				}
			}
			catch
			{
			}
		}

		private void CopyFontFrom(TextMeshPro anchor, TimerStyle style)
		{
			//IL_00b6: 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_0144: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Label == (Object)null)
			{
				return;
			}
			try
			{
				if ((Object)(object)((TMP_Text)anchor).font != (Object)null)
				{
					((TMP_Text)Label).font = ((TMP_Text)anchor).font;
				}
			}
			catch
			{
			}
			try
			{
				Material fontSharedMaterial = ((TMP_Text)anchor).fontSharedMaterial;
				if ((Object)(object)fontSharedMaterial != (Object)null)
				{
					((TMP_Text)Label).fontSharedMaterial = fontSharedMaterial;
				}
				else if ((Object)(object)((TMP_Text)Label).font != (Object)null)
				{
					((TMP_Text)Label).fontSharedMaterial = ((TMP_Asset)((TMP_Text)Label).font).material;
				}
			}
			catch
			{
			}
			try
			{
				((TMP_Text)Label).fontSize = ((TMP_Text)anchor).fontSize;
				_fontSize = ((TMP_Text)anchor).fontSize;
			}
			catch
			{
			}
			ResetFontFit();
			try
			{
				((TMP_Text)Label).fontStyle = ((TMP_Text)anchor).fontStyle;
			}
			catch
			{
			}
			try
			{
				((TMP_Text)Label).alignment = (TextAlignmentOptions)513;
			}
			catch
			{
			}
			try
			{
				((TMP_Text)Label).enableWordWrapping = false;
			}
			catch
			{
			}
			try
			{
				((TMP_Text)Label).enableAutoSizing = false;
			}
			catch
			{
			}
			try
			{
				((TMP_Text)Label).overflowMode = (TextOverflowModes)0;
			}
			catch
			{
			}
			try
			{
				((Graphic)Label).raycastTarget = false;
			}
			catch
			{
			}
			try
			{
				((TMP_Text)Label).richText = false;
			}
			catch
			{
			}
			try
			{
				((Graphic)Label).color = style.Neutral(((Graphic)anchor).color);
			}
			catch
			{
			}
		}

		private void ApplyRectStyle(TextMeshPro anchor, RectTransform anchorRect, TimerStyle style)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: 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_0045: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: 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)
			if ((Object)(object)_labelRect == (Object)null || (Object)(object)anchorRect == (Object)null)
			{
				return;
			}
			try
			{
				bool flag = false;
				Vector2 val = PointAnchorOf(anchorRect);
				if (!TimerLayout.SameAnchor(_labelRect.anchorMin.x, val.x) || !TimerLayout.SameAnchor(_labelRect.anchorMin.y, val.y) || !TimerLayout.SameAnchor(_labelRect.anchorMax.x, val.x) || !TimerLayout.SameAnchor(_labelRect.anchorMax.y, val.y))
				{
					_labelRect.anchorMin = val;
					_labelRect.anchorMax = val;
					flag = true;
				}
				if (!TimerLayout.SameAnchor(_labelRect.pivot.x, 0f) || !TimerLayout.SameAnchor(_labelRect.pivot.y, 0.5f))
				{
					_labelRect.pivot = new Vector2(0f, 0.5f);
					flag = true;
				}
				float fontSize = EffectiveFontSize(anchor);
				float num = TimerLayout.LabelWidth(fontSize, style.WidthRatio, style.MinWidth);
				Rect rect = anchorRect.rect;
				Vector2 val2 = default(Vector2);
				((Vector2)(ref val2))..ctor(num, LabelHeight(((Rect)(ref rect)).height, fontSize));
				if (flag || !TimerLayout.SameAnchor(_labelRect.sizeDelta.x, val2.x) || !TimerLayout.SameAnchor(_labelRect.sizeDelta.y, val2.y))
				{
					_labelRect.sizeDelta = val2;
				}
			}
			catch
			{
			}
		}

		private void ActivateForMeshBuild()
		{
			if ((Object)(object)Label == (Object)null)
			{
				return;
			}
			DisableRendererOnly();
			try
			{
				if (!((Component)Label).gameObject.activeSelf)
				{
					((Component)Label).gameObject.SetActive(true);
				}
			}
			catch (Exception ex)
			{
				ReportInvalidMesh("activate:" + ex.GetType().Name);
			}
			DisableRendererOnly();
		}

		private void DisableRendererOnly()
		{
			if ((Object)(object)Label == (Object)null)
			{
				return;
			}
			try
			{
				Renderer renderer = Label.renderer;
				if ((Object)(object)renderer != (Object)null && renderer.enabled)
				{
					renderer.enabled = false;
				}
			}
			catch
			{
			}
		}

		private void ForceMeshUpdate()
		{
			if ((Object)(object)Label == (Object)null)
			{
				return;
			}
			if (VisibilityPolicy.HasText(_text))
			{
				ActivateForMeshBuild();
			}
			try
			{
				((TMP_Text)Label).havePropertiesChanged = true;
			}
			catch (Exception ex)
			{
				ReportInvalidMesh("props:" + ex.GetType().Name);
			}
			try
			{
				((Graphic)Label).SetAllDirty();
			}
			catch (Exception ex2)
			{
				ReportInvalidMesh("dirty:" + ex2.GetType().Name);
			}
			try
			{
				((TMP_Text)Label).ForceMeshUpdate(true, true);
			}
			catch (Exception ex3)
			{
				ReportInvalidMesh("force:" + ex3.GetType().Name);
			}
		}

		private void EnsureMesh()
		{
			if (!((Object)(object)Label == (Object)null) && VisibilityPolicy.HasText(_text) && VisibilityPolicy.CanRetryMesh(_meshRetries) && !VisibilityPolicy.CanShow(CharacterCount(), VertexCount()))
			{
				DisableRendererOnly();
				_meshRetries++;
				ForceMeshUpdate();
			}
		}

		private void HideRenderer()
		{
			if ((Object)(object)Label == (Object)null)
			{
				return;
			}
			DisableRendererOnly();
			try
			{
				if (((Component)Label).gameObject.activeSelf)
				{
					((Component)Label).gameObject.SetActive(false);
				}
			}
			catch
			{
			}
		}

		private void ClearMeshSafe()
		{
			if ((Object)(object)Label == (Object)null)
			{
				return;
			}
			try
			{
				((TMP_Text)Label).ClearMesh();
				return;
			}
			catch (Exception ex)
			{
				ReportInvalidMesh("clear:" + ex.GetType().Name);
			}
			try
			{
				((TMP_Text)Label).ClearMesh(false);
			}
			catch (Exception ex2)
			{
				ReportInvalidMesh("clear2:" + ex2.GetType().Name);
			}
		}

		private void HideAndClear()
		{
			HideRenderer();
			if (CharacterCount() > 0 || VertexCount() > 0)
			{
				ClearMeshSafe();
			}
			_visibleSampleArmed = false;
		}

		private bool ShowOnlyWhenValid(float now)
		{
			if ((Object)(object)Label == (Object)null)
			{
				return false;
			}
			int num = CharacterCount();
			int num2 = VertexCount();
			if (!VisibilityPolicy.ShouldShow(!string.IsNullOrEmpty(_text), num, num2))
			{
				DisableRendererOnly();
				if (num2 > 0 || num > 0)
				{
					ClearMeshSafe();
				}
				ReportInvalidMesh("chars=" + num + " vtx=" + num2);
				return false;
			}
			try
			{
				Renderer renderer = Label.renderer;
				if ((Object)(object)renderer != (Object)null && !renderer.enabled)
				{
					renderer.enabled = true;
				}
			}
			catch
			{
			}
			try
			{
				if (!((Component)Label).gameObject.activeSelf)
				{
					((Component)Label).gameObject.SetActive(true);
				}
			}
			catch
			{
			}
			if (!SampleLogged && !_visibleSampleArmed)
			{
				_visibleSampleArmed = true;
				_shownAt = now;
			}
			return true;
		}

		public void SyncLayout(TimerStyle style)
		{
			//IL_00b2: 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_00be: 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_0132: 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_00db: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Label == (Object)null || (Object)(object)Anchor == (Object)null)
			{
				return;
			}
			try
			{
				if ((Object)(object)_anchorRect == (Object)null)
				{
					_anchorRect = ((Il2CppObjectBase)Anchor.transform).TryCast<RectTransform>();
				}
				if ((Object)(object)_labelRect == (Object)null)
				{
					_labelRect = ((Il2CppObjectBase)Label.transform).TryCast<RectTransform>();
				}
				if ((Object)(object)_anchorRect == (Object)null || (Object)(object)_labelRect == (Object)null)
				{
					DestroyLabel();
					return;
				}
				SyncLocalScale();
				FitFontToNative();
				ApplyRectStyle(Anchor, _anchorRect, style);
				Vector2 val = PointAnchorOf(_anchorRect);
				if (!TimerLayout.SameAnchor(_labelRect.anchorMin.x, val.x) || !TimerLayout.SameAnchor(_labelRect.anchorMin.y, val.y) || !TimerLayout.SameAnchor(_labelRect.anchorMax.x, val.x) || !TimerLayout.SameAnchor(_labelRect.anchorMax.y, val.y))
				{
					_labelRect.anchorMin = val;
					_labelRect.anchorMax = val;
				}
			}
			catch
			{
				DestroyLabel();
			}
		}

		public void SyncTransform(TimerStyle style)
		{
			SyncLayout(style);
			PlaceOnColumn(style, float.NaN);
		}

		public void PlaceOnColumn(TimerStyle style, float columnWorldX)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: 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_00af: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: 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)
			if ((Object)(object)Label == (Object)null || (Object)(object)Anchor == (Object)null || (Object)(object)_anchorRect == (Object)null || (Object)(object)_labelRect == (Object)null)
			{
				return;
			}
			try
			{
				Vector2 anchoredPosition = _anchorRect.anchoredPosition;
				Rect rect = _anchorRect.rect;
				Vector2 pivot = _anchorRect.pivot;
				float gap = TimerLayout.Gap(((TMP_Text)Anchor).fontSize, style.GapRatio, style.MinGap, style.MaxGap);
				float num = _labelRect.anchoredPosition.x;
				float anchoredX2;
				if (TrySharedColumnLocal(columnWorldX, out var anchoredX))
				{
					num = anchoredX;
				}
				else if (TryFallbackAnchoredX(style, anchoredPosition.x, rect, pivot.x, gap, out anchoredX2))
				{
					num = anchoredX2;
				}
				_labelRect.anchoredPosition = new Vector2(num, TimerLayout.LabelAnchoredY(anchoredPosition.y, ((Rect)(ref rect)).height, pivot.y));
			}
			catch
			{
				DestroyLabel();
			}
		}

		public bool TryMeasureNativeLeftEdge(out float worldX)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			worldX = 0f;
			if ((Object)(object)_anchorRect == (Object)null || !IsAlive((Object)(object)Anchor))
			{
				return false;
			}
			try
			{
				Bounds textBounds = ((TMP_Text)Anchor).textBounds;
				Vector3 val = default(Vector3);
				if (((Bounds)(ref textBounds)).size.x > 0.0001f)
				{
					((Vector3)(ref val))..ctor(((Bounds)(ref textBounds)).min.x, ((Bounds)(ref textBounds)).center.y, 0f);
				}
				else
				{
					Rect rect = _anchorRect.rect;
					if (!(((Rect)(ref rect)).width > 0f))
					{
						return false;
					}
					((Vector3)(ref val))..ctor(((Rect)(ref rect)).xMin, ((Rect)(ref rect)).center.y, 0f);
				}
				Vector3 val2 = Anchor.transform.TransformPoint(val);
				if (float.IsNaN(val2.x) || float.IsInfinity(val2.x))
				{
					return false;
				}
				worldX = val2.x;
				return true;
			}
			catch
			{
				return false;
			}
		}

		public bool TryMeasureColumnVote(TimerStyle style, out float nameLeftEdge, out float labelWidth, out float gap)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			nameLeftEdge = 0f;
			labelWidth = 0f;
			gap = 0f;
			if ((Object)(object)Label == (Object)null || (Object)(object)_labelRect == (Object)null)
			{
				return false;
			}
			if (!VisibilityPolicy.HasText(_text))
			{
				return false;
			}
			if (!TryMeasureNativeLeftEdge(out nameLeftEdge))
			{
				return false;
			}
			if (!TryMeasureLabelWidthLocal(out var width))
			{
				return false;
			}
			float num;
			float fontSize;
			try
			{
				num = Math.Abs(((Transform)_labelRect).lossyScale.x);
				fontSize = (((Object)(object)Anchor == (Object)null) ? 0f : ((TMP_Text)Anchor).fontSize);
			}
			catch
			{
				return false;
			}
			if (float.IsNaN(num) || float.IsInfinity(num) || !(num > 0f))
			{
				return false;
			}
			float num2 = TimerLayout.Gap(fontSize, style.GapRatio, style.MinGap, style.MaxGap);
			labelWidth = width * num;
			gap = num2 * num;
			if (!float.IsNaN(labelWidth) && !float.IsInfinity(labelWidth) && !float.IsNaN(gap))
			{
				return !float.IsInfinity(gap);
			}
			return false;
		}

		private bool TryMeasureLabelWidthLocal(out float width)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			width = 0f;
			if ((Object)(object)Label == (Object)null || (Object)(object)_labelRect == (Object)null)
			{
				return false;
			}
			bool flag = false;
			float num = 0f;
			try
			{
				Bounds textBounds = ((TMP_Text)Label).textBounds;
				if (((Bounds)(ref textBounds)).size.x > 0.0001f && !float.IsNaN(((Bounds)(ref textBounds)).size.x) && !float.IsInfinity(((Bounds)(ref textBounds)).size.x))
				{
					num = ((Bounds)(ref textBounds)).size.x;
					flag = true;
				}
			}
			catch
			{
				flag = false;
			}
			if (flag)
			{
				width = ((num > 0f) ? num : 0f);
			}
			else
			{
				try
				{
					Rect rect = _labelRect.rect;
					width = Math.Abs(((Rect)(ref rect)).width);
				}
				catch
				{
					width = 0f;
				}
			}
			if (float.IsNaN(width) || float.IsInfinity(width) || !(width > 0f))
			{
				return false;
			}
			return true;
		}

		private bool TrySharedColumnLocal(float columnWorldX, out float anchoredX)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			anchoredX = 0f;
			if (float.IsNaN(columnWorldX) || float.IsInfinity(columnWorldX))
			{
				return false;
			}
			try
			{
				RectTransform val = ParentRect();
				if ((Object)(object)val == (Object)null)
				{
					return false;
				}
				Rect rect = val.rect;
				Vector2 anchorMin = _labelRect.anchorMin;
				return TimerLayout.TryPlaceLeftEdge(columnWorldX, ((Transform)val).position.x, ((Transform)val).lossyScale.x, ((Rect)(ref rect)).xMin, ((Rect)(ref rect)).width, anchorMin.x, out anchoredX);
			}
			catch
			{
				return false;
			}
		}

		private bool TryFallbackAnchoredX(TimerStyle style, float nativeAnchoredX, Rect nativeBounds, float nativePivotX, float gap, out float anchoredX)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			anchoredX = 0f;
			try
			{
				RectTransform val = ParentRect();
				if ((Object)(object)val == (Object)null)
				{
					return false;
				}
				Rect rect = val.rect;
				Vector2 anchorMin = _labelRect.anchorMin;
				if (!TryMeasureLabelWidthLocal(out var width))
				{
					width = TimerLayout.LabelWidth(EffectiveFontSize(Anchor), style.WidthRatio, style.MinWidth);
				}
				float delta;
				float num = ((!TryGlyphLeftDelta(out delta)) ? TimerLayout.LabelAnchoredX(nativeAnchoredX, ((Rect)(ref nativeBounds)).width, nativePivotX, 0f) : TimerLayout.LabelAnchoredXFromGlyph(nativeAnchoredX, delta, 0f));
				float num2 = TimerLayout.AnchorReferenceLocalX(((Rect)(ref rect)).xMin, ((Rect)(ref rect)).width, anchorMin.x);
				float num3 = num - gap - width - num2;
				if (float.IsNaN(num3) || float.IsInfinity(num3))
				{
					return false;
				}
				anchoredX = num3;
				return true;
			}
			catch
			{
				return false;
			}
		}

		private RectTransform ParentRect()
		{
			try
			{
				if ((Object)(object)_labelRect == (Object)null)
				{
					return null;
				}
				Transform parent = ((Transform)_labelRect).parent;
				if ((Object)(object)parent == (Object)null)
				{
					return null;
				}
				return ((Il2CppObjectBase)parent).TryCast<RectTransform>();
			}
			catch
			{
				return null;
			}
		}

		private void SyncLocalScale()
		{
			//IL_0028: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Label == (Object)null || !IsAlive((Object)(object)Anchor))
			{
				return;
			}
			Vector3 localScale;
			Vector3 localScale2;
			try
			{
				localScale = Anchor.transform.localScale;
				localScale2 = Label.transform.localScale;
			}
			catch
			{
				return;
			}
			if (SameScale(localScale2, localScale))
			{
				return;
			}
			try
			{
				Label.transform.localScale = localScale;
			}
			catch
			{
			}
		}

		private static bool SameScale(Vector3 left, Vector3 right)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			if (Math.Abs(left.x - right.x) <= 0.0005f && Math.Abs(left.y - right.y) <= 0.0005f)
			{
				return Math.Abs(left.z - right.z) <= 0.0005f;
			}
			return false;
		}

		private void FitFontToNative()
		{
			if ((Object)(object)Label == (Object)null || !IsAlive((Object)(object)Anchor))
			{
				return;
			}
			float fontSize;
			try
			{
				fontSize = ((TMP_Text)Anchor).fontSize;
			}
			catch
			{
				return;
			}
			if (float.IsNaN(fontSize) || float.IsInfinity(fontSize) || fontSize <= 0f)
			{
				return;
			}
			if (_text == "--")
			{
				_nativeGlyphHeight = 0f;
				_labelGlyphHeight = 0f;
				ApplyFontSize(fontSize * _fontScale);
				return;
			}
			float height = 0f;
			float height2 = 0f;
			bool flag = MeasureGlyphHeight(Anchor, out height);
			if (flag)
			{
				flag = MeasureGlyphHeight(Label, out height2);
			}
			if (flag)
			{
				flag = SameFontAsNative();
			}
			_nativeGlyphHeight = (flag ? height : 0f);
			_labelGlyphHeight = (flag ? height2 : 0f);
			if (flag)
			{
				float num = TimerLayout.FontScaleToMatchGlyphHeight(height, height2);
				if (num > 1.001f)
				{
					float num2 = _fontScale * num;
					_fontScale = ((num2 > 8f) ? 8f : num2);
				}
			}
			ApplyFontSize(fontSize * _fontScale);
		}

		private static bool MeasureGlyphHeight(TextMeshPro text, out float height)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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)
			height = 0f;
			if (!IsAlive((Object)(object)text))
			{
				return false;
			}
			try
			{
				Bounds textBounds = ((TMP_Text)text).textBounds;
				float num = Math.Abs(((Bounds)(ref textBounds)).size.y);
				float num2 = Math.Abs(text.transform.lossyScale.y);
				if (float.IsNaN(num) || float.IsInfinity(num) || num <= 0.0001f)
				{
					return false;
				}
				if (float.IsNaN(num2) || float.IsInfinity(num2) || num2 <= 0.0001f)
				{
					return false;
				}
				height = num * num2;
				return true;
			}
			catch
			{
				return false;
			}
		}

		private bool SameFontAsNative()
		{
			try
			{
				TMP_FontAsset val = (IsAlive((Object)(object)Anchor) ? ((TMP_Text)Anchor).font : null);
				TMP_FontAsset val2 = (((Object)(object)Label == (Object)null) ? null : ((TMP_Text)Label).font);
				if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
				{
					return false;
				}
				return ((Il2CppObjectBase)val).Pointer == ((Il2CppObjectBase)val2).Pointer;
			}
			catch
			{
				return false;
			}
		}

		private void ApplyFontSize(float size)
		{
			if ((Object)(object)Label == (Object)null || float.IsNaN(size) || float.IsInfinity(size) || size <= 0f)
			{
				return;
			}
			float fontSize;
			try
			{
				fontSize = ((TMP_Text)Label).fontSize;
			}
			catch
			{
				return;
			}
			if (Math.Abs(fontSize - size) <= 0.01f)
			{
				_fontSize = fontSize;
				return;
			}
			try
			{
				((TMP_Text)Label).fontSize = size;
			}
			catch
			{
				return;
			}
			_fontSize = size;
			_meshRetries = 0;
			ForceMeshUpdate();
		}

		private void ResetFontFit()
		{
			_fontScale = 1f;
			_nativeGlyphHeight = 0f;
			_labelGlyphHeight = 0f;
		}

		private string DescribeFontFit()
		{
			StringBuilder stringBuilder = new StringBuilder(96);
			float num = 0f;
			try
			{
				num = (((Object)(object)Label == (Object)null) ? 0f : ((TMP_Text)Label).fontSize);
			}
			catch
			{
				num = 0f;
			}
			float num2 = 0f;
			try
			{
				num2 = (IsAlive((Object)(object)Anchor) ? ((TMP_Text)Anchor).fontSize : 0f);
			}
			catch
			{
				num2 = 0f;
			}
			stringBuilder.Append(" fontSize=").Append(F(num));
			stringBuilder.Append(" native.fontSize=").Append(F(num2));
			stringBuilder.Append(" nativeGlyphHeight=").Append(F(_nativeGlyphHeight));
			stringBuilder.Append(" labelGlyphHeight=").Append(F(_labelGlyphHeight));
			stringBuilder.Append(" fontScale=").Append(F(_fontScale));
			return stringBuilder.ToString();
		}

		private float EffectiveFontSize(TextMeshPro anchor)
		{
			if (_fontSize > 0f)
			{
				return _fontSize;
			}
			try
			{
				return ((Object)(object)anchor == (Object)null) ? 0f : ((TMP_Text)anchor).fontSize;
			}
			catch
			{
				return 0f;
			}
		}

		public string DescribeGeometry()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: 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_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: 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)
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0406: Unknown result type (might be due to invalid IL or missing references)
			//IL_0423: Unknown result type (might be due to invalid IL or missing references)
			//IL_0440: Unknown result type (might be due to invalid IL or missing references)
			//IL_045d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0382: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			RectTransform labelRect = _labelRect;
			if ((Object)(object)labelRect == (Object)null)
			{
				return "label=none";
			}
			StringBuilder stringBuilder = new StringBuilder(320);
			try
			{
				stringBuilder.Append("ancMin=").Append(V2(labelRect.anchorMin));
			}
			catch
			{
				stringBuilder.Append("ancMin=?");
			}
			try
			{
				stringBuilder.Append(" ancMax=").Append(V2(labelRect.anchorMax));
			}
			catch
			{
				stringBuilder.Append(" ancMax=?");
			}
			try
			{
				stringBuilder.Append(" pivot=").Append(V2(labelRect.pivot));
			}
			catch
			{
				stringBuilder.Append(" pivot=?");
			}
			try
			{
				stringBuilder.Append(" anchored=").Append(V2(labelRect.anchoredPosition));
			}
			catch
			{
				stringBuilder.Append(" anchored=?");
			}
			try
			{
				stringBuilder.Append(" sizeDelta=").Append(V2(labelRect.sizeDelta));
			}
			catch
			{
				stringBuilder.Append(" sizeDelta=?");
			}
			try
			{
				Rect rect = labelRect.rect;
				stringBuilder.Append(" rect=").Append(F(((Rect)(ref rect)).x)).Append(',')
					.Append(F(((Rect)(ref rect)).y))
					.Append(',')
					.Append(F(((Rect)(ref rect)).width))
					.Append(',')
					.Append(F(((Rect)(ref rect)).height));
			}
			catch
			{
				stringBuilder.Append(" rect=?");
			}
			try
			{
				Vector3 lossyScale = ((Transform)labelRect).lossyScale;
				stringBuilder.Append(" scale=").Append(F(lossyScale.x)).Append(',')
					.Append(F(lossyScale.y))
					.Append(',')
					.Append(F(lossyScale.z));
			}
			catch
			{
				stringBuilder.Append(" scale=?");
			}
			try
			{
				stringBuilder.Append(" active=").Append(((Component)labelRect).gameObject.activeInHierarchy ? "1" : "0");
			}
			catch
			{
				stringBuilder.Append(" active=?");
			}
			try
			{
				stringBuilder.Append(" enabled=").Append(((Object)(object)Label != (Object)null && ((Behaviour)Label).enabled) ? "1" : "0");
			}
			catch
			{
				stringBuilder.Append(" enabled=?");
			}
			try
			{
				Canvas val = (((Object)(object)Label == (Object)null) ? null : ((Graphic)Label).canvas);
				stringBuilder.Append(" canvas=").Append(((Object)(object)val == (Object)null) ? "none" : ((object)val.renderMode/*cast due to .constrained prefix*/).ToString());
			}
			catch
			{
				stringBuilder.Append(" canvas=?");
			}
			try
			{
				CanvasGroup val2 = (((Object)(object)Label == (Object)null) ? null : ((Component)Label).GetComponentInParent<CanvasGroup>());
				stringBuilder.Append(" group=").Append(((Object)(object)val2 == (Object)null) ? "none" : F(val2.alpha));
			}
			catch
			{
				stringBuilder.Append(" group=?");
			}
			try
			{
				Canvas val3 = (((Object)(object)Label == (Object)null) ? null : ((Graphic)Label).canvas);
				Camera val4 = (((Object)(object)val3 == (Object)null) ? null : val3.worldCamera);
				Vector3 position = ((Transform)labelRect).position;
				Vector3 val5 = (((Object)(object)val4 != (Object)null) ? val4.WorldToScreenPoint(position) : Vector2.op_Implicit(RectTransformUtility.WorldToScreenPoint((Camera)null, position)));
				stringBuilder.Append(" screen=").Append(F(val5.x)).Append(',')
					.Append(F(val5.y));
			}
			catch
			{
				stringBuilder.Append(" screen=?");
			}
			try
			{
				if ((Object)(object)Label != (Object)null)
				{
					Bounds textBounds = ((TMP_Text)Label).textBounds;
					stringBuilder.Append(" glyph=").Append(F(((Bounds)(ref textBounds)).center.x)).Append(',')
						.Append(F(((Bounds)(ref textBounds)).center.y))
						.Append(',')
						.Append(F(((Bounds)(ref textBounds)).size.x))
						.Append(',')
						.Append(F(((Bounds)(ref textBounds)).size.y));
				}
			}
			catch
			{
				stringBuilder.Append(" glyph=?");
			}
			try
			{
				if ((Object)(object)_anchorRect != (Object)null)
				{
					stringBuilder.Append(" native.anc=").Append(V2(_anchorRect.anchorMin)).Append("..")
						.Append(V2(_anchorRect.anchorMax))
						.Append(" pv=")
						.Append(V2(_anchorRect.pivot));
				}
			}
			catch
			{
			}
			try
			{
				stringBuilder.Append(" text='").Append((_text == null) ? string.Empty : _text).Append("'");
			}
			catch
			{
				stringBuilder.Append(" text=?");
			}
			stringBuilder.Append(' ').Append(DescribeSurface());
			return stringBuilder.ToString();
		}

		public string DescribeSurface()
		{
			if ((Object)(object)Label == (Object)null)
			{
				return "surface=none";
			}
			StringBuilder stringBuilder = new StringBuilder(160);
			stringBuilder.Append("chars=").Append(CharacterCount());
			stringBuilder.Append(" vtx=").Append(VertexCount());
			try
			{
				Renderer renderer = Label.renderer;
				stringBuilder.Append(" rend=").Append(((Object)(object)renderer == (Object)null) ? "none" : (renderer.enabled ? "1" : "0"));
				stringBuilder.Append(" vis=").Append(((Object)(object)renderer == (Object)null) ? "none" : (renderer.isVisible ? "1" : "0"));
			}
			catch
			{
				stringBuilder.Append(" rend=? vis=?");
			}
			try
			{
				stringBuilder.Append(" font=").Append(((Object)(object)((TMP_Text)Label).font == (Object)null) ? "none" : ((Object)((TMP_Text)Label).font).name);
			}
			catch
			{
				stringBuilder.Append(" font=?");
			}
			try
			{
				stringBuilder.Append(" mat=").Append(((Object)(object)((TMP_Text)Label).fontSharedMaterial == (Object)null) ? "none" : ((Object)((TMP_Text)Label).fontSharedMaterial).name);
			}
			catch
			{
				stringBuilder.Append(" mat=?");
			}
			try
			{
				Material fontSharedMaterial = ((TMP_Text)Label).fontSharedMaterial;
				stringBuilder.Append(" shader=").Append(((Object)(object)fontSharedMaterial == (Object)null || (Object)(object)fontSharedMaterial.shader == (Object)null) ? "none" : ((Object)fontSharedMaterial.shader).name);
			}
			catch
			{
				stringBuilder.Append(" shader=?");
			}
			return stringBuilder.ToString();
		}

		public string TakeVisibleSample(float now)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Label == (Object)null || (Object)(object)Anchor == (Object)null)
			{
				return null;
			}
			if (!VisibilityPolicy.CanReportVisibleSample(SampleLogged, _visibleSampleArmed, _shownAt, now, IsActiveInHierarchy(), CharacterCount(), VertexCount()))
			{
				return null;
			}
			SampleLogged = true;
			_visibleSampleArmed = false;
			return "[hud] slot " + ((object)Slot/*cast due to .constrained prefix*/).ToString() + " visible sample; " + DescribeVisibleState();
		}

		public string TakeInvalidMeshNote()
		{
			string pendingInvalidNote = _pendingInvalidNote;
			_pendingInvalidNote = null;
			return pendingInvalidNote;
		}

		private void ReportInvalidMesh(string reason)
		{
			//IL_001f: 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 (_invalidMeshReports < 3)
			{
				_invalidMeshReports++;
				_pendingInvalidNote = "[hud] slot " + ((object)Slot/*cast due to .constrained prefix*/).ToString() + " label kept hidden; " + reason;
			}
		}

		private bool IsActiveInHierarchy()
		{
			if ((Object)(object)Label == (Object)null)
			{
				return false;
			}
			try
			{
				return ((Component)Label).gameObject.activeInHierarchy;
			}
			catch
			{
				return false;
			}
		}

		public string DescribeVisibleState()
		{
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			StringBuilder stringBuilder = new StringBuilder(256);
			try
			{
				stringBuilder.Append("text='").Append((_text == null) ? string.Empty : _text).Append('\'');
			}
			catch
			{
				stringBuilder.Append("text=?");
			}
			try
			{
				stringBuilder.Append(" activeInHierarchy=").Append(((Object)(object)Label != (Object)null && ((Component)Label).gameObject.activeInHierarchy) ? "1" : "0");
			}
			catch
			{
				stringBuilder.Append(" activeInHierarchy=?");
			}
			stringBuilder.Append(" chars=").Append(CharacterCount());
			stringBuilder.Append(" vtx=").Append(VertexCount());
			try
			{
				Renderer val = (((Object)(object)Label == (Object)null) ? null : Label.renderer);
				stringBuilder.Append(" rend=").Append(((Object)(object)val == (Object)null) ? "none" : (val.enabled ? "1" : "0"));
				stringBuilder.Append(" vis=").Append(((Object)(object)val == (Object)null) ? "none" : (val.isVisible ? "1" : "0"));
			}
			catch
			{
				stringBuilder.Append(" rend=? vis=?");
			}
			try
			{
				Mesh val2 = (((Object)(object)Label == (Object)null) ? null : ((TMP_Text)Label).mesh);
				if ((Object)(object)val2 == (Object)null)
				{
					stringBuilder.Append(" bounds=none");
				}
				else
				{
					Bounds bounds = val2.bounds;
					stringBuilder.Append(" bounds=").Append(F(((Bounds)(ref bounds)).center.x)).Append(',')
						.Append(F(((Bounds)(ref bounds)).center.y))
						.Append(',')
						.Append(F(((Bounds)(ref bounds)).size.x))
						.Append(',')
						.Append(F(((Bounds)(ref bounds)