Decompiled source of ReferToCompendium v1.0.1

ReferToCompendium.dll

Decompiled 9 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Xml;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("ReferToCompendium")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Client-side compendium hints, personal list organization, and configurable status effect HUD for Valheim.")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("ReferToCompendium")]
[assembly: AssemblyTitle("ReferToCompendium")]
[assembly: AssemblyVersion("1.0.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ReferToCompendium
{
	internal sealed class CompendiumController : MonoBehaviour
	{
		private sealed class Entry
		{
			internal readonly string Id;

			internal readonly TextInfo Info;

			internal readonly TMP_Text? Label;

			internal readonly Vector2 OriginalOffsetMax;

			internal GameObject? Controls;

			internal Button? Up;

			internal Button? Down;

			internal TMP_Text? CollapseLabel;

			internal Entry(string id, TextInfo info)
			{
				//IL_0064: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				Id = id;
				Info = info;
				Transform val = Utils.FindChild(info.m_listElement.transform, "name", (IterativeSearchType)0);
				Label = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<TMP_Text>() : null);
				OriginalOffsetMax = (((Object)(object)Label != (Object)null) ? Label.rectTransform.offsetMax : Vector2.zero);
			}
		}

		private static readonly FieldRef<TextsDialog, List<TextInfo>> Texts = AccessTools.FieldRefAccess<TextsDialog, List<TextInfo>>("m_texts");

		private static readonly FieldRef<TextsDialog, int> SelectionIndex = AccessTools.FieldRefAccess<TextsDialog, int>("m_selectionIndex");

		private static readonly FieldRef<TextsDialog, float> BaseListSize = AccessTools.FieldRefAccess<TextsDialog, float>("m_baseListSize");

		private static readonly MethodInfo ShowText = AccessTools.Method(typeof(TextsDialog), "ShowText", new Type[1] { typeof(TextInfo) }, (Type[])null);

		private static readonly HashSet<CompendiumController> Instances = new HashSet<CompendiumController>();

		private readonly List<Entry> _entries = new List<Entry>();

		private readonly List<TextInfo> _displayed = new List<TextInfo>();

		private TextsDialog _dialog;

		private TextInfo? _selection;

		private TextInfo? _collapsedHeader;

		private GameObject? _toolbar;

		private TMP_Text? _editLabel;

		private GameObject? _resetButton;

		private bool _editing;

		private bool _expanded;

		private bool _pending;

		private int _readyFrame;

		private int _lastHeaderToggleFrame = -1;

		private bool _disposed;

		private float RowHeight => Mathf.Max(32f, _dialog.m_spacing);

		private float ToolbarHeight => RowHeight * 0.78f;

		private float ButtonSize => Mathf.Clamp(RowHeight * 0.55f, 24f, 42f);

		internal static void Schedule(TextsDialog dialog)
		{
			CompendiumController compendiumController = ((Component)dialog).GetComponent<CompendiumController>();
			if ((Object)(object)compendiumController == (Object)null)
			{
				compendiumController = ((Component)dialog).gameObject.AddComponent<CompendiumController>();
				compendiumController._dialog = dialog;
				Instances.Add(compendiumController);
			}
			compendiumController._pending = true;
			compendiumController._readyFrame = Time.frameCount + 1;
		}

		internal static void BeforeFill(TextsDialog dialog)
		{
			CompendiumController component = ((Component)dialog).GetComponent<CompendiumController>();
			if ((Object)(object)component != (Object)null)
			{
				component.ReleaseRows(restoreLayout: false);
			}
		}

		internal static void Selected(TextsDialog dialog, TextInfo text)
		{
			CompendiumController component = ((Component)dialog).GetComponent<CompendiumController>();
			if (!((Object)(object)component == (Object)null) && !component._disposed)
			{
				component._selection = text;
				int num = Texts.Invoke(dialog).IndexOf(text);
				if (num >= 0)
				{
					SelectionIndex.Invoke(dialog) = num;
				}
			}
		}

		internal static void Shutdown()
		{
			CompendiumController[] array = Instances.ToArray();
			foreach (CompendiumController compendiumController in array)
			{
				if ((Object)(object)compendiumController != (Object)null)
				{
					compendiumController.ReleaseRows(restoreLayout: true);
					compendiumController._disposed = true;
					Object.Destroy((Object)(object)compendiumController);
				}
			}
			Instances.Clear();
		}

		private void LateUpdate()
		{
			if (_disposed || (Object)(object)_dialog == (Object)null)
			{
				return;
			}
			if (!_pending)
			{
				if (_collapsedHeader != null && _selection == _collapsedHeader && ZInput.IsExclusiveGamepadActive() && ZInput.GetButtonDown("JoyButtonA"))
				{
					ToggleHeader();
				}
			}
			else if (Time.frameCount >= _readyFrame)
			{
				_pending = false;
				try
				{
					CaptureRows();
					ApplyLayout();
				}
				catch (Exception ex)
				{
					Plugin.LogWarning("Compendium layout could not be applied: " + ex);
					ReleaseRows(restoreLayout: true);
				}
			}
		}

		private void OnDestroy()
		{
			Instances.Remove(this);
		}

		private void CaptureRows()
		{
			List<TextInfo> list = (from val in Texts.Invoke(_dialog)
				where val != _collapsedHeader
				select val).ToList();
			foreach (Entry entry in _entries)
			{
				if ((Object)(object)entry.Info.m_listElement != (Object)null && !list.Contains(entry.Info))
				{
					list.Add(entry.Info);
				}
			}
			ClearDecorations();
			_entries.Clear();
			Dictionary<string, string> knownTopics = BuildKnownTopicKeys();
			Dictionary<string, int> dictionary = new Dictionary<string, int>(StringComparer.Ordinal);
			foreach (TextInfo item2 in list)
			{
				if (item2 != null)
				{
					string text = StableTopicKey(item2.m_topic ?? string.Empty, knownTopics);
					Type type = ((object)item2).GetType();
					if (type != typeof(TextInfo))
					{
						text = "provider:" + type.Assembly.GetName().Name + ":" + type.FullName + ":" + text;
					}
					dictionary.TryGetValue(text, out var value);
					dictionary[text] = value + 1;
					string id = text.Length + ":" + text + ":" + value;
					EnsureRow(item2);
					Entry item = new Entry(id, item2);
					_entries.Add(item);
					if ((Object)(object)item2.m_selected != (Object)null && item2.m_selected.activeSelf)
					{
						_selection = item2;
					}
				}
			}
			if (_entries.Count > 0)
			{
				CreateToolbar();
			}
		}

		private static Dictionary<string, string> BuildKnownTopicKeys()
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal);
			if ((Object)(object)Player.m_localPlayer == (Object)null || Localization.instance == null)
			{
				return dictionary;
			}
			foreach (KeyValuePair<string, string> knownText in Player.m_localPlayer.GetKnownTexts())
			{
				string text = knownText.Key.Replace("\u0016", string.Empty);
				string key = Localization.instance.Localize(text);
				if (!dictionary.ContainsKey(key))
				{
					dictionary.Add(key, text);
				}
				else if (dictionary[key] != text)
				{
					dictionary[key] = string.Empty;
				}
			}
			return dictionary;
		}

		private static string StableTopicKey(string topic, Dictionary<string, string> knownTopics)
		{
			string[] array = new string[3] { "$inventory_activeeffects", "$inventory_logs", "$inventory_stats" };
			foreach (string text in array)
			{
				if (topic == text || (Localization.instance != null && topic == Localization.instance.Localize(text)))
				{
					return "builtin:" + text;
				}
			}
			if (topic.StartsWith("$", StringComparison.Ordinal))
			{
				return "token:" + topic;
			}
			if (knownTopics.TryGetValue(topic, out string value) && value.Length > 0)
			{
				return "known:" + value;
			}
			return "title:" + topic;
		}

		private void EnsureRow(TextInfo info)
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			if ((Object)(object)info.m_listElement == (Object)null)
			{
				info.m_listElement = Object.Instantiate<GameObject>(_dialog.m_elementPrefab, (Transform)(object)_dialog.m_listRoot, false);
				info.m_listElement.SetActive(true);
				Transform val = Utils.FindChild(info.m_listElement.transform, "name", (IterativeSearchType)0);
				if ((Object)(object)val != (Object)null)
				{
					((Component)val).GetComponent<TMP_Text>().text = Localization.instance.Localize(info.m_topic);
				}
				((UnityEvent)info.m_listElement.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
				{
					Select(info);
				});
			}
			Transform val2 = Utils.FindChild(info.m_listElement.transform, "selected", (IterativeSearchType)0);
			if ((Object)(object)info.m_selected == (Object)null && (Object)(object)val2 != (Object)null)
			{
				info.m_selected = ((Component)val2).gameObject;
				info.m_selected.SetActive(false);
			}
		}

		private void ApplyLayout()
		{
			if (_entries.Count == 0)
			{
				return;
			}
			Dictionary<string, Entry> byId = _entries.ToDictionary<Entry, string>((Entry entry3) => entry3.Id, StringComparer.Ordinal);
			List<Entry> source = (from id in Plugin.State.GetOrderedIds(_entries.Select((Entry entry3) => entry3.Id)).Where(byId.ContainsKey)
				select byId[id]).ToList();
			List<Entry> list = source.Where((Entry entry3) => !Plugin.State.IsCollapsed(entry3.Id)).ToList();
			List<Entry> list2 = source.Where((Entry entry3) => Plugin.State.IsCollapsed(entry3.Id)).ToList();
			_displayed.Clear();
			float num = ToolbarHeight;
			for (int num2 = 0; num2 < list.Count; num2++)
			{
				Entry entry = list[num2];
				ArrangeRow(entry, num, collapsed: false, num2, list.Count);
				_displayed.Add(entry.Info);
				num += RowHeight;
			}
			if (list2.Count > 0)
			{
				EnsureHeader();
				UpdateHeader(list2.Count);
				SetRowPosition(_collapsedHeader.m_listElement, num);
				_collapsedHeader.m_listElement.SetActive(true);
				_displayed.Add(_collapsedHeader);
				num += RowHeight;
				for (int num3 = 0; num3 < list2.Count; num3++)
				{
					Entry entry2 = list2[num3];
					if (_expanded)
					{
						ArrangeRow(entry2, num, collapsed: true, num3, list2.Count);
						_displayed.Add(entry2.Info);
						num += RowHeight;
						continue;
					}
					entry2.Info.m_listElement.SetActive(false);
					if ((Object)(object)entry2.Info.m_selected != (Object)null)
					{
						entry2.Info.m_selected.SetActive(false);
					}
				}
			}
			else if (_collapsedHeader != null)
			{
				_collapsedHeader.m_listElement.SetActive(false);
			}
			List<TextInfo> obj = Texts.Invoke(_dialog);
			obj.Clear();
			obj.AddRange(_displayed);
			_dialog.m_listRoot.SetSizeWithCurrentAnchors((Axis)1, Mathf.Max(BaseListSize.Invoke(_dialog), num));
			if ((Object)(object)_editLabel != (Object)null)
			{
				_editLabel.text = (_editing ? Plugin.Ui("Done", "완료") : Plugin.Ui("Edit order", "목록 편집"));
			}
			if ((Object)(object)_resetButton != (Object)null)
			{
				_resetButton.SetActive(_editing);
			}
			if (_selection != null && _displayed.Contains(_selection))
			{
				SelectionIndex.Invoke(_dialog) = _displayed.IndexOf(_selection);
			}
			else if (_displayed.Count > 0)
			{
				Select((TextInfo)(list2.Any((Entry entry3) => entry3.Info == _selection) ? ((object)_collapsedHeader) : ((object)_displayed[0])));
			}
			LayoutRebuilder.MarkLayoutForRebuild(_dialog.m_listRoot);
		}

		private void ArrangeRow(Entry entry, float y, bool collapsed, int groupIndex, int groupCount)
		{
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			entry.Info.m_listElement.SetActive(true);
			SetRowPosition(entry.Info.m_listElement, y);
			if ((Object)(object)entry.Controls == (Object)null)
			{
				CreateRowControls(entry);
			}
			bool flag = _editing || collapsed;
			entry.Controls.SetActive(flag);
			((Component)entry.Up).gameObject.SetActive(_editing);
			((Component)entry.Down).gameObject.SetActive(_editing);
			((Selectable)entry.Up).interactable = groupIndex > 0;
			((Selectable)entry.Down).interactable = groupIndex < groupCount - 1;
			entry.CollapseLabel.text = (collapsed ? "+" : "-");
			if ((Object)(object)entry.Label != (Object)null)
			{
				Vector2 originalOffsetMax = entry.OriginalOffsetMax;
				if (flag)
				{
					originalOffsetMax.x -= (float)((!_editing) ? 1 : 3) * (ButtonSize + 4f) + 4f;
				}
				entry.Label.rectTransform.offsetMax = originalOffsetMax;
			}
		}

		private static void SetRowPosition(GameObject row, float y)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)row.transform;
			val.anchoredPosition = new Vector2(val.anchoredPosition.x, 0f - y);
		}

		private void CreateToolbar()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Expected O, but got Unknown
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Expected O, but got Unknown
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			_toolbar = new GameObject("ReferToCompendium.Toolbar", new Type[1] { typeof(RectTransform) });
			_toolbar.layer = ((Component)_dialog.m_listRoot).gameObject.layer;
			RectTransform val = (RectTransform)_toolbar.transform;
			((Transform)val).SetParent((Transform)(object)_dialog.m_listRoot, false);
			val.anchorMin = new Vector2(0f, 1f);
			val.anchorMax = new Vector2(1f, 1f);
			val.pivot = new Vector2(0.5f, 1f);
			val.sizeDelta = new Vector2(0f, ToolbarHeight - 4f);
			val.anchoredPosition = Vector2.zero;
			TMP_Text style = _entries[0].Label ?? _dialog.m_textAreaTopic;
			Button val2 = MakeButton((Transform)val, "Edit", Plugin.Ui("Edit order", "목록 편집"), style, delegate
			{
				_editing = !_editing;
				ApplyLayout();
			});
			Transform transform = ((Component)val2).transform;
			SetStretch((RectTransform?)(object)((transform is RectTransform) ? transform : null), new Vector2(0f, 0f), new Vector2(0.65f, 1f));
			_editLabel = ((Component)val2).GetComponentInChildren<TMP_Text>();
			Button val3 = MakeButton((Transform)val, "Reset", Plugin.Ui("Reset", "초기화"), style, delegate
			{
				Plugin.State.Reset(_entries.Select((Entry entry) => entry.Id));
				Plugin.SaveLayout();
				_expanded = false;
				ApplyLayout();
			});
			Transform transform2 = ((Component)val3).transform;
			SetStretch((RectTransform?)(object)((transform2 is RectTransform) ? transform2 : null), new Vector2(0.68f, 0f), new Vector2(1f, 1f));
			_resetButton = ((Component)val3).gameObject;
		}

		private void CreateRowControls(Entry entry)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			//IL_009e: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			entry.Controls = new GameObject("ReferToCompendium.Controls", new Type[1] { typeof(RectTransform) });
			entry.Controls.layer = entry.Info.m_listElement.layer;
			RectTransform val = (RectTransform)entry.Controls.transform;
			((Transform)val).SetParent(entry.Info.m_listElement.transform, false);
			val.anchorMin = new Vector2(1f, 0.5f);
			val.anchorMax = new Vector2(1f, 0.5f);
			val.pivot = new Vector2(1f, 0.5f);
			val.sizeDelta = new Vector2(3f * (ButtonSize + 4f), ButtonSize);
			val.anchoredPosition = new Vector2(-4f, 0f);
			TMP_Text style = entry.Label ?? _dialog.m_textAreaTopic;
			entry.Up = MakeButton((Transform)(object)val, "MoveUp", string.Empty, style, delegate
			{
				Move(entry, -1);
			});
			entry.Down = MakeButton((Transform)(object)val, "MoveDown", string.Empty, style, delegate
			{
				Move(entry, 1);
			});
			Button val2 = MakeButton((Transform)(object)val, "CollapseRestore", "-", style, delegate
			{
				Plugin.State.SetCollapsed(entry.Id, !Plugin.State.IsCollapsed(entry.Id));
				Plugin.SaveLayout();
				ApplyLayout();
			});
			entry.CollapseLabel = ((Component)val2).GetComponentInChildren<TMP_Text>();
			PositionRowButton(entry.Up, 2);
			PositionRowButton(entry.Down, 1);
			PositionRowButton(val2, 0);
			AddArrow(entry.Up, down: false);
			AddArrow(entry.Down, down: true);
		}

		private void PositionRowButton(Button button, int fromRight)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)((Component)button).transform;
			val.anchorMin = new Vector2(1f, 0.5f);
			val.anchorMax = val.anchorMin;
			val.pivot = new Vector2(1f, 0.5f);
			val.sizeDelta = new Vector2(ButtonSize, ButtonSize);
			val.anchoredPosition = new Vector2((float)(-fromRight) * (ButtonSize + 4f), 0f);
		}

		private void Move(Entry entry, int direction)
		{
			Plugin.State.Move(entry.Id, direction, _entries.Select((Entry item) => item.Id));
			Plugin.SaveLayout();
			ApplyLayout();
		}

		private void EnsureHeader()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			if (_collapsedHeader == null || !((Object)(object)_collapsedHeader.m_listElement != (Object)null))
			{
				_collapsedHeader = new TextInfo(string.Empty, string.Empty);
				GameObject val = Object.Instantiate<GameObject>(_dialog.m_elementPrefab, (Transform)(object)_dialog.m_listRoot, false);
				((Object)val).name = "ReferToCompendium.CollapsedGroup";
				_collapsedHeader.m_listElement = val;
				_collapsedHeader.m_selected = ((Component)Utils.FindChild(val.transform, "selected", (IterativeSearchType)0)).gameObject;
				_collapsedHeader.m_selected.SetActive(false);
				((UnityEvent)val.GetComponent<Button>().onClick).AddListener(new UnityAction(ToggleHeader));
			}
		}

		private void ToggleHeader()
		{
			if (_collapsedHeader != null && _lastHeaderToggleFrame != Time.frameCount)
			{
				_lastHeaderToggleFrame = Time.frameCount;
				_expanded = !_expanded;
				Select(_collapsedHeader);
				ApplyLayout();
			}
		}

		private void UpdateHeader(int count)
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			_collapsedHeader.m_topic = Plugin.Ui("Collapsed entries", "접어 둔 항목");
			_collapsedHeader.m_text = Plugin.Ui("Click the collapsed entries heading to expand or fold the group (gamepad: select this heading and press A). Use + to restore an entry.\n\nEdit order shows the up/down and collapse buttons. Reset restores the entries currently available in this compendium.", "접어 둔 항목의 제목을 누르면 목록을 펼치거나 접을 수 있습니다. 게임패드는 이 제목을 선택한 뒤 A 버튼을 누르세요. + 버튼으로 항목을 원래 목록에 되돌립니다.\n\n목록 편집에서 위/아래 이동과 접기 버튼을 사용할 수 있습니다. 초기화는 현재 도감에 있는 항목만 되돌립니다.");
			TMP_Text component = ((Component)Utils.FindChild(_collapsedHeader.m_listElement.transform, "name", (IterativeSearchType)0)).GetComponent<TMP_Text>();
			component.text = (_expanded ? "[-] " : "[+] ") + _collapsedHeader.m_topic + " (" + count + ")";
			((Graphic)component).color = new Color(1f, 0.76f, 0.37f, 1f);
		}

		private void Select(TextInfo info)
		{
			if (info != null && !((Object)(object)info.m_listElement == (Object)null))
			{
				ShowText.Invoke(_dialog, new object[1] { info });
				Selected(_dialog, info);
			}
		}

		private void ReleaseRows(bool restoreLayout)
		{
			_pending = false;
			if ((Object)(object)_dialog == (Object)null)
			{
				return;
			}
			List<TextInfo> list = Texts.Invoke(_dialog);
			if (_entries.Count > 0)
			{
				TextInfo[] collection = list.Where((TextInfo info) => info != _collapsedHeader && !_entries.Any((Entry entry) => entry.Info == info)).ToArray();
				list.Clear();
				list.AddRange(_entries.Select((Entry entry) => entry.Info));
				list.AddRange(collection);
			}
			else if (_collapsedHeader != null)
			{
				list.Remove(_collapsedHeader);
			}
			ClearDecorations();
			if (restoreLayout)
			{
				for (int num = 0; num < list.Count; num++)
				{
					if ((Object)(object)list[num].m_listElement != (Object)null)
					{
						list[num].m_listElement.SetActive(true);
						SetRowPosition(list[num].m_listElement, (float)num * RowHeight);
					}
				}
				_dialog.m_listRoot.SetSizeWithCurrentAnchors((Axis)1, Mathf.Max(BaseListSize.Invoke(_dialog), (float)list.Count * RowHeight));
				if (_selection != null && list.Contains(_selection))
				{
					SelectionIndex.Invoke(_dialog) = list.IndexOf(_selection);
				}
				else if (list.Count > 0 && ((Component)_dialog).gameObject.activeInHierarchy)
				{
					Select(list[0]);
				}
			}
			_entries.Clear();
			_displayed.Clear();
			_selection = null;
		}

		private void ClearDecorations()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			foreach (Entry entry in _entries)
			{
				if ((Object)(object)entry.Label != (Object)null)
				{
					entry.Label.rectTransform.offsetMax = entry.OriginalOffsetMax;
				}
				RemoveObject(entry.Controls);
				entry.Controls = null;
			}
			RemoveObject(_toolbar);
			_toolbar = null;
			_editLabel = null;
			_resetButton = null;
			if (_collapsedHeader != null)
			{
				RemoveObject(_collapsedHeader.m_listElement);
				_collapsedHeader = null;
			}
		}

		private static void RemoveObject(GameObject? gameObject)
		{
			if ((Object)(object)gameObject != (Object)null)
			{
				gameObject.SetActive(false);
				Object.Destroy((Object)(object)gameObject);
			}
		}

		private static Button MakeButton(Transform parent, string name, string caption, TMP_Text style, Action onClick)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: 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_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Expected O, but got Unknown
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("ReferToCompendium." + name, new Type[4]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image),
				typeof(Button)
			});
			val.layer = ((Component)parent).gameObject.layer;
			val.transform.SetParent(parent, false);
			Image component = val.GetComponent<Image>();
			((Graphic)component).color = new Color(0.12f, 0.09f, 0.055f, 0.93f);
			Button component2 = val.GetComponent<Button>();
			((Selectable)component2).targetGraphic = (Graphic)(object)component;
			ColorBlock colors = ((Selectable)component2).colors;
			((ColorBlock)(ref colors)).normalColor = Color.white;
			((ColorBlock)(ref colors)).highlightedColor = new Color(1.6f, 1.5f, 1.2f, 1f);
			((ColorBlock)(ref colors)).pressedColor = new Color(0.8f, 0.65f, 0.4f, 1f);
			((ColorBlock)(ref colors)).disabledColor = new Color(0.55f, 0.55f, 0.55f, 0.65f);
			((Selectable)component2).colors = colors;
			Navigation navigation = default(Navigation);
			((Navigation)(ref navigation)).mode = (Mode)0;
			((Selectable)component2).navigation = navigation;
			((UnityEvent)component2.onClick).AddListener((UnityAction)delegate
			{
				onClick();
			});
			GameObject val2 = new GameObject("Label", new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(TextMeshProUGUI)
			})
			{
				layer = val.layer
			};
			val2.transform.SetParent(val.transform, false);
			TMP_Text component3 = val2.GetComponent<TMP_Text>();
			component3.font = style.font;
			component3.fontSharedMaterial = style.fontSharedMaterial;
			component3.fontSize = Mathf.Clamp(style.fontSize * 0.75f, 16f, 28f);
			component3.enableAutoSizing = true;
			component3.fontSizeMin = 12f;
			component3.fontSizeMax = component3.fontSize;
			component3.alignment = (TextAlignmentOptions)514;
			((Graphic)component3).color = new Color(1f, 0.77f, 0.4f, 1f);
			((Graphic)component3).raycastTarget = false;
			component3.text = caption;
			SetStretch(component3.rectTransform, Vector2.zero, Vector2.one);
			component3.rectTransform.offsetMin = new Vector2(3f, 1f);
			component3.rectTransform.offsetMax = new Vector2(-3f, -1f);
			return component2;
		}

		private static void AddArrow(Button button, bool down)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Arrow", new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(OrderArrowGraphic)
			})
			{
				layer = ((Component)button).gameObject.layer
			};
			val.transform.SetParent(((Component)button).transform, false);
			OrderArrowGraphic component = val.GetComponent<OrderArrowGraphic>();
			component.Down = down;
			((Graphic)component).color = new Color(1f, 0.77f, 0.4f, 1f);
			((Graphic)component).raycastTarget = false;
			SetStretch(((Graphic)component).rectTransform, new Vector2(0.27f, 0.28f), new Vector2(0.73f, 0.72f));
		}

		private static void SetStretch(RectTransform? rect, Vector2 min, Vector2 max)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)rect == (Object)null))
			{
				rect.anchorMin = min;
				rect.anchorMax = max;
				rect.offsetMin = Vector2.zero;
				rect.offsetMax = Vector2.zero;
			}
		}
	}
	internal sealed class OrderArrowGraphic : MaskableGraphic
	{
		internal bool Down;

		protected override void OnPopulateMesh(VertexHelper helper)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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_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)
			helper.Clear();
			Rect rect = ((Graphic)this).rectTransform.rect;
			float num = (Down ? ((Rect)(ref rect)).yMax : ((Rect)(ref rect)).yMin);
			float num2 = (Down ? ((Rect)(ref rect)).yMin : ((Rect)(ref rect)).yMax);
			helper.AddVert(new Vector3(((Rect)(ref rect)).xMin, num), Color32.op_Implicit(((Graphic)this).color), Vector4.op_Implicit(Vector2.zero));
			helper.AddVert(new Vector3(((Rect)(ref rect)).xMax, num), Color32.op_Implicit(((Graphic)this).color), Vector4.op_Implicit(Vector2.zero));
			helper.AddVert(new Vector3(((Rect)(ref rect)).center.x, num2), Color32.op_Implicit(((Graphic)this).color), Vector4.op_Implicit(Vector2.zero));
			helper.AddTriangle(0, 1, 2);
		}
	}
	[HarmonyPatch(typeof(TextsDialog), "Setup")]
	internal static class CompendiumSetupPatch
	{
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(TextsDialog __instance)
		{
			CompendiumController.Schedule(__instance);
		}
	}
	[HarmonyPatch(typeof(TextsDialog), "FillTextList")]
	internal static class CompendiumFillPatch
	{
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static void Prefix(TextsDialog __instance)
		{
			CompendiumController.BeforeFill(__instance);
		}
	}
	[HarmonyPatch(typeof(TextsDialog), "ShowText", new Type[] { typeof(TextInfo) })]
	internal static class CompendiumSelectionPatch
	{
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(TextsDialog __instance, TextInfo text)
		{
			CompendiumController.Selected(__instance, text);
		}
	}
	public sealed class LayoutState
	{
		private readonly object gate = new object();

		private readonly List<string> order = new List<string>();

		private readonly HashSet<string> collapsed = new HashSet<string>(StringComparer.Ordinal);

		public List<string> GetOrderedIds(IEnumerable<string?> availableIds)
		{
			List<string> list = DistinctIds(availableIds);
			lock (gate)
			{
				Reconcile(list);
				HashSet<string> hashSet = new HashSet<string>(list, StringComparer.Ordinal);
				return order.FindAll(hashSet.Contains);
			}
		}

		public bool IsCollapsed(string? id)
		{
			lock (gate)
			{
				return id != null && collapsed.Contains(id);
			}
		}

		public bool SetCollapsed(string? id, bool value)
		{
			if (id == null || id.Length == 0)
			{
				return false;
			}
			lock (gate)
			{
				if (!value)
				{
					return collapsed.Remove(id);
				}
				if (!order.Contains(id))
				{
					order.Add(id);
				}
				return collapsed.Add(id);
			}
		}

		public bool Move(string? id, int delta, IEnumerable<string?> availableIds)
		{
			List<string> list = DistinctIds(availableIds);
			lock (gate)
			{
				Reconcile(list);
				if (delta == 0 || id == null || id.Length == 0)
				{
					return false;
				}
				HashSet<string> hashSet = new HashSet<string>(list, StringComparer.Ordinal);
				if (!hashSet.Contains(id))
				{
					return false;
				}
				bool flag = collapsed.Contains(id);
				List<int> list2 = new List<int>();
				for (int i = 0; i < order.Count; i++)
				{
					if (hashSet.Contains(order[i]) && collapsed.Contains(order[i]) == flag)
					{
						list2.Add(i);
					}
				}
				int num = list2.FindIndex((int index) => order[index] == id);
				if (num < 0)
				{
					return false;
				}
				int num2 = (int)Math.Max(0L, Math.Min((long)list2.Count - 1L, (long)num + (long)delta));
				if (num == num2)
				{
					return false;
				}
				int num3 = ((num2 > num) ? 1 : (-1));
				for (int num4 = num; num4 != num2; num4 += num3)
				{
					order[list2[num4]] = order[list2[num4 + num3]];
				}
				order[list2[num2]] = id;
				return true;
			}
		}

		public void Reset(IEnumerable<string?> availableIds)
		{
			List<string> list = DistinctIds(availableIds);
			lock (gate)
			{
				Reconcile(list);
				HashSet<string> hashSet = new HashSet<string>(list, StringComparer.Ordinal);
				int num = 0;
				for (int i = 0; i < order.Count; i++)
				{
					if (hashSet.Contains(order[i]))
					{
						order[i] = list[num++];
					}
				}
				foreach (string item in list)
				{
					collapsed.Remove(item);
				}
			}
		}

		internal List<LayoutEntry> Snapshot()
		{
			lock (gate)
			{
				List<LayoutEntry> list = new List<LayoutEntry>(order.Count);
				foreach (string item in order)
				{
					list.Add(new LayoutEntry
					{
						Id = item,
						Collapsed = collapsed.Contains(item)
					});
				}
				return list;
			}
		}

		internal static LayoutState FromEntries(List<LayoutEntry> entries)
		{
			LayoutState layoutState = new LayoutState();
			foreach (LayoutEntry entry in entries)
			{
				layoutState.order.Add(entry.Id);
				if (entry.Collapsed)
				{
					layoutState.collapsed.Add(entry.Id);
				}
			}
			return layoutState;
		}

		private void Reconcile(List<string> available)
		{
			HashSet<string> hashSet = new HashSet<string>(order, StringComparer.Ordinal);
			foreach (string item in available)
			{
				if (hashSet.Add(item))
				{
					order.Add(item);
				}
			}
		}

		private static List<string> DistinctIds(IEnumerable<string?> ids)
		{
			if (ids == null)
			{
				throw new ArgumentNullException("ids");
			}
			List<string> list = new List<string>();
			HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
			foreach (string id in ids)
			{
				if (id != null && id.Length != 0 && hashSet.Add(id))
				{
					list.Add(id);
				}
			}
			return list;
		}
	}
	[DataContract]
	internal sealed class LayoutEntry
	{
		[DataMember(Name = "id", Order = 0, IsRequired = true)]
		public string Id = string.Empty;

		[DataMember(Name = "collapsed", Order = 1)]
		public bool Collapsed;
	}
	public sealed class LayoutStore
	{
		private enum ReadKind
		{
			Missing,
			Supported,
			Unsupported,
			Corrupt,
			Unavailable
		}

		private sealed class ReadResult
		{
			public readonly ReadKind Kind;

			public readonly string Message;

			public byte[] Bytes = Array.Empty<byte>();

			public LayoutState? State;

			public ReadResult(ReadKind kind, string message = "")
			{
				Kind = kind;
				Message = message;
			}
		}

		[DataContract]
		private sealed class LayoutHeader
		{
			[DataMember(Name = "version", IsRequired = true)]
			public int Version { get; set; }
		}

		[DataContract]
		private sealed class LayoutDocument
		{
			[DataMember(Name = "version", Order = 0, IsRequired = true)]
			public int Version;

			[DataMember(Name = "entries", Order = 1, IsRequired = true)]
			public List<LayoutEntry> Entries = new List<LayoutEntry>();
		}

		private const int CurrentVersion = 1;

		private const int MaximumBytes = 2097152;

		private const int MaximumEntries = 4096;

		private const int MaximumIdLength = 4096;

		private readonly string path;

		private readonly Action<string> warning;

		private readonly HashSet<string> preserved = new HashSet<string>(StringComparer.Ordinal);

		private bool readOnly;

		public LayoutState State { get; private set; }

		public LayoutStore(string path, Action<string>? warning)
		{
			this.path = Path.GetFullPath(path ?? throw new ArgumentNullException("path"));
			this.warning = warning ?? ((Action<string>)delegate
			{
			});
			State = new LayoutState();
			Load();
		}

		public bool Save()
		{
			if (readOnly)
			{
				return false;
			}
			string text = null;
			try
			{
				ReadResult readResult = Read(path);
				if (readResult.Kind == ReadKind.Unsupported || readResult.Kind == ReadKind.Unavailable)
				{
					Block(readResult.Message);
					return false;
				}
				if (readResult.Kind == ReadKind.Corrupt && !Preserve(path, readResult.Bytes))
				{
					return false;
				}
				List<LayoutEntry> entries = State.Snapshot();
				Validate(entries);
				byte[] bytes;
				using (MemoryStream memoryStream = new MemoryStream())
				{
					((XmlObjectSerializer)Serializer(typeof(LayoutDocument))).WriteObject((Stream)memoryStream, (object)new LayoutDocument
					{
						Version = 1,
						Entries = entries
					});
					if (memoryStream.Length > 2097152)
					{
						throw new SerializationException("Layout exceeds the maximum file size.");
					}
					bytes = memoryStream.ToArray();
				}
				Directory.CreateDirectory(Path.GetDirectoryName(path) ?? throw new IOException("Layout path has no parent directory."));
				text = path + "." + Guid.NewGuid().ToString("N") + ".tmp";
				WriteNew(text, bytes);
				if (readResult.Kind == ReadKind.Missing)
				{
					File.Move(text, path);
				}
				else
				{
					File.Replace(text, path, (readResult.Kind == ReadKind.Supported) ? (path + ".bak") : null, ignoreMetadataErrors: true);
				}
				text = null;
				return true;
			}
			catch (Exception ex) when (IsFileOrDataError(ex))
			{
				warning("Could not save compendium layout: " + ex.Message);
				return false;
			}
			finally
			{
				if (text != null)
				{
					try
					{
						File.Delete(text);
					}
					catch (Exception ex2) when (IsFileOrDataError(ex2))
					{
						warning("Could not remove layout temporary file: " + ex2.Message);
					}
				}
			}
		}

		private void Load()
		{
			ReadResult readResult = Read(path);
			if (readResult.Kind == ReadKind.Supported)
			{
				State = readResult.State;
				return;
			}
			if (readResult.Kind == ReadKind.Unsupported || readResult.Kind == ReadKind.Unavailable)
			{
				Block(readResult.Message);
				return;
			}
			if (readResult.Kind == ReadKind.Corrupt)
			{
				warning("Compendium layout is invalid; trying its backup. " + readResult.Message);
				if (!Preserve(path, readResult.Bytes))
				{
					readOnly = true;
				}
			}
			ReadResult readResult2 = Read(path + ".bak");
			if (readResult2.Kind == ReadKind.Supported)
			{
				State = readResult2.State;
				warning("Recovered compendium layout from its backup.");
			}
			else if (readResult2.Kind == ReadKind.Unsupported || readResult2.Kind == ReadKind.Unavailable)
			{
				Block(readResult2.Message);
			}
			else if (readResult2.Kind == ReadKind.Corrupt)
			{
				warning("Compendium layout backup is invalid; using an empty layout. " + readResult2.Message);
				if (!Preserve(path + ".bak", readResult2.Bytes))
				{
					readOnly = true;
				}
			}
		}

		private ReadResult Read(string source)
		{
			byte[] bytes;
			try
			{
				using FileStream fileStream = new FileStream(source, FileMode.Open, FileAccess.Read, FileShare.Read);
				using MemoryStream memoryStream = new MemoryStream();
				if (fileStream.Length > 2097152)
				{
					return new ReadResult(ReadKind.Unavailable, "Layout is larger than the supported read limit: " + source);
				}
				byte[] array = new byte[8192];
				int num;
				while ((num = fileStream.Read(array, 0, array.Length)) != 0)
				{
					if (memoryStream.Length + num > 2097152)
					{
						return new ReadResult(ReadKind.Unavailable, "Layout grew beyond the supported read limit: " + source);
					}
					memoryStream.Write(array, 0, num);
				}
				bytes = memoryStream.ToArray();
			}
			catch (FileNotFoundException)
			{
				return new ReadResult(ReadKind.Missing);
			}
			catch (DirectoryNotFoundException)
			{
				return new ReadResult(ReadKind.Missing);
			}
			catch (Exception ex3) when (IsFileOrDataError(ex3))
			{
				return new ReadResult(ReadKind.Unavailable, ex3.Message);
			}
			try
			{
				LayoutHeader layoutHeader = (LayoutHeader)Deserialize(typeof(LayoutHeader), bytes);
				if (layoutHeader == null)
				{
					throw new SerializationException("Missing layout object.");
				}
				if (layoutHeader.Version != 1)
				{
					return new ReadResult(ReadKind.Unsupported, "Unsupported layout format " + layoutHeader.Version + "; preserving " + source + " without changes.");
				}
				LayoutDocument layoutDocument = (LayoutDocument)Deserialize(typeof(LayoutDocument), bytes);
				Validate(layoutDocument.Entries);
				return new ReadResult(ReadKind.Supported)
				{
					State = LayoutState.FromEntries(layoutDocument.Entries)
				};
			}
			catch (Exception ex4) when (IsFileOrDataError(ex4))
			{
				return new ReadResult(ReadKind.Corrupt, ex4.Message)
				{
					Bytes = bytes
				};
			}
		}

		private bool Preserve(string source, byte[] bytes)
		{
			string item;
			using (SHA256 sHA = SHA256.Create())
			{
				item = source + ":" + Convert.ToBase64String(sHA.ComputeHash(bytes));
			}
			if (preserved.Contains(item))
			{
				return true;
			}
			try
			{
				string text = source + ".corrupt-" + DateTime.UtcNow.ToString("yyyyMMddTHHmmssfffZ", CultureInfo.InvariantCulture) + "-" + Guid.NewGuid().ToString("N");
				WriteNew(text, bytes);
				preserved.Add(item);
				warning("Preserved invalid compendium layout as " + text);
				return true;
			}
			catch (Exception ex) when (IsFileOrDataError(ex))
			{
				Block("Cannot preserve invalid layout; saving is disabled to avoid data loss. " + ex.Message);
				return false;
			}
		}

		private void Block(string message)
		{
			readOnly = true;
			warning(message + " Layout saving is disabled for this session.");
		}

		private static object Deserialize(Type type, byte[] bytes)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			XmlDictionaryReaderQuotas val = new XmlDictionaryReaderQuotas
			{
				MaxDepth = 32,
				MaxStringContentLength = 2097152,
				MaxArrayLength = 2097152,
				MaxBytesPerRead = 2097152,
				MaxNameTableCharCount = 65536
			};
			XmlDictionaryReader val2 = JsonReaderWriterFactory.CreateJsonReader(bytes, val);
			try
			{
				object result = ((XmlObjectSerializer)Serializer(type)).ReadObject(val2) ?? throw new SerializationException("Missing layout object.");
				if ((int)((XmlReader)val2).MoveToContent() != 0)
				{
					throw new SerializationException("Unexpected data after layout object.");
				}
				return result;
			}
			finally
			{
				((IDisposable)val2)?.Dispose();
			}
		}

		private static DataContractJsonSerializer Serializer(Type type)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			return new DataContractJsonSerializer(type, new DataContractJsonSerializerSettings
			{
				MaxItemsInObjectGraph = 32768
			});
		}

		private static void Validate(List<LayoutEntry> entries)
		{
			if (entries == null || entries.Count > 4096)
			{
				throw new SerializationException("Invalid layout entry count.");
			}
			HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
			foreach (LayoutEntry entry in entries)
			{
				if (entry == null || string.IsNullOrEmpty(entry.Id) || entry.Id.Length > 4096 || !hashSet.Add(entry.Id))
				{
					throw new SerializationException("Layout has an invalid or duplicate entry ID.");
				}
			}
		}

		private static void WriteNew(string destination, byte[] bytes)
		{
			using FileStream fileStream = new FileStream(destination, FileMode.CreateNew, FileAccess.Write, FileShare.None, 4096, FileOptions.WriteThrough);
			fileStream.Write(bytes, 0, bytes.Length);
			fileStream.Flush(flushToDisk: true);
		}

		private static bool IsFileOrDataError(Exception exception)
		{
			if (!(exception is IOException) && !(exception is UnauthorizedAccessException) && !(exception is SerializationException) && !(exception is XmlException) && !(exception is ArgumentException) && !(exception is SecurityException) && !(exception is NotSupportedException))
			{
				return exception is FormatException;
			}
			return true;
		}
	}
	[BepInPlugin("sighsorry.ReferToCompendium", "ReferToCompendium", "1.0.1")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginId = "sighsorry.ReferToCompendium";

		public const string PluginName = "ReferToCompendium";

		public const string PluginVersion = "1.0.1";

		private static ManualLogSource? _log;

		private static LayoutStore? _store;

		private static readonly LayoutState EmptyState = new LayoutState();

		private ConfigEntry<bool> _showHint;

		private ConfigEntry<string> _hintText;

		private Harmony? _harmony;

		private bool _ready;

		private bool _hintFailed;

		internal static LayoutState State => _store?.State ?? EmptyState;

		internal static bool SaveLayout()
		{
			return _store?.Save() ?? false;
		}

		internal static void LogWarning(string message)
		{
			ManualLogSource? log = _log;
			if (log != null)
			{
				log.LogWarning((object)message);
			}
		}

		private void Awake()
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			_log = ((BaseUnityPlugin)this).Logger;
			if (!Application.isBatchMode)
			{
				_showHint = ((BaseUnityPlugin)this).Config.Bind<bool>("Raven hint", "Enabled", true, "Keep a speech hint in front of the compendium raven's beak while the inventory is open. Client only; takes effect immediately.");
				_hintText = ((BaseUnityPlugin)this).Config.Bind<string>("Raven hint", "Text", "", "Custom hint text. Leave empty for the default English/Korean text selected by the game language. Client only.");
				string text = Path.Combine(Application.persistentDataPath, "ReferToCompendium", "layout-shared.json");
				_store = new LayoutStore(text, LogWarning);
				_harmony = new Harmony("sighsorry.ReferToCompendium");
				try
				{
					_harmony.PatchAll(typeof(Plugin).Assembly);
					_ready = true;
					((BaseUnityPlugin)this).Logger.LogInfo((object)("ReferToCompendium 1.0.1: client layout at " + text));
				}
				catch (Exception arg)
				{
					_harmony.UnpatchSelf();
					((BaseUnityPlugin)this).Logger.LogError((object)$"Could not install compendium UI patches: {arg}");
				}
				StatusEffectHud.Initialize(((BaseUnityPlugin)this).Config);
			}
		}

		private void LateUpdate()
		{
			if (!_ready || _hintFailed)
			{
				return;
			}
			try
			{
				string text = (string.IsNullOrWhiteSpace(_hintText.Value) ? Ui("Click for more info\nCaw!", "클릭해서 정보 확인\n까악!") : _hintText.Value);
				RavenHint.Tick(_showHint.Value, text);
			}
			catch (Exception arg)
			{
				_hintFailed = true;
				RavenHint.Dispose();
				LogWarning($"Raven hint disabled for this session after a UI error: {arg}");
			}
		}

		private void OnDestroy()
		{
			_ready = false;
			StatusEffectHud.Shutdown();
			RavenHint.Dispose();
			CompendiumController.Shutdown();
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			_store = null;
			_log = null;
		}

		internal static string Ui(string english, string korean)
		{
			if (Localization.instance == null || !(Localization.instance.GetSelectedLanguage() == "Korean"))
			{
				return english;
			}
			return korean;
		}
	}
	internal static class RavenHint
	{
		private const float Padding = 8f;

		private const float BeakGap = 4f;

		private const float ScreenMargin = 10f;

		private static InventoryGui? _inventory;

		private static Button? _raven;

		private static Canvas? _canvas;

		private static RectTransform? _layer;

		private static RectTransform? _bubble;

		private static TMP_Text? _text;

		private static CanvasGroup? _layerGroup;

		private static CanvasGroup[] _bubbleGroups = Array.Empty<CanvasGroup>();

		private static GameObject? _failedPrefab;

		private static bool _wasOpen;

		private static bool _showing;

		private static bool _warnedMissingButton;

		private static bool _warnedMissingPrefab;

		private static float _nextFind;

		private static float _nextCreate;

		private static float _openedAt;

		private static float _layoutWidth;

		private static float _layoutHeight;

		private static string _currentText = "";

		internal static void Tick(bool enabled, string text)
		{
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			InventoryGui instance = InventoryGui.instance;
			if (_inventory != instance)
			{
				Dispose();
				_inventory = instance;
			}
			if (!enabled || !((Object)(object)instance != (Object)null) || !((Object)(object)Player.m_localPlayer != (Object)null) || !InventoryGui.IsVisible())
			{
				HideImmediately();
				_wasOpen = false;
				return;
			}
			float unscaledTime = Time.unscaledTime;
			if (!_wasOpen)
			{
				_wasOpen = true;
				_openedAt = unscaledTime;
			}
			if (string.IsNullOrWhiteSpace(text) || HasBlockingPanel(instance))
			{
				HideImmediately();
				return;
			}
			if ((Object)(object)_raven == (Object)null && unscaledTime >= _nextFind)
			{
				_nextFind = unscaledTime + 1f;
				_raven = FindRaven(instance);
				if ((Object)(object)_raven == (Object)null && unscaledTime - _openedAt > 5f && !_warnedMissingButton)
				{
					_warnedMissingButton = true;
					Debug.LogWarning((object)"[ReferToCompendium] Could not find the Compendium button's OnOpenTexts listener; the raven hint is unavailable for this inventory UI.");
				}
			}
			if ((Object)(object)_raven == (Object)null || !((Component)_raven).gameObject.activeInHierarchy || !((Selectable)_raven).interactable)
			{
				HideImmediately();
				return;
			}
			if ((Object)(object)_bubble == (Object)null)
			{
				if (unscaledTime < _nextCreate)
				{
					return;
				}
				_nextCreate = unscaledTime + 1f;
				if (!CreateBubble(instance))
				{
					return;
				}
			}
			Vector2 beakPosition = GetBeakPosition();
			UpdateLayout(text, beakPosition);
			if (!_showing || !((Component)_bubble).gameObject.activeSelf)
			{
				_showing = true;
				((Component)_bubble).gameObject.SetActive(true);
			}
			KeepOpaque();
			PositionBubble(beakPosition);
		}

		private static bool HasBlockingPanel(InventoryGui inventory)
		{
			if (!Menu.IsVisible() && !Console.IsVisible() && (!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && (!((Object)(object)TextViewer.instance != (Object)null) || !TextViewer.instance.IsVisible()) && (!((Object)(object)Hud.instance != (Object)null) || !Hud.instance.m_userHidden) && (!((Object)(object)inventory.m_textsDialog != (Object)null) || !((Component)inventory.m_textsDialog).gameObject.activeInHierarchy) && (!((Object)(object)inventory.m_skillsDialog != (Object)null) || !((Component)inventory.m_skillsDialog).gameObject.activeInHierarchy) && (!((Object)(object)inventory.m_trophiesPanel != (Object)null) || !inventory.m_trophiesPanel.activeInHierarchy) && (!((Object)(object)inventory.m_achievementsPanel != (Object)null) || !((Component)inventory.m_achievementsPanel).gameObject.activeInHierarchy) && (!((Object)(object)inventory.m_variantDialog != (Object)null) || !((Component)inventory.m_variantDialog).gameObject.activeInHierarchy))
			{
				if ((Object)(object)inventory.m_splitDialog != (Object)null)
				{
					return inventory.m_splitDialog.IsActive;
				}
				return false;
			}
			return true;
		}

		private static Button? FindRaven(InventoryGui inventory)
		{
			Button[] componentsInChildren = ((Component)inventory).GetComponentsInChildren<Button>(true);
			foreach (Button val in componentsInChildren)
			{
				for (int j = 0; j < ((UnityEventBase)val.onClick).GetPersistentEventCount(); j++)
				{
					if (((UnityEventBase)val.onClick).GetPersistentTarget(j) == (Object)(object)inventory && ((UnityEventBase)val.onClick).GetPersistentMethodName(j) == "OnOpenTexts")
					{
						return val;
					}
				}
			}
			return null;
		}

		private static bool CreateBubble(InventoryGui inventory)
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Expected O, but got Unknown
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Chat.instance == (Object)null || (Object)(object)Chat.instance.m_npcTextBase == (Object)null)
			{
				return false;
			}
			GameObject npcTextBase = Chat.instance.m_npcTextBase;
			if (_failedPrefab == npcTextBase)
			{
				return false;
			}
			Canvas componentInParent = ((Component)inventory).GetComponentInParent<Canvas>();
			_canvas = (((Object)(object)componentInParent != (Object)null) ? componentInParent.rootCanvas : null);
			if ((Object)(object)_canvas == (Object)null)
			{
				return false;
			}
			if ((Object)(object)_layer != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_layer).gameObject);
			}
			GameObject val = new GameObject("ReferToCompendium.RavenHint", new Type[2]
			{
				typeof(RectTransform),
				typeof(CanvasGroup)
			});
			_layer = (RectTransform)val.transform;
			((Transform)_layer).SetParent(((Component)_canvas).transform, false);
			_layer.anchorMin = Vector2.zero;
			_layer.anchorMax = Vector2.one;
			_layer.offsetMin = Vector2.zero;
			_layer.offsetMax = Vector2.zero;
			_layerGroup = val.GetComponent<CanvasGroup>();
			_layerGroup.alpha = 1f;
			_layerGroup.ignoreParentGroups = true;
			_layerGroup.interactable = false;
			_layerGroup.blocksRaycasts = false;
			GameObject val2 = Object.Instantiate<GameObject>(npcTextBase, (Transform)(object)_layer, false);
			((Object)val2).name = "AmbientCompendiumHint";
			Transform transform = val2.transform;
			_bubble = (RectTransform?)(object)((transform is RectTransform) ? transform : null);
			Transform val3 = val2.transform.Find("Text");
			_text = (((Object)(object)val3 != (Object)null) ? ((Component)val3).GetComponent<TMP_Text>() : null);
			if ((Object)(object)_bubble == (Object)null || (Object)(object)_text == (Object)null)
			{
				_failedPrefab = npcTextBase;
				if (!_warnedMissingPrefab)
				{
					_warnedMissingPrefab = true;
					Debug.LogWarning((object)"[ReferToCompendium] Native ambient-speech UI is missing its RectTransform or Text child; raven hint disabled for this UI.");
				}
				Object.Destroy((Object)(object)val);
				_layer = null;
				_layerGroup = null;
				_bubble = null;
				_text = null;
				return false;
			}
			Animator[] componentsInChildren = val2.GetComponentsInChildren<Animator>(true);
			foreach (Animator obj in componentsInChildren)
			{
				((Behaviour)obj).enabled = false;
				obj.runtimeAnimatorController = null;
				Object.Destroy((Object)(object)obj);
			}
			Animation[] componentsInChildren2 = val2.GetComponentsInChildren<Animation>(true);
			foreach (Animation obj2 in componentsInChildren2)
			{
				obj2.Stop();
				((Behaviour)obj2).enabled = false;
				Object.Destroy((Object)(object)obj2);
			}
			Graphic[] componentsInChildren3 = val2.GetComponentsInChildren<Graphic>(true);
			foreach (Graphic obj3 in componentsInChildren3)
			{
				obj3.raycastTarget = false;
				obj3.canvasRenderer.SetAlpha(1f);
			}
			_bubbleGroups = val2.GetComponentsInChildren<CanvasGroup>(true);
			CanvasGroup[] bubbleGroups = _bubbleGroups;
			foreach (CanvasGroup obj4 in bubbleGroups)
			{
				obj4.alpha = 1f;
				obj4.ignoreParentGroups = false;
				obj4.interactable = false;
				obj4.blocksRaycasts = false;
			}
			ContentSizeFitter[] componentsInChildren4 = val2.GetComponentsInChildren<ContentSizeFitter>(true);
			for (int i = 0; i < componentsInChildren4.Length; i++)
			{
				((Behaviour)componentsInChildren4[i]).enabled = false;
			}
			LayoutGroup[] componentsInChildren5 = val2.GetComponentsInChildren<LayoutGroup>(true);
			for (int i = 0; i < componentsInChildren5.Length; i++)
			{
				((Behaviour)componentsInChildren5[i]).enabled = false;
			}
			Transform val4 = val2.transform.Find("Topic");
			if ((Object)(object)val4 != (Object)null)
			{
				((Component)val4).gameObject.SetActive(false);
			}
			RectTransform? bubble = _bubble;
			RectTransform? bubble2 = _bubble;
			Vector2 val5 = default(Vector2);
			((Vector2)(ref val5))..ctor(0.5f, 0.5f);
			bubble2.anchorMax = val5;
			bubble.anchorMin = val5;
			_bubble.pivot = new Vector2(0.5f, 0.5f);
			((Transform)_bubble).localScale = Vector3.one;
			((Transform)_bubble).localRotation = Quaternion.identity;
			_text.enableAutoSizing = false;
			_text.textWrappingMode = (TextWrappingModes)1;
			_text.overflowMode = (TextOverflowModes)1;
			_text.alignment = (TextAlignmentOptions)516;
			_text.maxVisibleCharacters = int.MaxValue;
			_text.maxVisibleWords = int.MaxValue;
			_text.maxVisibleLines = int.MaxValue;
			_text.alpha = 1f;
			_layoutWidth = (_layoutHeight = 0f);
			_currentText = "";
			_showing = false;
			val2.SetActive(false);
			return true;
		}

		private static void KeepOpaque()
		{
			if ((Object)(object)_layerGroup != (Object)null)
			{
				_layerGroup.alpha = 1f;
			}
			CanvasGroup[] bubbleGroups = _bubbleGroups;
			foreach (CanvasGroup val in bubbleGroups)
			{
				if ((Object)(object)val != (Object)null)
				{
					val.alpha = 1f;
				}
			}
		}

		private static Vector2 GetBeakPosition()
		{
			//IL_001c: 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)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)(((Object)(object)((Selectable)_raven).targetGraphic != (Object)null) ? ((object)((Selectable)_raven).targetGraphic.rectTransform) : ((object)(RectTransform)((Component)_raven).transform));
			Rect rect = val.rect;
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(Mathf.Lerp(((Rect)(ref rect)).xMin, ((Rect)(ref rect)).xMax, 0.1f), Mathf.Lerp(((Rect)(ref rect)).yMin, ((Rect)(ref rect)).yMax, 0.72f), 0f);
			return Vector2.op_Implicit(((Transform)_layer).InverseTransformPoint(((Transform)val).TransformPoint(val2)));
		}

		private static void UpdateLayout(string text, Vector2 beak)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_layer == (Object)null || (Object)(object)_bubble == (Object)null || (Object)(object)_text == (Object)null)
			{
				return;
			}
			Rect rect = _layer.rect;
			float num = ((Rect)(ref rect)).width - 20f;
			float num2 = beak.x - 4f;
			rect = _layer.rect;
			float num3 = Mathf.Max(1f, Mathf.Min(num, num2 - (((Rect)(ref rect)).xMin + 10f)));
			rect = _layer.rect;
			float num4 = Mathf.Max(1f, ((Rect)(ref rect)).height - 20f);
			if (!(_currentText == text) || !Mathf.Approximately(_layoutWidth, num3) || !Mathf.Approximately(_layoutHeight, num4))
			{
				_currentText = text;
				_layoutWidth = num3;
				_layoutHeight = num4;
				_text.text = text;
				float num5 = Mathf.Min(280f, num3);
				float num6 = ((_text.fontSize > 0f) ? _text.fontSize : 20f);
				float num7 = Mathf.Max(1f, num5 - 16f);
				float num8 = _text.GetPreferredValues(text, num7, float.PositiveInfinity).y;
				if (float.IsNaN(num8) || float.IsInfinity(num8))
				{
					num8 = num6 * 3f;
				}
				float num9 = Mathf.Min(num4, Mathf.Max(num6 * 1.35f, num8) + 16f);
				_bubble.SetSizeWithCurrentAnchors((Axis)0, num5);
				_bubble.SetSizeWithCurrentAnchors((Axis)1, num9);
				RectTransform rectTransform = _text.rectTransform;
				rectTransform.anchorMin = Vector2.zero;
				rectTransform.anchorMax = Vector2.one;
				rectTransform.offsetMin = new Vector2(8f, 8f);
				rectTransform.offsetMax = new Vector2(-8f, -8f);
			}
		}

		private static void PositionBubble(Vector2 beak)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_raven == (Object)null) && !((Object)(object)_layer == (Object)null) && !((Object)(object)_bubble == (Object)null) && !((Object)(object)_canvas == (Object)null))
			{
				Rect rect = _bubble.rect;
				float width = ((Rect)(ref rect)).width;
				rect = _bubble.rect;
				float height = ((Rect)(ref rect)).height;
				Rect rect2 = _layer.rect;
				float num = beak.x - 4f - width * 0.5f;
				float y = beak.y;
				num = Mathf.Clamp(num, ((Rect)(ref rect2)).xMin + 10f + width * 0.5f, ((Rect)(ref rect2)).xMax - 10f - width * 0.5f);
				y = Mathf.Clamp(y, ((Rect)(ref rect2)).yMin + 10f + height * 0.5f, ((Rect)(ref rect2)).yMax - 10f - height * 0.5f);
				((Transform)_bubble).localPosition = new Vector3(num, y, 0f);
			}
		}

		private static void HideImmediately()
		{
			_showing = false;
			if ((Object)(object)_bubble != (Object)null)
			{
				((Component)_bubble).gameObject.SetActive(false);
			}
		}

		internal static void Dispose()
		{
			if ((Object)(object)_layer != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_layer).gameObject);
			}
			_inventory = null;
			_raven = null;
			_canvas = null;
			_layer = null;
			_bubble = null;
			_text = null;
			_layerGroup = null;
			_bubbleGroups = Array.Empty<CanvasGroup>();
			_failedPrefab = null;
			_wasOpen = (_showing = false);
			_warnedMissingButton = (_warnedMissingPrefab = false);
			_nextFind = (_nextCreate = (_openedAt = 0f));
			_layoutWidth = (_layoutHeight = 0f);
			_currentText = "";
		}
	}
	internal sealed class StatusEffectFilterRules
	{
		private readonly HashSet<string> _keys = new HashSet<string>(StringComparer.Ordinal);

		internal bool IsEmpty => _keys.Count == 0;

		internal StatusEffectFilterRules(string? value)
		{
			string[] array = (value ?? "").Split(new char[4] { ',', ';', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length != 0)
				{
					_keys.Add(text);
				}
			}
		}

		internal bool Hides(string? internalName, string? nameToken)
		{
			if (string.IsNullOrEmpty(internalName) || !_keys.Contains(internalName))
			{
				if (!string.IsNullOrEmpty(nameToken))
				{
					return _keys.Contains(nameToken);
				}
				return false;
			}
			return true;
		}

		internal static string NormalizeInternalName(string? name)
		{
			string text = (name ?? "").Trim();
			if (text.EndsWith("(Clone)", StringComparison.Ordinal))
			{
				text = text.Substring(0, text.Length - "(Clone)".Length).TrimEnd(Array.Empty<char>());
			}
			return text;
		}
	}
	internal static class StatusEffectHud
	{
		private sealed class EffectName
		{
			internal readonly string Name;

			internal EffectName(string name)
			{
				Name = StatusEffectFilterRules.NormalizeInternalName(name);
			}
		}

		private static ConfigEntry<bool>? _singleColumn;

		private static ConfigEntry<Vector2>? _position;

		private static ConfigEntry<float>? _scale;

		private static ConfigEntry<float>? _spacing;

		private static ConfigEntry<string>? _hiddenEffects;

		private static volatile StatusEffectFilterRules _rules = new StatusEffectFilterRules("");

		private static ConditionalWeakTable<StatusEffect, EffectName> _names = new ConditionalWeakTable<StatusEffect, EffectName>();

		private static Harmony? _harmony;

		private static bool _ready;

		private static bool _filterFailed;

		private static bool _layoutFailed;

		internal static void Initialize(ConfigFile config)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Expected O, but got Unknown
			//IL_01c3: Expected O, but got Unknown
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Expected O, but got Unknown
			try
			{
				_singleColumn = config.Bind<bool>("Status effects", "Single column", true, "Arrange HUD status effects in one vertical column. Client only. Leave off when another HUD mod controls the layout. Changes apply on the next HUD update.");
				_position = config.Bind<Vector2>("Status effects", "Position", new Vector2(-40f, -250f), "Position of the column's upper-right corner, relative to the HUD's upper-right corner. Fixed UI coordinates; does not follow a moved minimap. Also used in no-map mode.");
				_scale = config.Bind<float>("Status effects", "Scale", 0.8f, new ConfigDescription("Scale of each status effect row. Client only. Row spacing is adjusted separately.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>()));
				_spacing = config.Bind<float>("Status effects", "Row spacing", 40f, new ConfigDescription("Vertical distance between rows in UI units. Client only.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 150f), Array.Empty<object>()));
				_hiddenEffects = config.Bind<string>("Status effects", "Hidden effects", "", "Hide these effects from the HUD only, even when Single column is off. Separate internal names or raw localization tokens with commas, semicolons, or newlines. Exact, case-sensitive matching; example: Rested,Resting. Empty shows all effects. Gameplay and Compendium information are unchanged.");
				_hiddenEffects.SettingChanged += HiddenEffectsChanged;
				_rules = new StatusEffectFilterRules(_hiddenEffects.Value);
				_filterFailed = false;
				_layoutFailed = false;
				_harmony = new Harmony("sighsorry.ReferToCompendium.StatusEffects");
				MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(Hud), "UpdateStatusEffects", new Type[1] { typeof(List<StatusEffect>) }, (Type[])null) ?? throw new MissingMethodException("Hud.UpdateStatusEffects(List<StatusEffect>)");
				MethodInfo methodInfo2 = AccessTools.DeclaredMethod(typeof(Hud), "OnDestroy", Type.EmptyTypes, (Type[])null) ?? throw new MissingMethodException("Hud.OnDestroy()");
				_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(StatusEffectHud), "Prefix", (Type[])null), new HarmonyMethod(typeof(StatusEffectHud), "Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(StatusEffectHud), "HudDestroyed", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_ready = true;
			}
			catch (Exception ex)
			{
				Shutdown();
				Plugin.LogWarning("Status effect HUD could not initialize; Compendium features are unaffected: " + ex);
			}
		}

		private static void HiddenEffectsChanged(object sender, EventArgs args)
		{
			_rules = new StatusEffectFilterRules(_hiddenEffects?.Value);
		}

		[HarmonyAfter(new string[] { "Azumatt.StatusEffectFilter" })]
		[HarmonyPriority(0)]
		internal static void Prefix(ref List<StatusEffect> statusEffects)
		{
			if (!_ready || _filterFailed || statusEffects == null)
			{
				return;
			}
			StatusEffectFilterRules rules = _rules;
			if (rules.IsEmpty)
			{
				return;
			}
			try
			{
				List<StatusEffect> list = null;
				for (int i = 0; i < statusEffects.Count; i++)
				{
					StatusEffect val = statusEffects[i];
					bool flag = false;
					if (val != null)
					{
						string name = _names.GetValue(val, ReadName).Name;
						flag = rules.Hides(name, val.m_name);
					}
					if (flag)
					{
						if (list == null)
						{
							list = new List<StatusEffect>(statusEffects.Count);
							for (int j = 0; j < i; j++)
							{
								list.Add(statusEffects[j]);
							}
						}
					}
					else
					{
						list?.Add(val);
					}
				}
				if (list != null)
				{
					statusEffects = list;
				}
			}
			catch (Exception ex)
			{
				_filterFailed = true;
				Plugin.LogWarning("Status effect filtering disabled for this session after an error: " + ex);
			}
		}

		private static EffectName ReadName(StatusEffect effect)
		{
			return new EffectName(((Object)effect).name);
		}

		[HarmonyAfter(new string[] { "shudnal.MyLittleUI", "com.ttolg.compactstatuseffects" })]
		[HarmonyPriority(0)]
		internal static void Postfix(Hud __instance, List<RectTransform> ___m_statusEffects)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			if (!_ready || _layoutFailed)
			{
				return;
			}
			try
			{
				Vector2 value = _position.Value;
				if (!Finite(value.x))
				{
					value.x = -40f;
				}
				if (!Finite(value.y))
				{
					value.y = -250f;
				}
				float value2 = _scale.Value;
				float value3 = _spacing.Value;
				StatusEffectLayout.Apply(__instance, ___m_statusEffects, _singleColumn.Value, value, Finite(value2) ? Mathf.Clamp(value2, 0.5f, 2f) : 0.8f, Finite(value3) ? Mathf.Clamp(value3, 20f, 150f) : 40f);
			}
			catch (Exception ex)
			{
				_layoutFailed = true;
				RestoreLayout();
				Plugin.LogWarning("Single-column layout disabled for this session after an error; filtering and Compendium features remain available: " + ex);
			}
		}

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

		internal static void HudDestroyed(Hud __instance)
		{
			try
			{
				StatusEffectLayout.Release(__instance);
			}
			catch (Exception ex)
			{
				Plugin.LogWarning("Could not restore status effect layout during HUD cleanup: " + ex);
			}
			_names = new ConditionalWeakTable<StatusEffect, EffectName>();
		}

		private static void RestoreLayout()
		{
			try
			{
				StatusEffectLayout.Shutdown();
			}
			catch (Exception ex)
			{
				Plugin.LogWarning("Could not restore status effect layout: " + ex);
			}
		}

		internal static void Shutdown()
		{
			_ready = false;
			if (_hiddenEffects != null)
			{
				_hiddenEffects.SettingChanged -= HiddenEffectsChanged;
			}
			RestoreLayout();
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			_harmony = null;
			_names = new ConditionalWeakTable<StatusEffect, EffectName>();
			_rules = new StatusEffectFilterRules("");
			_singleColumn = null;
			_position = null;
			_scale = null;
			_spacing = null;
			_hiddenEffects = null;
		}
	}
	internal static class StatusEffectLayout
	{
		private sealed class LayoutOwner
		{
			internal readonly RectTransform NativeRoot;

			internal bool Blocked;

			private RectTransform? _container;

			private readonly Dictionary<RectTransform, RowSnapshot> _rows = new Dictionary<RectTransform, RowSnapshot>();

			private readonly HashSet<RectTransform> _currentRows = new HashSet<RectTransform>();

			private readonly List<RectTransform> _removedRows = new List<RectTransform>();

			private readonly List<RowSnapshot> _restoreOrder = new List<RowSnapshot>();

			internal LayoutOwner(RectTransform nativeRoot)
			{
				NativeRoot = nativeRoot;
			}

			internal void Apply(List<RectTransform> rows, RectTransform parent, Vector2 position, float scale, float spacing)
			{
				//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
				//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
				//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
				//IL_0209: Unknown result type (might be due to invalid IL or missing references)
				//IL_0210: Expected O, but got Unknown
				//IL_022f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0239: Expected O, but got Unknown
				//IL_025b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0271: Unknown result type (might be due to invalid IL or missing references)
				//IL_0281: Unknown result type (might be due to invalid IL or missing references)
				//IL_0291: Unknown result type (might be due to invalid IL or missing references)
				_currentRows.Clear();
				foreach (RectTransform row in rows)
				{
					if ((Object)(object)row != (Object)null)
					{
						_currentRows.Add(row);
					}
				}
				_removedRows.Clear();
				foreach (KeyValuePair<RectTransform, RowSnapshot> row2 in _rows)
				{
					if ((Object)(object)row2.Key == (Object)null || !_currentRows.Contains(row2.Key))
					{
						_removedRows.Add(row2.Key);
					}
				}
				foreach (RectTransform removedRow in _removedRows)
				{
					_rows[removedRow].Restore(_container);
					_rows.Remove(removedRow);
				}
				_removedRows.Clear();
				foreach (RectTransform row3 in rows)
				{
					if ((Object)(object)row3 == (Object)null)
					{
						continue;
					}
					if (_rows.TryGetValue(row3, out RowSnapshot value))
					{
						if (!value.Valid || (Object)(object)((Transform)row3).parent != (Object)(object)_container)
						{
							Stop("A status effect row was replaced or moved by another UI owner.");
							return;
						}
						continue;
					}
					if ((Object)(object)((Transform)row3).parent != (Object)(object)NativeRoot || !RowSnapshot.TryCapture(row3, out RowSnapshot snapshot))
					{
						Stop("A status effect row does not have the expected native UI structure.");
						return;
					}
					_rows.Add(row3, snapshot);
				}
				if ((Object)(object)_container == (Object)null)
				{
					GameObject val = new GameObject("ReferToCompendium.StatusEffectColumn", new Type[2]
					{
						typeof(RectTransform),
						typeof(LayoutElement)
					});
					val.layer = ((Component)NativeRoot).gameObject.layer;
					_container = (RectTransform)val.transform;
					((Transform)_container).SetParent((Transform)(object)NativeRoot, false);
					_container.anchorMin = new Vector2(0.5f, 0.5f);
					_container.anchorMax = _container.anchorMin;
					_container.pivot = Vector2.one;
					_container.sizeDelta = Vector2.zero;
					val.GetComponent<LayoutElement>().ignoreLayout = true;
				}
				Rect rect = parent.rect;
				float num = ((Rect)(ref rect)).xMax + position.x;
				rect = parent.rect;
				Vector3 val2 = default(Vector3);
				((Vector3)(ref val2))..ctor(num, ((Rect)(ref rect)).yMax + position.y, ((Transform)NativeRoot).localPosition.z);
				((Transform)_container).localPosition = ((Transform)NativeRoot).InverseTransformPoint(((Transform)parent).TransformPoint(val2));
				for (int i = 0; i < rows.Count; i++)
				{
					RectTransform val3 = rows[i];
					if (!((Object)(object)val3 == (Object)null))
					{
						_rows[val3].Apply(_container, i, scale, spacing);
					}
				}
			}

			internal void Stop(string reason)
			{
				Restore();
				Blocked = true;
				Plugin.LogWarning("Status effect column left to the original UI: " + reason + " Toggle Single column off and on after resolving the UI conflict to retry.");
			}

			internal void Restore()
			{
				_restoreOrder.Clear();
				_restoreOrder.AddRange(_rows.Values);
				_restoreOrder.Sort(delegate(RowSnapshot left, RowSnapshot right)
				{
					int siblingIndex = left.SiblingIndex;
					return siblingIndex.CompareTo(right.SiblingIndex);
				});
				foreach (RowSnapshot item in _restoreOrder)
				{
					item.Restore(_container);
				}
				_restoreOrder.Clear();
				_rows.Clear();
				_currentRows.Clear();
				_removedRows.Clear();
				if ((Object)(object)_container != (Object)null)
				{
					if (((Transform)_container).childCount == 0)
					{
						Object.Destroy((Object)(object)((Component)_container).gameObject);
					}
					_container = null;
				}
			}
		}

		private sealed class RowSnapshot
		{
			private const float Width = 250f;

			private const float Height = 44f;

			private readonly RectTransform _row;

			private readonly Transform _parent;

			internal readonly int SiblingIndex;

			private readonly RectSnapshot _rowRect;

			private readonly RectSnapshot _iconRect;

			private readonly RectSnapshot _cooldownRect;

			private readonly RectSnapshot _nameRect;

			private readonly RectSnapshot _timeRect;

			private readonly TextSnapshot _nameStyle;

			private readonly TextSnapshot _timeStyle;

			internal bool Valid
			{
				get
				{
					if ((Object)(object)_row != (Object)null && (Object)(object)_iconRect.Target != (Object)null && (Object)(object)_cooldownRect.Target != (Object)null && (Object)(object)_nameStyle.Target != (Object)null)
					{
						return (Object)(object)_timeStyle.Target != (Object)null;
					}
					return false;
				}
			}

			private RowSnapshot(RectTransform row, RectTransform icon, RectTransform cooldown, TMP_Text name, TMP_Text time)
			{
				_row = row;
				_parent = ((Transform)row).parent;
				SiblingIndex = ((Transform)row).GetSiblingIndex();
				_rowRect = new RectSnapshot(row);
				_iconRect = new RectSnapshot(icon);
				_cooldownRect = new RectSnapshot(cooldown);
				_nameRect = new RectSnapshot(name.rectTransform);
				_timeRect = new RectSnapshot(time.rectTransform);
				_nameStyle = new TextSnapshot(name);
				_timeStyle = new TextSnapshot(time);
			}

			internal static bool TryCapture(RectTransform row, out RowSnapshot snapshot)
			{
				snapshot = null;
				Transform obj = ((Transform)row).Find("Icon");
				RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null);
				Transform obj2 = ((Transform)row).Find("Cooldown");
				RectTransform val2 = (RectTransform)(object)((obj2 is RectTransform) ? obj2 : null);
				Transform val3 = ((Transform)row).Find("Name");
				Transform val4 = ((Transform)row).Find("TimeText");
				TMP_Text val5 = (((Object)(object)val3 != (Object)null) ? ((Component)val3).GetComponent<TMP_Text>() : null);
				TMP_Text val6 = (((Object)(object)val4 != (Object)null) ? ((Component)val4).GetComponent<TMP_Text>() : null);
				if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val5 == (Object)null || (Object)(object)val6 == (Object)null)
				{
					return false;
				}
				snapshot = new RowSnapshot(row, val, val2, val5, val6);
				return true;
			}

			internal void Apply(RectTransform container, int index, float scale, float spacing)
			{
				//IL_0032: 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_0052: 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_008c: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)((Transform)_row).parent != (Object)(object)container)
				{
					((Transform)_row).SetParent((Transform)(object)container, false);
				}
				((Transform)_row).SetSiblingIndex(index);
				_row.anchorMin = Vector2.one;
				_row.anchorMax = Vector2.one;
				_row.pivot = Vector2.one;
				_row.sizeDelta = new Vector2(250f, 44f);
				_row.anchoredPosition3D = new Vector3(0f, (float)(-index) * spacing, 0f);
				((Transform)_row).localScale = Vector3.one * scale;
				((Transform)_row).localRotation = Quaternion.identity;
				Place(_iconRect.Target, 0f, -4f, 36f, 36f);
				Place(_cooldownRect.Target, 0f, -4f, 36f, 36f);
				bool activeSelf = ((Component)_timeStyle.Target).gameObject.activeSelf;
				Place(_nameRect.Target, 46f, activeSelf ? (-1f) : 0f, 204f, activeSelf ? 24f : 44f);
				Place(_timeRect.Target, 46f, -25f, 204f, 18f);
				_nameStyle.Apply(18f);
				_timeStyle.Apply(14f);
			}

			internal void Restore(RectTransform? container)
			{
				if (!((Object)(object)_row == (Object)null) && !((Object)(object)container == (Object)null) && !((Object)(object)((Transform)_row).parent != (Object)(object)container) && !((Object)(object)_parent == (Object)null))
				{
					((Transform)_row).SetParent(_parent, false);
					((Transform)_row).SetSiblingIndex(SiblingIndex);
					_rowRect.Restore();
					_iconRect.Restore();
					_cooldownRect.Restore();
					_nameRect.Restore();
					_timeRect.Restore();
					_nameStyle.Restore();
					_timeStyle.Restore();
				}
			}

			private static void Place(RectTransform rect, float x, float y, float width, float height)
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: 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_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				rect.anchorMin = new Vector2(0f, 1f);
				rect.anchorMax = rect.anchorMin;
				rect.pivot = new Vector2(0f, 1f);
				rect.anchoredPosition3D = new Vector3(x, y, 0f);
				rect.sizeDelta = new Vector2(width, height);
				((Transform)rect).localScale = Vector3.one;
				((Transform)rect).localRotation = Quaternion.identity;
			}
		}

		private sealed class RectSnapshot
		{
			internal readonly RectTransform Target;

			private readonly Vector2 _anchorMin;

			private readonly Vector2 _anchorMax;

			private readonly Vector2 _pivot;

			private readonly Vector2 _size;

			private readonly Vector3 _position;

			private readonly Vector3 _scale;

			private readonly Quaternion _rotation;

			internal RectSnapshot(RectTransform target)
			{
				//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)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//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_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				Target = target;
				_anchorMin = target.anchorMin;
				_anchorMax = target.anchorMax;
				_pivot = target.pivot;
				_size = target.sizeDelta;
				_position = target.anchoredPosition3D;
				_scale = ((Transform)target).localScale;
				_rotation = ((Transform)target).localRotation;
			}

			internal void Restore()
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)Target == (Object)null))
				{
					Target.anchorMin = _anchorMin;
					Target.anchorMax = _anchorMax;
					Target.pivot = _pivot;
					Target.sizeDelta = _size;
					Target.anchoredPosition3D = _position;
					((Transform)Target).localScale = _scale;
					((Transform)Target).localRotation = _rotation;
				}
			}
		}

		private sealed class TextSnapshot
		{
			internal readonly TMP_Text Target;

			private readonly float _size;

			private readonly float _sizeMin;

			private readonly float _sizeMax;

			private readonly bool _autoSize;

			private readonly TextAlignmentOptions _alignment;

			private readonly TextWrappingModes _wrapping;

			private readonly TextOverflowModes _overflow;

			private readonly Vector4 _margin;

			internal TextSnapshot(TMP_Text target)
			{
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				Target = target;
				_size = target.fontSize;
				_sizeMin = target.fontSizeMin;
				_sizeMax = target.fontSizeMax;
				_autoSize = target.enableAutoSizing;
				_alignment = target.alignment;
				_wrapping = target.textWrappingMode;
				_overflow = target.overflowMode;
				_margin = target.margin;
			}

			internal void Apply(float fontSize)
			{
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				Target.enableAutoSizing = false;
				Target.fontSize = fontSize;
				Target.fontSizeMin = fontSize;
				Target.fontSizeMax = fontSize;
				Target.alignment = (TextAlignmentOptions)4097;
				Target.textWrappingMode = (TextWrappingModes)0;
				Target.overflowMode = (TextOverflowModes)1;
				Target.margin = Vector4.zero;
			}

			internal void Restore()
			{
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_0077: Unknown result type (might be due to invalid IL or missing references)
				//IL_0088: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)Target == (Object)null))
				{
					Target.enableAutoSizing = false;
					Target.fontSize = _size;
					Target.fontSizeMin = _sizeMin;
					Target.fontSizeMax = _sizeMax;
					Target.alignment = _alignment;
					Target.textWrappingMode = _wrapping;
					Target.overflowMode = _overflow;
					Target.margin = _margin;
					Target.enableAutoSizing = _autoSize;
				}
			}
		}

		private static readonly Dictionary<Hud, LayoutOwner> Owners = new Dictionary<Hud, LayoutOwner>();

		private static readonly List<Hud> DeadOwners = new List<Hud>();

		internal static void Apply(Hud hud, List<RectTransform> rows, bool enabled, Vector2 position, float scale, float spacing)
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			RemoveDestroyedOwners();
			if ((Object)(object)hud == (Object)null)
			{
				return;
			}
			if (!enabled)
			{
				Release(hud);
				return;
			}
			RectTransform statusEffectListRoot = hud.m_statusEffectListRoot;
			if (Owners.TryGetValue(hud, out LayoutOwner value) && (Object)(object)value.NativeRoot != (Object)(object)statusEffectListRoot)
			{
				Release(hud);
				value = null;
			}
			if (value == null)
			{
				value = new LayoutOwner(statusEffectListRoot);
				Owners.Add(hud, value);
			}
			if (value.Blocked)
			{
				return;
			}
			if (!((Object)(object)statusEffectListRoot == (Object)null))
			{
				Transform parent = ((Transform)statusEffectListRoot).parent;
				RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
				if (val != null)
				{
					if (!Finite(position.x) || !Finite(position.y))
					{
						((Vector2)(ref position))..ctor(-40f, -250f);
					}
					if (!Finite(scale) || scale <= 0f)
					{
						scale = 0.8f;
					}
					if (!Finite(spacing) || spacing <= 0f)
					{
						spacing = 40f;
					}
					value.Apply(rows, val, position, scale, spacing);
					return;
				}
			}
			value.Stop("The status effect root has no UI parent.");
		}

		internal static void Release(Hud hud)
		{
			if (hud != null && Owners.TryGetValue(hud, out LayoutOwner value))
			{
				value.Restore();
				Owners.Remove(hud);
			}
		}

		internal static void Shutdown()
		{
			foreach (LayoutOwner value in Owners.Values)
			{
				value.Restore();
			}
			Owners.Clear();
			DeadOwners.Clear();
		}

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

		private static void RemoveDestroyedOwners()
		{
			DeadOwners.Clear();
			foreach (KeyValuePair<Hud, LayoutOwner> owner in Owners)
			{
				if ((Object)(object)owner.Key == (Object)null)
				{
					DeadOwners.Add(owner.Key);
				}
			}
			foreach (Hud deadOwner in DeadOwners)
			{
				Release(deadOwner);
			}
			DeadOwners.Clear();
		}
	}
}