Decompiled source of ModsApp v1.2.3

ModsApp.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using ModsApp;
using ModsApp.Helpers;
using ModsApp.Helpers.Registries;
using ModsApp.Managers;
using ModsApp.UI;
using ModsApp.UI.Input;
using ModsApp.UI.Input.FieldFactories;
using ModsApp.UI.Input.Handlers;
using ModsApp.UI.Panels;
using ModsApp.UI.Search;
using ModsApp.UI.Themes;
using Mono.Cecil;
using Mono.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using S1API.Input;
using S1API.Internal.Abstraction;
using S1API.PhoneApp;
using S1API.UI;
using S1API.Utils;
using Semver;
using Tomlet;
using Tomlet.Models;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(global::ModsApp.ModsApp), "ModsApp", "1.2.3", "k073l", "https://github.com/k073l/s1-modsapp")]
[assembly: MelonColor(1, 255, 0, 0)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: MelonPriority(-2147483548)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ModsApp")]
[assembly: AssemblyConfiguration("Mono")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+84d0320a8654110bf585a4847cda4d4858bd8691")]
[assembly: AssemblyProduct("ModsApp")]
[assembly: AssemblyTitle("ModsApp")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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 ModsApp
{
	public class App : PhoneApp
	{
		[CompilerGenerated]
		private sealed class <WaitForModsIcon>d__16 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public App <>4__this;

			private Transform <modsappIcon>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <WaitForModsIcon>d__16(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<modsappIcon>5__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if ((Object)(object)(<modsappIcon>5__1 = _homeScreenInstanceTransform.FindInHierarchy("AppIcons/Mods")) == (Object)null)
				{
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 1;
					return true;
				}
				NotificationBadge.Initialize(<modsappIcon>5__1);
				if (ModVersionTracker.AreAnyUpdatedOrNew())
				{
					NotificationBadge.ShowDot();
				}
				UpdateNotificationBadge();
				LogManager.Instance.OnError += UpdateNotificationBadge;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static App Instance;

		private static Instance _logger = Melon<ModsApp>.Logger;

		private static Transform _homeScreenInstanceTransform;

		private UIManager _uiManager;

		private ModManager _modManager;

		protected override string AppName => "Mods";

		protected override string AppTitle => "Mods";

		protected override string IconLabel => "Mods";

		protected override string IconFileName => Path.Combine(MelonEnvironment.UserDataDirectory, "ModsApp", "appicon.png");

		protected override void OnCreated()
		{
			if (!((PhoneApp)this).SetIconSprite(IconRegistry.AppIconSprite))
			{
				_logger.Error("[Pre-base] Failed to set app icon sprite");
			}
			((PhoneApp)this).OnCreated();
			Instance = this;
			_modManager = new ModManager(_logger);
			_logger.Msg($"ModsApp initialized with {_modManager.ModCount} mods");
		}

		protected override void OnCreatedUI(GameObject container)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			try
			{
				_uiManager = new UIManager(container, _modManager, _logger);
				_uiManager.Initialize();
			}
			catch (Exception ex)
			{
				_logger.Error("UI initialization failed: " + ex.Message);
				_logger.Error(ex.StackTrace);
			}
			Component val = (Component)(typeof(PhoneApp).GetField("_homeScreenInstance", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(this));
			_homeScreenInstanceTransform = (((Object)(object)val != (Object)null) ? val.transform : container.transform.root.FindInHierarchy("Player_Local/CameraContainer/Camera/OverlayCamera/GameplayMenu/Phone/phone/HomeScreen"));
			if ((Object)(object)_homeScreenInstanceTransform != (Object)null)
			{
				MelonCoroutines.Start(WaitForModsIcon());
			}
		}

		protected override void OnPhoneClosed()
		{
			Controls.IsTyping = false;
			DropdownComponent<object>.CloseAll();
			FloatingPanelComponent.Cleanup();
			PhoneSizeManager.Instance.Collapse();
			((PhoneApp)this).OnPhoneClosed();
		}

		[IteratorStateMachine(typeof(<WaitForModsIcon>d__16))]
		private IEnumerator WaitForModsIcon()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitForModsIcon>d__16(0)
			{
				<>4__this = this
			};
		}

		private static void UpdateNotificationBadge()
		{
			if (LogManager.Instance.ModsWithErrors.Count > 0)
			{
				NotificationBadge.ShowCount(LogManager.Instance.ModsWithErrors.Count);
			}
		}
	}
	public static class BuildInfo
	{
		public const string Name = "ModsApp";

		public const string Description = "In-game app to manage mods' preferences";

		public const string DownloadLink = "https://github.com/k073l/s1-modsapp";

		public const string Author = "k073l";

		public const string Version = "1.2.3";
	}
	public class ModsApp : MelonMod
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static LemonAction <0>__OnDefiniteQuit;
		}

		private static Instance _logger;

		private bool _shouldUpdate = true;

		public override void OnInitializeMelon()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			_logger = ((MelonBase)this).LoggerInstance;
			LogManager.Instance.WireEvents();
			IconRegistry.Prefetch();
			SettingsRegistry.Initialize();
			ReflectionHelper.TryInitTMP();
			ReflectionHelper.TryInitGameTypes();
			CategoryState.Load();
			ModVersionTracker.Load();
			MelonEvent onApplicationDefiniteQuit = MelonEvents.OnApplicationDefiniteQuit;
			object obj = <>O.<0>__OnDefiniteQuit;
			if (obj == null)
			{
				LemonAction val = OnDefiniteQuit;
				<>O.<0>__OnDefiniteQuit = val;
				obj = (object)val;
			}
			((MelonEventBase<LemonAction>)(object)onApplicationDefiniteQuit).Subscribe((LemonAction)obj, 0, false);
			_logger.Msg("ModsApp initialized");
		}

		public override void OnUpdate()
		{
			if (!_shouldUpdate)
			{
				return;
			}
			try
			{
				InitHelper.CloseAppAndPanels();
			}
			catch (Exception arg)
			{
				_shouldUpdate = false;
				_logger.Error($"Update loop error. This can happen if S1API is not installed.\nException: {arg}");
			}
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			if (sceneName == "Menu")
			{
				MissingDepsPanelComponent.CheckAndShow();
			}
			else
			{
				MissingDepsPanelComponent.Hide();
			}
		}

		private static void OnDefiniteQuit()
		{
			ModToggleManager.ApplyPendingChanges(_logger);
			CategoryState.Save();
			ModVersionTracker.Save();
		}
	}
}
namespace ModsApp.UI
{
	public static class ModToggleUI
	{
		private static ModManager _modManager;

		public static void Initialize(ModManager modManager)
		{
			_modManager = modManager;
		}

		public static Toggle CreateToggleForActive(MelonMod mod, Transform parent, UITheme theme, Action onToggled = null)
		{
			MelonAssembly melonAssembly = ((MelonBase)mod).MelonAssembly;
			string text = ((melonAssembly == null) ? null : melonAssembly.Assembly?.Location);
			if (string.IsNullOrEmpty(text))
			{
				return null;
			}
			if (ModToggleManager.IsProtected(text))
			{
				return null;
			}
			return CreateModToggle(text, parent, theme, onToggled);
		}

		public static Toggle CreateToggleForInactive(InactiveModInfo mod, Transform parent, UITheme theme, Action onToggled = null)
		{
			if (ModToggleManager.IsProtected(mod.ActivePath))
			{
				return null;
			}
			return CreateModToggle(mod.ActivePath, parent, theme, onToggled);
		}

		private static Toggle CreateModToggle(string dllPath, Transform parent, UITheme theme, Action onToggled = null)
		{
			var (toggle, refreshColors) = ToggleFactory.CreateModToggleSlider(parent, "ModToggle", ModToggleManager.GetDesiredState(dllPath), ModToggleManager.HasPendingChange(dllPath));
			ToggleUtils.AddListener(toggle, (Action<bool>)delegate(bool val)
			{
				HandleToggleClick(dllPath, val, toggle, refreshColors, theme);
				onToggled?.Invoke();
			});
			return toggle;
		}

		private static void HandleToggleClick(string dllPath, bool newVal, Toggle toggle, Action<bool, bool> refreshColors, UITheme theme)
		{
			bool shiftHeld = Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303);
			if (ModToggleManager.HasBothFiles(dllPath) && !ModToggleManager.HasConfirmedOverwrite(dllPath))
			{
				ShowOverwriteConflictPanel(dllPath, newVal, toggle, refreshColors, theme, shiftHeld);
			}
			else
			{
				ProcessToggle(dllPath, newVal, toggle, refreshColors, theme, shiftHeld);
			}
		}

		private static void ProcessToggle(string dllPath, bool newVal, Toggle toggle, Action<bool, bool> refreshColors, UITheme theme, bool shiftHeld)
		{
			if (!newVal)
			{
				List<MelonMod> list = _modManager?.GetDependants(dllPath) ?? new List<MelonMod>();
				if (list.Count > 0 && !shiftHeld)
				{
					toggle.SetIsOnWithoutNotify(true);
					refreshColors(arg1: true, ModToggleManager.HasPendingChange(dllPath));
					ShowDependencyWarningPanel(dllPath, list, toggle, refreshColors, theme);
					return;
				}
				ModToggleManager.RequestDisable(dllPath);
				if (!(list.Count > 0 && shiftHeld))
				{
					foreach (MelonMod item in list)
					{
						MelonAssembly melonAssembly = ((MelonBase)item).MelonAssembly;
						string text = ((melonAssembly == null) ? null : melonAssembly.Assembly?.Location);
						if (!string.IsNullOrEmpty(text))
						{
							ModToggleManager.RequestDisable(text);
						}
					}
				}
			}
			else
			{
				ModToggleManager.RequestEnable(dllPath);
			}
			refreshColors(newVal, ModToggleManager.HasPendingChange(dllPath));
			UIManager.ModListPanel?.UpdateButtonHighlights();
		}

