Decompiled source of CharacterSidebar v0.1.2

BepInEx\plugins\OstranautsSidebar\OstranautsSidebar.dll

Decompiled 11 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Ostranauts.Core;
using Ostranauts.UI.CrewBar;
using Ostranauts.UI.MegaToolTip;
using OstranautsSidebar.Core;
using OstranautsSidebar.Data;
using OstranautsSidebar.UI;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.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 OstranautsSidebar
{
	[BepInPlugin("com.ostranauts.sidebar", "Character Sidebar", "0.1.2")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		internal static Plugin Instance;

		internal static ConfigEntry<float> PanelWidth;

		internal static ConfigEntry<float> BottomOffset;

		internal static ConfigEntry<float> ReferenceHeight;

		internal static ConfigEntry<bool> StartVisible;

		private void Awake()
		{
			//IL_00b1: 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_00c2: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			PanelWidth = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "PanelWidth", 195f, "Sidebar width, in 1080p-reference pixels.");
			BottomOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "BottomOffset", 88f, "Fallback bottom gap (reference pixels) used only if the vanilla HUD bar can't be measured. Normally the panel pins itself to the actual bar height.");
			ReferenceHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "ReferenceHeight", 720f, "Canvas reference height. Lower = larger UI/fonts; raise if the panel feels too big.");
			StartVisible = ((BaseUnityPlugin)this).Config.Bind<bool>("Behaviour", "StartVisible", true, "Whether the panel is shown when a game loads (toggle anytime with the side tab).");
			Log.LogInfo((object)"Character Sidebar v0.1.2 loading...");
			GameObject val = new GameObject("OstranautsSidebarController");
			val.AddComponent<SidebarController>();
			Object.DontDestroyOnLoad((Object)val);
			Log.LogInfo((object)"SidebarController bootstrapped.");
		}

		private void OnDestroy()
		{
			SidebarController.Instance?.Destroy();
		}
	}
	internal static class PluginInfo
	{
		public const string GUID = "com.ostranauts.sidebar";

		public const string NAME = "Character Sidebar";

		public const string VERSION = "0.1.2";
	}
}
namespace OstranautsSidebar.UI
{
	public class RowTooltip : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		public string Title = string.Empty;

		public string Body = string.Empty;

