Decompiled source of CatUIPanel v0.0.1

CatUIPanel.dll

Decompiled 4 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CatUIPanel.UI;
using HarmonyLib;
using Microsoft.CodeAnalysis;
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.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace CatUIPanel
{
	public static class L10n
	{
		private static int cachedLcid = int.MinValue;

		public static bool Refresh()
		{
			int num = ReadLcid();
			if (cachedLcid == num)
			{
				return false;
			}
			cachedLcid = num;
			return true;
		}

		public static string Pick(string zh, string en)
		{
			if (cachedLcid == int.MinValue)
			{
				Refresh();
			}
			if (string.IsNullOrEmpty(zh))
			{
				return en ?? "";
			}
			if (string.IsNullOrEmpty(en))
			{
				return zh;
			}
			if (cachedLcid != 2052)
			{
				return en;
			}
			return zh;
		}

		private static int ReadLcid()
		{
			try
			{
				if (Localization.Loaded)
				{
					return Localization.CurrentLanguageLCID;
				}
				return DSPGame.globalOption.languageLCID;
			}
			catch
			{
			}
			if ((CultureInfo.CurrentUICulture.LCID & 0x3FF) != 4)
			{
				return 1033;
			}
			return 2052;
		}
	}
	internal static class Patches
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(UIGame), "_OnUpdate")]
		public static void UIGame_OnUpdate_Prefix()
		{
			PanelWindow.OnGameUiUpdate();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameMain), "End")]
		public static void GameMain_End_Postfix()
		{
			PanelWindow.OnGameEnd();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Localization), "NotifyLanguageChange")]
		public static void Localization_NotifyLanguageChange_Postfix()
		{
			if (!L10n.Refresh())
			{
				return;
			}
			try
			{
				LauncherButton.ApplyLanguage();
				PanelWindow.OnLanguageChanged();
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Language refresh failed: " + ex));
			}
		}
	}
	[BepInPlugin("com.cat.dsp.catuipanel", "CatUIPanel", "0.0.1")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "com.cat.dsp.catuipanel";

		public const string Version = "0.0.1";

		private static readonly Harmony harmony = new Harmony("com.cat.dsp.catuipanel");

		internal static ManualLogSource Log;

		internal static ConfigEntry<float> LauncherOffsetX;

		internal static ConfigEntry<float> LauncherOffsetY;

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			LauncherOffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("Launcher", "OffsetX", 0f, "Horizontal offset of the cat button relative to the screenshot button. | 小猫按钮相对截图按钮的水平偏移。");
			LauncherOffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("Launcher", "OffsetY", 4f, "Gap between the cat button and the screenshot button below it. | 小猫按钮与下方截图按钮的间距。");
			harmony.PatchAll(typeof(Patches));
			L10n.Refresh();
		}

		private void OnDestroy()
		{
			harmony.UnpatchSelf();
		}
	}
	public static class UIPanel
	{
		public const string Guid = "com.cat.dsp.catuipanel";

		public const int ApiVersion = 3;

		internal static readonly List<Page> Pages = new List<Page>();

		internal static int Revision;

		public static bool IsOpen => PanelWindow.IsOpen;

		public static string CurrentPageKey => PanelWindow.CurrentPageKey;

		public static Page RegisterPage(string key, string titleZh, string titleEn)
		{
			if (string.IsNullOrEmpty(key))
			{
				throw new ArgumentException("Page key must not be empty", "key");
			}
			Page page = FindPage(key);
			if (page != null)
			{
				return page;
			}
			page = new Page(key, titleZh, titleEn);
			Pages.Add(page);
			Revision++;
			return page;
		}

		public static Page RegisterPage(string key)
		{
			return RegisterPage(key, key, key);
		}

		public static void OpenPage(string key)
		{
			PanelWindow.RequestOpen(key);
		}

		public static void TogglePage(string key)
		{
			if (IsOpen && CurrentPageKey == key)
			{
				Close();
			}
			else
			{
				OpenPage(key);
			}
		}

		public static void Close()
		{
			PanelWindow.Close();
		}

		internal static Page FindPage(string key)
		{
			foreach (Page page in Pages)
			{
				if (page.Key == key)
				{
					return page;
				}
			}
			return null;
		}
	}
	public sealed class Page
	{
		internal readonly string TitleZh;

		internal readonly string TitleEn;

		internal readonly List<PageItem> Items = new List<PageItem>();

		public string Key { get; }

		internal string Title => L10n.Pick(TitleZh, TitleEn);

		internal Page(string key, string titleZh, string titleEn)
		{
			Key = key;
			TitleZh = titleZh ?? key;
			TitleEn = (string.IsNullOrEmpty(titleEn) ? TitleZh : titleEn);
		}

		public Page AddCheckbox(ConfigEntry<bool> entry, string labelZh, string labelEn)
		{
			if (entry == null)
			{
				throw new ArgumentNullException("entry");
			}
			return Add(new CheckboxItem(entry, labelZh, labelEn));
		}

		public Page AddCheckbox(ConfigEntry<bool> entry, string label)
		{
			return AddCheckbox(entry, label, label);
		}

		public Page AddButton(string labelZh, string labelEn, Action onClick)
		{
			return AddButton(labelZh, labelEn, onClick, 0f);
		}

		public Page AddButton(string label, Action onClick)
		{
			return AddButton(label, label, onClick, 0f);
		}

		public Page AddButton(string labelZh, string labelEn, Action onClick, float width)
		{
			if (onClick == null)
			{
				throw new ArgumentNullException("onClick");
			}
			return Add(new ButtonItem(labelZh, labelEn, onClick, width));
		}

		public Page AddButton(string label, Action onClick, float width)
		{
			return AddButton(label, label, onClick, width);
		}

		public Page AddLabel(string textZh, string textEn)
		{
			return Add(new LabelItem(textZh, textEn));
		}

		public Page AddLabel(string text)
		{
			return AddLabel(text, text);
		}

		private Page Add(PageItem item)
		{
			Items.Add(item);
			UIPanel.Revision++;
			return this;
		}
	}
	internal abstract class PageItem
	{
		public readonly string TextZh;

		public readonly string TextEn;

		public string Text => L10n.Pick(TextZh, TextEn);

		protected PageItem(string zh, string en)
		{
			TextZh = zh ?? "";
			TextEn = (string.IsNullOrEmpty(en) ? TextZh : en);
		}
	}
	internal sealed class CheckboxItem : PageItem
	{
		public readonly ConfigEntry<bool> Entry;

		public CheckboxItem(ConfigEntry<bool> entry, string labelZh, string labelEn)
			: base(labelZh, labelEn)
		{
			Entry = entry;
		}
	}
	internal sealed class ButtonItem : PageItem
	{
		public readonly Action OnClick;

		public readonly float Width;

		public ButtonItem(string labelZh, string labelEn, Action onClick, float width)
			: base(labelZh, labelEn)
		{
			OnClick = onClick;
			Width = width;
		}
	}
	internal sealed class LabelItem : PageItem
	{
		public LabelItem(string textZh, string textEn)
			: base(textZh, textEn)
		{
		}
	}
}
namespace CatUIPanel.UI
{
	internal static class CatIcon
	{
		private const int Size = 64;