		private static void ShowOverwriteConflictPanel(string dllPath, bool isEnabling, Toggle sourceToggle, Action<bool, bool> refreshColors, UITheme theme, bool shiftHeld)
		{
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Expected O, but got Unknown
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Expected O, but got Unknown
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			FloatingPanelComponent floatingPanelComponent = new FloatingPanelComponent(480f, 300f, "File Conflict");
			Transform transform = floatingPanelComponent.ContentPanel.transform;
			bool desiredState = ModToggleManager.GetDesiredState(dllPath);
			sourceToggle.SetIsOnWithoutNotify(desiredState);
			refreshColors(desiredState, ModToggleManager.HasPendingChange(dllPath));
			VerticalLayoutGroup val = floatingPanelComponent.ContentPanel.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val).spacing = 8f;
			((LayoutGroup)val).padding = new RectOffset(12, 12, 10, 10);
			((HorizontalOrVerticalLayoutGroup)val).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)val).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)val).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)val).childControlHeight = true;
			string text = (isEnabling ? "Both .dll and .inactive files exist for this mod.\n\nEnabling will overwrite the .dll file. Continue?" : "Both .dll and .inactive files exist for this mod.\n\nDisabling will overwrite the .inactive file. Continue?");
			Text val2 = UIFactory.Text("ConflictText", text, transform, theme.SizeStandard, (TextAnchor)0, (FontStyle)0);
			((Graphic)val2).color = theme.TextPrimary;
			((Component)val2).gameObject.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			((Component)val2).gameObject.AddComponent<ContentSizeFitter>().horizontalFit = (FitMode)0;
			((Component)val2).gameObject.GetOrAddComponent<LayoutElement>().flexibleWidth = 1f;
			GameObject val3 = new GameObject("Spacer");
			val3.transform.SetParent(transform, false);
			val3.AddComponent<LayoutElement>().flexibleHeight = 1f;
			GameObject val4 = new GameObject("BtnRow");
			val4.transform.SetParent(transform, false);
			HorizontalLayoutGroup val5 = val4.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val5).spacing = 8f;
			((LayoutGroup)val5).childAlignment = (TextAnchor)4;
			((HorizontalOrVerticalLayoutGroup)val5).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val5).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)val5).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)val5).childControlHeight = true;
			val4.AddComponent<LayoutElement>().preferredHeight = 30f;
			Button item = UIFactory.RoundedButtonWithLabel("OverwriteBtn", "Overwrite", val4.transform, theme.AccentPrimary, 100f, 28f, theme.SizeSmall, theme.TextPrimary).Item2;
			EventHelper.AddListener((Action)delegate
			{
				ModToggleManager.ConfirmOverwrite(dllPath);
				ProcessToggle(dllPath, isEnabling, sourceToggle, refreshColors, theme, shiftHeld);
				FloatingPanelComponent.Cleanup();
			}, (UnityEvent)(object)item.onClick);
			Button item2 = UIFactory.RoundedButtonWithLabel("CancelBtn", "Cancel", val4.transform, theme.AccentSecondary, 80f, 28f, theme.SizeSmall, theme.TextPrimary).Item2;
			string no = "";
			EventHelper.AddListener((Action)delegate
			{
				no = no;
				FloatingPanelComponent.Cleanup();
			}, (UnityEvent)(object)item2.onClick);
		}

		private static void ShowDependencyWarningPanel(string dllPath, List<MelonMod> dependants, Toggle sourceToggle, Action<bool, bool> refreshColors, UITheme theme)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Expected O, but got Unknown
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Expected O, but got Unknown
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			FloatingPanelComponent floatingPanelComponent = new FloatingPanelComponent(480f, 300f, "Dependency Warning");
			Transform transform = floatingPanelComponent.ContentPanel.transform;
			VerticalLayoutGroup val = floatingPanelComponent.ContentPanel.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val).spacing = 8f;
			((LayoutGroup)val).padding = new RectOffset(12, 12, 10, 10);
			((HorizontalOrVerticalLayoutGroup)val).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)val).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)val).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)val).childControlHeight = true;
			Text val2 = UIFactory.Text("WarnText", "The following mods depend on this one and may not work if it's disabled:\n\n" + string.Join(", ", dependants.Select((MelonMod d) => ((MelonBase)d).Info.Name)), transform, theme.SizeStandard, (TextAnchor)0, (FontStyle)0);
			((Graphic)val2).color = theme.TextPrimary;
			((Component)val2).gameObject.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			((Component)val2).gameObject.AddComponent<ContentSizeFitter>().horizontalFit = (FitMode)0;
			((Component)val2).gameObject.GetOrAddComponent<LayoutElement>().flexibleWidth = 1f;
			Text val3 = UIFactory.Text("HintText", "Hold Shift when clicking the toggle to disable only this mod (dependants stay enabled at your own risk).", transform, theme.SizeSmall, (TextAnchor)0, (FontStyle)2);
			((Graphic)val3).color = theme.TextSecondary;
			((Component)val3).gameObject.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			((Component)val3).gameObject.AddComponent<ContentSizeFitter>().horizontalFit = (FitMode)0;
			GameObject val4 = new GameObject("Spacer");
			val4.transform.SetParent(transform, false);
			val4.AddComponent<LayoutElement>().flexibleHeight = 1f;
			GameObject val5 = new GameObject("BtnRow");
			val5.transform.SetParent(transform, false);
			HorizontalLayoutGroup val6 = val5.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val6).spacing = 8f;
			((LayoutGroup)val6).childAlignment = (TextAnchor)4;
			((HorizontalOrVerticalLayoutGroup)val6).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val6).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)val6).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)val6).childControlHeight = true;
			val5.AddComponent<LayoutElement>().preferredHeight = 30f;
			Button item = UIFactory.RoundedButtonWithLabel("DisableAllBtn", "Disable All", val5.transform, theme.ErrorColor, 120f, 28f, theme.SizeSmall, theme.TextPrimary).Item2;
			EventHelper.AddListener((Action)delegate
			{
				ModToggleManager.RequestDisable(dllPath);
				foreach (MelonMod dependant in dependants)
				{
					MelonAssembly melonAssembly = ((MelonBase)dependant).MelonAssembly;
					string text = ((melonAssembly == null) ? null : melonAssembly.Assembly?.Location);
					if (!string.IsNullOrEmpty(text))
					{
						ModToggleManager.RequestDisable(text);
					}
				}
				sourceToggle.SetIsOnWithoutNotify(false);
				refreshColors(arg1: false, ModToggleManager.HasPendingChange(dllPath));
				UIManager.ModListPanel?.UpdateButtonHighlights();
				FloatingPanelComponent.Cleanup();
			}, (UnityEvent)(object)item.onClick);
			Button item2 = UIFactory.RoundedButtonWithLabel("CancelBtn", "Cancel", val5.transform, theme.AccentSecondary, 80f, 28f, theme.SizeSmall, theme.TextPrimary).Item2;
			string empty = "";
			EventHelper.AddListener((Action)delegate
			{
				empty = empty;
				FloatingPanelComponent.Cleanup();
			}, (UnityEvent)(object)item2.onClick);
		}
	}
	public static class NotificationBadge
	{
		private static GameObject _countBadge;

		private static GameObject _dotBadge;

		private static Image _countImage;

		private static Text _countText;

		private static Image _dotImage;

		private static bool _ready;

		public static void Initialize(Transform modsIcon)
		{
			_ready = false;
			try
			{
				if ((Object)(object)modsIcon == (Object)null)
				{
					return;
				}
				Transform val = modsIcon.Find("Notifications");
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				Transform val2 = val.Find("Text");
				if ((Object)(object)val2 == (Object)null)
				{
					return;
				}
				_countBadge = ((Component)val).gameObject;
				_countImage = ((Component)val).GetComponent<Image>();
				_countText = ((Component)val2).GetComponent<Text>();
				if (!((Object)(object)_countImage == (Object)null) && !((Object)(object)_countText == (Object)null))
				{
					_dotBadge = BuildDotBadge(val);
					if (!((Object)(object)_dotBadge == (Object)null))
					{
						_dotImage = _dotBadge.GetComponent<Image>();
						_countBadge.SetActive(false);
						_dotBadge.SetActive(false);
						_ready = true;
					}
				}
			}
			catch (Exception ex)
			{
				Melon<ModsApp>.Logger.Warning("[NotificationBadge] Init failed: " + ex.Message);
			}
		}

		public static void ShowCount(int count)
		{
			if (_ready && RefsValid())
			{
				if (count <= 0)
				{
					Hide();
					return;
				}
				_dotBadge.SetActive(false);
				((Component)_countText).gameObject.SetActive(true);
				_countText.text = ((count > 99) ? "99" : count.ToString());
				_countBadge.SetActive(true);
			}
		}

		public static void ShowDot()
		{
			if (_ready && RefsValid())
			{
				_countBadge.SetActive(true);
				_dotBadge.SetActive(true);
				((Component)_countText).gameObject.SetActive(false);
			}
		}

		public static void Hide()
		{
			if (_ready && RefsValid())
			{
				_countBadge.SetActive(false);
				_dotBadge.SetActive(false);
			}
		}

		private static bool RefsValid()
		{
			return (Object)(object)_countBadge != (Object)null && (Object)(object)_dotBadge != (Object)null && (Object)(object)_countImage != (Object)null && (Object)(object)_countText != (Object)null && (Object)(object)_dotImage != (Object)null;
		}

		private static GameObject BuildDotBadge(Transform sourceImage)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_0045: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				RectTransform component = ((Component)sourceImage).GetComponent<RectTransform>();
				if ((Object)(object)component == (Object)null)
				{
					return null;
				}
				GameObject val = new GameObject("NotificationDot");
				val.transform.SetParent(sourceImage.parent, false);
				RectTransform val2 = val.AddComponent<RectTransform>();
				val2.anchorMin = component.anchorMin;
				val2.anchorMax = component.anchorMax;
				val2.pivot = component.pivot;
				val2.sizeDelta = component.sizeDelta * 0.4f;
				val2.anchoredPosition = component.anchoredPosition;
				Image val3 = val.AddComponent<Image>();
				((Graphic)val3).color = Color.white;
				Image component2 = ((Component)sourceImage).GetComponent<Image>();
				if ((Object)(object)component2 != (Object)null)
				{
					val3.sprite = component2.sprite;
					val3.type = component2.type;
				}
				return val;
			}
			catch (Exception ex)
			{
				Melon<ModsApp>.Logger.Warning("[NotificationBadge] BuildDotBadge failed: " + ex.Message);
				return null;
			}
		}
	}
	public enum TextSizeProfile
	{
		ExtraSmall,
		Small,
		Normal,
		Large,
		ExtraLarge
	}
	public static class Tooltip
	{
		private class TooltipInstance
		{
			public GameObject Target;

			public string Text;

			public float MaxWidth;

			public EventTrigger Trigger;

			public Action<BaseEventData> EnterHandler;

			public Action<BaseEventData> ExitHandler;

			public WeakReference<GameObject> TargetRef;
		}

		[CompilerGenerated]
		private sealed class <ShowAfterDelay>d__22 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public TooltipInstance instance;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ShowAfterDelay>d__22(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.3f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (!IsTargetValid(instance.Target) || (Object)(object)_currentTarget != (Object)(object)instance.Target)
					{
						return false;
					}
					if ((Object)(object)_tooltipText == (Object)null || (Object)(object)_tooltipObject == (Object)null)
					{
						return false;
					}
					_tooltipText.text = WrapText(instance.Text, instance.MaxWidth);
					_tooltipObject.SetActive(true);
					PositionNearCursor();
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private static GameObject _tooltipObject;

		private static RectTransform _tooltipRect;

		private static Text _tooltipText;

		private static GameObject _tooltipCanvas;

		private static readonly Dictionary<GameObject, TooltipInstance> _instances = new Dictionary<GameObject, TooltipInstance>();

		private static object _showCoroutine;

		private static GameObject _currentTarget;

		private static float _maxWidth = float.MinValue;

		private const float ShowDelay = 0.3f;

		private const float CursorOffsetX = -5f;

		private const float CursorOffsetY = -57f;

		private const float TooltipWidthMultiplier = 12f;

		private const float TooltipMinWidth = 150f;

		private const float TooltipHeight = 32f;

		private const float TooltipPadding = 8f;

		public static void Attach(GameObject target, string text, float maxWidth = float.MinValue)
		{
			if (!((Object)(object)target == (Object)null))
			{
				_maxWidth = maxWidth;
				Detach(target);
				TooltipInstance instance = new TooltipInstance
				{
					Target = target,
					Text = text,
					MaxWidth = maxWidth,
					TargetRef = new WeakReference<GameObject>(target)
				};
				EventTrigger val = target.GetComponent<EventTrigger>() ?? target.AddComponent<EventTrigger>();
				instance.EnterHandler = delegate
				{
					OnPointerEnter(instance);
				};
				instance.ExitHandler = delegate
				{
					OnPointerExit(instance);
				};
				instance.Trigger = val;
				EventHelper.AddEventTrigger(val, (EventTriggerType)0, instance.EnterHandler);
				EventHelper.AddEventTrigger(val, (EventTriggerType)1, instance.ExitHandler);
				_instances[target] = instance;
				EnsureTooltipExists();
			}
		}

		public static void Detach(GameObject target)
		{
			if (!((Object)(object)target == (Object)null) && _instances.TryGetValue(target, out var value))
			{
				if ((Object)(object)value.Trigger != (Object)null)
				{
					EventHelper.RemoveEventTrigger(value.Trigger, (EventTriggerType)0, value.EnterHandler);
					EventHelper.RemoveEventTrigger(value.Trigger, (EventTriggerType)1, value.ExitHandler);
					Object.Destroy((Object)(object)value.Trigger);
				}
				_instances.Remove(target);
				if ((Object)(object)_currentTarget == (Object)(object)target)
				{
					_currentTarget = null;
					HideTooltip();
				}
			}
		}

		public static void Cleanup()
		{
			foreach (GameObject item in _instances.Keys.ToList())
			{
				Detach(item);
			}
			if (_showCoroutine != null)
			{
				MelonCoroutines.Stop(_showCoroutine);
			}
			if ((Object)(object)_tooltipObject != (Object)null)
			{
				Object.Destroy((Object)(object)_tooltipObject);
				_tooltipObject = null;
			}
			if ((Object)(object)_tooltipCanvas != (Object)null)
			{
				Object.Destroy((Object)(object)_tooltipCanvas);
				_tooltipCanvas = null;
			}
		}

		public static void Update()
		{
			TooltipInstance value;
			GameObject target;
			if ((Object)(object)_currentTarget == (Object)null)
			{
				HideTooltip();
			}
			else if (!_currentTarget.activeInHierarchy)
			{
				_currentTarget = null;
				HideTooltip();
			}
			else if (!_instances.TryGetValue(_currentTarget, out value))
			{
				_currentTarget = null;
				HideTooltip();
			}
			else if (!value.TargetRef.TryGetTarget(out target) || (Object)(object)target == (Object)null)
			{
				Detach(_currentTarget);
				_currentTarget = null;
				HideTooltip();
			}
			else
			{
				PositionNearCursor();
			}
		}

		private static void OnPointerEnter(TooltipInstance instance)
		{
			if (_showCoroutine != null)
			{
				MelonCoroutines.Stop(_showCoroutine);
			}
			if ((Object)(object)_currentTarget != (Object)(object)instance.Target)
			{
				HideTooltip();
			}
			_currentTarget = instance.Target;
			_showCoroutine = MelonCoroutines.Start(ShowAfterDelay(instance));
		}

		private static void OnPointerExit(TooltipInstance instance)
		{
			if ((Object)(object)_currentTarget == (Object)(object)instance.Target)
			{
				_currentTarget = null;
				HideTooltip();
			}
			if (_showCoroutine != null)
			{
				MelonCoroutines.Stop(_showCoroutine);
			}
		}

		[IteratorStateMachine(typeof(<ShowAfterDelay>d__22))]
		private static IEnumerator ShowAfterDelay(TooltipInstance instance)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ShowAfterDelay>d__22(0)
			{
				instance = instance
			};
		}

		private static void HideTooltip()
		{
			if ((Object)(object)_tooltipObject != (Object)null)
			{
				_tooltipObject.SetActive(false);
			}
		}

		private static void PositionNearCursor()
		{
			//IL_0017: 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_0037: 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)
			if (!((Object)(object)_tooltipRect == (Object)null))
			{
				((Transform)_tooltipRect).position = Vector2.op_Implicit(new Vector2(Input.mousePosition.x + -5f, Input.mousePosition.y + -57f));
			}
		}

		private static void EnsureTooltipExists()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			//IL_0116: 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_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: 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_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_tooltipObject != (Object)null))
			{
				if ((Object)(object)_tooltipCanvas == (Object)null)
				{
					_tooltipCanvas = new GameObject("ModsAppTooltipCanvas");
					Canvas val = _tooltipCanvas.AddComponent<Canvas>();
					val.renderMode = (RenderMode)0;
					val.sortingOrder = 999;
					_tooltipCanvas.AddComponent<CanvasScaler>();
					_tooltipCanvas.AddComponent<GraphicRaycaster>();
					Object.DontDestroyOnLoad((Object)(object)_tooltipCanvas);
				}
				UITheme theme = UIManager._theme;
				float num = ((_maxWidth > 0f) ? _maxWidth : ((theme == null) ? 150f : ((float)theme.SizeSmall * 12f)));
				_tooltipObject = new GameObject("Tooltip");
				_tooltipObject.transform.SetParent(_tooltipCanvas.transform, false);
				_tooltipObject.SetActive(false);
				Image val2 = _tooltipObject.AddComponent<Image>();
				val2.sprite = UIHelper.GetRoundedSprite();
				val2.type = (Type)1;
				((Graphic)val2).color = theme.BgPrimary;
				((Graphic)val2).raycastTarget = false;
				_tooltipRect = _tooltipObject.GetComponent<RectTransform>();
				_tooltipRect.pivot = new Vector2(0f, 0f);
				_tooltipRect.sizeDelta = new Vector2(num, 32f);
				_tooltipText = UIFactory.Text("TooltipText", string.Empty, _tooltipObject.transform, theme.SizeSmall, (TextAnchor)0, (FontStyle)0);
				((Graphic)_tooltipText).color = theme.TextPrimary;
				_tooltipText.horizontalOverflow = (HorizontalWrapMode)0;
				_tooltipText.verticalOverflow = (VerticalWrapMode)1;
				((Graphic)_tooltipText).raycastTarget = false;
				RectTransform component = ((Component)_tooltipText).GetComponent<RectTransform>();
				component.anchorMin = Vector2.zero;
				component.anchorMax = Vector2.one;
				component.offsetMin = new Vector2(8f, 8f);
				component.offsetMax = new Vector2(-8f, -8f);
			}
		}

		private static bool IsTargetValid(GameObject target)
		{
			if ((Object)(object)target == (Object)null)
			{
				return false;
			}
			if (!_instances.TryGetValue(target, out var value))
			{
				return false;
			}
			GameObject target2;
			return value.TargetRef.TryGetTarget(out target2) && (Object)(object)target2 != (Object)null;
		}

		private static string WrapText(string text, float maxWidth)
		{
			return text;
		}
	}
	public class UITheme
	{
		private ITheme _theme;

		private const int _sizeTiny = 10;

		private const int _sizeSmall = 12;

		private const int _sizeStandard = 14;

		private const int _sizeMedium = 16;

		private const int _sizeLarge = 20;

		private float _textScale = 1f;

		public Color BgPrimary => _theme.BgPrimary;

		public Color BgSecondary => _theme.BgSecondary;

		public Color BgCard => _theme.BgCard;

		public Color BgCategory => _theme.BgCategory;

		public Color BgInput => _theme.BgInput;

		public Color AccentPrimary => _theme.AccentPrimary;

		public Color AccentSecondary => _theme.AccentSecondary;

		public Color TextPrimary => _theme.TextPrimary;

		public Color TextSecondary => _theme.TextSecondary;

		public Color InputPrimary => _theme.InputPrimary;

		public Color InputSecondary => _theme.InputSecondary;

		public Color SuccessColor => _theme.SuccessColor;

		public Color WarningColor => _theme.WarningColor;

		public Color ErrorColor => _theme.ErrorColor;

		public Color JsonKeyColor => _theme.JsonKeyColor;

		public Color JsonStringColor => _theme.JsonStringColor;

		public Color JsonNumberColor => _theme.JsonNumberColor;

		public Color JsonLiteralColor => _theme.JsonLiteralColor;

		public Color JsonBracketColor => _theme.JsonBracketColor;

		public Color JsonPunctuationColor => _theme.JsonPunctuationColor;

		public int SizeTiny => Mathf.RoundToInt(10f * _textScale);

		public int SizeSmall => Mathf.RoundToInt(12f * _textScale);

		public int SizeStandard => Mathf.RoundToInt(14f * _textScale);

		public int SizeMedium => Mathf.RoundToInt(16f * _textScale);

		public int SizeLarge => Mathf.RoundToInt(20f * _textScale);

		public void SetTextScale(TextSizeProfile profile)
		{
			if (1 == 0)
			{
			}
			float textScale = profile switch
			{
				TextSizeProfile.ExtraSmall => 0.75f, 
				TextSizeProfile.Small => 0.85f, 
				TextSizeProfile.Normal => 1f, 
				TextSizeProfile.Large => 1.25f, 
				TextSizeProfile.ExtraLarge => 1.5f, 
				_ => 1f, 
			};
			if (1 == 0)
			{
			}
			_textScale = textScale;
		}

		public void SetTheme(ThemeOption theme)
		{
			if (1 == 0)
			{
			}
			ITheme theme2 = theme switch
			{
				ThemeOption.Forest => new Forest(), 
				ThemeOption.Metal => new Metal(), 
				ThemeOption.Neon => new Neon(), 
				ThemeOption.Ocean => new Ocean(), 
				ThemeOption.Slate => new Slate(), 
				ThemeOption.Solar => new Solar(), 
				ThemeOption.Twilight => new Twilight(), 
				ThemeOption.Custom => new Custom(), 
				_ => new Slate(), 
			};
			if (1 == 0)
			{
			}
			_theme = theme2;
		}

		public UITheme()
		{
			SetTextScale(SettingsRegistry.TextSizeProfileEntry.Value);
			SetTheme(SettingsRegistry.ThemeOptionEntry.Value);
		}

		internal void CopyThemeToCustom()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: 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_00fa: 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_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			if (SettingsRegistry.ThemeOptionEntry.Value != ThemeOption.Custom && _theme != null)
			{
				SettingsRegistry.BackgroundPrimaryEntry.Value = _theme.BgPrimary;
				SettingsRegistry.BackgroundSecondaryEntry.Value = _theme.BgSecondary;
				SettingsRegistry.BackgroundCardEntry.Value = _theme.BgCard;
				SettingsRegistry.BackgroundCategoryEntry.Value = _theme.BgCategory;
				SettingsRegistry.BackgroundInputEntry.Value = _theme.BgInput;
				SettingsRegistry.AccentPrimaryEntry.Value = _theme.AccentPrimary;
				SettingsRegistry.AccentSecondaryEntry.Value = _theme.AccentSecondary;
				SettingsRegistry.TextPrimaryEntry.Value = _theme.TextPrimary;
				SettingsRegistry.TextSecondaryEntry.Value = _theme.TextSecondary;
				SettingsRegistry.InputPrimaryEntry.Value = _theme.InputPrimary;
				SettingsRegistry.InputSecondaryEntry.Value = _theme.InputSecondary;
				SettingsRegistry.SuccessColorEntry.Value = _theme.SuccessColor;
				SettingsRegistry.WarningColorEntry.Value = _theme.WarningColor;
				SettingsRegistry.ErrorColorEntry.Value = _theme.ErrorColor;
			}
		}
	}
}
namespace ModsApp.UI.Themes
{
	public class Custom : ITheme
	{
		public Color BgPrimary => SettingsRegistry.BackgroundPrimaryEntry.Value;