		public void OnPointerEnter(PointerEventData eventData)
		{
			if (!string.IsNullOrEmpty(Title) || !string.IsNullOrEmpty(Body))
			{
				SidebarTooltip.Instance?.Show(Title, Body);
			}
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			SidebarTooltip.Instance?.Hide();
		}
	}
	public class SidebarPanel : MonoBehaviour
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__41_0;

			internal void <BuildToggleTab>b__41_0()
			{
				SidebarController.Instance?.ToggleVisibility();
			}
		}

		private static readonly Color BgColor = Hex("#121218");

		private static readonly Color HeaderBgColor = Hex("#14141e");

		private static readonly Color SectionBgColor = Hex("#141420");

		private static readonly Color BorderColor = Hex("#1e1e2e");

		private static readonly Color TextDefault = Hex("#b0a898");

		private static readonly Color TextDim = Hex("#505068");

		private static readonly Color TextHeader = Hex("#d0c8b8");

		private static readonly Color TextSectionTitle = Hex("#505070");

		private static readonly Color SkillLearnedText = Hex("#b0a898");

		private static readonly Color SkillTrainingText = Hex("#505068");

		private static readonly Color TraitPosBg = Hex("#121e12");

		private static readonly Color TraitPosBorder = Hex("#1e2e1e");

		private static readonly Color TraitPosText = Hex("#4a7a4a");

		private static readonly Color TraitNegBg = Hex("#1e1212");

		private static readonly Color TraitNegBorder = Hex("#2e1e1e");

		private static readonly Color TraitNegText = Hex("#7a4a4a");

		private static readonly Color TraitNeuText = Hex("#505070");

		private static readonly Color DotWarning = Hex("#b08028");

		private static readonly Color DotCritical = Hex("#a02828");

		private static readonly Color CondWarningText = Hex("#907840");

		private static readonly Color CondCriticalText = Hex("#905050");

		private static readonly Color AliveDot = Hex("#3aaa5a");

		private static readonly Color FooterText = Hex("#252535");

		private Text? _charNameText;

		private Transform? _skillsContent;

		private Transform? _skillTrainingContent;

		private GameObject? _skillTrainingSection;

		private Transform? _traitTrainingContent;

		private GameObject? _traitTrainingSection;

		private Transform? _traitsContent;

		private Transform? _conditionsContent;

		private GameObject? _conditionsSection;

		private GameObject? _canvasRoot;

		private Canvas? _canvas;

		private RectTransform? _rt;

		private RectTransform? _tabRect;

		private Text? _tabLabel;

		private static readonly Vector3[] _corners = (Vector3[])(object)new Vector3[4];

		private float _heightFraction = 1f;

		private string _sigSkills = "";

		private string _sigTrainSkills = "";

		private string _sigTraits = "";

		private string _sigTrainTraits = "";

		private string _sigConds = "";

		private static Sprite? _gridSprite;

		private static Sprite? _gradientSprite;

		private static Sprite? _fadeSprite;

		public Canvas? Canvas => _canvas;

		public static SidebarPanel Create()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CreateOwnCanvas();
			GameObject val2 = new GameObject("OstranautsSidebarPanel");
			val2.transform.SetParent(val.transform, false);
			SidebarPanel sidebarPanel = val2.AddComponent<SidebarPanel>();
			sidebarPanel._canvasRoot = val;
			sidebarPanel.Build(val.GetComponent<Canvas>());
			sidebarPanel.BuildToggleTab(val.transform);
			SidebarTooltip.Create(val.transform);
			return sidebarPanel;
		}

		private void BuildToggleTab(Transform canvas)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0034: 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_0068: 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_00a2: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			GameObject val = new GameObject("OstranautsSidebarTab");
			val.transform.SetParent(canvas, false);
			_tabRect = val.AddComponent<RectTransform>();
			_tabRect.anchorMin = new Vector2(1f, 0f);
			_tabRect.anchorMax = new Vector2(1f, 0f);
			_tabRect.pivot = new Vector2(1f, 0.5f);
			_tabRect.sizeDelta = new Vector2(16f, 64f);
			_tabRect.anchoredPosition = new Vector2(0f - Plugin.PanelWidth.Value, 0f);
			AddImage(val, HeaderBgColor);
			ButtonClickedEvent onClick = val.AddComponent<Button>().onClick;
			object obj = <>c.<>9__41_0;
			if (obj == null)
			{
				UnityAction val2 = delegate
				{
					SidebarController.Instance?.ToggleVisibility();
				};
				<>c.<>9__41_0 = val2;
				obj = (object)val2;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
			GameObject val3 = MakeRect("TabLabel", val.transform);
			RectTransform component = val3.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			_tabLabel = AddText(val3, "◀\nS\nT\nA\nT\nS", 9, TextSectionTitle, (FontStyle)0);
			_tabLabel.alignment = (TextAnchor)4;
		}

		public void SetHeightFraction(float frac)
		{
			_heightFraction = Mathf.Clamp(frac, 0.1f, 1f);
			ApplyGeometry();
		}

		public void ApplyGeometry()
		{
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_rt == (Object)null)
			{
				return;
			}
			float num = Plugin.BottomOffset.Value;
			RectTransform val = TryGetCrewBarRect();
			if ((Object)(object)val != (Object)null && (Object)(object)_canvas != (Object)null)
			{
				val.GetWorldCorners(_corners);
				Canvas componentInParent = ((Component)val).GetComponentInParent<Canvas>();
				Vector2 val2 = RectTransformUtility.WorldToScreenPoint(((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) ? componentInParent.worldCamera : null, _corners[1]);
				float scaleFactor = _canvas.scaleFactor;
				if (scaleFactor > 0f)
				{
					num = val2.y / scaleFactor;
				}
			}
			float num2 = (((Object)(object)_canvas != (Object)null && _canvas.scaleFactor > 0f) ? ((float)Screen.height / _canvas.scaleFactor) : ((float)Screen.height));
			float num3 = Mathf.Max(0f, num2 - num);
			float num4 = num3 * (1f - _heightFraction);
			float value = Plugin.PanelWidth.Value;
			_rt.offsetMin = new Vector2(0f - value, num);
			_rt.offsetMax = new Vector2(0f, 0f - num4);
			if ((Object)(object)_tabRect != (Object)null)
			{
				_tabRect.anchoredPosition = new Vector2(_tabRect.anchoredPosition.x, num + num3 / 6f);
			}
		}

		private static RectTransform? TryGetCrewBarRect()
		{
			try
			{
				GUICrewStatus instance = MonoSingleton<GUICrewStatus>.Instance;
				return ((Object)(object)instance != (Object)null) ? ((Component)instance).GetComponent<RectTransform>() : null;
			}
			catch (Exception)
			{
				return null;
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)_canvasRoot != (Object)null)
			{
				Object.Destroy((Object)(object)_canvasRoot);
			}
		}

		private void Build(Canvas rootCanvas)
		{
			//IL_0033: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: 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)
			_canvas = rootCanvas;
			float value = Plugin.PanelWidth.Value;
			_rt = ((Component)this).gameObject.AddComponent<RectTransform>();
			_rt.anchorMin = new Vector2(1f, 0f);
			_rt.anchorMax = new Vector2(1f, 1f);
			_rt.pivot = new Vector2(1f, 1f);
			_rt.offsetMin = new Vector2(0f - value, Plugin.BottomOffset.Value);
			_rt.offsetMax = new Vector2(0f, 0f);
			AddImage(((Component)this).gameObject, BgColor);
			AddBackgroundDecor(((Component)this).gameObject);
			BuildHeader();
			BuildScrollArea();
			BuildFooter();
			ApplyGeometry();
		}

		private void BuildHeader()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_00a4: 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)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = MakeRect("Header", ((Component)this).gameObject.transform);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(1f, 1f);
			component.pivot = new Vector2(0.5f, 1f);
			component.sizeDelta = new Vector2(0f, 32f);
			AddImage(val, HeaderBgColor);
			GameObject obj = MakeRect("AliveDot", val.transform);
			RectTransform component2 = obj.GetComponent<RectTransform>();
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0f, 0.5f);
			component2.anchorMax = val2;
			component2.anchorMin = val2;
			component2.pivot = new Vector2(0f, 0.5f);
			component2.sizeDelta = new Vector2(7f, 7f);
			component2.anchoredPosition = new Vector2(10f, 0f);
			AddImage(obj, AliveDot);
			GameObject val3 = MakeRect("CharName", val.transform);
			RectTransform component3 = val3.GetComponent<RectTransform>();
			component3.anchorMin = new Vector2(0f, 0f);
			component3.anchorMax = new Vector2(1f, 1f);
			component3.pivot = new Vector2(0f, 0.5f);
			component3.offsetMin = new Vector2(24f, 0f);
			component3.offsetMax = new Vector2(-8f, 0f);
			_charNameText = AddText(val3, "UNKNOWN", 11, TextHeader, (FontStyle)1);
		}

		private void BuildScrollArea()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = MakeRect("ScrollArea", ((Component)this).gameObject.transform);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 0f);
			component.anchorMax = new Vector2(1f, 1f);
			component.offsetMin = new Vector2(0f, 20f);
			component.offsetMax = new Vector2(0f, -32f);
			ScrollRect obj = val.AddComponent<ScrollRect>();
			obj.horizontal = false;
			obj.vertical = true;
			obj.scrollSensitivity = 24f;
			obj.movementType = (MovementType)2;
			obj.viewport = component;
			val.AddComponent<RectMask2D>();
			GameObject val2 = MakeRect("Content", val.transform);
			RectTransform component2 = val2.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0f, 1f);
			component2.anchorMax = new Vector2(1f, 1f);
			component2.pivot = new Vector2(0.5f, 1f);
			component2.sizeDelta = new Vector2(0f, 0f);
			VerticalLayoutGroup obj2 = val2.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj2).spacing = 0f;
			val2.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			obj.content = val2.GetComponent<RectTransform>();
			_skillsContent = BuildSection(val2.transform, "SKILLS");
			(GameObject, GameObject, Transform) tuple = BuildSectionWithRoot(val2.transform, "SKILLS IN TRAINING");
			_skillTrainingSection = tuple.Item1;
			_skillTrainingContent = tuple.Item3;
			_traitsContent = BuildSection(val2.transform, "TRAITS");
			(_traitTrainingSection, _, _traitTrainingContent) = BuildSectionWithRoot(val2.transform, "TRAITS IN TRAINING");
			(_conditionsSection, _, _conditionsContent) = BuildSectionWithRoot(val2.transform, "ACTIVE CONDITIONS");
		}

		private void BuildFooter()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_009c: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = MakeRect("Footer", ((Component)this).gameObject.transform);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 0f);
			component.anchorMax = new Vector2(1f, 0f);
			component.pivot = new Vector2(0.5f, 0f);
			component.sizeDelta = new Vector2(0f, 20f);
			AddImage(val, HeaderBgColor);
			GameObject obj = MakeRect("FooterLabel", val.transform);
			RectTransform component2 = obj.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0f, 0f);
			component2.anchorMax = new Vector2(1f, 1f);
			component2.offsetMin = new Vector2(10f, 0f);
			component2.offsetMax = new Vector2(-10f, 0f);
			AddText(obj, "CharSidebar  v0.1.2", 9, FooterText, (FontStyle)0);
		}

		private Transform BuildSection(Transform parent, string title)
		{
			return BuildSectionWithRoot(parent, title).content;
		}

		private (GameObject root, GameObject header, Transform content) BuildSectionWithRoot(Transform parent, string title)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: 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)
			//IL_01d4: Expected O, but got Unknown
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Expected O, but got Unknown
			GameObject val = MakeRect("Section_" + title, parent);
			VerticalLayoutGroup obj = val.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 0f;
			val.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			GameObject val2 = MakeRect("SectionHeader", val.transform);
			AddLayoutElement(val2, -1f, 22f);
			AddImage(val2, SectionBgColor);
			GameObject obj2 = MakeRect("Title", val2.transform);
			RectTransform component = obj2.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.offsetMin = new Vector2(10f, 0f);
			component.offsetMax = new Vector2(-22f, 0f);
			AddText(obj2, title, 9, TextSectionTitle, (FontStyle)0);
			GameObject val3 = MakeRect("Arrow", val2.transform);
			RectTransform component2 = val3.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(1f, 0f);
			component2.anchorMax = new Vector2(1f, 1f);
			component2.pivot = new Vector2(1f, 0.5f);
			component2.sizeDelta = new Vector2(18f, 0f);
			component2.anchoredPosition = new Vector2(-6f, 0f);
			Text arrow = AddText(val3, "▾", 9, TextSectionTitle, (FontStyle)0);
			arrow.alignment = (TextAnchor)4;
			GameObject val4 = MakeRect("SectionContent", val.transform);
			VerticalLayoutGroup obj3 = val4.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj3).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj3).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandHeight = false;
			((LayoutGroup)obj3).padding = new RectOffset(0, 0, 3, 3);
			((HorizontalOrVerticalLayoutGroup)obj3).spacing = 0f;
			val4.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			Button obj4 = val2.AddComponent<Button>();
			GameObject content = val4;
			((UnityEvent)obj4.onClick).AddListener((UnityAction)delegate
			{
				bool flag = !content.activeSelf;
				content.SetActive(flag);
				arrow.text = (flag ? "▾" : "▸");
			});
			return (root: val, header: val2, content: val4.transform);
		}

		public void Populate(CharacterSnapshot data)
		{
			if ((Object)(object)_charNameText != (Object)null)
			{
				_charNameText.text = data.CharacterName.ToUpper();
			}
			string sigSkills;
			if ((sigSkills = SkillSig(data.Skills)) != _sigSkills)
			{
				_sigSkills = sigSkills;
				PopulateSkillRows(_skillsContent, data.Skills);
			}
			if ((sigSkills = SkillSig(data.TrainingSkills)) != _sigTrainSkills)
			{
				_sigTrainSkills = sigSkills;
				PopulateTrainingSection(_skillTrainingSection, _skillTrainingContent, data.TrainingSkills);
			}
			if ((sigSkills = TraitSig(data.Traits)) != _sigTraits)
			{
				_sigTraits = sigSkills;
				PopulateTraits(data.Traits);
			}
			if ((sigSkills = SkillSig(data.TrainingTraits)) != _sigTrainTraits)
			{
				_sigTrainTraits = sigSkills;
				PopulateTrainingSection(_traitTrainingSection, _traitTrainingContent, data.TrainingTraits);
			}
			if ((sigSkills = CondSig(data.ActiveConditions)) != _sigConds)
			{
				_sigConds = sigSkills;
				PopulateConditions(data.ActiveConditions);
			}
		}

		private static string SkillSig(List<SkillEntry> list)
		{
			StringBuilder stringBuilder = new StringBuilder();
			foreach (SkillEntry item in list)
			{
				stringBuilder.Append(item.Name).Append(item.Learned ? '✓' : '◌').Append(item.TrainingPercent)
					.Append('|');
			}
			return stringBuilder.ToString();
		}

		private static string TraitSig(List<TraitEntry> list)
		{
			StringBuilder stringBuilder = new StringBuilder();
			foreach (TraitEntry item in list)
			{
				stringBuilder.Append(item.Name).Append((int)item.Polarity).Append('|');
			}
			return stringBuilder.ToString();
		}

		private static string CondSig(List<ConditionEntry> list)
		{
			StringBuilder stringBuilder = new StringBuilder();
			foreach (ConditionEntry item in list)
			{
				stringBuilder.Append(item.Name).Append((int)item.Tone).Append((int)item.Trend)
					.Append('|');
			}
			return stringBuilder.ToString();
		}

		private void PopulateTrainingSection(GameObject? section, Transform? content, List<SkillEntry> rows)
		{
			if ((Object)(object)section != (Object)null)
			{
				section.SetActive(rows.Count > 0);
			}
			PopulateSkillRows(content, rows);
		}

		private void PopulateSkillRows(Transform? content, List<SkillEntry> skills)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)content == (Object)null)
			{
				return;
			}
			ClearChildren(content);
			foreach (SkillEntry skill in skills)
			{
				GameObject val = MakeRect("SkillRow", content);
				AddLayoutElement(val, -1f, 22f);
				HorizontalLayoutGroup obj = val.AddComponent<HorizontalLayoutGroup>();
				((LayoutGroup)obj).childAlignment = (TextAnchor)3;
				((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
				((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
				((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false;
				((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
				((LayoutGroup)obj).padding = new RectOffset(12, 10, 0, 0);
				((HorizontalOrVerticalLayoutGroup)obj).spacing = 6f;
				GameObject go = MakeRect("Name", val.transform);
				AddLayoutElement(go, -1f, -1f, 1f);
				AddText(go, skill.Name, 11, SkillLearnedText, (FontStyle)0);
				string title = skill.Name;
				if (!skill.Learned)
				{
					GameObject go2 = MakeRect("Pct", val.transform);
					AddLayoutElement(go2, 34f, -1f, 0f);
					AddText(go2, skill.TrainingPercent + "%", 11, SkillTrainingText, (FontStyle)0).alignment = (TextAnchor)5;
					title = $"{skill.Name} ({skill.TrainingPercent}%)";
				}
				AddRowTooltip(val, title, skill.Description);
			}
		}

		private void PopulateTraits(List<TraitEntry> traits)
		{
			//IL_004d: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected O, but got Unknown
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_traitsContent == (Object)null)
			{
				return;
			}
			ClearChildren(_traitsContent);
			foreach (TraitEntry trait in traits)
			{
				Color color = ((trait.Polarity == TraitPolarity.Positive) ? TraitPosText : ((trait.Polarity == TraitPolarity.Negative) ? TraitNegText : TraitNeuText));
				GameObject val = MakeRect("TraitRow", _traitsContent);
				AddLayoutElement(val, -1f, 22f);
				HorizontalLayoutGroup obj = val.AddComponent<HorizontalLayoutGroup>();
				((LayoutGroup)obj).childAlignment = (TextAnchor)3;
				((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
				((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
				((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false;
				((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
				((LayoutGroup)obj).padding = new RectOffset(12, 10, 0, 0);
				((HorizontalOrVerticalLayoutGroup)obj).spacing = 7f;
				GameObject go = MakeRect("Dot", val.transform);
				AddLayoutElement(go, 6f, 6f, 0f);
				((Graphic)AddImage(go, color)).raycastTarget = false;
				GameObject go2 = MakeRect("Name", val.transform);
				AddLayoutElement(go2, -1f, -1f, 1f);
				AddText(go2, trait.Name, 11, color, (FontStyle)0);
				AddRowTooltip(val, trait.Name, trait.Description);
			}
		}

		private void PopulateConditions(List<ConditionEntry> conditions)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_conditionsContent == (Object)null || (Object)(object)_conditionsSection == (Object)null)
			{
				return;
			}
			ClearChildren(_conditionsContent);
			_conditionsSection.SetActive(conditions.Count > 0);
			foreach (ConditionEntry condition in conditions)
			{
				Color color = ToneDot(condition.Tone);
				Color color2 = ToneText(condition.Tone);
				GameObject val = MakeRect("CondRow", _conditionsContent);
				AddLayoutElement(val, -1f, 22f);
				HorizontalLayoutGroup obj = val.AddComponent<HorizontalLayoutGroup>();
				((LayoutGroup)obj).childAlignment = (TextAnchor)3;
				((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
				((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
				((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false;
				((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
				((LayoutGroup)obj).padding = new RectOffset(12, 10, 0, 0);
				((HorizontalOrVerticalLayoutGroup)obj).spacing = 7f;
				GameObject go = MakeRect("Dot", val.transform);
				AddLayoutElement(go, 6f, 6f, 0f);
				((Graphic)AddImage(go, color)).raycastTarget = false;
				GameObject go2 = MakeRect("Label", val.transform);
				AddLayoutElement(go2, -1f, -1f, 1f);
				AddText(go2, condition.Name, 11, color2, (FontStyle)0);
				if (condition.Trend != TrendDirection.None)
				{
					GameObject go3 = MakeRect("Trend", val.transform);
					AddLayoutElement(go3, 14f, -1f, 0f);
					AddText(go3, (condition.Trend == TrendDirection.Up) ? "↗" : "↘", 14, color2, (FontStyle)1).alignment = (TextAnchor)4;
				}
				AddRowTooltip(val, condition.Name, condition.Description);
			}
		}

		private static Color ToneDot(ConditionTone tone)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			return (Color)(tone switch
			{
				ConditionTone.Good => AliveDot, 
				ConditionTone.Critical => DotCritical, 
				ConditionTone.Warning => DotWarning, 
				_ => TextDim, 
			});
		}

		private static Color ToneText(ConditionTone tone)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			return (Color)(tone switch
			{
				ConditionTone.Good => TraitPosText, 
				ConditionTone.Critical => CondCriticalText, 
				ConditionTone.Warning => CondWarningText, 
				_ => TextDefault, 
			});
		}

		public void SetVisible(bool visible, bool showTab = true)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).gameObject.SetActive(visible);
			if ((Object)(object)_tabRect != (Object)null)
			{
				((Component)_tabRect).gameObject.SetActive(showTab);
				_tabRect.anchoredPosition = new Vector2(visible ? (0f - Plugin.PanelWidth.Value) : 0f, _tabRect.anchoredPosition.y);
			}
			if ((Object)(object)_tabLabel != (Object)null)
			{
				_tabLabel.text = (visible ? "◀\nS\nT\nA\nT\nS" : "▶\nS\nT\nA\nT\nS");
			}
		}

		private static GameObject MakeRect(string name, Transform parent)
		{
			//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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			val.AddComponent<RectTransform>();
			return val;
		}

		private static Image AddImage(GameObject go, Color color)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			Image obj = go.AddComponent<Image>();
			((Graphic)obj).color = color;
			return obj;
		}

		private static Text AddText(GameObject go, string content, int size, Color color, FontStyle style = (FontStyle)0)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			Text obj = go.AddComponent<Text>();
			obj.text = content;
			obj.fontSize = size;
			((Graphic)obj).color = color;
			obj.fontStyle = style;
			obj.font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
			obj.alignment = (TextAnchor)3;
			obj.horizontalOverflow = (HorizontalWrapMode)1;
			obj.verticalOverflow = (VerticalWrapMode)1;
			((Graphic)obj).raycastTarget = false;
			return obj;
		}

		private static void AddRowTooltip(GameObject row, string title, string body)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (!string.IsNullOrEmpty(body))
			{
				((Graphic)row.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0f);
				RowTooltip rowTooltip = row.AddComponent<RowTooltip>();
				rowTooltip.Title = title;
				rowTooltip.Body = body;
			}
		}

		private void AddBackgroundDecor(GameObject panel)
		{
			Image obj = MakeFullStretchChild("BgGradient", panel.transform).AddComponent<Image>();
			obj.sprite = _gradientSprite ?? (_gradientSprite = MakeGradientSprite());
			obj.type = (Type)0;
			((Graphic)obj).raycastTarget = false;
			Image obj2 = MakeFullStretchChild("BgGrid", panel.transform).AddComponent<Image>();
			obj2.sprite = _gridSprite ?? (_gridSprite = MakeGridSprite());
			obj2.type = (Type)2;
			((Graphic)obj2).raycastTarget = false;
			Image obj3 = MakeFullStretchChild("BgGridFade", panel.transform).AddComponent<Image>();
			obj3.sprite = _fadeSprite ?? (_fadeSprite = MakeLeftFadeSprite());
			obj3.type = (Type)0;
			((Graphic)obj3).raycastTarget = false;
		}

		private static GameObject MakeFullStretchChild(string name, Transform parent)
		{
			//IL_000e: 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)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = MakeRect(name, parent);
			RectTransform component = obj.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			return obj;
		}

		private static Sprite MakeGridSprite()
		{
			//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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(26, 26, (TextureFormat)4, false)
			{
				filterMode = (FilterMode)0,
				wrapMode = (TextureWrapMode)0
			};
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0f, 0f, 0f, 0f);
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(0.32f, 0.32f, 0.46f, 0.16f);
			Color[] array = (Color[])(object)new Color[676];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = val2;
			}
			for (int j = 0; j < 26; j++)
			{
				array[j] = val3;
			}
			for (int k = 0; k < 26; k++)
			{
				array[k * 26] = val3;
			}
			val.SetPixels(array);
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, 26f, 26f), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0);
		}

		private static Sprite MakeLeftFadeSprite()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: 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)
			Texture2D val = new Texture2D(64, 1, (TextureFormat)4, false)
			{
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			Color[] array = (Color[])(object)new Color[64];
			for (int i = 0; i < 64; i++)
			{
				float num = (float)i / 63f;
				float num2 = Mathf.Clamp01((1f - num) * 1.8f);
				array[i] = new Color(BgColor.r, BgColor.g, BgColor.b, num2);
			}
			val.SetPixels(array);
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, 64f, 1f), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0);
		}

		private static Sprite MakeGradientSprite()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_0046: 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_007b: 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)
			Texture2D val = new Texture2D(1, 64, (TextureFormat)4, false)
			{
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			Color[] array = (Color[])(object)new Color[64];
			for (int i = 0; i < 64; i++)
			{
				float num = (float)i / 63f;
				array[i] = new Color(0.4f, 0.4f, 0.55f, 0.06f * num);
			}
			val.SetPixels(array);
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, 1f, 64f), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0);
		}

		private static LayoutElement AddLayoutElement(GameObject go, float preferredWidth = -1f, float preferredHeight = -1f, float flexWidth = -1f, float flexHeight = -1f)
		{
			LayoutElement val = go.AddComponent<LayoutElement>();
			if (preferredWidth >= 0f)
			{
				val.preferredWidth = preferredWidth;
			}
			if (preferredHeight >= 0f)
			{
				val.preferredHeight = preferredHeight;
			}
			if (flexWidth >= 0f)
			{
				val.flexibleWidth = flexWidth;
			}
			if (flexHeight >= 0f)
			{
				val.flexibleHeight = flexHeight;
			}
			return val;
		}

		private static void ClearChildren(Transform parent)
		{
			for (int num = parent.childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)parent.GetChild(num)).gameObject);
			}
		}

		private static Color Hex(string hex)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			Color result = default(Color);
			ColorUtility.TryParseHtmlString(hex, ref result);
			return result;
		}

		private static GameObject CreateOwnCanvas()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_0067: Expected O, but got Unknown
			GameObject val = new GameObject("OstranautsSidebarCanvas");
			Canvas obj = val.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 5000;
			CanvasScaler obj2 = val.AddComponent<CanvasScaler>();
			obj2.uiScaleMode = (ScaleMode)1;
			obj2.referenceResolution = new Vector2(1920f, Plugin.ReferenceHeight.Value);
			obj2.screenMatchMode = (ScreenMatchMode)0;
			obj2.matchWidthOrHeight = 1f;
			val.AddComponent<GraphicRaycaster>();
			Object.DontDestroyOnLoad((Object)val);
			return val;
		}
	}
	public class SidebarTooltip : MonoBehaviour
	{
		private RectTransform _canvasRect;

		private RectTransform _rt;

		private Text _title;

		private Text _body;

		private bool _shown;

		private static readonly Color BgColor = Hex("#0c0c12");

		private static readonly Color TitleColor = Hex("#d0c8b8");

		private static readonly Color BodyColor = Hex("#9a9286");

		private const float Width = 240f;

		public static SidebarTooltip? Instance { get; private set; }

		public static SidebarTooltip Create(Transform canvas)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("OstranautsSidebarTooltip");
			val.transform.SetParent(canvas, false);
			SidebarTooltip sidebarTooltip = val.AddComponent<SidebarTooltip>();
			sidebarTooltip.Build((RectTransform?)(object)((canvas is RectTransform) ? canvas : null));
			return sidebarTooltip;
		}

		private void Awake()
		{
			Instance = this;
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		private void Build(RectTransform? canvasRect)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			_canvasRect = canvasRect;
			_rt = ((Component)this).gameObject.AddComponent<RectTransform>();
			RectTransform rt = _rt;
			RectTransform rt2 = _rt;
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0f, 0f);
			rt2.anchorMax = val;
			rt.anchorMin = val;
			_rt.pivot = new Vector2(1f, 1f);
			_rt.sizeDelta = new Vector2(240f, 0f);
			Image obj = ((Component)this).gameObject.AddComponent<Image>();
			((Graphic)obj).color = BgColor;
			((Graphic)obj).raycastTarget = false;
			VerticalLayoutGroup obj2 = ((Component)this).gameObject.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false;
			((LayoutGroup)obj2).padding = new RectOffset(8, 8, 6, 6);
			((HorizontalOrVerticalLayoutGroup)obj2).spacing = 3f;
			((Component)this).gameObject.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			_title = MakeText("Title", 12, TitleColor, (FontStyle)1);
			_body = MakeText("Body", 11, BodyColor, (FontStyle)0);
			((Component)this).gameObject.SetActive(false);
		}

		private Text MakeText(string name, int size, Color color, FontStyle style)
		{
			//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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(((Component)this).transform, false);
			val.AddComponent<RectTransform>();
			Text obj = val.AddComponent<Text>();
			obj.font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
			obj.fontSize = size;
			((Graphic)obj).color = color;
			obj.fontStyle = style;
			obj.alignment = (TextAnchor)0;
			obj.horizontalOverflow = (HorizontalWrapMode)0;
			obj.verticalOverflow = (VerticalWrapMode)1;
			((Graphic)obj).raycastTarget = false;
			return obj;
		}

		public void Show(string title, string body)
		{
			_title.text = title ?? string.Empty;
			_body.text = body ?? string.Empty;
			((Component)_body).gameObject.SetActive(!string.IsNullOrEmpty(body));
			_shown = true;
			((Component)this).transform.SetAsLastSibling();
			((Component)this).gameObject.SetActive(true);
			Reposition();
		}

		public void Hide()
		{
			_shown = false;
			((Component)this).gameObject.SetActive(false);
		}

		private void LateUpdate()
		{
			if (_shown)
			{
				Reposition();
			}
		}

		private void Reposition()
		{
			//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_0019: 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_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_0038: 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_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_canvasRect == (Object)null)
			{
				return;
			}
			Vector2 val = Vector2.op_Implicit(Input.mousePosition);
			Vector2 val2 = default(Vector2);
			if (RectTransformUtility.ScreenPointToLocalPointInRectangle(_canvasRect, val, (Camera)null, ref val2))
			{
				Rect rect = _canvasRect.rect;
				float num = val2.x - ((Rect)(ref rect)).xMin - 8f;
				float num2 = val2.y - ((Rect)(ref rect)).yMin + 8f;
				Rect rect2 = _rt.rect;
				float width = ((Rect)(ref rect2)).width;
				rect2 = _rt.rect;
				float height = ((Rect)(ref rect2)).height;
				if (num < width)
				{
					num = width;
				}
				if (num > ((Rect)(ref rect)).width)
				{
					num = ((Rect)(ref rect)).width;
				}
				if (num2 > ((Rect)(ref rect)).height)
				{
					num2 = ((Rect)(ref rect)).height;
				}
				if (num2 < height)
				{
					num2 = height;
				}
				_rt.anchoredPosition = new Vector2(num, num2);
			}
		}

		private static Color Hex(string hex)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			Color result = default(Color);
			ColorUtility.TryParseHtmlString(hex, ref result);
			return result;
		}
	}
}
namespace OstranautsSidebar.Data
{
	internal static class CharacterDataReader
	{
		private const int DISPLAY_NEVER = 0;