		private const int Supersample = 4;

		private static Sprite sprite;

		public static Sprite Get()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)sprite != (Object)null)
			{
				return sprite;
			}
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false)
			{
				name = "cat-cat-icon",
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			Color32[] array = (Color32[])(object)new Color32[4096];
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					int num = 0;
					for (int k = 0; k < 4; k++)
					{
						for (int l = 0; l < 4; l++)
						{
							float x = ((float)j + ((float)l + 0.5f) / 4f) / 64f * 2f - 1f;
							float y = ((float)i + ((float)k + 0.5f) / 4f) / 64f * 2f - 1f;
							if (Inside(x, y))
							{
								num++;
							}
						}
					}
					array[i * 64 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)(255 * num / 16));
				}
			}
			val.SetPixels32(array);
			val.Apply(false, true);
			sprite = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 100f);
			((Object)sprite).name = "cat-cat-icon";
			return sprite;
		}

		private static bool Inside(float x, float y)
		{
			if (!Ellipse(x, y, 0f, -0.14f, 0.8f, 0.64f) && !Triangle(x, y, -0.74f, 0f, -0.62f, 0.92f, -0.12f, 0.45f) && !Triangle(x, y, 0.74f, 0f, 0.62f, 0.92f, 0.12f, 0.45f))
			{
				return false;
			}
			bool num = Ellipse(x, y, -0.32f, -0.08f, 0.12f, 0.17f) || Ellipse(x, y, 0.32f, -0.08f, 0.12f, 0.17f);
			bool flag = Triangle(x, y, -0.09f, -0.31f, 0.09f, -0.31f, 0f, -0.42f);
			if (!num)
			{
				return !flag;
			}
			return false;
		}

		private static bool Ellipse(float x, float y, float cx, float cy, float rx, float ry)
		{
			float num = (x - cx) / rx;
			float num2 = (y - cy) / ry;
			return num * num + num2 * num2 <= 1f;
		}

		private static bool Triangle(float x, float y, float ax, float ay, float bx, float by, float cx, float cy)
		{
			float num = (x - bx) * (ay - by) - (ax - bx) * (y - by);
			float num2 = (x - cx) * (by - cy) - (bx - cx) * (y - cy);
			float num3 = (x - ax) * (cy - ay) - (cx - ax) * (y - ay);
			bool flag = num < 0f || num2 < 0f || num3 < 0f;
			bool flag2 = num > 0f || num2 > 0f || num3 > 0f;
			return !(flag && flag2);
		}
	}
	internal static class LauncherButton
	{
		private static GameObject root;

		private static RectTransform rect;

		private static RectTransform photoRect;

		private static bool failed;

		public static void Update(Action onClick)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			if (failed)
			{
				return;
			}
			if ((Object)(object)root == (Object)null)
			{
				try
				{
					Create(onClick);
				}
				catch (Exception ex)
				{
					failed = true;
					Plugin.Log.LogError((object)("Failed to create the cat button: " + ex));
					return;
				}
			}
			if (!((Object)(object)photoRect == (Object)null))
			{
				if (root.activeSelf != ((Component)photoRect).gameObject.activeSelf)
				{
					root.SetActive(((Component)photoRect).gameObject.activeSelf);
				}
				Rect val = photoRect.rect;
				float num = ((Rect)(ref val)).height * ((Transform)photoRect).localScale.y * 0.75f + Plugin.LauncherOffsetY.Value;
				rect.anchoredPosition = photoRect.anchoredPosition + new Vector2(Plugin.LauncherOffsetX.Value, num);
			}
		}

		private static void Create(Action onClick)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			Button buttonS = UIRoot.instance.uiGame.gameMenu.buttonS;
			photoRect = (RectTransform)((Component)buttonS).transform;
			root = Object.Instantiate<GameObject>(((Component)buttonS).gameObject, ((Transform)photoRect).parent, false);
			((Object)root).name = "cat-ui-harness-launcher";
			rect = (RectTransform)root.transform;
			Widgets.StripLocalizers(root);
			(root.GetComponent<LayoutElement>() ?? root.AddComponent<LayoutElement>()).ignoreLayout = true;
			Button component = root.GetComponent<Button>();
			component.onClick = new ButtonClickedEvent();
			((UnityEvent)component.onClick).AddListener((UnityAction)delegate
			{
				onClick();
			});
			UIButton component2 = root.GetComponent<UIButton>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.highlighted = false;
				ApplyTips(component2);
			}
			Image val = FindIcon(root.transform);
			if ((Object)(object)val != (Object)null)
			{
				val.sprite = CatIcon.Get();
				val.overrideSprite = null;
				val.preserveAspect = true;
				((Behaviour)val).enabled = true;
			}
			else
			{
				Plugin.Log.LogWarning((object)"Screenshot button has no icon image; the cat button shows without an icon.");
			}
			root.SetActive(((Component)buttonS).gameObject.activeSelf);
		}

		public static void ApplyLanguage()
		{
			if (!((Object)(object)root == (Object)null))
			{
				UIButton component = root.GetComponent<UIButton>();
				if ((Object)(object)component != (Object)null)
				{
					ApplyTips(component);
				}
			}
		}

		private static void ApplyTips(UIButton uiButton)
		{
			uiButton.tips.tipTitle = L10n.Pick("猫猫面板(F9)", "Cat Panel (F9)");
			uiButton.tips.tipText = L10n.Pick("一些mod的面板入口", "Entry to some mod panels");
			if (uiButton.tips.corner == 0)
			{
				uiButton.tips.corner = 7;
			}
		}

		private static Image FindIcon(Transform t)
		{
			Image val = null;
			Image[] componentsInChildren = ((Component)t).GetComponentsInChildren<Image>(true);
			foreach (Image val2 in componentsInChildren)
			{
				if (!((Object)(object)((Component)val2).transform == (Object)(object)t))
				{
					if (((Object)((Component)val2).gameObject).name.IndexOf("icon", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						return val2;
					}
					if (val == null)
					{
						val = val2;
					}
				}
			}
			return val ?? ((Component)t).GetComponent<Image>();
		}
	}
	internal static class PanelWindow
	{
		private sealed class PageView
		{
			public Page Page;

			public UIButton Tab;

			public GameObject Panel;

			public float ContentLeft;

			public readonly List<(CheckboxItem item, Image check)> Checkboxes = new List<(CheckboxItem, Image)>();
		}

		private struct LangText
		{
			public Text Label;

			public string Zh;

			public string En;
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static Action <0>__ToggleFromLauncher;

			public static UnityAction <1>__Close;
		}

		private const float TitleBand = 48f;

		private const float SidePad = 20f;

		private const float OuterMargin = 30f;

		private const float TabWidth = 105f;

		private const float TabHeight = 27f;

		private const float TabSpacing = 4f;

		private const float TabLeft = 8f;

		private const float ContentMinWidth = 460f;

		private const float RowSpacing = 12f;

		private const float ButtonHeight = 30f;

		private const float BottomPad = 24f;

		private const int BodyFontSize = 15;

		private const int ButtonFontSize = 14;

		private static readonly List<LangText> langTexts = new List<LangText>();

		private static GameObject window;

		private static RectTransform windowRect;

		private static RectTransform bodyHost;

		private static Transform panelBgTransform;

		private static readonly List<PageView> views = new List<PageView>();

		private static int builtRevision = -1;

		private static string pendingPage;

		private static bool pending;

		public static string CurrentPageKey { get; private set; }

		public static bool IsOpen
		{
			get
			{
				if ((Object)(object)window != (Object)null)
				{
					return window.activeSelf;
				}
				return false;
			}
		}

		private static bool InGame
		{
			get
			{
				if ((Object)(object)GameMain.instance != (Object)null && GameMain.isRunning && !GameMain.instance.isMenuDemo && (Object)(object)UIRoot.instance != (Object)null)
				{
					return (Object)(object)UIRoot.instance.uiGame != (Object)null;
				}
				return false;
			}
		}

		private static void BindText(Text label, string zh, string en)
		{
			if (!((Object)(object)label == (Object)null))
			{
				label.text = L10n.Pick(zh, en);
				langTexts.Add(new LangText
				{
					Label = label,
					Zh = zh,
					En = en
				});
			}
		}

		public static void RequestOpen(string key)
		{
			pendingPage = key;
			pending = true;
		}

		public static void Close()
		{
			pending = false;
			if ((Object)(object)window != (Object)null)
			{
				window.SetActive(false);
			}
		}

		public static void OnLanguageChanged()
		{
			if (langTexts.Count == 0)
			{
				return;
			}
			for (int i = 0; i < langTexts.Count; i++)
			{
				LangText langText = langTexts[i];
				if ((Object)(object)langText.Label != (Object)null)
				{
					langText.Label.text = L10n.Pick(langText.Zh, langText.En);
				}
			}
			FitTabColumn();
			if (IsOpen)
			{
				RefitFrameToContent();
			}
		}

		private static void FitTabColumn()
		{
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			if (views.Count == 0)
			{
				return;
			}
			float num = 105f;
			foreach (PageView view in views)
			{
				string text = ((view.Page != null) ? L10n.Pick(view.Page.TitleZh, view.Page.TitleEn) : "");
				num = Mathf.Max(num, MeasureTabWidth(text) + 24f);
			}
			float x = 8f + num + 20f;
			foreach (PageView view2 in views)
			{
				if ((Object)(object)view2.Tab != (Object)null)
				{
					Transform transform = ((Component)view2.Tab).transform;
					RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
					if (val != null)
					{
						val.sizeDelta = new Vector2(num, 27f);
					}
				}
				if ((Object)(object)view2.Panel != (Object)null)
				{
					Transform transform2 = view2.Panel.transform;
					RectTransform val2 = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null);
					if (val2 != null)
					{
						Vector2 anchoredPosition = val2.anchoredPosition;
						anchoredPosition.x = x;
						val2.anchoredPosition = anchoredPosition;
					}
				}
			}
		}

		public static void OnGameEnd()
		{
			if (!((Object)(object)GameMain.instance != (Object)null) || !GameMain.instance.isMenuDemo)
			{
				Close();
			}
		}

		public static void OnGameUiUpdate()
		{
			if (!InGame)
			{
				return;
			}
			LauncherButton.Update(ToggleFromLauncher);
			if (pending)
			{
				pending = false;
				Open(pendingPage);
			}
			if (IsOpen)
			{
				if (VFInput.escape)
				{
					VFInput.UseEscape();
					Close();
				}
				else
				{
					SyncCheckboxes();
				}
			}
		}

		private static void ToggleFromLauncher()
		{
			if (IsOpen)
			{
				Close();
			}
			else
			{
				Open(CurrentPageKey);
			}
		}

		private static void Open(string key)
		{
			if ((Object)(object)window == (Object)null || builtRevision != UIPanel.Revision)
			{
				Rebuild();
			}
			if (!((Object)(object)window == (Object)null))
			{
				PageView pageView = views.Find((PageView v) => v.Page.Key == key) ?? ((views.Count > 0) ? views[0] : null);
				if (key != null && pageView != null && pageView.Page.Key != key)
				{
					Plugin.Log.LogWarning((object)("OpenPage: no page \"" + key + "\", showing \"" + pageView.Page.Key + "\" instead."));
				}
				ShowPage(pageView);
				window.SetActive(true);
				window.transform.SetAsLastSibling();
				RefitFrameToContent();
				SyncCheckboxes();
			}
		}

		private static void ShowPage(PageView current)
		{
			CurrentPageKey = current?.Page.Key;
			foreach (PageView view in views)
			{
				bool flag = view == current;
				view.Panel.SetActive(flag);
				view.Tab.highlighted = flag;
			}
		}

		private static void SyncCheckboxes()
		{
			foreach (PageView view in views)
			{
				if (!view.Panel.activeSelf)
				{
					continue;
				}
				foreach (var (checkboxItem, val) in view.Checkboxes)
				{
					if ((Object)(object)val != (Object)null && ((Behaviour)val).enabled != checkboxItem.Entry.Value)
					{
						((Behaviour)val).enabled = checkboxItem.Entry.Value;
					}
				}
			}
		}

		private static void Rebuild()
		{
			//IL_0019: 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_001e: 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)
			Vector2 anchoredPosition = (((Object)(object)windowRect != (Object)null) ? windowRect.anchoredPosition : Vector2.zero);
			if ((Object)(object)window != (Object)null)
			{
				Object.Destroy((Object)(object)window);
			}
			window = null;
			views.Clear();
			langTexts.Clear();
			try
			{
				Build();
				windowRect.anchoredPosition = anchoredPosition;
				builtRevision = UIPanel.Revision;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Failed to build the panel window: " + ex));
				if ((Object)(object)window != (Object)null)
				{
					Object.Destroy((Object)(object)window);
				}
				window = null;
				views.Clear();
				langTexts.Clear();
			}
		}

		private static void Build()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected O, but got Unknown
			//IL_011a: 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_014c: 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_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Expected O, but got Unknown
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			GameObject gameObject = ((Component)UIRoot.instance.uiGame.inserterWindow).gameObject;
			GameObject val = new GameObject("cat-holder");
			val.SetActive(false);
			window = Object.Instantiate<GameObject>(gameObject, val.transform, false);
			Object.DestroyImmediate((Object)(object)window.GetComponent<UIInserterWindow>());
			NestPanelBgOnRoot(window.transform);
			for (int num = window.transform.childCount - 1; num >= 0; num--)
			{
				GameObject gameObject2 = ((Component)window.transform.GetChild(num)).gameObject;
				if (((Object)gameObject2).name != "panel-bg" && ((Object)gameObject2).name != "shadow")
				{
					Object.DestroyImmediate((Object)(object)gameObject2);
				}
			}
			((Object)window).name = "cat-ui-harness-window";
			window.transform.SetParent(gameObject.transform.parent, false);
			Object.Destroy((Object)(object)val);
			window.SetActive(false);
			windowRect = (RectTransform)window.transform;
			windowRect.anchorMin = new Vector2(0.5f, 0.5f);
			windowRect.anchorMax = new Vector2(0.5f, 0.5f);
			windowRect.pivot = new Vector2(0.5f, 0.5f);
			Transform val2 = FindPanelBg(window.transform);
			if ((Object)(object)val2 == (Object)null)
			{
				throw new InvalidOperationException("panel-bg not found on inserter window template");
			}
			Transform obj = val2.Find("title-text");
			Text val3 = ((obj != null) ? ((Component)obj).GetComponent<Text>() : null);
			if ((Object)(object)val3 != (Object)null)
			{
				Widgets.StripLocalizers(((Component)val3).gameObject);
				BindText(val3, "猫猫面板(F9)", "Cat Panel (F9)");
			}
			Button[] componentsInChildren = ((Component)val2).GetComponentsInChildren<Button>(true);
			foreach (Button obj2 in componentsInChildren)
			{
				obj2.onClick = new ButtonClickedEvent();
				ButtonClickedEvent onClick = obj2.onClick;
				object obj3 = <>O.<1>__Close;
				if (obj3 == null)
				{
					UnityAction val4 = Close;
					<>O.<1>__Close = val4;
					obj3 = (object)val4;
				}
				((UnityEvent)onClick).AddListener((UnityAction)obj3);
			}
			RectTransform parent = Widgets.CreateBodyHost(val2, 56f);
			float num2 = 105f;
			foreach (Page page in UIPanel.Pages)
			{
				num2 = Mathf.Max(num2, MeasureTabWidth(page.Title) + 24f);
			}
			float num3 = 8f + num2 + 20f;
			float num4 = 460f;
			float num5 = 0f;
			float num6 = 0f;
			if (UIPanel.Pages.Count == 0)
			{
				Text obj4 = Widgets.CreateLabel((Transform)(object)parent, "", 0f, 0f, num4 + num3);
				BindText(obj4, "还没有 mod 在这里注册页面。", "No mod has registered a page yet.");
				num6 = ((Graphic)obj4).rectTransform.sizeDelta.y;
			}
			foreach (Page page2 in UIPanel.Pages)
			{
				PageView captured;
				PageView pageView = (captured = new PageView
				{
					Page = page2
				});
				pageView.Tab = Widgets.CreateTabButton((Transform)(object)parent, page2.Title, 8f, num5, num2, 27f, delegate
				{
					ShowPage(captured);
					SyncCheckboxes();
				});
				Transform obj5 = ((Component)pageView.Tab).transform.Find("Text");
				BindText((obj5 != null) ? ((Component)obj5).GetComponent<Text>() : null, page2.TitleZh, page2.TitleEn);
				num5 += 31f;
				RectTransform val5 = Widgets.PlaceTopLeft(new GameObject("page-" + page2.Key, new Type[1] { typeof(RectTransform) }).transform, num3, 0f, (Transform)(object)parent);
				val5.sizeDelta = new Vector2(num4, 8f);
				pageView.Panel = ((Component)val5).gameObject;
				pageView.ContentLeft = 0f;
				float num7 = 0f;
				foreach (PageItem item in page2.Items)
				{
					float num8 = BuildItem(pageView, item, (Transform)(object)val5, 0f, num7, num4);
					num7 += num8 + 12f;
				}
				num6 = Mathf.Max(num6, num7);
				((Component)pageView.Tab).transform.SetAsLastSibling();
				views.Add(pageView);
			}
			bodyHost = parent;
			panelBgTransform = val2;
			RefitFrameToContent();
		}

		private static void RefitFrameToContent()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			if ((Object)(object)windowRect == (Object)null || (Object)(object)bodyHost == (Object)null || (Object)(object)panelBgTransform == (Object)null)
			{
				return;
			}
			RefreshDynamicHeights(bodyHost);
			foreach (PageView view in views)
			{
				RelayoutPageStack((RectTransform)view.Panel.transform, view.ContentLeft);
			}
			AccumulateWidgetExtents(bodyHost, out var maxX, out var maxY);
			float w = 12f + maxX + 30f;
			float h = 56f + maxY + 12f + 30f;
			ApplyFrameSize(windowRect, panelBgTransform, window.transform.Find("shadow"), w, h);
		}

		private static void RefreshDynamicHeights(RectTransform body)
		{
			Canvas.ForceUpdateCanvases();
			Text[] componentsInChildren = ((Component)body).GetComponentsInChildren<Text>(true);
			foreach (Text val in componentsInChildren)
			{
				if (((Object)((Component)val).gameObject).name == "cat-label")
				{
					Widgets.RefreshLabelHeight(val);
				}
			}
			RectTransform[] componentsInChildren2 = ((Component)body).GetComponentsInChildren<RectTransform>(true);
			foreach (RectTransform val2 in componentsInChildren2)
			{
				if (((Object)((Component)val2).gameObject).name == "cat-checkbox")
				{
					Widgets.RefreshCheckboxRow(val2);
				}
			}
		}

		private static void RelayoutPageStack(RectTransform panel, float contentLeft)
		{
			if ((Object)(object)panel == (Object)null)
			{
				return;
			}
			float num = 0f;
			Transform transform = ((Component)panel).transform;
			for (int i = 0; i < transform.childCount; i++)
			{
				Transform child = transform.GetChild(i);
				if (((Object)child).name.StartsWith("cat-", StringComparison.Ordinal) && child is RectTransform)
				{
					float num2 = Widgets.MeasureStackRowHeight(child);
					Widgets.PlaceTopLeft(child, contentLeft, num, transform);
					num += num2 + 12f;
				}
			}
		}

		private static void AccumulateWidgetExtents(RectTransform body, out float maxX, out float maxY)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			maxX = 0f;
			maxY = 0f;
			RectTransform[] componentsInChildren = ((Component)body).GetComponentsInChildren<RectTransform>(true);
			foreach (RectTransform val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)(object)body))
				{
					string name = ((Object)((Component)val).gameObject).name;
					if (!(name != "cat-checkbox") || !(name != "cat-button") || !(name != "cat-label") || !(name != "cat-tab"))
					{
						OffsetFromBodyTopLeft(body, val, out var left, out var top);
						maxX = Mathf.Max(maxX, left + val.sizeDelta.x);
						maxY = Mathf.Max(maxY, top + val.sizeDelta.y);
					}
				}
			}
		}

		private static void OffsetFromBodyTopLeft(RectTransform body, RectTransform rt, out float left, out float top)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			left = 0f;
			top = 0f;
			RectTransform val = rt;
			while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)body)
			{
				left += val.anchoredPosition.x;
				top += 0f - val.anchoredPosition.y;
				Transform parent = ((Transform)val).parent;
				val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
			}
		}

		private static void NestPanelBgOnRoot(Transform root)
		{
			Transform val = FindPanelBg(root);
			if ((Object)(object)val == (Object)null || (Object)(object)val.parent == (Object)(object)root)
			{
				return;
			}
			Transform val2 = root.Find("shadow");
			if ((Object)(object)val2 != (Object)null && (Object)(object)val2.parent != (Object)(object)root)
			{
				val2.SetParent(root, false);
			}
			val.SetParent(root, false);
			for (int num = root.childCount - 1; num >= 0; num--)
			{
				Transform child = root.GetChild(num);
				if ((Object)(object)child != (Object)(object)val && (Object)(object)child != (Object)(object)val2)
				{
					Object.DestroyImmediate((Object)(object)((Component)child).gameObject);
				}
			}
		}

		private static Transform FindPanelBg(Transform root)
		{
			if ((Object)(object)root.Find("panel-bg") != (Object)null)
			{
				return root.Find("panel-bg");
			}
			Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if (((Object)val).name == "panel-bg")
				{
					return val;
				}
			}
			return null;
		}

		private static void ApplyFrameSize(RectTransform root, Transform panelBg, Transform shadow, float w, float h)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			root.sizeDelta = new Vector2(w, h);
			StretchChildFill(panelBg);
			StretchChildFill(shadow);
		}

		private static void StretchChildFill(Transform t)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0042: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)(object)((t is RectTransform) ? t : null);
			if (val != null)
			{
				val.anchorMin = Vector2.zero;
				val.anchorMax = Vector2.one;
				val.pivot = new Vector2(0.5f, 0.5f);
				val.anchoredPosition = Vector2.zero;
				val.offsetMin = Vector2.zero;
				val.offsetMax = Vector2.zero;
				((Transform)val).localScale = Vector3.one;
			}
		}

		private static float MeasureTabWidth(string text)
		{
			Text obj = Object.Instantiate<Text>(UIRoot.instance.uiGame.assemblerWindow.stateText);
			((Component)obj).gameObject.SetActive(false);
			Widgets.StripLocalizers(((Component)obj).gameObject);
			obj.text = text;
			obj.fontSize = 16;
			obj.horizontalOverflow = (HorizontalWrapMode)1;
			float preferredWidth = obj.preferredWidth;
			Object.Destroy((Object)(object)((Component)obj).gameObject);
			return preferredWidth;
		}

		private static float BuildItem(PageView view, PageItem item, Transform parent, float x, float y, float contentWidth)
		{
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			CheckboxItem checkboxItem = item as CheckboxItem;
			if (checkboxItem == null)
			{
				if (!(item is ButtonItem buttonItem))
				{
					if (item is LabelItem labelItem)
					{
						Text obj = Widgets.CreateLabel(parent, "", x, y, contentWidth, 15);
						BindText(obj, labelItem.TextZh, labelItem.TextEn);
						return ((Graphic)obj).rectTransform.sizeDelta.y;
					}
					return 0f;
				}
				float width = ((buttonItem.Width > 0f) ? buttonItem.Width : contentWidth);
				UIButton val = Widgets.CreateButton(parent, "", x, y, width, 30f, 14, buttonItem.OnClick);
				Transform obj2 = ((Component)val).transform.Find("button-text");
				BindText(((obj2 != null) ? ((Component)obj2).GetComponent<Text>() : null) ?? ((Component)val).GetComponentInChildren<Text>(true), buttonItem.TextZh, buttonItem.TextEn);
				return 30f;
			}
			UIButton btn;
			Image check;
			float result = Widgets.CreateCheckbox(parent, "", x, y, 15, contentWidth, out btn, out check);
			Transform obj3 = ((Component)btn).transform.Find("text");
			BindText((obj3 != null) ? ((Component)obj3).GetComponent<Text>() : null, checkboxItem.TextZh, checkboxItem.TextEn);
			btn.onClick += delegate
			{
				checkboxItem.Entry.Value = !checkboxItem.Entry.Value;
			};
			view.Checkboxes.Add((checkboxItem, check));
			return result;
		}
	}
	internal static class Widgets
	{
		public static readonly Color LabelColor = new Color(1f, 1f, 1f, 0.6f);

		private static readonly Color TabNormal = new Color(0.1f, 0.1f, 0.1f, 0.68f);

		private static readonly Color TabHighlight = new Color(0.9906f, 0.5897f, 0.3691f, 0.4f);

		internal const float SidePadBody = 12f;

		public static RectTransform PlaceTopLeft(Transform t, float left, float top, Transform parent)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0023: 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_0058: 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)
			RectTransform val = (RectTransform)t;
			if ((Object)(object)parent != (Object)null)
			{
				((Transform)val).SetParent(parent, false);
			}
			val.anchorMin = new Vector2(0f, 1f);
			val.anchorMax = new Vector2(0f, 1f);
			val.pivot = new Vector2(0f, 1f);
			((Transform)val).localScale = Vector3.one;
			val.anchoredPosition3D = new Vector3(left, 0f - top, 0f);
			return val;
		}

		public static RectTransform CreateContainer(string name, Transform parent)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			RectTransform val = (RectTransform)new GameObject(name, new Type[1] { typeof(RectTransform) }).transform;
			((Transform)val).SetParent(parent, false);
			val.anchorMin = Vector2.zero;
			val.anchorMax = Vector2.one;
			val.pivot = new Vector2(0.5f, 0.5f);
			val.offsetMin = Vector2.zero;
			val.offsetMax = Vector2.zero;
			return val;
		}

		public static RectTransform CreateBodyHost(Transform panelBg, float topInset)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_003a: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			RectTransform val = (RectTransform)new GameObject("cat-body", new Type[1] { typeof(RectTransform) }).transform;
			((Transform)val).SetParent(panelBg, false);
			val.anchorMin = Vector2.zero;
			val.anchorMax = Vector2.one;
			val.pivot = new Vector2(0.5f, 0.5f);
			val.offsetMin = new Vector2(12f, 12f);
			val.offsetMax = new Vector2(-12f, 0f - topInset);
			return val;
		}

		public static void StripLocalizers(GameObject go)
		{
			Localizer[] componentsInChildren = go.GetComponentsInChildren<Localizer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
		}

		public static void ResetUIButton(UIButton btn)
		{
			//IL_0014: 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_0038: Expected O, but got Unknown
			btn.highlighted = false;
			btn.data = 0;
			btn.tips = default(TipSettings);
			if ((Object)(object)btn.button != (Object)null)
			{
				btn.button.onClick = new ButtonClickedEvent();
				((Behaviour)btn.button).enabled = true;
				((Selectable)btn.button).interactable = true;
			}
		}

		public static UIButton CreateTabButton(Transform parent, string text, float x, float y, float width, float height, Action onClick)
		{
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			UIDESwarmPanel swarmPanel = UIRoot.instance.uiGame.dysonEditor.controlPanel.hierarchy.swarmPanel;
			UIButton val = Object.Instantiate<UIButton>(swarmPanel.orbitButtons[0], parent, false);
			((Object)((Component)val).gameObject).name = "cat-tab";
			((Component)val).gameObject.SetActive(true);
			ResetUIButton(val);
			StripLocalizers(((Component)val).gameObject);
			Image component = ((Component)val).GetComponent<Image>();
			if ((Object)(object)component != (Object)null)
			{
				component.sprite = swarmPanel.buttonDefaultSprite;
				((Behaviour)component).enabled = true;
			}
			Transform val2 = ((Component)val).transform.Find("frame");
			if ((Object)(object)val2 != (Object)null)
			{
				((Component)val2).gameObject.SetActive(false);
			}
			if (val.transitions != null && val.transitions.Length >= 2)
			{
				val.transitions[0].normalColor = TabNormal;
				val.transitions[0].highlightColorOverride = TabHighlight;
				val.transitions[1].normalColor = new Color(1f, 1f, 1f, 0.8f);
				val.transitions[1].highlightColorOverride = new Color(0.2f, 0.2f, 0.2f, 1f);
			}
			PlaceTopLeft(((Component)val).transform, x, y, parent).sizeDelta = new Vector2(width, height);
			Transform val3 = ((Component)val).transform.Find("Text");
			if ((Object)(object)val3 != (Object)null)
			{
				Text component2 = ((Component)val3).GetComponent<Text>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.text = text;
					component2.fontSize = 16;
					component2.fontStyle = (FontStyle)0;
					component2.alignment = (TextAnchor)4;
					component2.horizontalOverflow = (HorizontalWrapMode)1;
					component2.verticalOverflow = (VerticalWrapMode)0;
					RectTransform rectTransform = ((Graphic)component2).rectTransform;
					rectTransform.anchorMin = Vector2.zero;
					rectTransform.anchorMax = Vector2.one;
					rectTransform.pivot = new Vector2(0.5f, 0.5f);
					rectTransform.offsetMin = new Vector2(10f, 0f);
					rectTransform.offsetMax = new Vector2(-10f, 0f);
				}
				Shadow obj = ((Component)val3).GetComponent<Shadow>() ?? ((Component)val3).gameObject.AddComponent<Shadow>();
				obj.effectColor = new Color(0f, 0f, 0f, 0.4f);
				obj.effectDistance = new Vector2(1f, -1f);
			}
			val.onClick += delegate
			{
				SafeInvoke(onClick, text);
			};
			return val;
		}

		public static Text CreateLabel(Transform parent, string text, float x, float y, float width, int fontSize = 18)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			Text val = Object.Instantiate<Text>(UIRoot.instance.uiGame.assemblerWindow.stateText, parent, false);
			((Object)((Component)val).gameObject).name = "cat-label";
			((Component)val).gameObject.SetActive(true);
			StripLocalizers(((Component)val).gameObject);
			val.text = text;
			((Graphic)val).color = LabelColor;
			val.alignment = (TextAnchor)3;
			val.fontSize = fontSize;
			val.horizontalOverflow = (HorizontalWrapMode)0;
			val.verticalOverflow = (VerticalWrapMode)1;
			RectTransform obj = PlaceTopLeft(((Component)val).transform, x, y, parent);
			float num = (float)fontSize + 8f;
			obj.sizeDelta = new Vector2(width, num);
			obj.sizeDelta = new Vector2(width, Mathf.Max(num, val.preferredHeight + 8f));
			return val;
		}

		public static void RefreshLabelHeight(Text label)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)label == (Object)null))
			{
				Canvas.ForceUpdateCanvases();
				RectTransform rectTransform = ((Graphic)label).rectTransform;
				float num = (float)label.fontSize + 8f;
				rectTransform.sizeDelta = new Vector2(rectTransform.sizeDelta.x, Mathf.Max(num, label.preferredHeight + 8f));
			}
		}

		public static void RefreshCheckboxRow(RectTransform host)
		{
			//IL_0096: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)host == (Object)null || ((Object)host).name != "cat-checkbox")
			{
				return;
			}
			Transform obj = ((Transform)host).Find("cat-checkbox-box");
			RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null);
			Text val2 = ((Component)host).GetComponentInChildren<Text>(true);
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || ((Object)((Component)val2).gameObject).name != "text")
			{
				object obj2;
				if (!((Object)(object)val != (Object)null))
				{
					obj2 = null;
				}
				else
				{
					Transform obj3 = ((Transform)val).Find("text");
					obj2 = ((obj3 != null) ? ((Component)obj3).GetComponent<Text>() : null);
				}
				val2 = (Text)obj2;
			}
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null))
			{
				float x = val.sizeDelta.x;
				float y = val.sizeDelta.y;
				float num = ((Graphic)val2).rectTransform.sizeDelta.x;
				if (num <= 0f)
				{
					num = 200f;
				}
				float num2 = LayoutCheckboxLabel(val2, x, y, num);
				host.sizeDelta = new Vector2(Mathf.Max(host.sizeDelta.x, x + 6f + num), num2);
			}
		}

		private static float LayoutCheckboxLabel(Text t, float boxW, float boxH, float labelW)
		{
			//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_0041: 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_0098: 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)
			Canvas.ForceUpdateCanvases();
			RectTransform rectTransform = ((Graphic)t).rectTransform;
			rectTransform.anchorMin = new Vector2(0f, 1f);
			rectTransform.anchorMax = new Vector2(0f, 1f);
			rectTransform.pivot = new Vector2(0f, 1f);
			rectTransform.anchoredPosition = new Vector2(boxW + 4f, 0f);
			float preferredHeight = t.preferredHeight;
			if (preferredHeight <= boxH + 1f)
			{
				t.alignment = (TextAnchor)3;
				rectTransform.sizeDelta = new Vector2(labelW, boxH);
			}
			else
			{
				t.alignment = (TextAnchor)0;
				rectTransform.sizeDelta = new Vector2(labelW, preferredHeight);
			}
			return Mathf.Max(boxH, preferredHeight + 2f);
		}

		public static UIButton CreateButton(Transform parent, string text, float x, float y, float width, float height, int fontSize, Action onClick)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			UIButton val = Object.Instantiate<UIButton>(UIRoot.instance.uiGame.statWindow.performancePanelUI.cpuActiveButton, parent, false);
			((Object)((Component)val).gameObject).name = "cat-button";
			((Component)val).gameObject.SetActive(true);
			ResetUIButton(val);
			StripLocalizers(((Component)val).gameObject);
			PlaceTopLeft(((Component)val).transform, x, y, parent).sizeDelta = new Vector2(width, height);
			Transform obj = ((Component)val).transform.Find("button-text");
			Text val2 = ((obj != null) ? ((Component)obj).GetComponent<Text>() : null) ?? ((Component)val).GetComponentInChildren<Text>(true);
			if ((Object)(object)val2 != (Object)null)
			{
				val2.text = text;
				val2.fontSize = fontSize;
			}
			val.onClick += delegate
			{
				SafeInvoke(onClick, text);
			};
			return val;
		}

		public static float CreateCheckbox(Transform parent, string text, float x, float y, int fontSize, float maxRowWidth, out UIButton btn, out Image check)
		{
			//IL_0018: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = PlaceTopLeft(new GameObject("cat-checkbox", new Type[1] { typeof(RectTransform) }).transform, x, y, parent);
			UIButton uxFacilityCheck = UIRoot.instance.uiGame.buildMenu.uxFacilityCheck;
			btn = Object.Instantiate<UIButton>(uxFacilityCheck, (Transform)(object)val, false);
			((Object)((Component)btn).gameObject).name = "cat-checkbox-box";
			((Component)btn).gameObject.SetActive(true);
			ResetUIButton(btn);
			StripLocalizers(((Component)btn).gameObject);
			RectTransform obj = PlaceTopLeft(((Component)btn).transform, 0f, 0f, (Transform)(object)val);
			float x2 = obj.sizeDelta.x;
			float y2 = obj.sizeDelta.y;
			Transform obj2 = ((Component)btn).transform.Find("checked");
			check = ((obj2 != null) ? ((Component)obj2).GetComponent<Image>() : null);
			Transform obj3 = ((Component)btn).transform.Find("text");
			Text val2 = ((obj3 != null) ? ((Component)obj3).GetComponent<Text>() : null);
			float num = Mathf.Max(60f, maxRowWidth - x2 - 6f);
			float num2 = y2;
			if ((Object)(object)val2 != (Object)null)
			{
				((Graphic)val2).raycastTarget = false;
				val2.text = text;
				val2.fontSize = fontSize;
				val2.horizontalOverflow = (HorizontalWrapMode)0;
				val2.verticalOverflow = (VerticalWrapMode)1;
				num2 = LayoutCheckboxLabel(val2, x2, y2, num);
			}
			val.sizeDelta = new Vector2(x2 + 6f + num, num2);
			return num2;
		}

		public static float MeasureStackRowHeight(Transform row)
		{
			//IL_0093: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)(object)((row is RectTransform) ? row : null);
			if (val == null)
			{
				return 0f;
			}
			if (((Object)row).name == "cat-checkbox")
			{
				Text componentInChildren = ((Component)row).GetComponentInChildren<Text>(true);
				Transform obj = row.Find("cat-checkbox-box");
				RectTransform val2 = (RectTransform)(object)((obj is RectTransform) ? obj : null);
				float num = (((Object)(object)val2 != (Object)null) ? val2.sizeDelta.y : 0f);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					return Mathf.Max(new float[3]
					{
						num,
						componentInChildren.preferredHeight + 2f,
						val.sizeDelta.y
					});
				}
			}
			return Mathf.Max(1f, val.sizeDelta.y);
		}

		public static void SafeInvoke(Action action, string what)
		{
			try
			{
				action();
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Callback of \"{what}\" threw: {arg}");
			}
		}
	}
}