		public Color BgSecondary => SettingsRegistry.BackgroundSecondaryEntry.Value;

		public Color BgCard => SettingsRegistry.BackgroundCardEntry.Value;

		public Color BgCategory => SettingsRegistry.BackgroundCategoryEntry.Value;

		public Color BgInput => SettingsRegistry.BackgroundInputEntry.Value;

		public Color AccentPrimary => SettingsRegistry.AccentPrimaryEntry.Value;

		public Color AccentSecondary => SettingsRegistry.AccentSecondaryEntry.Value;

		public Color TextPrimary => SettingsRegistry.TextPrimaryEntry.Value;

		public Color TextSecondary => SettingsRegistry.TextSecondaryEntry.Value;

		public Color InputPrimary => SettingsRegistry.InputPrimaryEntry.Value;

		public Color InputSecondary => SettingsRegistry.InputSecondaryEntry.Value;

		public Color SuccessColor => SettingsRegistry.SuccessColorEntry.Value;

		public Color WarningColor => SettingsRegistry.WarningColorEntry.Value;

		public Color ErrorColor => SettingsRegistry.ErrorColorEntry.Value;

		public Color JsonKeyColor => SettingsRegistry.JsonKeyColor.Value;

		public Color JsonStringColor => SettingsRegistry.JsonStringColor.Value;

		public Color JsonNumberColor => SettingsRegistry.JsonNumberColor.Value;

		public Color JsonLiteralColor => SettingsRegistry.JsonLiteralColor.Value;

		public Color JsonBracketColor => SettingsRegistry.JsonBracketColor.Value;