		private static readonly HashSet<string> TraitNames = new HashSet<string>(StringComparer.Ordinal)
		{
			"IsAgliophobic", "IsAmbitious", "IsApathetic", "IsArrogant", "IsBeautiful", "IsBrave", "IsCharismatic", "IsChaste", "IsClumsy", "IsComedian",
			"IsComplacent", "IsCoordinated", "IsCraven", "IsCruel", "IsDiligent", "IsFeeble", "IsFinicky", "IsFit", "IsFollower", "IsForgiving",
			"IsFragile", "IsGenius", "IsGlutton", "IsGregarious", "IsHealerFast", "IsHealerSlow", "IsHonest", "IsHumble", "IsHumorless", "IsHypovolemic2",
			"IsImmunoSuppressed", "IsImpatient", "IsInsomniac", "IsIronStomach", "IsKind", "IsLeader", "IsLiar", "IsLoyal", "IsLustful", "IsMasochist",
			"IsMetabFast", "IsMetabSlow", "IsOblivious", "IsObservant", "IsObtuse", "IsOptimist", "IsPatient", "IsPessimist", "IsPoorHearing", "IsPushover",
			"IsQuitter", "IsRepulsive", "IsSelfish", "IsSelfless", "IsSharpHearing", "IsShy", "IsSleeperHeavy", "IsSleeperLight", "IsSlovenly", "IsSmoker",
			"IsStrong", "IsStubborn", "IsSuspicious", "IsTemperate", "IsTidy", "IsTough", "IsTreacherous", "IsTrusting", "IsUgly", "IsUnfit",
			"IsVengeful", "IsVisualImpaired", "IsWeakStomach"
		};

		private static bool _loggedDiag;

		private static readonly HashSet<string> TraitTrainings = new HashSet<string>(StringComparer.Ordinal) { "Fit", "Strong", "Feeble", "Unfit" };

		private const int DISPLAY_ALWAYS = 2;

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

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

		private const double TrendEpsilon = 0.25;

		public static CharacterSnapshot? ReadPlayer()
		{
			CondOwner coPlayer;
			try
			{
				coPlayer = CrewSim.coPlayer;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogDebug((object)("ReadPlayer: CrewSim not ready (" + ex.GetType().Name + ")."));
				return null;
			}
			if ((Object)(object)coPlayer == (Object)null || coPlayer.mapConds == null)
			{
				return null;
			}
			CharacterSnapshot characterSnapshot = new CharacterSnapshot
			{
				CharacterName = ((!string.IsNullOrEmpty(coPlayer.strNameFriendly)) ? coPlayer.strNameFriendly : (coPlayer.strName ?? "Unknown"))
			};
			foreach (Condition value in coPlayer.mapConds.Values)
			{
				if (value == null || string.IsNullOrEmpty(value.strName))
				{
					continue;
				}
				if (value.strName.StartsWith("Skill", StringComparison.Ordinal))
				{
					characterSnapshot.Skills.Add(new SkillEntry(CleanSkillName(value), learned: true, 0, DescOf(coPlayer, value)));
				}
				else if (value.strName.StartsWith("DcTraining", StringComparison.Ordinal))
				{
					if (TryReadTraining(coPlayer, value, out SkillEntry entry, out bool isTrait))
					{
						(isTrait ? characterSnapshot.TrainingTraits : characterSnapshot.TrainingSkills).Add(entry);
					}
				}
				else if (TraitNames.Contains(value.strName))
				{
					characterSnapshot.Traits.Add(new TraitEntry(FriendlyName(value), PolarityOf(value), DescOf(coPlayer, value)));
				}
				else if (IsActiveStatus(value))
				{
					characterSnapshot.ActiveConditions.Add(new ConditionEntry(FriendlyName(value), ToneOf(value), TrendOf(coPlayer, value), DescOf(coPlayer, value)));
				}
			}
			characterSnapshot.Skills.Sort((SkillEntry a, SkillEntry b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase));
			characterSnapshot.TrainingSkills.Sort((SkillEntry a, SkillEntry b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase));
			characterSnapshot.TrainingTraits.Sort((SkillEntry a, SkillEntry b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase));
			characterSnapshot.Traits.Sort((TraitEntry a, TraitEntry b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase));
			characterSnapshot.ActiveConditions.Sort(delegate(ConditionEntry a, ConditionEntry b)
			{
				int num = ToneRank(a.Tone).CompareTo(ToneRank(b.Tone));
				return (num == 0) ? string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase) : num;
			});
			LogDiagnosticsOnce(coPlayer, characterSnapshot);
			return characterSnapshot;
		}