		public Color JsonPunctuationColor => SettingsRegistry.JsonPunctuationColor.Value;
	}
	public class Forest : ITheme
	{
		public Color BgPrimary => new Color(0.05f, 0.2f, 0.1f, 1f);

		public Color BgSecondary => new Color(0.1f, 0.25f, 0.15f, 1f);

		public Color BgCard => new Color(0.12f, 0.3f, 0.18f, 1f);

		public Color BgCategory => new Color(0.08f, 0.22f, 0.12f, 1f);

		public Color BgInput => new Color(0.95f, 0.98f, 0.95f, 1f);

		public Color AccentPrimary => new Color(0.15f, 0.7f, 0.3f, 1f);

		public Color AccentSecondary => new Color(0.1f, 0.5f, 0.2f, 1f);

		public Color TextPrimary => new Color(0.9f, 0.95f, 0.9f, 1f);

		public Color TextSecondary => new Color(0.65f, 0.75f, 0.65f, 0.75f);

		public Color InputPrimary => new Color(0.1f, 0.15f, 0.1f, 1f);

		public Color InputSecondary => new Color(0.45f, 0.5f, 0.45f, 1f);

		public Color SuccessColor => new Color(0.25f, 0.85f, 0.25f, 1f);

		public Color WarningColor => new Color(0.95f, 0.85f, 0.2f, 1f);

		public Color ErrorColor => new Color(0.9f, 0.25f, 0.2f, 1f);

		public Color JsonKeyColor => new Color(0.016f, 0.318f, 0.647f, 1f);

		public Color JsonStringColor => new Color(0.639f, 0.082f, 0.082f, 1f);

		public Color JsonNumberColor => new Color(0.035f, 0.525f, 0.345f, 1f);

		public Color JsonLiteralColor => new Color(0f, 0f, 1f, 1f);

		public Color JsonBracketColor => new Color(0.686f, 0f, 0.859f, 1f);

		public Color JsonPunctuationColor => new Color(0.2f, 0.2f, 0.2f, 1f);
	}
	public interface ITheme
	{
		Color BgPrimary { get; }

		Color BgSecondary { get; }

		Color BgCard { get; }

		Color BgCategory { get; }

		Color BgInput { get; }

		Color AccentPrimary { get; }

		Color AccentSecondary { get; }

		Color TextPrimary { get; }

		Color TextSecondary { get; }

		Color InputPrimary { get; }

		Color InputSecondary { get; }

		Color SuccessColor { get; }

		Color WarningColor { get; }

		Color ErrorColor { get; }

		Color JsonKeyColor { get; }

		Color JsonStringColor { get; }

		Color JsonNumberColor { get; }

		Color JsonLiteralColor { get; }

		Color JsonBracketColor { get; }

		Color JsonPunctuationColor { get; }
	}
	public class Metal : ITheme
	{
		public Color BgPrimary => new Color(0.18f, 0.18f, 0.2f, 1f);

		public Color BgSecondary => new Color(0.22f, 0.22f, 0.25f, 1f);

		public Color BgCard => new Color(0.25f, 0.25f, 0.28f, 1f);

		public Color BgCategory => new Color(0.2f, 0.2f, 0.23f, 1f);

		public Color BgInput => new Color(0.95f, 0.95f, 0.95f, 1f);

		public Color AccentPrimary => new Color(0.6f, 0.6f, 0.65f, 1f);

		public Color AccentSecondary => new Color(0.4f, 0.4f, 0.45f, 1f);

		public Color TextPrimary => new Color(0.95f, 0.95f, 0.95f, 1f);

		public Color TextSecondary => new Color(0.7f, 0.7f, 0.7f, 0.75f);

		public Color InputPrimary => new Color(0.1f, 0.1f, 0.12f, 1f);

		public Color InputSecondary => new Color(0.5f, 0.5f, 0.55f, 1f);

		public Color SuccessColor => new Color(0.2f, 0.8f, 0.2f, 1f);

		public Color WarningColor => new Color(0.95f, 0.75f, 0.2f, 1f);

		public Color ErrorColor => new Color(0.95f, 0.2f, 0.2f, 1f);

		public Color JsonKeyColor => new Color(0.016f, 0.318f, 0.647f, 1f);

		public Color JsonStringColor => new Color(0.639f, 0.082f, 0.082f, 1f);

		public Color JsonNumberColor => new Color(0.035f, 0.525f, 0.345f, 1f);

		public Color JsonLiteralColor => new Color(0f, 0f, 1f, 1f);

		public Color JsonBracketColor => new Color(0.686f, 0f, 0.859f, 1f);

		public Color JsonPunctuationColor => new Color(0.2f, 0.2f, 0.2f, 1f);
	}
	public class Neon : ITheme
	{
		public Color BgPrimary => new Color(0.05f, 0.05f, 0.1f, 1f);

		public Color BgSecondary => new Color(0.08f, 0.08f, 0.15f, 1f);

		public Color BgCard => new Color(0.1f, 0.1f, 0.2f, 1f);

		public Color BgCategory => new Color(0.06f, 0.06f, 0.12f, 1f);

		public Color BgInput => new Color(0.98f, 0.98f, 0.98f, 1f);

		public Color AccentPrimary => new Color(0f, 1f, 0.9f, 1f);

		public Color AccentSecondary => new Color(1f, 0.1f, 0.8f, 1f);

		public Color TextPrimary => new Color(0.95f, 0.95f, 0.95f, 1f);

		public Color TextSecondary => new Color(0.7f, 0.7f, 0.7f, 0.75f);

		public Color InputPrimary => new Color(0.05f, 0.05f, 0.05f, 1f);

		public Color InputSecondary => new Color(0.5f, 0.5f, 0.5f, 1f);

		public Color SuccessColor => new Color(0f, 1f, 0.4f, 1f);

		public Color WarningColor => new Color(1f, 0.8f, 0f, 1f);

		public Color ErrorColor => new Color(1f, 0.05f, 0.2f, 1f);

		public Color JsonKeyColor => new Color(0.016f, 0.318f, 0.647f, 1f);

		public Color JsonStringColor => new Color(0.639f, 0.082f, 0.082f, 1f);

		public Color JsonNumberColor => new Color(0.035f, 0.525f, 0.345f, 1f);

		public Color JsonLiteralColor => new Color(0f, 0f, 1f, 1f);

		public Color JsonBracketColor => new Color(0.686f, 0f, 0.859f, 1f);

		public Color JsonPunctuationColor => new Color(0.2f, 0.2f, 0.2f, 1f);
	}
	public class Ocean : ITheme
	{
		public Color BgPrimary => new Color(0.05f, 0.2f, 0.3f, 1f);

		public Color BgSecondary => new Color(0.08f, 0.25f, 0.35f, 1f);

		public Color BgCard => new Color(0.1f, 0.3f, 0.4f, 1f);

		public Color BgCategory => new Color(0.07f, 0.22f, 0.32f, 1f);

		public Color BgInput => new Color(0.9f, 0.95f, 0.98f, 1f);

		public Color AccentPrimary => new Color(0f, 0.6f, 0.9f, 1f);

		public Color AccentSecondary => new Color(0f, 0.4f, 0.7f, 1f);

		public Color TextPrimary => new Color(0.95f, 0.95f, 0.95f, 1f);

		public Color TextSecondary => new Color(0.7f, 0.8f, 0.85f, 0.75f);

		public Color InputPrimary => new Color(0.05f, 0.1f, 0.15f, 1f);

		public Color InputSecondary => new Color(0.45f, 0.55f, 0.65f, 1f);

		public Color SuccessColor => new Color(0.2f, 0.8f, 0.5f, 1f);

		public Color WarningColor => new Color(0.95f, 0.85f, 0.2f, 1f);

		public Color ErrorColor => new Color(0.9f, 0.25f, 0.2f, 1f);

		public Color JsonKeyColor => new Color(0.016f, 0.318f, 0.647f, 1f);

		public Color JsonStringColor => new Color(0.639f, 0.082f, 0.082f, 1f);

		public Color JsonNumberColor => new Color(0.035f, 0.525f, 0.345f, 1f);

		public Color JsonLiteralColor => new Color(0f, 0f, 1f, 1f);

		public Color JsonBracketColor => new Color(0.686f, 0f, 0.859f, 1f);

		public Color JsonPunctuationColor => new Color(0.2f, 0.2f, 0.2f, 1f);
	}
	public class Slate : ITheme
	{
		public Color BgPrimary => new Color(0.12f, 0.12f, 0.15f, 1f);

		public Color BgSecondary => new Color(0.16f, 0.16f, 0.2f, 1f);

		public Color BgCard => new Color(0.2f, 0.2f, 0.24f, 1f);

		public Color BgCategory => new Color(0.18f, 0.18f, 0.22f, 1f);

		public Color BgInput => new Color(0.98f, 0.98f, 0.98f, 1f);

		public Color AccentPrimary => new Color(0.26f, 0.59f, 0.98f, 1f);

		public Color AccentSecondary => new Color(0.15f, 0.15f, 0.18f, 1f);

		public Color TextPrimary => new Color(0.95f, 0.95f, 0.95f, 1f);

		public Color TextSecondary => new Color(0.7f, 0.7f, 0.7f, 0.75f);

		public Color InputPrimary => new Color(0.05f, 0.05f, 0.05f, 1f);

		public Color InputSecondary => new Color(0.5f, 0.5f, 0.5f, 1f);

		public Color SuccessColor => new Color(0.2f, 0.8f, 0.2f, 1f);

		public Color WarningColor => new Color(0.95f, 0.75f, 0.2f, 1f);

		public Color ErrorColor => new Color(0.95f, 0.2f, 0.2f, 1f);

		public Color JsonKeyColor => new Color(0.016f, 0.318f, 0.647f, 1f);

		public Color JsonStringColor => new Color(0.639f, 0.082f, 0.082f, 1f);

		public Color JsonNumberColor => new Color(0.035f, 0.525f, 0.345f, 1f);

		public Color JsonLiteralColor => new Color(0f, 0f, 1f, 1f);

		public Color JsonBracketColor => new Color(0.686f, 0f, 0.859f, 1f);

		public Color JsonPunctuationColor => new Color(0.2f, 0.2f, 0.2f, 1f);
	}
	public class Solar : ITheme
	{
		public Color BgPrimary => new Color(1f, 0.95f, 0.85f, 1f);

		public Color BgSecondary => new Color(0.98f, 0.9f, 0.75f, 1f);

		public Color BgCard => new Color(1f, 0.85f, 0.6f, 1f);

		public Color BgCategory => new Color(1f, 0.88f, 0.65f, 1f);

		public Color BgInput => new Color(1f, 1f, 1f, 1f);

		public Color AccentPrimary => new Color(1f, 0.6f, 0.1f, 1f);

		public Color AccentSecondary => new Color(0.85f, 0.45f, 0.05f, 1f);

		public Color TextPrimary => new Color(0.15f, 0.1f, 0.05f, 1f);

		public Color TextSecondary => new Color(0.35f, 0.25f, 0.15f, 0.75f);

		public Color InputPrimary => new Color(0.95f, 0.9f, 0.8f, 1f);

		public Color InputSecondary => new Color(0.7f, 0.6f, 0.5f, 1f);

		public Color SuccessColor => new Color(0.2f, 0.6f, 0.1f, 1f);

		public Color WarningColor => new Color(0.95f, 0.6f, 0.05f, 1f);

		public Color ErrorColor => new Color(0.85f, 0.1f, 0.05f, 1f);

		public Color JsonKeyColor => new Color(0.016f, 0.318f, 0.647f, 1f);

		public Color JsonStringColor => new Color(0.639f, 0.082f, 0.082f, 1f);

		public Color JsonNumberColor => new Color(0.035f, 0.525f, 0.345f, 1f);

		public Color JsonLiteralColor => new Color(0f, 0f, 1f, 1f);

		public Color JsonBracketColor => new Color(0.686f, 0f, 0.859f, 1f);