		private static void LogDiagnosticsOnce(CondOwner player, CharacterSnapshot s)
		{
			if (_loggedDiag)
			{
				return;
			}
			_loggedDiag = true;
			Plugin.Log.LogInfo((object)($"[diag] mapConds={player.mapConds.Count} skills={s.Skills.Count} " + $"trainSkills={s.TrainingSkills.Count} trainTraits={s.TrainingTraits.Count} " + $"traits={s.Traits.Count} conditions={s.ActiveConditions.Count}"));
			List<string> list = new List<string>();
			foreach (ConditionEntry activeCondition in s.ActiveConditions)
			{
				list.Add(activeCondition.Name + "[" + activeCondition.Tone.ToString() + "]");
			}
			Plugin.Log.LogInfo((object)string.Format("[diag] active conditions ({0}): {1}", list.Count, string.Join(", ", list.ToArray())));
			List<string> list2 = new List<string>();
			foreach (Condition value in player.mapConds.Values)
			{
				if (value != null && value.strName != null && value.nDisplaySelf == 2 && !value.strName.StartsWith("Skill", StringComparison.Ordinal) && !value.strName.StartsWith("DcTraining", StringComparison.Ordinal) && !TraitNames.Contains(value.strName))
				{
					list2.Add($"{value.strName}(other={value.nDisplayOther},{value.strColor})");
				}
			}
			list2.Sort();
			Plugin.Log.LogInfo((object)string.Format("[diag] disp2 pool ({0}): {1}", list2.Count, string.Join(", ", list2.ToArray())));
		}

		private static bool TryReadTraining(CondOwner player, Condition cond, out SkillEntry entry, out bool isTrait)
		{
			entry = null;
			string text = cond.strName.Substring("DcTraining".Length).TrimEnd('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
			isTrait = TraitTrainings.Contains(text);
			if (text.Length == 0)
			{
				return false;
			}
			string text2 = (isTrait ? ("Is" + text) : ("Skill" + text));
			try
			{
				if (player.HasCond(text2))
				{
					return false;
				}
			}
			catch (Exception)
			{
			}
			double val;
			try
			{
				val = player.GetCondAmount("StatTraining" + text);
			}
			catch (Exception)
			{
				val = 0.0;
			}
			int trainingPercent = (int)Math.Round(Math.Max(0.0, Math.Min(100.0, val)));
			entry = new SkillEntry(CleanTrainingName(cond, text), learned: false, trainingPercent, DescOf(player, cond));
			return true;
		}

		private static string CleanTrainingName(Condition cond, string suffix)
		{
			string text = cond.strNameFriendly ?? string.Empty;
			if (text.StartsWith("Training: ", StringComparison.OrdinalIgnoreCase))
			{
				text = text.Substring("Training: ".Length);
			}
			int num = text.LastIndexOf(' ');
			if (num > 0 && text.EndsWith("%", StringComparison.Ordinal))
			{
				text = text.Substring(0, num);
			}
			text = text.Trim();
			if (text.Length <= 0)
			{
				return Prettify(suffix);
			}
			return text;
		}

		private static bool IsActiveStatus(Condition cond)
		{
			if (cond.nDisplaySelf != 2)
			{
				return false;
			}
			if (cond.nDisplayOther < 1)
			{
				return false;
			}
			if (cond.strName.StartsWith("Is", StringComparison.Ordinal))
			{
				return false;
			}
			if (cond.strName.StartsWith("Career", StringComparison.Ordinal))
			{
				return false;
			}
			if (cond.strName.StartsWith("Dc", StringComparison.Ordinal) && !IsNeedBacked(cond))
			{
				return false;
			}
			return true;
		}

		private static bool IsNeedBacked(Condition cond)
		{
			try
			{
				if (!string.IsNullOrEmpty(cond.strTrackCond) && DataHandler.GetCond(cond.strTrackCond) != null)
				{
					return true;
				}
				string text = cond.strName.Substring(2).TrimEnd('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
				return DataHandler.GetCond("Stat" + text) != null;
			}
			catch (Exception)
			{
				return true;
			}
		}

		private static TraitPolarity PolarityOf(Condition cond)
		{
			if (string.Equals(cond.strColor, "Good", StringComparison.OrdinalIgnoreCase))
			{
				return TraitPolarity.Positive;
			}
			if (cond.bNegative || string.Equals(cond.strColor, "Bad", StringComparison.OrdinalIgnoreCase))
			{
				return TraitPolarity.Negative;
			}
			return TraitPolarity.Neutral;
		}

		private static int ToneRank(ConditionTone tone)
		{
			return tone switch
			{
				ConditionTone.Critical => 0, 
				ConditionTone.Warning => 1, 
				ConditionTone.Neutral => 2, 
				_ => 3, 
			};
		}

		private static ConditionTone ToneOf(Condition cond)
		{
			string text = cond.strColor ?? string.Empty;
			if (text.StartsWith("Good", StringComparison.OrdinalIgnoreCase))
			{
				return ConditionTone.Good;
			}
			if (cond.bFatal || cond.bKO || string.Equals(text, "Bad", StringComparison.OrdinalIgnoreCase))
			{
				return ConditionTone.Critical;
			}
			if (cond.bNegative || text.StartsWith("Bad", StringComparison.OrdinalIgnoreCase) || string.Equals(text, "Warning", StringComparison.OrdinalIgnoreCase))
			{
				return ConditionTone.Warning;
			}
			return ConditionTone.Neutral;
		}

		private static TrendDirection TrendOf(CondOwner player, Condition cond)
		{
			string key = ((!string.IsNullOrEmpty(cond.strTrackCond)) ? cond.strTrackCond : cond.strName);
			double num;
			try
			{
				num = ((!string.IsNullOrEmpty(cond.strTrackCond)) ? player.GetCondAmount(cond.strTrackCond) : cond.fCount);
			}
			catch (Exception)
			{
				num = cond.fCount;
			}
			if (!_prevValues.TryGetValue(key, out var value))
			{
				_prevValues[key] = num;
				_lastTrend[key] = TrendDirection.None;
				return TrendDirection.None;
			}
			double num2 = num - value;
			if (num2 >= 0.25)
			{
				_lastTrend[key] = TrendDirection.Up;
				_prevValues[key] = num;
			}
			else if (num2 <= -0.25)
			{
				_lastTrend[key] = TrendDirection.Down;
				_prevValues[key] = num;
			}
			if (!_lastTrend.TryGetValue(key, out var value2))
			{
				return TrendDirection.None;
			}
			return value2;
		}

		private static string FriendlyName(Condition cond)
		{
			if (string.IsNullOrEmpty(cond.strNameFriendly))
			{
				return cond.strName;
			}
			return cond.strNameFriendly;
		}

		private static string DescOf(CondOwner player, Condition cond)
		{
			if (string.IsNullOrEmpty(cond.strDesc))
			{
				return string.Empty;
			}
			try
			{
				return GrammarUtils.GetInflectedString(cond.strDesc, (object)player);
			}
			catch (Exception)
			{
				return cond.strDesc;
			}
		}

		private static string CleanSkillName(Condition cond)
		{
			string text = FriendlyName(cond);
			if (text.StartsWith("Skilled in ", StringComparison.OrdinalIgnoreCase))
			{
				return text.Substring("Skilled in ".Length);
			}
			if (!string.IsNullOrEmpty(cond.strNameFriendly))
			{
				return text;
			}
			return Prettify(cond.strName.Substring("Skill".Length));
		}

		private static string Prettify(string raw)
		{
			if (string.IsNullOrEmpty(raw))
			{
				return raw;
			}
			StringBuilder stringBuilder = new StringBuilder(raw.Length + 4);
			for (int i = 0; i < raw.Length; i++)
			{
				char c = raw[i];
				if (i > 0 && char.IsUpper(c) && !char.IsUpper(raw[i - 1]))
				{
					stringBuilder.Append(' ');
				}
				stringBuilder.Append(c);
			}
			return stringBuilder.ToString();
		}
	}
	public class CharacterSnapshot
	{
		public string CharacterName { get; set; } = string.Empty;

		public List<SkillEntry> Skills { get; } = new List<SkillEntry>();

		public List<SkillEntry> TrainingSkills { get; } = new List<SkillEntry>();

		public List<SkillEntry> TrainingTraits { get; } = new List<SkillEntry>();

		public List<TraitEntry> Traits { get; } = new List<TraitEntry>();

		public List<ConditionEntry> ActiveConditions { get; } = new List<ConditionEntry>();
	}
	public class SkillEntry
	{
		public string Name { get; }

		public bool Learned { get; }

		public int TrainingPercent { get; }

		public string Description { get; }

		public SkillEntry(string name, bool learned, int trainingPercent = 0, string description = "")
		{
			Name = name;
			Learned = learned;
			TrainingPercent = trainingPercent;
			Description = description;
		}
	}
	public class TraitEntry
	{
		public string Name { get; }

		public TraitPolarity Polarity { get; }

		public string Description { get; }

		public TraitEntry(string name, TraitPolarity polarity, string description = "")
		{
			Name = name;
			Polarity = polarity;
			Description = description;
		}
	}
	public enum TraitPolarity
	{
		Positive,
		Negative,
		Neutral
	}
	public class ConditionEntry
	{
		public string Name { get; }

		public ConditionTone Tone { get; }

		public TrendDirection Trend { get; }

		public string Description { get; }

		public ConditionEntry(string name, ConditionTone tone, TrendDirection trend, string description = "")
		{
			Name = name;
			Tone = tone;
			Trend = trend;
			Description = description;
		}
	}
	public enum ConditionTone
	{
		Good,
		Neutral,
		Warning,
		Critical
	}
	public enum TrendDirection
	{
		None,
		Up,
		Down
	}
}
namespace OstranautsSidebar.Core
{
	internal static class Diagnostics
	{
		private static bool _done;