		public Color JsonPunctuationColor => new Color(0.2f, 0.2f, 0.2f, 1f);
	}
	public enum ThemeOption
	{
		Forest,
		Metal,
		Neon,
		Ocean,
		Slate,
		Solar,
		Twilight,
		Custom
	}
	public class Twilight : ITheme
	{
		public Color BgPrimary => new Color(0.1f, 0.05f, 0.25f, 1f);

		public Color BgSecondary => new Color(0.12f, 0.08f, 0.3f, 1f);

		public Color BgCard => new Color(0.15f, 0.1f, 0.35f, 1f);

		public Color BgCategory => new Color(0.11f, 0.07f, 0.28f, 1f);

		public Color BgInput => new Color(0.95f, 0.95f, 0.98f, 1f);

		public Color AccentPrimary => new Color(0.7f, 0.4f, 0.95f, 1f);

		public Color AccentSecondary => new Color(0.5f, 0.25f, 0.8f, 1f);

		public Color TextPrimary => new Color(0.95f, 0.95f, 0.95f, 1f);

		public Color TextSecondary => new Color(0.7f, 0.7f, 0.85f, 0.75f);

		public Color InputPrimary => new Color(0.08f, 0.05f, 0.12f, 1f);

		public Color InputSecondary => new Color(0.45f, 0.35f, 0.55f, 1f);

		public Color SuccessColor => new Color(0.2f, 0.8f, 0.2f, 1f);

		public Color WarningColor => new Color(0.95f, 0.75f, 0.2f, 1f);

		public Color ErrorColor => new Color(0.95f, 0.2f, 0.25f, 1f);

		public Color JsonKeyColor => new Color(0.016f, 0.318f, 0.647f, 1f);

		public Color JsonStringColor => new Color(0.639f, 0.082f, 0.082f, 1f);

		public Color JsonNumberColor => new Color(0.035f, 0.525f, 0.345f, 1f);

		public Color JsonLiteralColor => new Color(0f, 0f, 1f, 1f);

		public Color JsonBracketColor => new Color(0.686f, 0f, 0.859f, 1f);

		public Color JsonPunctuationColor => new Color(0.2f, 0.2f, 0.2f, 1f);
	}
}
namespace ModsApp.UI.Search
{
	public static class Levenshtein
	{
		public static int Distance(string a, string b)
		{
			if (string.IsNullOrEmpty(a))
			{
				return b?.Length ?? 0;
			}
			if (string.IsNullOrEmpty(b))
			{
				return a.Length;
			}
			int length = a.Length;
			int length2 = b.Length;
			int[,] array = new int[length + 1, length2 + 1];
			for (int i = 0; i <= length; i++)
			{
				array[i, 0] = i;
			}
			for (int j = 0; j <= length2; j++)
			{
				array[0, j] = j;
			}
			for (int k = 1; k <= length; k++)
			{
				for (int l = 1; l <= length2; l++)
				{
					int num = ((a[k - 1] != b[l - 1]) ? 1 : 0);
					array[k, l] = Math.Min(Math.Min(array[k - 1, l] + 1, array[k, l - 1] + 1), array[k - 1, l - 1] + num);
				}
			}
			return array[length, length2];
		}