		public static void DumpOnce()
		{
			if (_done)
			{
				return;
			}
			_done = true;
			try
			{
				DumpCanvases();
				GUIMegaToolTip obj = Object.FindFirstObjectByType<GUIMegaToolTip>();
				DumpChain("GUIMegaToolTip", (obj != null) ? ((Component)obj).transform : null);
				ModuleHost obj2 = Object.FindFirstObjectByType<ModuleHost>();
				DumpChain("ModuleHost", (obj2 != null) ? ((Component)obj2).transform : null);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[diag] UI dump failed: " + ex.Message));
			}
		}

		private static void DumpCanvases()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			Canvas[] array = Object.FindObjectsByType<Canvas>((FindObjectsSortMode)0);
			Array.Sort(array, (Canvas a, Canvas b) => a.sortingOrder.CompareTo(b.sortingOrder));
			StringBuilder stringBuilder = new StringBuilder("[diag] canvases (name#order/mode): ");
			Canvas[] array2 = array;
			foreach (Canvas val in array2)
			{
				stringBuilder.Append($"{((Object)val).name}#{val.sortingOrder}/{val.renderMode} | ");
			}
			Plugin.Log.LogInfo((object)stringBuilder.ToString());
		}

		private static void DumpChain(string label, Transform? t)
		{
			//IL_00b3: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)t == (Object)null)
			{
				Plugin.Log.LogInfo((object)("[diag] " + label + ": <not found>"));
				return;
			}
			StringBuilder stringBuilder = new StringBuilder("[diag] " + label + " chain: ");
			Transform val = t;
			while ((Object)(object)val != (Object)null)
			{
				Canvas component = ((Component)val).GetComponent<Canvas>();
				RectTransform val2 = (RectTransform)(object)((val is RectTransform) ? val : null);
				stringBuilder.Append(((Object)val).name);
				if ((Object)(object)component != (Object)null)
				{
					stringBuilder.Append($"[Canvas#{component.sortingOrder}]");
				}
				if ((Object)(object)((Component)val).GetComponent<CanvasGroup>() != (Object)null)
				{
					stringBuilder.Append("[CG]");
				}
				if ((Object)(object)val2 != (Object)null)
				{
					stringBuilder.Append($"{{aMin{val2.anchorMin} aMax{val2.anchorMax} sz{val2.sizeDelta} pos{val2.anchoredPosition}}}");
				}
				stringBuilder.Append(" < ");
				val = val.parent;
			}
			Plugin.Log.LogInfo((object)stringBuilder.ToString());
		}
	}
	internal class MttWatcher
	{
		private RectTransform? _container;

		private CanvasGroup? _cg;

		private Canvas? _mttCanvas;

		private float _lastAcquireTry;

		private bool _loggedCollapsed;

		private bool _loggedExpanded;

		private static readonly Vector3[] _corners = (Vector3[])(object)new Vector3[4];

		public bool Open { get; private set; }

		public bool Expanded { get; private set; }

		public void Refresh()
		{
			if ((Object)(object)_container == (Object)null)
			{
				if (Time.unscaledTime - _lastAcquireTry < 1f)
				{
					return;
				}
				_lastAcquireTry = Time.unscaledTime;
				TryAcquire();
				if ((Object)(object)_container == (Object)null)
				{
					return;
				}
			}
			try
			{
				Open = ModuleHost.Opened;
			}
			catch
			{
				Open = (Object)(object)_cg != (Object)null && _cg.alpha > 0.5f;
			}
			try
			{
				Expanded = ModuleHost.ShowExpandedTooltip;
			}
			catch
			{
				Expanded = false;
			}
			LogBottomOnce();
		}

		private void LogBottomOnce()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			if (!Open || (Expanded ? _loggedExpanded : _loggedCollapsed))
			{
				return;
			}
			Camera val = (((Object)(object)_mttCanvas != (Object)null && (int)_mttCanvas.renderMode != 0) ? _mttCanvas.worldCamera : null);
			float num = float.MaxValue;
			bool flag = false;
			Graphic[] componentsInChildren = ((Component)_container).GetComponentsInChildren<Graphic>(false);
			foreach (Graphic val2 in componentsInChildren)
			{
				if (!((Object)(object)val2 == (Object)null) && ((Behaviour)val2).isActiveAndEnabled && val2.color.a > 0.05f && ((Object)(object)val2.canvasRenderer == (Object)null || (!val2.canvasRenderer.cull && val2.canvasRenderer.GetAlpha() > 0.05f)))
				{
					val2.rectTransform.GetWorldCorners(_corners);
					float y = RectTransformUtility.WorldToScreenPoint(val, _corners[0]).y;
					if (y < num)
					{
						num = y;
						flag = true;
					}
				}
			}
			_container.GetWorldCorners(_corners);
			float y2 = RectTransformUtility.WorldToScreenPoint(val, _corners[0]).y;
			float num2 = Mathf.Max(1f, (float)Screen.height);
			string arg = (Expanded ? "EXPANDED" : "collapsed");
			Plugin.Log.LogInfo((object)($"[diag] MTT {arg}: visibleBottomFracFromTop={(flag ? (1f - num / num2) : (-1f)):F3} " + $"rawRectFracFromTop={1f - y2 / num2:F3} screenH={Screen.height}"));
			if (Expanded)
			{
				_loggedExpanded = true;
			}
			else
			{
				_loggedCollapsed = true;
			}
		}

		private void TryAcquire()
		{
			try
			{
				GUIMegaToolTip val = Object.FindFirstObjectByType<GUIMegaToolTip>();
				if (!((Object)(object)val == (Object)null))
				{
					CanvasGroup componentInParent = ((Component)val).GetComponentInParent<CanvasGroup>();
					if (!((Object)(object)componentInParent == (Object)null))
					{
						_cg = componentInParent;
						_container = ((Component)componentInParent).GetComponent<RectTransform>();
						_mttCanvas = ((Component)componentInParent).GetComponentInParent<Canvas>();
						Plugin.Log.LogInfo((object)"[diag] MTT watcher attached.");
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogDebug((object)("MTT acquire failed: " + ex.Message));
			}
		}
	}
	public class SidebarController : MonoBehaviour
	{
		private const float RefreshInterval = 0.5f;

		private SidebarPanel? _panel;

		private float _timer;

		private bool _userVisible = Plugin.StartVisible?.Value ?? true;

		private readonly MttWatcher _mtt = new MttWatcher();

		public static SidebarController? Instance { get; private set; }

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
			else
			{
				Instance = this;
			}
		}

		private void Update()
		{
			_timer += Time.unscaledDeltaTime;
			if (!(_timer < 0.5f))
			{
				_timer = 0f;
				Tick();
			}
		}

		private void LateUpdate()
		{
			if (!((Object)(object)_panel == (Object)null))
			{
				_mtt.Refresh();
				float heightFraction = ((!_mtt.Open) ? 1f : (_mtt.Expanded ? 0.29f : 0.64f));
				_panel.SetVisible(_userVisible);
				_panel.SetHeightFraction(heightFraction);
			}
		}

		private void Tick()
		{
			CharacterSnapshot characterSnapshot = CharacterDataReader.ReadPlayer();
			if (characterSnapshot == null)
			{
				if ((Object)(object)_panel != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)_panel).gameObject);
					_panel = null;
					Plugin.Log.LogInfo((object)"Player gone — sidebar panel removed.");
				}
				return;
			}
			if ((Object)(object)_panel == (Object)null)
			{
				_panel = SidebarPanel.Create();
				_panel.SetVisible(_userVisible);
				Plugin.Log.LogInfo((object)"Sidebar panel created.");
				Diagnostics.DumpOnce();
			}
			_panel.Populate(characterSnapshot);
		}

		public void ToggleVisibility()
		{
			_userVisible = !_userVisible;
			_panel?.SetVisible(_userVisible);
		}

		public void Destroy()
		{
			if ((Object)(object)_panel != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_panel).gameObject);
			}
			_panel = null;
			Instance = null;
		}
	}
}