		public static float Similarity(string a, string b)
		{
			if (string.IsNullOrEmpty(a) && string.IsNullOrEmpty(b))
			{
				return 1f;
			}
			if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(b))
			{
				return 0f;
			}
			int num = Distance(a, b);
			int num2 = Math.Max(a.Length, b.Length);
			return 1f - (float)num / (float)num2;
		}
	}
	public class SearchBar
	{
		private readonly SearchManager _searchManager;

		private readonly UITheme _theme;

		private readonly Action<string> _onSearchChanged;

		private readonly Action<IReadOnlyList<SearchResult>, string> _onAllModsSelected;

		private InputField _searchInput;

		private Button _clearButton;

		public string Query { get; private set; } = string.Empty;


		public IReadOnlyList<SearchResult> Results { get; private set; } = new List<SearchResult>();


		public bool IsAllModsSelected { get; private set; }

		public SearchBar(SearchManager searchManager, UITheme theme, Action<string> onSearchChanged, Action<IReadOnlyList<SearchResult>, string> onAllModsSelected)
		{
			_searchManager = searchManager;
			_theme = theme;
			_onSearchChanged = onSearchChanged;
			_onAllModsSelected = onAllModsSelected;
		}

		public void Initialize(GameObject parent)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Expected O, but got Unknown
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = UIFactory.Panel("SearchPanel", parent.transform, _theme.BgCard, (Vector2?)null, (Vector2?)null, false);
			val.GetComponent<Image>()?.MakeRounded(4, 16);
			UIHelper.ForceRectToAnchors(val.GetComponent<RectTransform>(), new Vector2(0f, 0.85f), new Vector2(1f, 0.95f), Vector2.zero, Vector2.zero);
			HorizontalLayoutGroup val2 = val.GetComponent<HorizontalLayoutGroup>();
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = val.AddComponent<HorizontalLayoutGroup>();
			}
			((HorizontalOrVerticalLayoutGroup)val2).spacing = 4f;
			((LayoutGroup)val2).padding = new RectOffset(8, 8, 0, 0);
			((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = false;
			((LayoutGroup)val2).childAlignment = (TextAnchor)1;
			_searchInput = InputFieldFactory.CreateInputField(val, "SearchMods", "", (ContentType)0, 100);
			if ((Object)(object)_searchInput != (Object)null)
			{
				((Component)_searchInput).gameObject.GetComponent<Image>()?.MakeRounded(4, 16);
				LayoutElement val3 = ((Component)_searchInput).GetComponent<LayoutElement>();
				if ((Object)(object)val3 == (Object)null)
				{
					val3 = ((Component)_searchInput).gameObject.AddComponent<LayoutElement>();
				}
				val3.preferredHeight = 28f;
				val3.flexibleHeight = 0f;
				val3.flexibleWidth = 1f;
				ProcessTextInChildren(((Component)_searchInput).transform, delegate(Text text)
				{
					if (((Object)((Component)text).gameObject).name.Contains("Placeholder"))
					{
						text.text = "Search mods...";
					}
				});
				EventHelper.AddListener<string>((Action<string>)delegate(string text)
				{
					Controls.IsTyping = true;
					OnSearchTextChanged(text);
				}, (UnityEvent<string>)(object)_searchInput.onValueChanged);
				EventHelper.AddListener<string>((Action<string>)delegate
				{
					Controls.IsTyping = false;
				}, (UnityEvent<string>)(object)_searchInput.onEndEdit);
			}
			Button item = UIFactory.RoundedButtonWithLabel("SearchClear", "x", val.transform, _theme.TextPrimary * new Color(0f, 0f, 0f, 0.2f), 30f, 30f, _theme.SizeStandard, _theme.WarningColor).Item2;
			((Component)item).gameObject.SetActive(false);
			_clearButton = item;
			if ((Object)(object)item != (Object)null)
			{
				LayoutElement val4 = ((Component)item).gameObject.GetComponent<LayoutElement>();
				if ((Object)(object)val4 == (Object)null)
				{
					val4 = ((Component)item).gameObject.AddComponent<LayoutElement>();
				}
				val4.preferredHeight = 28f;
				val4.preferredWidth = 28f;
				val4.flexibleWidth = 0f;
				EventHelper.AddListener((Action)OnSearchClear, (UnityEvent)(object)item.onClick);
				Tooltip.Attach(((Component)item).gameObject, "Clear search", (float)_theme.SizeSmall * 8f);
			}
		}

		private void OnSearchTextChanged(string text)
		{
			Query = text;
			CategoryState.ClearTempExpanded();
			if ((Object)(object)_clearButton != (Object)null)
			{
				((Component)_clearButton).gameObject.SetActive(!string.IsNullOrWhiteSpace(text));
			}
			if (!string.IsNullOrWhiteSpace(text))
			{
				Results = _searchManager.Search(text);
			}
			else
			{
				Results = new List<SearchResult>();
				IsAllModsSelected = false;
			}
			_onSearchChanged?.Invoke(Query);
			if (IsAllModsSelected)
			{
				_onAllModsSelected?.Invoke(Results, text);
			}
		}

		private void OnSearchClear()
		{
			if ((Object)(object)_searchInput != (Object)null)
			{
				_searchInput.text = string.Empty;
			}
			Query = string.Empty;
			Results = new List<SearchResult>();
			IsAllModsSelected = false;
			CategoryState.ClearTempExpanded();
			_onSearchChanged?.Invoke(Query);
		}

		private static void ProcessTextInChildren(Transform root, Action<Text> action)
		{
			if (!((Object)(object)root == (Object)null))
			{
				Text obj = default(Text);
				if (((Component)root).TryGetComponent<Text>(ref obj))
				{
					action(obj);
				}
				for (int i = 0; i < root.childCount; i++)
				{
					ProcessTextInChildren(root.GetChild(i), action);
				}
			}
		}
	}
	public class SearchManager
	{
		internal const int MaxSearchResults = 50;

		private readonly ModManager _modManager;

		public static float SimilarityThreshold => SettingsRegistry.SearchSimilarityThreshold?.Value ?? 0.6f;

		public SearchManager(ModManager modManager)
		{
			_modManager = modManager;
		}

		public IReadOnlyList<SearchResult> Search(string query)
		{
			if (string.IsNullOrWhiteSpace(query))
			{
				return new List<SearchResult>();
			}
			List<SearchResult> list = new List<SearchResult>();
			HashSet<string> hashSet = new HashSet<string>();
			HashSet<string> hashSet2 = new HashSet<string>();
			string query2 = query.ToLowerInvariant();
			foreach (MelonMod allMod in _modManager.GetAllMods())
			{
				List<MelonPreferences_Category> list2 = _modManager.GetPreferencesForMod(allMod).ToList();
				foreach (MelonPreferences_Category item2 in list2)
				{
					string text = ((MelonBase)allMod).Info.Name + "." + item2.Identifier;
					string text2 = item2.DisplayName ?? item2.Identifier;
					float wordMatchScore = GetWordMatchScore(text2, query2);
					float wordMatchScore2 = GetWordMatchScore(item2.Identifier, query2);
					float num = Math.Max(wordMatchScore, wordMatchScore2);
					if (num >= SimilarityThreshold && !hashSet.Contains(text))
					{
						list.Add(new SearchResult(allMod, item2, null, num));
						hashSet.Add(text);
					}
					if (item2.Entries == null)
					{
						continue;
					}
					foreach (MelonPreferences_Entry entry in item2.Entries)
					{
						string item = text + "." + entry.Identifier;
						string text3 = entry.DisplayName ?? entry.Identifier;
						string text4 = entry.Description ?? "";
						float wordMatchScore3 = GetWordMatchScore(text3, query2);
						float wordMatchScore4 = GetWordMatchScore(text4, query2);
						float num2 = Math.Max(wordMatchScore3, wordMatchScore4);
						if (num2 >= SimilarityThreshold)
						{
							if (!hashSet.Contains(text))
							{
								list.Add(new SearchResult(allMod, item2, null, num));
								hashSet.Add(text);
							}
							if (!hashSet2.Contains(item))
							{
								list.Add(new SearchResult(allMod, item2, entry, num2));
								hashSet2.Add(item);
							}
						}
					}
				}
				if (list.Count >= 50)
				{
					break;
				}
			}
			return list.OrderByDescending((SearchResult r) => r.Score).Take(50).ToList();
		}

		private static float GetWordMatchScore(string text, string query)
		{
			if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(query))
			{
				return 0f;
			}
			if (text.IndexOf(query, StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return 1f;
			}
			if (SimilarityThreshold >= 1f)
			{
				return 0f;
			}
			string[] array = text.Split(' ', '-', '_');
			float num = 0f;
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				string a = text2.ToLowerInvariant();
				float num2 = Levenshtein.Similarity(a, query);
				if (num2 > num)
				{
					num = num2;
				}
			}
			return (num >= SimilarityThreshold) ? num : 0f;
		}
	}
	public struct SearchResult
	{
		public MelonMod Mod;

		public MelonPreferences_Category Category;

		public MelonPreferences_Entry Entry;

		public float Score;

		public SearchResult(MelonMod mod, MelonPreferences_Category category, MelonPreferences_Entry entry, float score = 0f)
		{
			Mod = mod;
			Category = category;
			Entry = entry;
			Score = score;
		}
	}
	public class SearchResultsView
	{
		private readonly RectTransform _detailsContent;

		private readonly UITheme _theme;

		private readonly GameObject _actionButtonContainer;

		public event Action<MelonMod, MelonPreferences_Category, MelonPreferences_Entry> OnNavigateToEntry;

		public SearchResultsView(RectTransform detailsContent, UITheme theme, GameObject actionButtonContainer)
		{
			_detailsContent = detailsContent;
			_theme = theme;
			_actionButtonContainer = actionButtonContainer;
		}

		public void Show(IReadOnlyList<SearchResult> results, string searchQuery = "")
		{
			//IL_0057: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
			UIFactory.ClearChildren((Transform)(object)_detailsContent);
			GameObject actionButtonContainer = _actionButtonContainer;
			if (actionButtonContainer != null)
			{
				actionButtonContainer.SetActive(false);
			}
			GameObject val = CreateInfoCard("AllModsSearchHeaderCard");
			Text val2 = UIFactory.Text("AllModsSearchTitle", "All Mods - Settings Search", val.transform, _theme.SizeLarge, (TextAnchor)3, (FontStyle)1);
			((Graphic)val2).color = _theme.TextPrimary;
			Text val3 = UIFactory.Text("AllModsSearchSubtitle", "Click a result to navigate to it", val.transform, _theme.SizeStandard, (TextAnchor)0, (FontStyle)0);
			((Graphic)val3).color = _theme.TextSecondary;
			if (results.Count >= 50)
			{
				Text val4 = UIFactory.Text("TruncatedWarning", $"Showing first {50} results...", val.transform, _theme.SizeSmall, (TextAnchor)0, (FontStyle)0);
				((Graphic)val4).color = _theme.WarningColor;
			}
			IOrderedEnumerable<IGrouping<(MelonMod, MelonPreferences_Category), SearchResult>> orderedEnumerable = from r in results
				group r by (r.Mod, r.Category) into g
				orderby g.Max((SearchResult r) => r.Score) descending, ((MelonBase)g.Key.mod).Info.Name, g.Key.category.DisplayName ?? g.Key.category.Identifier
				select g;
			GameObject parent = CreateInfoCard("AllModsSearchResultsCard");
			foreach (IGrouping<(MelonMod, MelonPreferences_Category), SearchResult> item3 in orderedEnumerable)
			{
				MelonMod item = item3.Key.Item1;
				MelonPreferences_Category item2 = item3.Key.Item2;
				string text = item2.DisplayName ?? item2.Identifier;
				string name = ((MelonBase)item).Info.Name;
				string groupKey = name + "." + item2.Identifier;
				string categoryName = HighlightMatch(text, searchQuery);
				GameObject val5 = CreateSearchResultCategory(parent, name, categoryName, groupKey, item, item2);
				IEnumerable<SearchResult> enumerable = item3.Where((SearchResult g) => g.Entry != null);
				foreach (SearchResult item4 in enumerable)
				{
					MelonPreferences_Entry entry = item4.Entry;
					string text2 = entry.DisplayName ?? entry.Identifier;
					string entryName = HighlightMatch(text2, searchQuery);
					CreateSearchResultEntry(val5.transform, entryName, item, item2, entry, searchQuery);
				}
			}
			UIHelper.RefreshLayout(_detailsContent);
		}

		private GameObject CreateInfoCard(string name, Transform parent = null)
		{
			//IL_0015: 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_006e: Expected O, but got Unknown
			Transform val = (Transform)(((object)parent) ?? ((object)_detailsContent));
			GameObject val2 = UIFactory.Panel(name, val, _theme.BgSecondary, (Vector2?)null, (Vector2?)null, false);
			val2.GetComponent<Image>()?.MakeRounded();
			VerticalLayoutGroup orAddComponent = val2.GetOrAddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)orAddComponent).spacing = 8f;
			((LayoutGroup)orAddComponent).padding = new RectOffset(12, 12, 8, 8);
			((HorizontalOrVerticalLayoutGroup)orAddComponent).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)orAddComponent).childForceExpandHeight = false;
			((LayoutGroup)orAddComponent).childAlignment = (TextAnchor)0;
			ContentSizeFitter orAddComponent2 = val2.GetOrAddComponent<ContentSizeFitter>();
			orAddComponent2.verticalFit = (FitMode)2;
			orAddComponent2.horizontalFit = (FitMode)0;
			LayoutElement orAddComponent3 = val2.GetOrAddComponent<LayoutElement>();
			orAddComponent3.preferredHeight = -1f;
			orAddComponent3.minHeight = 0f;
			orAddComponent3.flexibleHeight = 0f;
			orAddComponent3.flexibleWidth = 1f;
			return val2;
		}

		private string HighlightMatch(string text, string query)
		{
			if (string.IsNullOrEmpty(query) || string.IsNullOrEmpty(text))
			{
				return text;
			}
			int num = text.IndexOf(query, StringComparison.OrdinalIgnoreCase);
			if (num >= 0)
			{
				return ApplyHighlight(text, num, query.Length);
			}
			if (SearchManager.SimilarityThreshold >= 1f)
			{
				return text;
			}
			string b = query.ToLowerInvariant();
			string[] array = text.Split(' ', '-', '_', '.', ',', ':', ';', '(', ')', '[', ']');
			string text2 = "";
			float num2 = 0f;
			string[] array2 = array;
			foreach (string text3 in array2)
			{
				if (!string.IsNullOrEmpty(text3))
				{
					string a = text3.ToLowerInvariant();
					float num3 = Levenshtein.Similarity(a, b);
					if (num3 > num2)
					{
						num2 = num3;
						text2 = text3;
					}
				}
			}
			if (num2 < SearchManager.SimilarityThreshold)
			{
				return text;
			}
			num = text.IndexOf(text2, StringComparison.OrdinalIgnoreCase);
			if (num < 0)
			{
				return text;
			}
			return ApplyHighlight(text, num, text2.Length);
		}

		private string ApplyHighlight(string text, int index, int length)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			string text2 = ColorUtility.ToHtmlStringRGB(_theme.AccentPrimary);
			return text.Insert(index + length, "</color>").Insert(index, "<color=#" + text2 + ">");
		}

		private GameObject CreateSearchResultCategory(GameObject parent, string modName, string categoryName, string groupKey, MelonMod mod = null, MelonPreferences_Category category = null)
		{
			//IL_0036: 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_008d: Expected O, but got Unknown
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = UIFactory.Panel("SearchResult_" + groupKey, parent.transform, _theme.BgCategory, (Vector2?)null, (Vector2?)null, false);
			val.GetComponent<Image>()?.MakeRounded();
			VerticalLayoutGroup orAddComponent = val.GetOrAddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)orAddComponent).spacing = 4f;
			((LayoutGroup)orAddComponent).padding = new RectOffset(8, 8, 6, 6);
			((HorizontalOrVerticalLayoutGroup)orAddComponent).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)orAddComponent).childForceExpandHeight = false;
			((LayoutGroup)orAddComponent).childAlignment = (TextAnchor)0;
			ContentSizeFitter orAddComponent2 = val.GetOrAddComponent<ContentSizeFitter>();
			orAddComponent2.verticalFit = (FitMode)2;
			orAddComponent2.horizontalFit = (FitMode)0;
			LayoutElement orAddComponent3 = val.GetOrAddComponent<LayoutElement>();
			orAddComponent3.preferredHeight = -1f;
			orAddComponent3.flexibleHeight = 0f;
			orAddComponent3.flexibleWidth = 1f;
			string text = modName + " > " + categoryName;
			Text val2 = UIFactory.Text("SearchResult_" + groupKey + "_Title", text, val.transform, _theme.SizeMedium, (TextAnchor)0, (FontStyle)1);
			((Graphic)val2).color = _theme.TextPrimary;
			val2.supportRichText = true;
			if (mod != null && category != null)
			{
				Button val3 = ((Component)val2).gameObject.AddComponent<Button>();
				ColorBlock colors = ((Selectable)val3).colors;
				((ColorBlock)(ref colors)).normalColor = _theme.AccentPrimary;
				((ColorBlock)(ref colors)).highlightedColor = _theme.AccentPrimary;
				((ColorBlock)(ref colors)).pressedColor = _theme.AccentPrimary;
				((ColorBlock)(ref colors)).selectedColor = _theme.AccentPrimary;
				((ColorBlock)(ref colors)).fadeDuration = 0.1f;
				((Selectable)val3).colors = colors;
				EventHelper.AddListener((Action)delegate
				{
					this.OnNavigateToEntry?.Invoke(mod, category, null);
				}, (UnityEvent)(object)val3.onClick);
			}
			return val;
		}

		private void CreateSearchResultEntry(Transform parent, string entryName, MelonMod mod, MelonPreferences_Category category, MelonPreferences_Entry entry, string searchQuery)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: 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)
			GameObject val = UIFactory.Panel("SearchResultEntry_" + category.Identifier + "_" + entry.Identifier, parent, _theme.AccentSecondary, (Vector2?)null, (Vector2?)null, false);
			val.GetComponent<Image>()?.MakeRounded(4, 16);
			HorizontalLayoutGroup val2 = val.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val2).spacing = 8f;
			((LayoutGroup)val2).padding = new RectOffset(8, 8, 4, 4);
			((LayoutGroup)val2).childAlignment = (TextAnchor)3;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)val2).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = true;
			LayoutElement orAddComponent = val.GetOrAddComponent<LayoutElement>();
			orAddComponent.preferredHeight = 36f;
			orAddComponent.flexibleWidth = 1f;
			Text val3 = UIFactory.Text("EntryLabel_" + entry.Identifier, entryName, val.transform, _theme.SizeStandard, (TextAnchor)3, (FontStyle)0);
			((Graphic)val3).color = _theme.TextPrimary;
			val3.horizontalOverflow = (HorizontalWrapMode)0;
			val3.verticalOverflow = (VerticalWrapMode)0;
			val3.supportRichText = true;
			if (!string.IsNullOrEmpty(entry.Description))
			{
				string text = ((!string.IsNullOrEmpty(searchQuery)) ? HighlightMatch(entry.Description, searchQuery) : entry.Description);
				Text val4 = UIFactory.Text("EntryDesc_" + entry.Identifier, text, val.transform, _theme.SizeSmall, (TextAnchor)0, (FontStyle)0);
				((Graphic)val4).color = _theme.TextSecondary;
				val4.horizontalOverflow = (HorizontalWrapMode)0;
				val4.supportRichText = true;
			}
			Button orAddComponent2 = val.GetOrAddComponent<Button>();
			ColorBlock colors = ((Selectable)orAddComponent2).colors;
			((ColorBlock)(ref colors)).normalColor = Color.clear;
			((ColorBlock)(ref colors)).highlightedColor = _theme.AccentSecondary;
			((ColorBlock)(ref colors)).pressedColor = _theme.AccentPrimary;
			((ColorBlock)(ref colors)).selectedColor = _theme.AccentPrimary;
			((ColorBlock)(ref colors)).fadeDuration = 0.1f;
			((Selectable)orAddComponent2).colors = colors;
			EventHelper.AddListener((Action)delegate
			{
				this.OnNavigateToEntry?.Invoke(mod, category, entry);
			}, (UnityEvent)(object)orAddComponent2.onClick);
		}
	}
}
namespace ModsApp.UI.Panels
{
	public class FloatingPanelComponent
	{
		private static GameObject _panelObject;

		private RectTransform _rectTransform;

		private UITheme _theme;

		private static Button _closeBtn;

		public GameObject ContentPanel;

		private const float topBarHeight = 65f;

		public FloatingPanelComponent(float width, float height, string title)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: 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)
			_theme = UIManager._theme;
			Transform val = UIManager.MainPanel.transform.Find("FloatingPanel");
			if ((Object)(object)val != (Object)null)
			{
				Cleanup();
			}
			_panelObject = UIFactory.Panel("FloatingPanel", UIManager.MainPanel.transform, _theme.BgPrimary, (Vector2?)null, (Vector2?)null, false);
			_panelObject.transform.SetParent(UIManager.MainPanel.transform, false);
			_panelObject.transform.SetAsLastSibling();
			_panelObject.GetComponent<Image>()?.MakeRounded(12, 48);
			_rectTransform = _panelObject.GetComponent<RectTransform>();
			_rectTransform.sizeDelta = new Vector2(width, height);
			AddTopBar(title);
			UIHelper.AddBorderEffect(_panelObject, _theme.AccentPrimary);
			ContentPanel = AddContentPanel();
		}

		private void AddTopBar(string title)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = UIFactory.TopBar("FloatingPanelTopBar", _panelObject.transform, title, 0.99f, 8, 8, 4, 4);
			val.GetComponent<Image>()?.MakeRounded(12, 48);
			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, 65f);
			component.anchoredPosition = new Vector2(0f, 0f);
			HorizontalLayoutGroup component2 = val.GetComponent<HorizontalLayoutGroup>();
			if ((Object)(object)component2 != (Object)null)
			{
				((HorizontalOrVerticalLayoutGroup)component2).childForceExpandHeight = false;
			}
			Transform obj = val.transform.Find("TopBarTitle");
			Text val2 = ((obj != null) ? ((Component)obj).GetComponent<Text>() : null);
			if ((Object)(object)val2 != (Object)null)
			{
				val2.fontSize = _theme.SizeMedium;
			}
			ValueTuple<GameObject, Button, Text> valueTuple = UIFactory.RoundedButtonWithLabel("CloseButton", "X", val.transform, _theme.WarningColor, 48.75f, 48.75f, _theme.SizeMedium, _theme.TextPrimary);
			GameObject item = valueTuple.Item1;
			Button item2 = valueTuple.Item2;
			RectTransform component3 = item.GetComponent<RectTransform>();
			component3.anchorMin = new Vector2(1f, 0.5f);
			component3.anchorMax = new Vector2(1f, 0.5f);
			component3.pivot = new Vector2(0.5f, 0.5f);
			component3.anchoredPosition = new Vector2(-20f, 0f);
			EventHelper.AddListener((Action)Cleanup, (UnityEvent)(object)item2.onClick);
			_closeBtn = item2;
			item.transform.SetAsLastSibling();
		}

		private GameObject AddContentPanel()
		{
			//IL_0016: 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_005c: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = UIFactory.Panel("ContentPanel", _panelObject.transform, _theme.BgSecondary, (Vector2?)null, (Vector2?)null, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 0f);
			component.anchorMax = new Vector2(1f, 1f);
			component.offsetMin = new Vector2(8f, 8f);
			component.offsetMax = new Vector2(-8f, -73f);
			val.GetComponent<Image>()?.MakeRounded(8, 48);
			return val;
		}

		public static void Cleanup()
		{
			if ((Object)(object)_closeBtn != (Object)null)
			{
				EventHelper.RemoveListener((Action)Cleanup, (UnityEvent)(object)_closeBtn.onClick);
			}
			if (!((Object)(object)_panelObject == (Object)null))
			{
				Object.Destroy((Object)(object)_panelObject);
				Transform val = _panelObject.transform.parent.Find(((Object)_panelObject).name + "_Border");
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)val).gameObject);
				}
			}
		}
	}
	public class JsonConfigUI
	{
		private readonly UITheme _theme;

		private readonly Instance _logger;

		private readonly JsonConfigManager _configManager;

		private object _tmpInputField;

		private object _tmpTextComponent;

		private static object _tmpFontAsset;

		private InputField _legacyEditor;

		private Button _saveButton;

		private Button _revertButton;

		private Button _formatButton;

		private InputField _jsonFileInput;

		private GameObject _editorSectionRoot;

		private Font _consolaFont;

		private EventTrigger _overlayScrollTrigger;

		private Action<BaseEventData> _scrollCallback;

		private string _currentJsonContent = "";

		private string _originalJsonContent = "";

		private string _currentFilename = "";

		private Action _onConfigSaved;

		private int _lastRawCaret;

		private static readonly Regex _tagStripper = new Regex("<[^>]*>", RegexOptions.Compiled);

		public JsonConfigUI(UITheme theme, Instance logger, JsonConfigManager configManager)
		{
			_theme = theme;
			_logger = logger;
			_configManager = configManager;
			CheckTMP();
		}

		public void ResetState()
		{
			_currentJsonContent = "";
			_originalJsonContent = "";
			_currentFilename = "";
			_tmpInputField = null;
			_tmpTextComponent = null;
			_legacyEditor = null;
			_jsonFileInput = null;
			_saveButton = null;
			_revertButton = null;
			_formatButton = null;
			_editorSectionRoot = null;
		}

		public void CreateJsonConfigSection(MelonMod mod, GameObject card, Action onLayoutRefresh, Action onConfigSaved)
		{
			//IL_002b: 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)
			Text val = UIFactory.Text("JsonConfigHeader", "No MelonPreferences", card.transform, _theme.SizeMedium, (TextAnchor)0, (FontStyle)1);
			((Graphic)val).color = _theme.TextPrimary;
			Text val2 = UIFactory.Text("JsonConfigDesc", "No MelonPreferences were found; though they might exist. If the mod uses JSON files, you can specify the path manually. Long files may not display correctly.", card.transform, _theme.SizeSmall, (TextAnchor)0, (FontStyle)0);
			((Graphic)val2).color = _theme.TextSecondary;
			_onConfigSaved = onConfigSaved;
			CreateFileInputSection(mod, card, onLayoutRefresh);
		}

		private void CreateFileInputSection(MelonMod mod, GameObject parent, Action onLayoutRefresh)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = UIFactory.Panel("FileInputContainer", parent.transform, Color.clear, (Vector2?)null, (Vector2?)null, false);
			VerticalLayoutGroup val2 = val.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val2).spacing = 4f;
			((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = false;
			Text val3 = UIFactory.Text("PathLabel", "JSON file path (relative to UserData/):", val.transform, _theme.SizeSmall, (TextAnchor)0, (FontStyle)0);
			((Graphic)val3).color = _theme.TextSecondary;
			GameObject val4 = UIFactory.Panel("InputRow", val.transform, Color.clear, (Vector2?)null, (Vector2?)null, false);
			HorizontalLayoutGroup val5 = val4.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val5).spacing = 8f;
			((HorizontalOrVerticalLayoutGroup)val5).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val5).childControlWidth = true;
			string text = _configManager.GetSavedFilename(((MelonBase)mod).Info.Name);
			if (string.IsNullOrEmpty(text))
			{
				text = GuessFilename(((MelonBase)mod).Info.Name);
			}
			_jsonFileInput = InputFieldFactory.CreateInputField(val4, "JsonFileInput", text, (ContentType)0, 200);
			Button item = UIFactory.RoundedButtonWithLabel("LoadJsonButton", "Load", val4.transform, _theme.AccentPrimary, 60f, 25f, _theme.SizeSmall, _theme.TextPrimary).Item2;
			EventHelper.AddListener((Action)delegate
			{
				LoadJsonFile(mod);
				if ((Object)(object)_editorSectionRoot != (Object)null)
				{
					Object.Destroy((Object)(object)_editorSectionRoot);
					_editorSectionRoot = null;
					_tmpInputField = null;
					_legacyEditor = null;
					_saveButton = null;
					_revertButton = null;
					_formatButton = null;
				}
				if (!string.IsNullOrEmpty(_currentJsonContent))
				{
					CreateEditorSection(mod, parent);
				}
				onLayoutRefresh?.Invoke();
			}, (UnityEvent)(object)item.onClick);
			if (!string.IsNullOrEmpty(text))
			{
				LoadJsonFile(mod);
				if (!string.IsNullOrEmpty(_currentJsonContent))
				{
					CreateEditorSection(mod, parent);
				}
				onLayoutRefresh?.Invoke();
			}
			Text val6 = UIFactory.Text("UserDataPath", "UserData path: " + MelonEnvironment.UserDataDirectory, val.transform, _theme.SizeTiny, (TextAnchor)0, (FontStyle)0);
			((Graphic)val6).color = _theme.TextSecondary * 0.7f;
		}

		private string GuessFilename(string modName)
		{
			string text = _configManager.FindFileForMod(modName, MelonEnvironment.UserDataDirectory);
			if (string.IsNullOrEmpty(text))
			{
				text = _configManager.FindFileForMod(modName, Path.Combine(MelonEnvironment.UserDataDirectory, "..", "Mods"));
			}
			if (string.IsNullOrEmpty(text))
			{
				return "";
			}
			string text2 = Path.Combine(MelonEnvironment.UserDataDirectory, text);
			if (File.Exists(text2) && new FileInfo(text2).Length > 16000)
			{
				_logger.Warning("[JSON] Skipping large guessed config: " + text2 + " (>16kB)");
				return "";
			}
			return text;
		}

		private void CreateEditorSection(MelonMod mod, GameObject parent)
		{
			//IL_000c: 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)
			GameObject val = (_editorSectionRoot = UIFactory.Panel("JsonEditorContainer", parent.transform, Color.clear, (Vector2?)null, (Vector2?)null, false));
			VerticalLayoutGroup val2 = val.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val2).spacing = 4f;
			((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = false;
			Text val3 = UIFactory.Text("JsonEditorLabel", "JSON Content:", val.transform, _theme.SizeSmall, (TextAnchor)0, (FontStyle)1);
			((Graphic)val3).color = _theme.TextPrimary;
			if (ReflectionHelper.TMPAvailable)
			{
				CreateTMPEditor(val);
			}
			else
			{
				CreateLegacyEditor(val);
			}
			CreateActionButtons(val);
		}

		private void CreateTMPEditor(GameObject parent)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Expected O, but got Unknown
			//IL_0118: 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_013d: Expected O, but got Unknown
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = UIFactory.Panel("JsonEditorWrapper", parent.transform, _theme.BgInput, (Vector2?)null, (Vector2?)null, false);
			val.GetComponent<Image>()?.MakeRounded(4, 16);
			LayoutElement orAddComponent = val.GetOrAddComponent<LayoutElement>();
			orAddComponent.minHeight = 200f;
			orAddComponent.preferredHeight = 200f;
			orAddComponent.flexibleWidth = 1f;
			GameObject val2 = new GameObject("Text Area");
			val2.transform.SetParent(val.transform, false);
			val2.AddComponent<RectMask2D>();
			RectTransform component = val2.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.offsetMin = new Vector2(8f, 6f);
			component.offsetMax = new Vector2(-8f, -6f);
			GameObject val3 = new GameObject("Placeholder");
			val3.transform.SetParent(val2.transform, false);
			FullStretch(val3);
			object obj = AddTMPText(val3, "Enter JSON...", _theme.InputSecondary, _theme.SizeStandard, richText: false);
			GameObject val4 = new GameObject("Text");
			val4.transform.SetParent(val2.transform, false);
			FullStretch(val4);
			_tmpTextComponent = AddTMPText(val4, "", _theme.InputPrimary, _theme.SizeStandard, richText: true);
			if (_tmpTextComponent == null || obj == null)
			{
				_logger.Warning("[JsonConfigUI] TMP text AddComponent failed — falling back.");
				ReflectionHelper.TMPAvailable = false;
				Object.Destroy((Object)(object)val);
				CreateLegacyEditor(parent);
				return;
			}
			val.SetActive(false);
			object obj2;
			try
			{
				obj2 = ReflectionHelper.AddComponent(val, ReflectionHelper.TMPInputFieldType);
			}
			catch (Exception ex)
			{
				_logger.Warning("[JsonConfigUI] TMP_InputField AddComponent threw: " + ex.Message);
				ReflectionHelper.TMPAvailable = false;
				val.SetActive(true);
				Object.Destroy((Object)(object)val);
				CreateLegacyEditor(parent);
				return;
			}
			if (obj2 == null)
			{
				_logger.Warning("[JsonConfigUI] TMP_InputField AddComponent returned null.");
				ReflectionHelper.TMPAvailable = false;
				val.SetActive(true);
				Object.Destroy((Object)(object)val);
				CreateLegacyEditor(parent);
				return;
			}
			_tmpInputField = obj2;
			ReflectionHelper.SetValue(ReflectionHelper.MIfTextViewport, _tmpInputField, component);
			ReflectionHelper.SetValue(ReflectionHelper.MIfTextComponent, _tmpInputField, _tmpTextComponent);
			ReflectionHelper.SetValue(ReflectionHelper.MIfPlaceholder, _tmpInputField, obj);
			ReflectionHelper.SetValue(ReflectionHelper.MIfContentType, _tmpInputField, ReflectionHelper.EnumValue(ReflectionHelper.MIfContentType, 0));
			ReflectionHelper.SetValue(ReflectionHelper.MIfLineType, _tmpInputField, ReflectionHelper.EnumValue(ReflectionHelper.MIfLineType, 2));
			ReflectionHelper.SetValue(ReflectionHelper.MIfRichText, _tmpInputField, true);
			ReflectionHelper.SetValue(ReflectionHelper.MIfCustomCaret, _tmpInputField, true);
			ReflectionHelper.SetValue(ReflectionHelper.MIfCaretColor, _tmpInputField, _theme.InputPrimary);
			ReflectionHelper.SetValue(ReflectionHelper.MIfCaretBlinkRate, _tmpInputField, 0.6f);
			if (ReflectionHelper.MIfOnFocusSelectAll != null)
			{
				ReflectionHelper.SetValue(ReflectionHelper.MIfOnFocusSelectAll, _tmpInputField, false);
			}
			List<bool> list = new List<bool>();
			object value = ReflectionHelper.GetValue(ReflectionHelper.MIfOnValueChanged, _tmpInputField);
			list.Add(ReflectionHelper.AddStringListener(value, OnEditorValueChanged));
			object value2 = ReflectionHelper.GetValue(ReflectionHelper.MIfOnEndEdit, _tmpInputField);
			list.Add(ReflectionHelper.AddStringListener(value2, OnEditorEndEdit));
			MemberInfo member = ReflectionHelper.GetMember(ReflectionHelper.TMPInputFieldType, "onSelect");
			if (member != null)
			{
				object value3 = ReflectionHelper.GetValue(member, _tmpInputField);
				list.Add(ReflectionHelper.AddStringListener(value3, delegate
				{
					Controls.IsTyping = true;
				}));
			}
			MemberInfo member2 = ReflectionHelper.GetMember(ReflectionHelper.TMPInputFieldType, "onDeselect");
			if (member2 != null)
			{
				object value4 = ReflectionHelper.GetValue(member2, _tmpInputField);
				list.Add(ReflectionHelper.AddStringListener(value4, delegate
				{
					Controls.IsTyping = false;
				}));
			}
			if (!list.All((bool b) => b))
			{
				_logger.Warning("[JsonConfigUI] Some TMP events couldn't be wired correctly");
				ReflectionHelper.TMPAvailable = false;
				val.SetActive(true);
				Object.Destroy((Object)(object)val);
				CreateLegacyEditor(parent);
			}
			else
			{
				AddScrollPassthrough(val);
				val.SetActive(true);
				ApplyHighlight(_currentJsonContent);
			}
		}

		private void AddScrollPassthrough(GameObject wrapper)
		{
			ScrollRect parentScrollRect = wrapper.GetComponentInParent<ScrollRect>();
			if (!((Object)(object)parentScrollRect == (Object)null))
			{
				EventTrigger orAddComponent = wrapper.GetOrAddComponent<EventTrigger>();
				if (_scrollCallback != null)
				{
					EventHelper.RemoveEventTrigger(orAddComponent, (EventTriggerType)7, _scrollCallback);
				}
				_scrollCallback = delegate(BaseEventData data)
				{
					//IL_0010: Unknown result type (might be due to invalid IL or missing references)
					//IL_0015: Unknown result type (might be due to invalid IL or missing references)
					//IL_0016: Unknown result type (might be due to invalid IL or missing references)
					PointerEventData val = (PointerEventData)(((object)((data is PointerEventData) ? data : null)) ?? ((object)new PointerEventData(EventSystem.current)
					{
						scrollDelta = Input.mouseScrollDelta
					}));
					parentScrollRect.OnScroll(val);
				};
				EventHelper.AddEventTrigger(orAddComponent, (EventTriggerType)7, _scrollCallback);
			}
		}

		private void OnEditorValueChanged(string value)
		{
			string text = StripTags(value);
			if (text != _currentJsonContent)
			{
				_lastRawCaret = FindRawCaretAfterEdit(_currentJsonContent, text);
			}
			_currentJsonContent = text;
			ApplyHighlight(text, _lastRawCaret);
			UpdateButtonStates();
			Controls.IsTyping = true;
		}

		private void OnEditorEndEdit(string value)
		{
			string text = StripTags(value);
			if (Input.GetKey((KeyCode)13) || Input.GetKey((KeyCode)271))
			{
				int num = 0;
				if (ReflectionHelper.MIfStringPosition != null)
				{
					int hlPos = (int)ReflectionHelper.GetValue(ReflectionHelper.MIfStringPosition, _tmpInputField);
					num = HighlightedIndexToRawIndex(text, hlPos);
				}
				ApplyHighlight(_currentJsonContent = text.Insert(num, "\n"), num);
				UpdateButtonStates();
				if (ReflectionHelper.MiActivateInputField != null)
				{
					ReflectionHelper.MiActivateInputField.Invoke(_tmpInputField, null);
				}
			}
			else
			{
				_currentJsonContent = text;
				ApplyHighlight(text, FindRawCaretAfterEdit(_currentJsonContent, text));
				Controls.IsTyping = false;
			}
		}

		private static int HighlightedIndexToRawIndex(string raw, int hlPos)
		{
			string text = JsonSyntaxHighlighter.Highlight(raw);
			int num = 0;
			int num2 = 0;
			while (num2 < hlPos && num2 < text.Length)
			{
				if (text[num2] == '<')
				{
					int num3 = text.IndexOf('>', num2);
					num2 = ((num3 >= 0) ? (num3 + 1) : text.Length);
					continue;
				}
				num2++;
				if (num < raw.Length)
				{
					num++;
				}
			}
			return num;
		}

		private static int FindRawCaretAfterEdit(string oldRaw, string newRaw)
		{
			if (oldRaw == null || newRaw == null)
			{
				return -1;
			}
			int num = oldRaw?.Length ?? 0;
			int num2 = newRaw?.Length ?? 0;
			int i = 0;
			for (int num3 = Math.Min(num, num2); i < num3 && oldRaw[i] == newRaw[i]; i++)
			{
			}
			int num4 = num - 1;
			int num5 = num2 - 1;
			while (num4 >= i && num5 >= i && oldRaw[num4] == newRaw[num5])
			{
				num4--;
				num5--;
			}
			int num6 = Math.Max(0, num5 - i + 1);
			return Math.Max(0, Math.Min(i + num6, num2));
		}

		private void ApplyHighlight(string raw, int rawCaret = 0)
		{
			if (_tmpInputField != null)
			{
				SetTMPFieldText(JsonSyntaxHighlighter.Highlight(raw));
				if (ReflectionHelper.MIfStringPosition != null)
				{
					ReflectionHelper.SetValue(ReflectionHelper.MIfStringPosition, _tmpInputField, JsonSyntaxHighlighter.RawIndexToHighlightedIndex(raw, rawCaret));
				}
			}
		}

		private void SetTMPFieldText(string text)
		{
			if (_tmpInputField == null)
			{
				return;
			}
			if (ReflectionHelper.MiSetTextWithoutNotify != null)
			{
				try
				{
					ReflectionHelper.MiSetTextWithoutNotify.Invoke(_tmpInputField, new object[1] { text });
					return;
				}
				catch
				{
				}
			}
			ReflectionHelper.SetValue(ReflectionHelper.MIfText, _tmpInputField, text);
		}

		private static string StripTags(string s)
		{
			if (string.IsNullOrEmpty(s))
			{
				return s;
			}
			return _tagStripper.Replace(s, "").Replace("<", "<").Replace(">", ">");
		}

		private object AddTMPText(GameObject go, string text, Color color, float fontSize, bool richText)
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			object obj;
			try
			{
				obj = ReflectionHelper.AddComponent(go, ReflectionHelper.TMPTextType);
			}
			catch (Exception ex)
			{
				_logger.Warning("[JsonConfigUI] AddComponent TMPro on '" + ((Object)go).name + "': " + ex.Message);
				return null;
			}
			if (obj == null)
			{
				return null;
			}
			if (_tmpFontAsset == null)
			{
				_tmpFontAsset = CreateTMPFontAsset();
			}
			if (_tmpFontAsset != null)
			{
				ReflectionHelper.SetValue(ReflectionHelper.GetMember(ReflectionHelper.TMPTextBaseType, "font"), obj, _tmpFontAsset);
			}
			ReflectionHelper.SetValue(ReflectionHelper.MTText, obj, text);
			ReflectionHelper.SetValue(ReflectionHelper.MTColor, obj, color);
			ReflectionHelper.SetValue(ReflectionHelper.MTFontSize, obj, fontSize);
			ReflectionHelper.SetValue(ReflectionHelper.MTRichText, obj, richText);
			ReflectionHelper.SetValue(ReflectionHelper.MTWordWrap, obj, true);
			ReflectionHelper.SetValue(ReflectionHelper.MTAutoSize, obj, false);
			ReflectionHelper.SetValue(ReflectionHelper.MTOverflow, obj, ReflectionHelper.EnumValue(ReflectionHelper.MTOverflow, 0));
			ReflectionHelper.SetValue(ReflectionHelper.MTAlignment, obj, ReflectionHelper.EnumValue(ReflectionHelper.MTAlignment, 257));
			return obj;
		}

		private void CreateLegacyEditor(GameObject parent)
		{
			_legacyEditor = InputFieldFactory.CreateInputField(parent, "JsonEditor", "", (ContentType)0, 400);
			_legacyEditor.lineType = (LineType)2;
			_legacyEditor.contentType = (ContentType)0;
			LayoutElement component = ((Component)_legacyEditor).GetComponent<LayoutElement>();
			component.minHeight = 200f;
			component.preferredHeight = 200f;
			Text textComponent = _legacyEditor.textComponent;
			textComponent.font = _consolaFont ?? Resources.GetBuiltinResource<Font>("Arial.ttf");
			textComponent.fontSize = _theme.SizeStandard;
			textComponent.alignment = (TextAnchor)0;
			textComponent.horizontalOverflow = (HorizontalWrapMode)0;
			textComponent.verticalOverflow = (VerticalWrapMode)1;
			textComponent.supportRichText = false;
			_legacyEditor.text = _currentJsonContent;
			AddScrollPassthrough(((Component)_legacyEditor).gameObject);
			EventHelper.AddListener<string>((Action<string>)delegate(string raw)
			{
				_currentJsonContent = raw;
				UpdateButtonStates();
			}, (UnityEvent<string>)(object)_legacyEditor.onValueChanged);
		}

		private void CreateActionButtons(GameObject parent)
		{
			//IL_000c: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = UIFactory.Panel("JsonButtonContainer", parent.transform, Col