Decompiled source of ModConfigEnhance v1.0.2

ModConfigEnhance.dll

Decompiled 20 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PEAKLib.ModConfig;
using PEAKLib.ModConfig.Components;
using PEAKLib.ModConfig.SettingOptions;
using PEAKLib.ModConfig.SettingOptions.SettingUI;
using PEAKLib.UI;
using PEAKLib.UI.Elements;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.UI;
using Zorro.ControllerSupport;
using Zorro.Core;
using Zorro.Settings;
using Zorro.UI;
using Zorro.UI.Modal;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("Accessibility")]
[assembly: IgnoresAccessChecksTo("Ashley.MeshSplitter")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("com.github.PEAKModding.PEAKLib.ModConfig")]
[assembly: IgnoresAccessChecksTo("com.rlabrecque.steamworks.net")]
[assembly: IgnoresAccessChecksTo("DemiLib")]
[assembly: IgnoresAccessChecksTo("DOTween")]
[assembly: IgnoresAccessChecksTo("DOTweenPro")]
[assembly: IgnoresAccessChecksTo("EpicCommon")]
[assembly: IgnoresAccessChecksTo("EpicOnlineService")]
[assembly: IgnoresAccessChecksTo("HBAO.Runtime")]
[assembly: IgnoresAccessChecksTo("HBAO.Universal.Runtime")]
[assembly: IgnoresAccessChecksTo("LightVolume.Runtime")]
[assembly: IgnoresAccessChecksTo("Managers")]
[assembly: IgnoresAccessChecksTo("Mono.Posix")]
[assembly: IgnoresAccessChecksTo("Mono.Security")]
[assembly: IgnoresAccessChecksTo("Mono.WebBrowser")]
[assembly: IgnoresAccessChecksTo("Newtonsoft.Json")]
[assembly: IgnoresAccessChecksTo("Photon")]
[assembly: IgnoresAccessChecksTo("Photon3Unity3D")]
[assembly: IgnoresAccessChecksTo("PhotonChat")]
[assembly: IgnoresAccessChecksTo("PhotonRealtime")]
[assembly: IgnoresAccessChecksTo("PhotonUnityNetworking")]
[assembly: IgnoresAccessChecksTo("PhotonUnityNetworking.Utilities")]
[assembly: IgnoresAccessChecksTo("PhotonVoice.API")]
[assembly: IgnoresAccessChecksTo("PhotonVoice")]
[assembly: IgnoresAccessChecksTo("PhotonVoice.PUN")]
[assembly: IgnoresAccessChecksTo("PlatformProviders")]
[assembly: IgnoresAccessChecksTo("Platforms")]
[assembly: IgnoresAccessChecksTo("PortningsbolagetMemory")]
[assembly: IgnoresAccessChecksTo("pworld")]
[assembly: IgnoresAccessChecksTo("sc.posteffects.runtime")]
[assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Attributes")]
[assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Modules.Unity.Addressables")]
[assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Modules.UnityLocalization")]
[assembly: IgnoresAccessChecksTo("Sirenix.Serialization.Config")]
[assembly: IgnoresAccessChecksTo("Sirenix.Serialization")]
[assembly: IgnoresAccessChecksTo("Sirenix.Utilities")]
[assembly: IgnoresAccessChecksTo("SteamCommon")]
[assembly: IgnoresAccessChecksTo("SteamManagerAssembly")]
[assembly: IgnoresAccessChecksTo("Tayx.Graphy")]
[assembly: IgnoresAccessChecksTo("unity-websocket-sharp")]
[assembly: IgnoresAccessChecksTo("Unity.Addressables")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Cinemachine")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.RebindingUI")]
[assembly: IgnoresAccessChecksTo("Unity.InternalAPIEngineBridge.004")]
[assembly: IgnoresAccessChecksTo("Unity.InternalAPIEngineBridge.013")]
[assembly: IgnoresAccessChecksTo("Unity.Localization")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.MemoryProfiler")]
[assembly: IgnoresAccessChecksTo("Unity.Microsoft.GDK")]
[assembly: IgnoresAccessChecksTo("Unity.Microsoft.GDK.Tools")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Center.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipeline.Universal.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime.Shared")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.GPUDriven.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Universal.2D.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Universal.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Universal.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Universal.Shaders")]
[assembly: IgnoresAccessChecksTo("Unity.ResourceManager")]
[assembly: IgnoresAccessChecksTo("Unity.ScriptableBuildPipeline")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication.PlayerAccounts")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Multiplayer")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Wire.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Splines")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.UnifiedRayTracing.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AccessibilityModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AdaptivePerformanceModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AMDModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AndroidJNIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AnimationModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AssetBundleModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.AudioModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ClothModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ClusterInputModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ClusterRendererModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ContentLoadModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.CoreModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.CrashReportingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.DirectorModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine")]
[assembly: IgnoresAccessChecksTo("UnityEngine.DSPGraphModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.GameCenterModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.GIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.GraphicsStateCollectionSerializerModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.GridModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.HierarchyCoreModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.HierarchyModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.HotReloadModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.IdentifiersModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ImageConversionModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.IMGUIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.InputForUIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.InputLegacyModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.InputModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.InsightsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.JSONSerializeModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.LocalizationModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.MarshallingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.MultiplayerModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ParticleSystemModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.PerformanceReportingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.Physics2DModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.PhysicsBackendPhysXModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.PhysicsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.PropertiesModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.RenderAs2DModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ScreenCaptureModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ShaderRuntimeModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ShaderVariantAnalyticsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SharedInternalsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SpriteMaskModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SpriteShapeModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.StreamingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SubstanceModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SubsystemsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TerrainModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TerrainPhysicsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TextCoreFontEngineModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TextCoreTextEngineModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TextRenderingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TilemapModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.TLSModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UIElementsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UmbraModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityAnalyticsCommonModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityAnalyticsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityConnectModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityConsentModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityCurlModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestAssetBundleModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestAudioModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestTextureModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestWWWModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.VectorGraphicsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.VehiclesModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.VFXModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.VideoModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.VirtualTexturingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.VRModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.WindModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.XRModule")]
[assembly: IgnoresAccessChecksTo("UnityUIExtensions")]
[assembly: IgnoresAccessChecksTo("User")]
[assembly: IgnoresAccessChecksTo("Utilities")]
[assembly: IgnoresAccessChecksTo("websocket-sharp")]
[assembly: IgnoresAccessChecksTo("Whinarn.UnityMeshSimplifier.Runtime")]
[assembly: IgnoresAccessChecksTo("XblPCSandbox")]
[assembly: IgnoresAccessChecksTo("Zorro.AutoLOD")]
[assembly: IgnoresAccessChecksTo("Zorro.ControllerSupport")]
[assembly: IgnoresAccessChecksTo("Zorro.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Zorro.JiggleBones")]
[assembly: IgnoresAccessChecksTo("Zorro.PhotonUtility")]
[assembly: IgnoresAccessChecksTo("Zorro.Settings.Runtime")]
[assembly: IgnoresAccessChecksTo("Zorro.UI.Runtime")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ModConfigEnhance
{
	internal static class GamepadSupport
	{
		private sealed class RowSubmitWired : MonoBehaviour
		{
		}

		internal sealed class NoopTransistion : PageTransistion
		{
			internal static readonly PageTransistion Shared = (PageTransistion)(object)new NoopTransistion();

			public override void Transistion(PageBase oldSubPage, PageBase newSubPage)
			{
			}
		}

		internal sealed class PanelFocus : MonoBehaviour
		{
			internal ModSettingsMenu? Menu;

			internal PeakChildPage? Page;

			internal ModdedTABSButton? LastSubmittedModRow;

			private UIPageHandler? _handler;

			private GameObject? _lastSidebar;

			private GameObject? _lastOptions;

			internal bool InOptions { get; private set; }

			private void Awake()
			{
				_handler = ((Component)this).GetComponentInParent<UIPageHandler>(true);
			}

			private void OnDisable()
			{
				InOptions = false;
				_lastSidebar = null;
				_lastOptions = null;
				LastSubmittedModRow = null;
			}

			private void Update()
			{
				if (!IsGamepad || (Object)(object)Menu == (Object)null || (Object)(object)Page == (Object)null || (Object)(object)_handler == (Object)null || (Object)(object)_handler.currentPage != (Object)(object)Page || !((Component)Page).gameObject.activeInHierarchy || Overlaid() || CaptureActive() || AnyDropdownOpen(((Component)Page).transform))
				{
					return;
				}
				EventSystem current = EventSystem.current;
				if ((Object)(object)current == (Object)null || current.alreadySelecting)
				{
					return;
				}
				GameObject currentSelectedGameObject = current.currentSelectedGameObject;
				bool flag = IsValid(currentSelectedGameObject);
				bool flag2 = IsInOptions(currentSelectedGameObject);
				if (InOptions)
				{
					if (flag && flag2)
					{
						_lastOptions = currentSelectedGameObject;
					}
					else
					{
						SelectOptions(current);
					}
				}
				else if (flag && !flag2)
				{
					_lastSidebar = currentSelectedGameObject;
				}
				else
				{
					SelectSidebar(current);
				}
			}

			internal void EnterOptions()
			{
				if (!IsGamepad || (Object)(object)Menu == (Object)null)
				{
					return;
				}
				GameObject val = (StillValid(_lastOptions, wantOptions: true) ? _lastOptions : FirstCellSelectable());
				if (!((Object)(object)val == (Object)null))
				{
					InOptions = true;
					EventSystem current = EventSystem.current;
					if (current != null)
					{
						current.SetSelectedGameObject(val);
					}
				}
			}

			internal bool ConsumeBack()
			{
				if (!IsGamepad || Overlaid())
				{
					return false;
				}
				InputBindingCaptureService val = CaptureService();
				if ((Object)(object)val != (Object)null && val.IsCapturing)
				{
					Object owner = val.owner;
					if (owner != (Object)null)
					{
						val.Cancel(owner);
					}
					return true;
				}
				if ((Object)(object)Page != (Object)null && AnyDropdownOpen(((Component)Page).transform))
				{
					return true;
				}
				GameObject val2 = (((Object)(object)EventSystem.current != (Object)null) ? EventSystem.current.currentSelectedGameObject : null);
				TMP_InputField val3 = (((Object)(object)val2 != (Object)null) ? val2.GetComponent<TMP_InputField>() : null);
				if ((Object)(object)val3 != (Object)null && val3.isFocused)
				{
					val3.DeactivateInputField(false);
					return true;
				}
				SliderGate sliderGate = (((Object)(object)val2 != (Object)null) ? val2.GetComponent<SliderGate>() : null);
				if ((Object)(object)sliderGate != (Object)null && sliderGate.Engaged)
				{
					sliderGate.Disengage();
					return true;
				}
				if (!InOptions)
				{
					return false;
				}
				InOptions = false;
				EventSystem current = EventSystem.current;
				if ((Object)(object)current != (Object)null)
				{
					SelectSidebar(current);
				}
				return true;
			}

			private bool IsValid(GameObject? selected)
			{
				if ((Object)(object)selected == (Object)null || !selected.activeInHierarchy || (Object)(object)Page == (Object)null)
				{
					return false;
				}
				if (!TransformExtensions.IsGrandChildOf(selected.transform, ((Component)Page).transform))
				{
					return false;
				}
				Selectable component = selected.GetComponent<Selectable>();
				return (Object)(object)component != (Object)null && component.IsInteractable();
			}

			private bool StillValid(GameObject? selected, bool wantOptions)
			{
				if ((Object)(object)selected == (Object)null || !selected.activeInHierarchy || IsInOptions(selected) != wantOptions)
				{
					return false;
				}
				Selectable component = selected.GetComponent<Selectable>();
				return (Object)(object)component != (Object)null && component.IsInteractable();
			}

			private bool IsInOptions(GameObject? go)
			{
				return (Object)(object)go != (Object)null && (Object)(object)Menu != (Object)null && (Object)(object)Menu.Content != (Object)null && TransformExtensions.IsGrandChildOf(go.transform, Menu.Content);
			}

			private void SelectOptions(EventSystem system)
			{
				GameObject val = (StillValid(_lastOptions, wantOptions: true) ? _lastOptions : FirstCellSelectable());
				if ((Object)(object)val == (Object)null)
				{
					InOptions = false;
					SelectSidebar(system);
				}
				else
				{
					system.SetSelectedGameObject(val);
				}
			}

			private void SelectSidebar(EventSystem system)
			{
				GameObject val = (StillValid(_lastSidebar, wantOptions: false) ? _lastSidebar : null);
				if ((Object)(object)val == (Object)null)
				{
					ModSettingsMenu? menu = Menu;
					ModdedTABSButton val2 = (((Object)(object)((menu != null) ? menu.ModTabs : null) != (Object)null) ? ((TABS<ModdedTABSButton>)(object)Menu.ModTabs).selectedButton : null);
					if ((Object)(object)val2 != (Object)null && ((Component)val2).gameObject.activeInHierarchy)
					{
						val = ((Component)val2).gameObject;
					}
				}
				if (val == null)
				{
					val = FirstVisibleModRow();
				}
				if ((Object)(object)val == (Object)null && (Object)(object)Page != (Object)null && (Object)(object)Page.BackButton != (Object)null)
				{
					val = ((Component)Page.BackButton).gameObject;
				}
				if ((Object)(object)val != (Object)null)
				{
					system.SetSelectedGameObject(val);
				}
			}

			private GameObject? FirstVisibleModRow()
			{
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Expected O, but got Unknown
				ModSettingsMenu? menu = Menu;
				ScrollRect val = (((Object)(object)((menu != null) ? menu.ModTabController : null) != (Object)null) ? ((Component)Menu.ModTabController).GetComponent<ScrollRect>() : null);
				if ((Object)(object)val == (Object)null || (Object)(object)val.content == (Object)null)
				{
					return null;
				}
				foreach (Transform item in (Transform)val.content)
				{
					Transform val2 = item;
					if (((Component)val2).gameObject.activeInHierarchy && (Object)(object)((Component)val2).GetComponent<ModdedTABSButton>() != (Object)null)
					{
						return ((Component)val2).gameObject;
					}
				}
				return null;
			}

			private GameObject? FirstCellSelectable()
			{
				if ((Object)(object)Menu == (Object)null)
				{
					return null;
				}
				foreach (SettingsUICell spawnedCell in Menu.m_spawnedCells)
				{
					if ((Object)(object)spawnedCell == (Object)null || !((Component)spawnedCell).gameObject.activeInHierarchy)
					{
						continue;
					}
					GameObject selectable = spawnedCell.GetSelectable();
					if (!((Object)(object)selectable == (Object)null) && selectable.activeInHierarchy)
					{
						Selectable component = selectable.GetComponent<Selectable>();
						if ((Object)(object)component != (Object)null && component.IsInteractable())
						{
							return selectable;
						}
					}
				}
				return null;
			}
		}

		internal sealed class NavChain : MonoBehaviour
		{
			private sealed class Line
			{
				internal readonly List<Selectable> Items = new List<Selectable>();

				internal readonly List<Group> Groups = new List<Group>();
			}

			private sealed class Group
			{
				internal readonly List<Selectable> Items = new List<Selectable>();

				internal float MeanX;

				internal int Col;
			}

			internal PeakChildPage? Page;

			internal RectTransform? Content;

			internal bool Sidebar;

			private const float ColumnTolerance = 14f;

			private UIPageHandler? _handler;

			private static readonly Comparison<Selectable> CompareX = (Selectable a, Selectable b) => ((Component)a).transform.position.x.CompareTo(((Component)b).transform.position.x);

			private static readonly Comparison<Selectable> CompareYDesc = (Selectable a, Selectable b) => ((Component)b).transform.position.y.CompareTo(((Component)a).transform.position.y);

			private void Awake()
			{
				_handler = ((Component)this).GetComponentInParent<UIPageHandler>(true);
			}

			private void Update()
			{
				if (IsGamepad && !((Object)(object)Page == (Object)null) && !((Object)(object)Content == (Object)null) && !((Object)(object)_handler == (Object)null) && !((Object)(object)_handler.currentPage != (Object)(object)Page))
				{
					Relink();
				}
			}

			private void Relink()
			{
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Expected O, but got Unknown
				//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b1: Expected O, but got Unknown
				//IL_045c: Unknown result type (might be due to invalid IL or missing references)
				//IL_046a: Unknown result type (might be due to invalid IL or missing references)
				//IL_046f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0569: Unknown result type (might be due to invalid IL or missing references)
				List<Line> list = new List<Line>();
				foreach (Transform item in (Transform)Content)
				{
					Transform val = item;
					if (!((Component)val).gameObject.activeInHierarchy)
					{
						continue;
					}
					if (Sidebar && (Object)(object)((Component)val).GetComponent<ModConfigTreeLayoutPatch.TreeMarker>() != (Object)null)
					{
						ScrollRect component = ((Component)val).GetComponent<ScrollRect>();
						RectTransform val2 = (((Object)(object)component != (Object)null) ? component.content : null);
						if ((Object)(object)val2 == (Object)null)
						{
							continue;
						}
						foreach (Transform item2 in (Transform)val2)
						{
							Transform val3 = item2;
							if (((Component)val3).gameObject.activeInHierarchy)
							{
								Selectable component2 = ((Component)val3).GetComponent<Selectable>();
								if ((Object)(object)component2 != (Object)null && component2.IsInteractable())
								{
									Line line = new Line();
									line.Items.Add(component2);
									list.Add(line);
								}
							}
						}
					}
					else
					{
						List<Selectable> list2 = CollectLineItems(val);
						if (list2 != null)
						{
							Line line2 = new Line();
							line2.Items.AddRange(list2);
							list.Add(line2);
						}
					}
				}
				if (list.Count == 0)
				{
					return;
				}
				foreach (Line item3 in list)
				{
					item3.Items.Sort(CompareX);
					Group obj = null;
					foreach (Selectable item4 in item3.Items)
					{
						float x = ((Component)item4).transform.position.x;
						if (obj == null || Mathf.Abs(x - obj.MeanX) > 14f)
						{
							obj = new Group();
							item3.Groups.Add(obj);
						}
						obj.Items.Add(item4);
						obj.MeanX = (obj.MeanX * (float)(obj.Items.Count - 1) + x) / (float)obj.Items.Count;
					}
					foreach (Group group in item3.Groups)
					{
						group.Items.Sort(CompareYDesc);
					}
				}
				List<float> list3 = new List<float>();
				foreach (Line item5 in list)
				{
					foreach (Group group2 in item5.Groups)
					{
						int num = -1;
						float num2 = float.MaxValue;
						for (int i = 0; i < list3.Count; i++)
						{
							float num3 = Mathf.Abs(list3[i] - group2.MeanX);
							if (num3 <= 14f && num3 < num2)
							{
								num2 = num3;
								num = i;
							}
						}
						if (num < 0)
						{
							num = list3.Count;
							list3.Add(group2.MeanX);
						}
						group2.Col = num;
					}
				}
				Selectable val4 = (Sidebar ? FindSearchField() : null);
				for (int j = 0; j < list.Count; j++)
				{
					Line line3 = list[j];
					for (int k = 0; k < line3.Groups.Count; k++)
					{
						Group obj2 = line3.Groups[k];
						for (int l = 0; l < obj2.Items.Count; l++)
						{
							Selectable val5 = obj2.Items[l];
							float y = ((Component)val5).transform.position.y;
							Navigation navigation = val5.navigation;
							((Navigation)(ref navigation)).mode = (Mode)4;
							((Navigation)(ref navigation)).selectOnUp = (Selectable)((l > 0) ? obj2.Items[l - 1] : ((j > 0) ? ((object)NearestInLine(list[j - 1], obj2.Col, y)) : ((object)val4)));
							((Navigation)(ref navigation)).selectOnDown = (Selectable)((l < obj2.Items.Count - 1) ? ((object)obj2.Items[l + 1]) : ((object)((j < list.Count - 1) ? NearestInLine(list[j + 1], obj2.Col, y) : null)));
							((Navigation)(ref navigation)).selectOnLeft = ((k > 0) ? NearestInGroup(line3.Groups[k - 1], y) : null);
							((Navigation)(ref navigation)).selectOnRight = ((k < line3.Groups.Count - 1) ? NearestInGroup(line3.Groups[k + 1], y) : null);
							val5.navigation = navigation;
						}
					}
				}
			}

			private static Selectable? NearestInLine(Line line, int col, float y)
			{
				Group obj = null;
				int num = int.MaxValue;
				foreach (Group group in line.Groups)
				{
					int num2 = Mathf.Abs(group.Col - col);
					if (num2 < num || (num2 == num && group.Col < (obj?.Col ?? int.MaxValue)))
					{
						obj = group;
						num = num2;
					}
				}
				return (obj != null) ? NearestInGroup(obj, y) : null;
			}

			private static Selectable NearestInGroup(Group group, float y)
			{
				//IL_0014: 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)
				Selectable val = group.Items[0];
				float num = Mathf.Abs(((Component)val).transform.position.y - y);
				for (int i = 1; i < group.Items.Count; i++)
				{
					float num2 = Mathf.Abs(((Component)group.Items[i]).transform.position.y - y);
					if (num2 < num)
					{
						val = group.Items[i];
						num = num2;
					}
				}
				return val;
			}

			private static List<Selectable>? CollectLineItems(Transform row)
			{
				List<Selectable> list = new List<Selectable>();
				Selectable component = ((Component)row).GetComponent<Selectable>();
				if ((Object)(object)component != (Object)null && component.IsInteractable())
				{
					list.Add(component);
				}
				Selectable[] componentsInChildren = ((Component)row).GetComponentsInChildren<Selectable>(true);
				foreach (Selectable val in componentsInChildren)
				{
					if (!((Object)(object)val == (Object)(object)component) && !(val is Scrollbar) && (val is TMP_Dropdown || !((Object)(object)((Component)val).GetComponentInParent<TMP_Dropdown>() != (Object)null)) && ((Component)val).gameObject.activeInHierarchy && val.IsInteractable())
					{
						list.Add(val);
					}
				}
				return (list.Count > 0) ? list : null;
			}

			private Selectable? FindSearchField()
			{
				Transform val = (((Object)(object)Page != (Object)null) ? ((Component)Page).transform.Find("SearchInput") : null);
				return ((Object)(object)val != (Object)null) ? ((Component)val).GetComponentInChildren<Selectable>(true) : null;
			}
		}

		internal sealed class FocusScrollIntoView : MonoBehaviour, ISelectHandler, IEventSystemHandler
		{
			internal ScrollRect? Scroll;

			internal RectTransform? Target;

			private bool _scrolling;

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

			public void OnSelect(BaseEventData eventData)
			{
				if (IsGamepad)
				{
					_scrolling = true;
				}
			}

			private void OnDisable()
			{
				_scrolling = false;
			}

			private void Update()
			{
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_0097: Unknown result type (might be due to invalid IL or missing references)
				if (!_scrolling)
				{
					return;
				}
				if (!IsGamepad || (Object)(object)Scroll == (Object)null || (Object)(object)Scroll.content == (Object)null)
				{
					_scrolling = false;
					return;
				}
				RectTransform rect = (RectTransform)(((Object)(object)Scroll.viewport != (Object)null) ? ((object)Scroll.viewport) : ((object)(RectTransform)((Component)Scroll).transform));
				RectTransform rect2 = (RectTransform)(((Object)(object)Target != (Object)null) ? ((object)Target) : ((object)(RectTransform)((Component)this).transform));
				float num = TopY(Scroll.content);
				float num2 = BottomY(Scroll.content);
				float num3 = TopY(rect);
				float num4 = BottomY(rect);
				float num5 = num - num2 - (num3 - num4);
				if (num5 <= 0.5f)
				{
					_scrolling = false;
					return;
				}
				float verticalNormalizedPosition = Scroll.verticalNormalizedPosition;
				float num6 = TopY(rect2);
				float num7 = BottomY(rect2);
				if (num6 > num3 + 1f)
				{
					verticalNormalizedPosition += (num6 - num3) / num5;
				}
				else
				{
					if (!(num7 < num4 - 1f))
					{
						_scrolling = false;
						return;
					}
					verticalNormalizedPosition -= (num4 - num7) / num5;
				}
				verticalNormalizedPosition = Mathf.Clamp01(verticalNormalizedPosition);
				float num8 = Mathf.MoveTowards(Scroll.verticalNormalizedPosition, verticalNormalizedPosition, Time.unscaledDeltaTime * 10f);
				Scroll.verticalNormalizedPosition = num8;
				if (Mathf.Approximately(num8, verticalNormalizedPosition))
				{
					_scrolling = false;
				}
			}

			private static float TopY(RectTransform rect)
			{
				rect.GetWorldCorners(Corners);
				return Corners[1].y;
			}

			private static float BottomY(RectTransform rect)
			{
				rect.GetWorldCorners(Corners);
				return Corners[0].y;
			}
		}

		internal sealed class FocusHighlight : MonoBehaviour, ISelectHandler, IEventSystemHandler, IDeselectHandler
		{
			private const float Outset = 2f;

			private static readonly Color EngagedColor = new Color(1f, 0.72f, 0.28f);

			private GameObject? _frame;

			private bool _engaged;

			private const int RingTexSize = 64;

			private const float RingRadiusPx = 12f;

			private const float RingStrokePx = 3f;

			private const int RingSliceBorder = 16;

			private static Sprite? _ringSprite;

			public void OnSelect(BaseEventData eventData)
			{
				SetVisible(visible: true);
			}

			public void OnDeselect(BaseEventData eventData)
			{
				SetVisible(visible: false);
				_engaged = false;
			}

			private void OnDisable()
			{
				SetVisible(visible: false);
				_engaged = false;
			}

			internal void SetEngaged(bool engaged)
			{
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				_engaged = engaged;
				Image val = default(Image);
				if ((Object)(object)_frame != (Object)null && _frame.TryGetComponent<Image>(ref val))
				{
					((Graphic)val).color = (engaged ? EngagedColor : ModConfigSidebarWidgets.Cream);
				}
			}

			private void SetVisible(bool visible)
			{
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Expected O, but got Unknown
				if (visible && (Object)(object)_frame == (Object)null)
				{
					_frame = CreateFrame((RectTransform)((Component)this).transform);
				}
				if ((Object)(object)_frame != (Object)null && _frame.activeSelf != visible)
				{
					_frame.SetActive(visible);
				}
			}

			private static GameObject CreateFrame(RectTransform host)
			{
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Expected O, but got Unknown
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Expected O, but got Unknown
				//IL_006f: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
				Selectable component = ((Component)host).GetComponent<Selectable>();
				Transform val = (Transform)(((Object)(object)component != (Object)null && (Object)(object)component.targetGraphic != (Object)null) ? ((object)((Component)component.targetGraphic).transform) : ((object)host));
				GameObject val2 = new GameObject("MCE_FocusFrame", new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				});
				RectTransform val3 = (RectTransform)val2.transform;
				((Transform)val3).SetParent(val, false);
				val3.anchorMin = Vector2.zero;
				val3.anchorMax = Vector2.one;
				val3.offsetMin = new Vector2(-2f, -2f);
				val3.offsetMax = new Vector2(2f, 2f);
				((Transform)val3).SetAsLastSibling();
				Image component2 = val2.GetComponent<Image>();
				component2.sprite = RingSprite();
				component2.type = (Type)1;
				component2.pixelsPerUnitMultiplier = 1.2f;
				((Graphic)component2).color = ModConfigSidebarWidgets.Cream;
				((Graphic)component2).raycastTarget = false;
				val2.SetActive(false);
				return val2;
			}

			private static Sprite RingSprite()
			{
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Expected O, but got Unknown
				//IL_0166: Unknown result type (might be due to invalid IL or missing references)
				//IL_0175: Unknown result type (might be due to invalid IL or missing references)
				//IL_0195: Unknown result type (might be due to invalid IL or missing references)
				//IL_0103: Unknown result type (might be due to invalid IL or missing references)
				//IL_0108: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_ringSprite != (Object)null)
				{
					return _ringSprite;
				}
				Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false)
				{
					filterMode = (FilterMode)1,
					wrapMode = (TextureWrapMode)1,
					name = "MCE_FocusRing"
				};
				Color32[] array = (Color32[])(object)new Color32[4096];
				for (int i = 0; i < 64; i++)
				{
					for (int j = 0; j < 64; j++)
					{
						float num = (float)j + 0.5f;
						float num2 = (float)i + 0.5f;
						float num3 = Mathf.Clamp(num, 12f, 52f);
						float num4 = Mathf.Clamp(num2, 12f, 52f);
						float num5 = 12f - Mathf.Sqrt((num - num3) * (num - num3) + (num2 - num4) * (num2 - num4));
						float num6 = Mathf.Clamp01(Mathf.Min(num5, 3f - num5) + 0.5f);
						array[i * 64 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)Mathf.RoundToInt(num6 * 255f));
					}
				}
				val.SetPixels32(array);
				val.Apply(false, true);
				Object.DontDestroyOnLoad((Object)(object)val);
				_ringSprite = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, new Vector4(16f, 16f, 16f, 16f));
				((Object)_ringSprite).name = "MCE_FocusRing";
				Object.DontDestroyOnLoad((Object)(object)_ringSprite);
				return _ringSprite;
			}
		}

		internal sealed class DropdownNavFix : MonoBehaviour
		{
			private TMP_Dropdown? _dropdown;

			private bool _wasExpanded;

			private void Awake()
			{
				_dropdown = ((Component)this).GetComponent<TMP_Dropdown>();
			}

			private void Update()
			{
				if (!((Object)(object)_dropdown == (Object)null))
				{
					bool isExpanded = _dropdown.IsExpanded;
					if (isExpanded && !_wasExpanded && IsGamepad)
					{
						RelinkItems();
					}
					_wasExpanded = isExpanded;
				}
			}

			private void RelinkItems()
			{
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				List<Toggle> list = new List<Toggle>(((Component)_dropdown).GetComponentsInChildren<Toggle>(false));
				for (int i = 0; i < list.Count; i++)
				{
					Navigation navigation = ((Selectable)list[i]).navigation;
					((Navigation)(ref navigation)).mode = (Mode)4;
					((Navigation)(ref navigation)).selectOnUp = (Selectable)(object)((i > 0) ? list[i - 1] : null);
					((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)((i < list.Count - 1) ? list[i + 1] : null);
					((Navigation)(ref navigation)).selectOnLeft = null;
					((Navigation)(ref navigation)).selectOnRight = null;
					((Selectable)list[i]).navigation = navigation;
				}
			}
		}

		internal sealed class InputFieldGate : MonoBehaviour
		{
			private TMP_InputField? _input;

			private FocusHighlight? _highlight;

			private bool _engaged;

			private void Awake()
			{
				_input = ((Component)this).GetComponent<TMP_InputField>();
			}

			private void Update()
			{
				bool flag = (Object)(object)_input != (Object)null && _input.isFocused;
				if (flag != _engaged)
				{
					_engaged = flag;
					if ((Object)(object)_highlight == (Object)null)
					{
						_highlight = ((Component)this).GetComponent<FocusHighlight>();
					}
					_highlight?.SetEngaged(flag);
				}
			}
		}

		internal sealed class CaptureGlow : MonoBehaviour
		{
			private InputBindingSettingUI? _cell;

			private FocusHighlight? _highlight;

			private bool _on;

			private void Awake()
			{
				_cell = ((Component)this).GetComponent<InputBindingSettingUI>();
			}

			private void Update()
			{
				InputBindingCaptureService val = CaptureService();
				bool flag = (Object)(object)val != (Object)null && (object)val.owner == _cell;
				if (flag != _on)
				{
					_on = flag;
					if ((Object)(object)_highlight == (Object)null)
					{
						_highlight = ((Component)this).GetComponent<FocusHighlight>();
					}
					_highlight?.SetEngaged(flag);
				}
			}
		}

		internal sealed class SliderGate : MonoBehaviour, ISubmitHandler, IEventSystemHandler, IDeselectHandler
		{
			private const float HoldDelay = 1f;

			private const float RepeatPerSecond = 10f;

			private const float FastRepeatAfter = 3f;

			private const float FastRepeatPerSecond = 40f;

			internal bool Engaged;

			private Slider? _slider;

			private FocusHighlight? _highlight;

			private int _dir;

			private float _held;

			private float _accum;

			private void Awake()
			{
				_slider = ((Component)this).GetComponent<Slider>();
			}

			public void OnSubmit(BaseEventData eventData)
			{
				if (IsGamepad)
				{
					Engaged = !Engaged;
					_dir = 0;
					_held = 0f;
					_accum = 0f;
					Highlight()?.SetEngaged(Engaged);
				}
			}

			public void OnDeselect(BaseEventData eventData)
			{
				Disengage();
			}

			private void OnDisable()
			{
				Disengage();
			}

			internal void Disengage()
			{
				Engaged = false;
				_dir = 0;
				Highlight()?.SetEngaged(engaged: false);
			}

			private FocusHighlight? Highlight()
			{
				return ((Object)(object)_highlight != (Object)null) ? _highlight : (_highlight = ((Component)this).GetComponent<FocusHighlight>());
			}

			private void Update()
			{
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				if (!Engaged || (Object)(object)_slider == (Object)null || !IsGamepad || NavAction == null)
				{
					_dir = 0;
					_held = 0f;
					_accum = 0f;
					return;
				}
				float x = NavAction.ReadValue<Vector2>().x;
				int num = ((x > 0.5f) ? 1 : ((x < -0.5f) ? (-1) : 0));
				if (num == 0)
				{
					_dir = 0;
					_held = 0f;
					_accum = 0f;
					return;
				}
				if (num != _dir)
				{
					_dir = num;
					_held = 0f;
					_accum = 0f;
					Step(num);
					return;
				}
				_held += Time.unscaledDeltaTime;
				if (!(_held < 1f))
				{
					_accum += Time.unscaledDeltaTime * ((_held >= 3f) ? 40f : 10f);
					while (_accum >= 1f)
					{
						_accum -= 1f;
						Step(_dir);
					}
				}
			}

			private void Step(int dir)
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Invalid comparison between Unknown and I4
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Invalid comparison between Unknown and I4
				float num = _slider.maxValue - _slider.minValue;
				if (!(num <= 0f))
				{
					Direction direction = _slider.direction;
					bool flag = (((int)direction == 1 || (int)direction == 3) ? true : false);
					bool flag2 = flag;
					float num2 = (_slider.wholeNumbers ? Mathf.Max(1f, Mathf.Round(num * 0.005f)) : Mathf.Min(num * 0.1f, num * 0.005f));
					_slider.value = Mathf.Clamp(_slider.value + num2 * (float)dir * (float)((!flag2) ? 1 : (-1)), _slider.minValue, _slider.maxValue);
				}
			}
		}

		internal sealed class SidebarTabHotkeys : MonoBehaviour
		{
			internal ModSettingsMenu? Menu;

			internal PeakChildPage? Page;

			private UIPageHandler? _handler;

			private InputAction? _left;

			private InputAction? _right;

			private bool _actionsResolved;

			private void Awake()
			{
				_handler = ((Component)this).GetComponentInParent<UIPageHandler>(true);
			}

			private void Update()
			{
				if (!IsGamepad || (Object)(object)Menu == (Object)null || (Object)(object)Page == (Object)null || (Object)(object)Menu.ModTabs == (Object)null || (Object)(object)Menu.ModTabController == (Object)null || (Object)(object)_handler == (Object)null || (Object)(object)_handler.currentPage != (Object)(object)Page)
				{
					return;
				}
				PanelFocus component = ((Component)Page).GetComponent<PanelFocus>();
				if (((Object)(object)component != (Object)null && component.InOptions) || !ResolveActions())
				{
					return;
				}
				bool flag = _left.WasPressedThisFrame();
				bool flag2 = !flag && _right.WasPressedThisFrame();
				if ((!flag && !flag2) || Overlaid() || CaptureActive() || TypingGuard.Active || AnyDropdownOpen(((Component)Page).transform))
				{
					return;
				}
				ModdedTABSButton val = SelectModRelative((!flag) ? 1 : (-1));
				if ((Object)(object)val != (Object)null)
				{
					EventSystem current = EventSystem.current;
					if (current != null)
					{
						current.SetSelectedGameObject(((Component)val).gameObject);
					}
				}
			}

			private bool ResolveActions()
			{
				if (_actionsResolved)
				{
					return _left != null && _right != null;
				}
				_actionsResolved = true;
				try
				{
					_left = InputSystem.actions.FindAction("UITabLeft", false);
					_right = InputSystem.actions.FindAction("UITabRight", false);
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("[手柄] UI 页签动作解析失败: " + ex.Message));
				}
				if (_left == null || _right == null)
				{
					Plugin.Log.LogWarning((object)"[手柄] 找不到 UITabLeft/UITabRight 动作,肩键切模组不可用。");
				}
				return _left != null && _right != null;
			}

			private ModdedTABSButton? SelectModRelative(int delta)
			{
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Expected O, but got Unknown
				ScrollRect component = ((Component)Menu.ModTabController).GetComponent<ScrollRect>();
				if ((Object)(object)component == (Object)null || (Object)(object)component.content == (Object)null)
				{
					return null;
				}
				List<ModdedTABSButton> list = new List<ModdedTABSButton>();
				foreach (Transform item in (Transform)component.content)
				{
					Transform val = item;
					if (((Component)val).gameObject.activeInHierarchy)
					{
						ModdedTABSButton component2 = ((Component)val).GetComponent<ModdedTABSButton>();
						if ((Object)(object)component2 != (Object)null)
						{
							list.Add(component2);
						}
					}
				}
				if (list.Count == 0)
				{
					return null;
				}
				int num = list.IndexOf(((TABS<ModdedTABSButton>)(object)Menu.ModTabs).selectedButton);
				num = ((num >= 0) ? ((num + delta + list.Count) % list.Count) : 0);
				ModdedTABSButton val2 = list[num];
				((TABS<ModdedTABSButton>)(object)Menu.ModTabs).Select(val2);
				return val2;
			}
		}

		private static bool _inputHandlerBroken;

		private static bool _noDeviceLogged;

		private static bool _lastInputInited;

		private static bool _lastInputIsGamepad;

		private static bool _lastInputWarned;

		private const float StickSqDeadzone = 0.0225f;

		private const float TriggerThreshold = 0.1f;

		private static InputAction? _navAction;

		private static bool _navResolved;

		private static bool _captureBroken;

		private const float BindHoldSeconds = 1f;

		private static KeyCode _bindHeldKey;

		private static float _bindHeldTime;

		internal static bool IsGamepad
		{
			get
			{
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Invalid comparison between Unknown and I4
				if (_inputHandlerBroken)
				{
					return false;
				}
				try
				{
					if (!(_lastInputInited ? _lastInputIsGamepad : ((int)InputHandler.GetCurrentUsedInputScheme() > 0)))
					{
						return false;
					}
					if (Gamepad.current == null)
					{
						if (!_noDeviceLogged)
						{
							_noDeviceLogged = true;
							Plugin.Log.LogWarning((object)"[手柄] 最后输入被判为手柄但系统里没有手柄设备,按键鼠处理(若接了手柄请动一下摇杆)。");
						}
						return false;
					}
					return true;
				}
				catch (Exception ex)
				{
					_inputHandlerBroken = true;
					Plugin.Log.LogWarning((object)("[手柄] Zorro InputHandler 不可用,手柄支持停用: " + ex.Message));
					return false;
				}
			}
		}

		internal static InputAction? NavAction
		{
			get
			{
				if (_navResolved)
				{
					return _navAction;
				}
				_navResolved = true;
				try
				{
					_navAction = InputSystem.actions.FindAction("UI/Navigate", false) ?? InputSystem.actions.FindAction("Navigate", false);
					if (_navAction != null && _navAction.expectedControlType != "Vector2")
					{
						_navAction = null;
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("[手柄] Navigate 动作解析失败: " + ex.Message));
				}
				return _navAction;
			}
		}

		private static void InputHandlerUpdatePostfix()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			try
			{
				if (!_lastInputInited)
				{
					_lastInputInited = true;
					_lastInputIsGamepad = (int)InputHandler.GetCurrentUsedInputScheme() == 1 && Gamepad.current != null;
				}
				else if (KeyboardMouseActive())
				{
					_lastInputIsGamepad = false;
				}
				else if (GamepadActive())
				{
					_lastInputIsGamepad = true;
				}
			}
			catch (Exception ex)
			{
				if (!_lastInputWarned)
				{
					_lastInputWarned = true;
					Plugin.Log.LogWarning((object)("[手柄] 最后输入设备跟踪失败: " + ex.Message));
				}
			}
		}

		private static bool KeyboardMouseActive()
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			Keyboard current = Keyboard.current;
			if (current != null && ((ButtonControl)current.anyKey).isPressed)
			{
				return true;
			}
			Mouse current2 = Mouse.current;
			if (current2 == null)
			{
				return false;
			}
			int result;
			if (!current2.leftButton.isPressed && !current2.rightButton.isPressed && !current2.middleButton.isPressed)
			{
				Vector2 val = ((InputControl<Vector2>)(object)((Pointer)current2).delta).ReadValue();
				if (!(((Vector2)(ref val)).sqrMagnitude > 0.01f))
				{
					result = ((((InputControl<Vector2>)(object)current2.scroll).ReadValue().y != 0f) ? 1 : 0);
					goto IL_0095;
				}
			}
			result = 1;
			goto IL_0095;
			IL_0095:
			return (byte)result != 0;
		}

		private static bool GamepadActive()
		{
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			Gamepad current = Gamepad.current;
			if (current == null)
			{
				return false;
			}
			if (current.buttonSouth.isPressed || current.buttonEast.isPressed || current.buttonNorth.isPressed || current.buttonWest.isPressed || current.leftShoulder.isPressed || current.rightShoulder.isPressed || current.leftStickButton.isPressed || current.rightStickButton.isPressed || current.startButton.isPressed || current.selectButton.isPressed || current.dpad.up.isPressed || current.dpad.down.isPressed || current.dpad.left.isPressed || current.dpad.right.isPressed)
			{
				return true;
			}
			Vector2 val = ((InputControl<Vector2>)(object)current.leftStick).ReadValue();
			int result;
			if (!(((Vector2)(ref val)).sqrMagnitude > 0.0225f))
			{
				val = ((InputControl<Vector2>)(object)current.rightStick).ReadValue();
				if (!(((Vector2)(ref val)).sqrMagnitude > 0.0225f) && !(((InputControl<float>)(object)current.leftTrigger).ReadValue() > 0.1f))
				{
					result = ((((InputControl<float>)(object)current.rightTrigger).ReadValue() > 0.1f) ? 1 : 0);
					goto IL_0157;
				}
			}
			result = 1;
			goto IL_0157;
			IL_0157:
			return (byte)result != 0;
		}

		internal static void Attach(ModSettingsMenu menu, PeakHorizontalTabs modTabs)
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			try
			{
				PeakChildPage mainPage = menu.MainPage;
				ScrollRect component = ((Component)modTabs).GetComponent<ScrollRect>();
				PanelFocus panelFocus = ((Component)mainPage).gameObject.AddComponent<PanelFocus>();
				panelFocus.Menu = menu;
				panelFocus.Page = mainPage;
				SidebarTabHotkeys sidebarTabHotkeys = ((Component)component).gameObject.AddComponent<SidebarTabHotkeys>();
				sidebarTabHotkeys.Menu = menu;
				sidebarTabHotkeys.Page = mainPage;
				NavChain navChain = ((Component)component).gameObject.AddComponent<NavChain>();
				navChain.Page = mainPage;
				navChain.Content = component.content;
				navChain.Sidebar = true;
				NavChain navChain2 = ((Component)menu.Content).gameObject.AddComponent<NavChain>();
				navChain2.Page = mainPage;
				navChain2.Content = (RectTransform)menu.Content;
				navChain2.Sidebar = false;
				if ((Object)(object)mainPage.BackButton != (Object)null)
				{
					MarkSelectable(((Component)mainPage.BackButton).gameObject, null, null);
				}
				if ((Object)(object)menu.FilterDropdown != (Object)null && (Object)(object)menu.FilterDropdown.Dropdown != (Object)null)
				{
					MarkSelectable(((Component)menu.FilterDropdown.Dropdown).gameObject, null, null);
				}
				Transform val = ((Component)mainPage).transform.Find("SearchInput");
				TMP_InputField val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponentInChildren<TMP_InputField>(true) : null);
				if ((Object)(object)val2 != (Object)null)
				{
					MarkSelectable(((Component)val2).gameObject, null, null);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[手柄] 挂载失败: " + ex.Message));
			}
		}

		internal static void MarkSelectable(GameObject go, ScrollRect? scroll, RectTransform? scrollTarget, bool highlight = true)
		{
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			if (highlight && (Object)(object)go.GetComponent<FocusHighlight>() == (Object)null)
			{
				go.AddComponent<FocusHighlight>();
			}
			if ((Object)(object)go.GetComponent<TMP_Dropdown>() != (Object)null && (Object)(object)go.GetComponent<DropdownNavFix>() == (Object)null)
			{
				go.AddComponent<DropdownNavFix>();
			}
			TMP_InputField component = go.GetComponent<TMP_InputField>();
			if ((Object)(object)component != (Object)null)
			{
				component.shouldActivateOnSelect = false;
				if ((Object)(object)go.GetComponent<InputFieldGate>() == (Object)null)
				{
					go.AddComponent<InputFieldGate>();
				}
			}
			if ((Object)(object)go.GetComponent<InputBindingSettingUI>() != (Object)null && (Object)(object)go.GetComponent<CaptureGlow>() == (Object)null)
			{
				go.AddComponent<CaptureGlow>();
			}
			if (!((Object)(object)scroll == (Object)null))
			{
				FocusScrollIntoView focusScrollIntoView = go.GetComponent<FocusScrollIntoView>() ?? go.AddComponent<FocusScrollIntoView>();
				focusScrollIntoView.Scroll = scroll;
				focusScrollIntoView.Target = (RectTransform?)(((Object)(object)scrollTarget != (Object)null) ? ((object)scrollTarget) : ((object)(RectTransform)go.transform));
			}
		}

		internal static void MarkCell(SettingsUICell cell, ScrollRect? scroll)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			if ((Object)(object)cell == (Object)null || (Object)(object)cell.m_settingsContentParent == (Object)null)
			{
				return;
			}
			Selectable[] componentsInChildren = ((Component)cell.m_settingsContentParent).GetComponentsInChildren<Selectable>(true);
			foreach (Selectable val in componentsInChildren)
			{
				if ((!(val is Toggle) && !(val is Scrollbar)) || 1 == 0)
				{
					MarkSelectable(((Component)val).gameObject, scroll, (RectTransform)((Component)cell).transform);
					if (val is Slider)
					{
						((Component)val).gameObject.AddComponent<SliderGate>();
					}
				}
			}
		}

		internal static void WireModRow(GameObject row)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			Button component = row.GetComponent<Button>();
			if (!((Object)(object)component == (Object)null) && !((Object)(object)row.GetComponent<RowSubmitWired>() != (Object)null))
			{
				row.AddComponent<RowSubmitWired>();
				((UnityEvent)component.onClick).AddListener((UnityAction)delegate
				{
					OnModRowSubmitted(row);
				});
			}
		}

		internal static void WireSectionRow(GameObject row)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			Button component = row.GetComponent<Button>();
			if (!((Object)(object)component == (Object)null) && !((Object)(object)row.GetComponent<RowSubmitWired>() != (Object)null))
			{
				row.AddComponent<RowSubmitWired>();
				((UnityEvent)component.onClick).AddListener((UnityAction)delegate
				{
					OnSectionRowSubmitted(row);
				});
			}
		}

		internal static void OnModRowSubmitted(GameObject row)
		{
			if (!IsGamepad)
			{
				return;
			}
			PanelFocus componentInParent = row.GetComponentInParent<PanelFocus>();
			ModdedTABSButton component = row.GetComponent<ModdedTABSButton>();
			if ((Object)(object)componentInParent == (Object)null || (Object)(object)component == (Object)null || (Object)(object)componentInParent.Menu == (Object)null)
			{
				return;
			}
			if ((Object)(object)componentInParent.LastSubmittedModRow == (Object)(object)component)
			{
				componentInParent.LastSubmittedModRow = null;
				GameObject val = FirstActiveSectionRow(componentInParent.Menu);
				if ((Object)(object)val != (Object)null)
				{
					EventSystem current = EventSystem.current;
					if (current != null)
					{
						current.SetSelectedGameObject(val);
					}
				}
				else
				{
					componentInParent.EnterOptions();
				}
			}
			else
			{
				componentInParent.LastSubmittedModRow = component;
			}
		}

		internal static void OnSectionRowSubmitted(GameObject row)
		{
			if (IsGamepad)
			{
				row.GetComponentInParent<PanelFocus>()?.EnterOptions();
			}
		}

		private static GameObject? FirstActiveSectionRow(ModSettingsMenu menu)
		{
			PeakHorizontalTabs sectionTabController = menu.SectionTabController;
			if ((Object)(object)sectionTabController == (Object)null || !((Component)sectionTabController).gameObject.activeInHierarchy)
			{
				return null;
			}
			foreach (GameObject tab in sectionTabController.Tabs)
			{
				if ((Object)(object)tab != (Object)null && tab.activeInHierarchy && (Object)(object)tab.GetComponent<ModdedTABSButton>() != (Object)null)
				{
					return tab;
				}
			}
			return null;
		}

		private static bool AnyDropdownOpen(Transform page)
		{
			TMP_Dropdown[] componentsInChildren = ((Component)page).GetComponentsInChildren<TMP_Dropdown>(false);
			foreach (TMP_Dropdown val in componentsInChildren)
			{
				if (val.IsExpanded)
				{
					return true;
				}
			}
			return false;
		}

		private static InputBindingCaptureService? CaptureService()
		{
			if (_captureBroken)
			{
				return null;
			}
			try
			{
				return ((Object)(object)ModConfigPlugin.instance != (Object)null) ? ModConfigPlugin.instance.InputBindingCapture : null;
			}
			catch (Exception ex)
			{
				_captureBroken = true;
				Plugin.Log.LogWarning((object)("[手柄] 按键捕获状态读取失败: " + ex.Message));
				return null;
			}
		}

		private static bool CaptureActive()
		{
			InputBindingCaptureService? obj = CaptureService();
			return obj != null && obj.IsCapturing;
		}

		private static bool Overlaid()
		{
			return Modal.IsOpen || MenuWindow.AllActiveWindows.Count > 0;
		}

		internal static void ApplyPatches(Harmony harmony)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Expected O, but got Unknown
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Expected O, but got Unknown
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Expected O, but got Unknown
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Expected O, but got Unknown
			try
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(Slider), "OnMove", new Type[1] { typeof(AxisEventData) }, (Type[])null);
				if (methodInfo != null)
				{
					harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(GamepadSupport), "SliderOnMovePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				else
				{
					Plugin.Log.LogWarning((object)"[手柄] 找不到 Slider.OnMove,滑条误触门控不可用。");
				}
				MethodInfo methodInfo2 = AccessTools.PropertyGetter(typeof(Slider), "stepSize");
				if (methodInfo2 != null)
				{
					harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(GamepadSupport), "SliderStepSizePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				else
				{
					Plugin.Log.LogWarning((object)"[手柄] 找不到 Slider.stepSize,步进上限不可用。");
				}
				MethodInfo methodInfo3 = AccessTools.Method(typeof(PeakChildPage), "GetParentPage", Type.EmptyTypes, (Type[])null);
				if (methodInfo3 != null)
				{
					harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(GamepadSupport), "GetParentPagePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				else
				{
					Plugin.Log.LogWarning((object)"[手柄] 找不到 PeakChildPage.GetParentPage,B 键分级返回不可用。");
				}
				MethodInfo methodInfo4 = AccessTools.Method(typeof(InputBindingCaptureService), "Update", (Type[])null, (Type[])null);
				if (methodInfo4 != null)
				{
					harmony.Patch((MethodBase)methodInfo4, new HarmonyMethod(typeof(GamepadSupport), "BindingCaptureUpdatePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				else
				{
					Plugin.Log.LogWarning((object)"[手柄] 找不到 InputBindingCaptureService.Update,绑定长按确认不可用。");
				}
				MethodInfo methodInfo5 = AccessTools.Method(typeof(InputBindingSettingUI), "ShowCapturePrompt", (Type[])null, (Type[])null);
				if (methodInfo5 != null)
				{
					harmony.Patch((MethodBase)methodInfo5, (HarmonyMethod)null, new HarmonyMethod(typeof(GamepadSupport), "BindingCapturePromptPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				MethodInfo methodInfo6 = AccessTools.Method(typeof(InputHandler), "Update", Type.EmptyTypes, (Type[])null);
				if (methodInfo6 != null)
				{
					harmony.Patch((MethodBase)methodInfo6, (HarmonyMethod)null, new HarmonyMethod(typeof(GamepadSupport), "InputHandlerUpdatePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				else
				{
					Plugin.Log.LogWarning((object)"[手柄] 找不到 InputHandler.Update,最后输入设备跟踪未挂载。");
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[手柄] 补丁挂载失败: " + ex.Message));
			}
		}

		private static bool BindingCaptureUpdatePrefix(InputBindingCaptureService __instance)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Invalid comparison between Unknown and I4
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Invalid comparison between Unknown and I4
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Invalid comparison between Unknown and I4
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			if (!IsGamepad)
			{
				return true;
			}
			if ((int)__instance.captureKind == 0)
			{
				_bindHeldKey = (KeyCode)0;
				return false;
			}
			if (Input.GetKeyDown((KeyCode)27) || (__instance.pauseAction != null && __instance.pauseAction.WasPressedThisFrame()))
			{
				_bindHeldKey = (KeyCode)0;
				_bindHeldTime = 0f;
				__instance.CancelCurrent();
				return false;
			}
			if ((int)__instance.captureKind != 1)
			{
				_bindHeldKey = (KeyCode)0;
				_bindHeldTime = 0f;
				return false;
			}
			KeyCode val = (KeyCode)0;
			KeyCode[] keyCodes = InputBindingCaptureService.KeyCodes;
			for (int i = 0; i < keyCodes.Length; i++)
			{
				if (Input.GetKey(keyCodes[i]))
				{
					val = keyCodes[i];
					break;
				}
			}
			if ((int)val == 0)
			{
				_bindHeldKey = (KeyCode)0;
				_bindHeldTime = 0f;
				return false;
			}
			if (val != _bindHeldKey)
			{
				_bindHeldKey = val;
				_bindHeldTime = 0f;
			}
			_bindHeldTime += Time.unscaledDeltaTime;
			if (_bindHeldTime >= 1f)
			{
				_bindHeldKey = (KeyCode)0;
				_bindHeldTime = 0f;
				__instance.CompleteKeyCode(val);
			}
			return false;
		}

		private static void BindingCapturePromptPostfix(InputBindingSettingUI __instance)
		{
			if (IsGamepad && !((Object)(object)__instance.KeyText == (Object)null))
			{
				((TMP_Text)__instance.KeyText).text = Loc.T("Hold a key for 1s to rebind", "长按某个键 1 秒换绑", "長按某個鍵 1 秒換綁");
			}
		}

		private static bool SliderOnMovePrefix(Slider __instance, AxisEventData eventData)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0048: 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_009a: Expected I4, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Invalid comparison between Unknown and I4
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			if (!IsGamepad)
			{
				return true;
			}
			SliderGate component = ((Component)__instance).GetComponent<SliderGate>();
			if ((Object)(object)component == (Object)null)
			{
				return true;
			}
			if (component.Engaged)
			{
				MoveDirection moveDir = eventData.moveDir;
				bool flag = (((int)moveDir == 0 || (int)moveDir == 2) ? true : false);
				return !flag || NavAction == null;
			}
			MoveDirection moveDir2 = eventData.moveDir;
			if (1 == 0)
			{
			}
			Vector3 val = (Vector3)((int)moveDir2 switch
			{
				0 => Vector3.left, 
				1 => Vector3.up, 
				3 => Vector3.down, 
				_ => Vector3.right, 
			});
			if (1 == 0)
			{
			}
			Vector3 val2 = val;
			Selectable val3 = ((Selectable)__instance).FindSelectable(val2);
			if ((Object)(object)val3 != (Object)null)
			{
				EventSystem current = EventSystem.current;
				if (current != null)
				{
					current.SetSelectedGameObject(((Component)val3).gameObject);
				}
			}
			return false;
		}

		private static void SliderStepSizePostfix(Slider __instance, ref float __result)
		{
			if (!((Object)(object)((Component)__instance).GetComponent<SliderGate>() == (Object)null))
			{
				float num = __instance.maxValue - __instance.minValue;
				if (!(num <= 0f))
				{
					__result = (__instance.wholeNumbers ? Mathf.Max(1f, Mathf.Round(num * 0.005f)) : Mathf.Min(__result, num * 0.005f));
				}
			}
		}

		private static bool GetParentPagePrefix(PeakChildPage __instance, ref (UIPage, PageTransistion) __result)
		{
			if (!IsGamepad)
			{
				return true;
			}
			PanelFocus component = ((Component)__instance).GetComponent<PanelFocus>();
			if ((Object)(object)component == (Object)null || !component.ConsumeBack())
			{
				return true;
			}
			__result = ((UIPage)(object)__instance, NoopTransistion.Shared);
			return false;
		}
	}
	internal static class LanguageReadme
	{
		private const string En = "# ModConfig Enhance {VERSION}\n\nPEAK · enhancements for the ModConfig (PEAKLib.ModConfig) settings page · Author AiAe\n\n*This file is generated by the mod: rewritten on every start and language switch, in the current UI language — manual edits are lost.*\n\n> Ever find yourself scrolling back and forth through a pile of mod settings just to change one value? Digging through cfg comments to figure out what an option does? Want to add multi-language support to your modpack? From now on, this mod lets you manage your modpack's settings far more elegantly!\n>\n> Tree-style mod list sidebar — √\n> An info panel showing mod name, version, option descriptions and more — √\n> One-click export of all unlocalized texts, free to translate, multi-language supported — √\n> Name sorting and pinning — √\n> Compatible with TimeTheme's purple night theme — √\n> …and other small tweaks\n\n## What is in this folder\n\n| Path | Purpose |\n|---|---|\n| `language\\xx-yy.txt` | A language file: this mod's UI terms + every mod's option texts |\n| `language\\en-us.txt` `zh-cn.txt` `zh-tw.txt` | Built-in. Created once, never overwritten; delete to reset |\n| `export\\` | Where \"Export texts\" and \"Untranslated\" write their files |\n| `readme.md` | This note |\n\nFiles starting with `_` never show in the dropdown. Only `.txt` files directly in `language\\` are read — subfolders are ignored, so keep backups in a subfolder.\n\n## Features\n\n| Feature | Details |\n|---|---|\n| Tree sidebar | The left column lists mods; the selected mod's sections expand beneath it, options on the right. Pinning supported. |\n| | Search, type filters, a Pin column and an Export column that exports only the ticked mods' texts. |\n| | Rows with no matches auto-hide while filtering; keybind options get their own filter button. |\n| Description panel | A persistent panel at the top right: hover/select an option to see its description, default value, range or choices; |\n| | select a mod/section to see its name, version and summary. Scrollable. |\n| UI localization | All UI text comes from language files; a dropdown on the page switches languages instantly. |\n| Translation tools | Export every text awaiting translation / only the untranslated entries; global original ↔ translation toggle; |\n| | live dictionary reload — add as many languages to your modpack as you like! |\n| Gamepad support | Two-level navigation between the left and right panels: A enters/confirms, B steps back, LB/RB switch mods; |\n| | sliders need A to arm before adjusting; on a keybind, press A then hold the key for 1 second to write it. |\n| Theme | Hand-drawn paper look; follows TimeTheme's day/night palette when installed; plus vanilla-style visuals and animations. |\n\n## Demo\n\n![Night-TimeTheme](https://raw.githubusercontent.com/AiAe-156/Peak-ModConfigEnhance/master/%E5%9B%BE%E7%89%87/%E5%A4%9C%E6%99%9A1.png)\n*Night theme (TimeTheme)*\n\n![Day](https://raw.githubusercontent.com/AiAe-156/Peak-ModConfigEnhance/master/%E5%9B%BE%E7%89%87/%E7%99%BD%E5%A4%A91.png)\n*Daytime look*\n\n![Demonstration](https://raw.githubusercontent.com/AiAe-156/Peak-ModConfigEnhance/master/%E5%9B%BE%E7%89%87/%E6%BC%94%E7%A4%BA%E8%A7%86%E9%A2%91main.gif)\n*Demo gif (may take a moment to load)*\n\n## Dependencies\n\n- **Required**: BepInEx 5, PEAKLib.Core, PEAKLib.UI, ModConfig 1.8.2\n- **Listed, but optional in practice**: XUnity AutoTranslator — it is in the dependency list so the mod manager installs it alongside, but nothing breaks without it: only the translation tools (Untranslated / Show original / dictionary mirroring) are greyed out, everything else works. See the note below — this mod changes one of its settings.\n- **Optional**: TimeTheme (day/night palette)\n\n## ⚠\ufe0f This mod changes an XUnity AutoTranslator setting\n\nWith its factory-default endpoint (GoogleTranslateV2), XUnity AutoTranslator sends **every** UI text — mod settings included — to online machine translation, and the results are often nonsense. So when XUnity is installed, this mod's option `Disable XUnity machine translation` (**on by default**; `BepInEx\\config\\com.aiae.modconfigenhance.cfg`, section `2. Localization`) does the following on every startup:\n\n- empties `Endpoint` / `FallbackEndpoint` in `AutoTranslatorConfig.ini`, so XUnity only applies dictionaries (this mod's language files, your own dictionaries) and no longer machine-translates;\n- empties the machine-translation caches `_AutoGeneratedTranslations*.txt` in every language folder, keeping a one-time `.bak` copy next to each file.\n\n**If you rely on live machine translation, set this option to `false` before the first launch** — or turn it off afterwards, put your endpoint back into `AutoTranslatorConfig.ini` and restore the `.bak` files.\n\n\n## Language files\n\nDirectory: `BepInEx\\config\\ModConfigEnhance\\language\\`\n\nFile format is identical to XUnity dictionaries: `key=translation`, `//` comments, `\\n` newline, `\\=` literal equals, `{0}` `{1}` placeholders kept — **never modify anything left of `=`** (it is the key the dictionary matches character-for-character against on-screen text). The first `MCE_…=…` block is this mod's UI terms (stable IDs — translate the right side only); the `original=translation` lines after it are handed to XUnity AutoTranslator.\n\nFiles starting with `_` stay out of the dropdown; only the top-level `.txt` files are read — keep backups in a subfolder.\n\n### File naming: `language-code[-variant][_part].txt`\n\nThe filename itself decides its group and how it's displayed — the two suffixes do different jobs:\n\n| Pattern | Meaning | Examples |\n|---|---|---|\n| `code.txt` | Base group for the language | `zh-cn.txt`, `en-us.txt` |\n| `code-variant.txt` | **Standalone group of the same language code** — a full, independent translation that may use a completely different style | `zh-cn-old.txt`, `zh-cn-memes.txt` |\n| `group_part.txt` | **Sub-file of a group** — merged into the group named before the `_`, loaded after it in filename order, later entries win | `zh-cn_topup.txt`, `zh-cn-old_fix.txt` |\n\n- **Language code** = the leading `xx` or `xx-yy` of the filename (`zh-cn-old` → `zh-cn`). It only governs two things: the XUnity mirror folder (`Translation\\<code>`) and \"Follow game language\" matching. Aliases: `zh`=`zh-cn`, `en`=`en-us`.\n- **Dropdown label**: a `// display: <name>` first line shows `name (filename)`; without it, the plain filename is shown. Groups with more than one file get `×count` appended. Examples: `zh-cn-old.txt` (with `// display: Old translation`) → `Old translation (zh-cn-old)`; `zh-cn.txt` (none) → `zh-cn`; `zh-cn-basic.txt` (`// display: 简体中文`) + `zh-cn-basic_ModB.txt` → `简体中文 (zh-cn-basic) ×2`.\n- **Loaded-files list**: after picking a group, the panel lists each file with its own display name, e.g. `zh-cn-basic.txt (简体中文)`, `zh-cn-basic_ModB.txt (Modb)`.\n- **Tooltip emphasis**: in `MCE_TIP_*` hover-tooltips, text inside `` `…` `` or `“…”` renders in the title color (backticks hidden, curly quotes kept).\n- **Variant groups are independent**: same-code groups are equal, self-contained translations — the untranslated check counts only the current group, like `cn` vs `tw`.\n- **Follow game language** with several same-code groups prefers the group named exactly the code (`zh-cn`), else the first variant.\n\n### Adding a language\n\n1. **Export** — mod settings → left column → **Export texts**; tick **Selected only** first to drop the mods you don't need (this mod is always included).\n2. **Translate** — fill the right side of each `=` following the rules inside the file; keep `\\n` and `\\=` notation as-is.\n3. **Rename & place** — save as UTF-8 and name by the rules above: a new language uses `lowercase-code.txt` (`de-de.txt`, `ja-jp.txt`…), an alternative style for the same language uses `code-variant.txt`; move it into `language\\`. To change the dropdown label, write `// display: <name>` on the first line.\n4. **Enable** — back in the game: click **Refresh**, pick the language in the dropdown — it loads automatically. After edits, click **Reload texts**.\n\n### Group sub-files & top-ups\n\n`group_part.txt` merges into the group named before the `_` (base file first, sub-files in filename order — text sorting, not numeric; pad sequential numbers `01`, `02`, `10`):\n\n```text\nzh-cn.txt             base file\nzh-cn_01_base.txt     sub-file: appended\nzh-cn_20_topup.txt    sub-file: overrides same keys\nzh-cn-old_fix.txt     joins the zh-cn-old group, not zh-cn\n```\n\n- Later files override earlier ones; identical entries are skipped; conflicting translations are logged with their source files.\n- Empty values, original-text placeholders and unchanged English `MCE_` values cannot overwrite existing translations.\n- A group is validated before applying; format errors (missing `=`, empty file…) show in the description panel in orange with line numbers — fix and reload.\n\nTop-up workflow: keep the old files → **Untranslated** → translate → save as a new `_part` file for the same group → **Reload texts**. The untranslated check counts only the current group's own coverage; **do not replace your full translation with a patch**. For a new language or variant group, click **Refresh** and select it.\n\n### After picking a language (no restart)\n\n- This mod's UI switches at once; the description panel lists every loaded filename in load order (with each file's display name).\n- XUnity AutoTranslator switches to that group's language code: its dictionary folder becomes `Translation\\<code>\\Text\\`, the translations are written there as `ModConfigEnhance_<code>.txt`, dictionaries reload, texts without a translation show the original, and `Language=` in `AutoTranslatorConfig.ini` is updated for the next start. Toggle this link with this mod's **Switch XUnity language with the language file** option.\n\n## Toolbar\n\n| Button | What it does |\n|---|---|\n| Export texts | Exports all UI texts to `export\\` (this mod's `MCE_` block + one block per mod, manifest summaries included) |\n| Untranslated | Exports only the entries the XUnity dictionary doesn't cover (requires XUnity AutoTranslator) |\n| Selected only | Adds an \"Export\" checkbox column to the sidebar — only the ticked mods get exported (this mod is always included) |\n| Show original / Show translated | Global original ↔ translation toggle (same as XUnity's Alt+T) |\n| Reload texts | Re-reads the language files and refreshes XUnity's dictionaries |\n| Open folder | Opens `config\\ModConfigEnhance\\` |\n| Language ▾ / Refresh | Pick a language group; **Refresh** after adding a new language, **Reload texts** after adding a sub-file to an existing one |\n\n## Gamepad controls\n\n- **Navigation**: stick / D-pad moves focus; A confirms/enters; B steps back level by level (slider → editing → capture → right panel → left panel → leave page)\n- **LB/RB**: switch mods\n- **Sliders**: A arms value mode, left/right adjust, A or B exits; each step is 0.5% of the range — hold for 1s to auto-repeat at 10 steps/s, 3s for 40 steps/s\n- **Dropdowns**: A opens, up/down to move, A picks, B closes\n- **Input fields**: A starts editing, B exits. No on-screen keyboard — type on a physical keyboard or the platform OSK (Steam+X on Steam Deck)\n- **Keybinds**: A starts capture, hold the target key for 1 second to write it; B cancels\n\n## Config file\n\n`BepInEx\\config\\com.aiae.modconfigenhance.cfg`:\n\n| Section | Contents |\n|---|---|\n| 1. Layout | Tree sidebar and description panel toggles (restart required) |\n| 2. Localization | UI localization, hide localization buttons (instant), make XUnity follow the chosen language file, disable XUnity machine translation (**on by default** — see the note above) |\n| 3. State | Runtime state: language file, pins, export exclusions etc. (Hidden) |\n\n## Extra details\n\n- **Sidebar cascade**: reopening the settings page reveals the selected mod row first, then one row above and below per beat; at the bottom rows appear upward; with no valid selection it starts from the top. Closing ends the animation and restores pending rows.\n- **Wheel step**: the left sidebar wheel step is about a third of vanilla, with a ~0.1s ease; scrollbar dragging and controller positioning take over immediately — other scroll areas are unchanged.\n- **Description panel**: selecting a mod/section shows its name, version and manifest summary; hovering/focusing an option restores that option's description.\n\n## Feedback & contribute\n\n`[email protected]` / QQ group `1104320838` / GitHub https://github.com/AiAe-156/Peak-ModConfigEnhance — finished language files are welcome too; send them to AiAe and they ship with the next release.\n";

		private const string ZhCn = "# ModConfig Enhance {VERSION}\n\nPEAK · ModConfig(PEAKLib.ModConfig)设置页增强 · 作者 AiAe\n\n*本文件由模组自动生成:每次启动 / 切语言后按当前界面语言重写,手工改动会被覆盖。*\n\n> 你是否经常在一堆模组配置里反复来回滑动,就为了改某一个参数;是否因为想知道某个配置项是做什么的而去 config 里翻注释;想为整合包添加多语言支持……从现在开始,你可以利用该模组更加优雅地管理你的整合包!\n>\n> 模组列表树形栏 - √\n> 一个能显示模组名称,版本号,配置项注释等信息的说明框 - √\n> 一键导出所有非本地化语言并自由发挥翻译,支持多重语言 - √\n> 名称排序和置顶功能 - √\n> 兼容 TimeTheme 夜间幽紫主题 - √\n> 以及其他小改动……\n\n## 这个目录放什么\n\n| 路径 | 用途 |\n|---|---|\n| `language\\xx-yy.txt` | 语言文件:本模组界面词条 + 所有模组的选项文本 |\n| `language\\en-us.txt` `zh-cn.txt` `zh-tw.txt` | 内建三种。只建不覆,可随意改;删掉即恢复默认 |\n| `export\\` | 「导出翻译」「补漏翻」写文件的地方 |\n| `readme.md` | 本说明 |\n\n`_` 开头的文件不进下拉框;只读 `language\\` 当前层的 `.txt`,子目录被忽略——备份请放进子目录。\n\n## 功能\n\n| 功能 | 说明 |\n|---|---|\n| 树形侧栏 | 左栏显示模组列表,选中模组会在其下方展开分区。可以置顶右侧为选项。 |\n| | 支持搜索、类型筛选、置顶选中列、仅导出勾选列的翻译文本。 |\n| | 筛选时无匹配项的行自动隐藏;单独为按键设置添加了筛选按钮。 |\n| 说明面板 | 右上方常驻面板:悬停/选中选项时显示其说明、默认值、范围或可选值; |\n| | 选中模组/分区时显示该模组名称、版本与简介。可滚动 |\n| 界面本地化 | 全部界面文字走语言文件,页面内下拉实时切换语言 |\n| 翻译工具 | 导出全部待翻文本/导出未翻条目、原文/译文全局切换; |\n| | 支持实时重载词典、为你的整合包添加多重语言! |\n| 手柄支持 | 左栏↔右栏两级导航,A 进入/确认、B 逐级返回、LB/RB 切模组; |\n| | 滑条按 A 激活后调值;按键绑定按 A 后长按 1 秒写入 |\n| 主题 | 手绘纸面风格;装 TimeTheme 后随昼夜配色;还有适配原本风格的视觉风格和动效 |\n\n## 演示\n\n![Night-TimeTheme](https://raw.githubusercontent.com/AiAe-156/Peak-ModConfigEnhance/master/%E5%9B%BE%E7%89%87/%E5%A4%9C%E6%99%9A1.png)\n*夜晚主题(TimeTheme)*\n\n![Day](https://raw.githubusercontent.com/AiAe-156/Peak-ModConfigEnhance/master/%E5%9B%BE%E7%89%87/%E7%99%BD%E5%A4%A91.png)\n*白天样式*\n\n![Demonstration](https://raw.githubusercontent.com/AiAe-156/Peak-ModConfigEnhance/master/%E5%9B%BE%E7%89%87/%E6%BC%94%E7%A4%BA%E8%A7%86%E9%A2%91main.gif)\n*演示图片(可能需要时间加载)*\n\n## 依赖\n\n- **必须**:BepInEx 5、PEAKLib.Core、PEAKLib.UI、ModConfig 1.8.2\n- **挂在依赖里,实际可选**:XUnity AutoTranslator——列进依赖只是让模组管理器一起装上;不装也不会出问题,只是翻译工具(补漏翻 / 显示原文 / 词典镜像)置灰,其余功能照常。注意下方提醒:本模组会改它的一项设置。\n- **可选**:TimeTheme(昼夜配色)\n\n## ⚠\ufe0f 本模组会改动 XUnity AutoTranslator 的一项设置\n\nXUnity AutoTranslator 保持出厂默认的 GoogleTranslateV2 端点时,会把**所有**界面文字(包括模组设置)丢去在线机翻,结果常常不知所云。因此装有 XUnity 时,本模组的选项 `Disable XUnity machine translation`(**默认开启**;`BepInEx\\config\\com.aiae.modconfigenhance.cfg` 的 `2. Localization` 分区)每次启动会:\n\n- 清空 `AutoTranslatorConfig.ini` 的 `Endpoint` / `FallbackEndpoint`,让 XUnity 只做词典翻译(本模组的语言文件、你自己的词典),不再机翻;\n- 清空各语言目录下的机翻缓存 `_AutoGeneratedTranslations*.txt`,每个文件旁留一份 `.bak`(只留第一次的)。\n\n**依赖在线机翻的话,请在首次启动前把这个选项改成 `false`**;事后想恢复也可以:关掉选项、把端点填回 `AutoTranslatorConfig.ini`、用 `.bak` 还原缓存。\n\n\n## 语言文件\n\n目录:`BepInEx\\config\\ModConfigEnhance\\language\\`\n\n文件格式同 XUnity 词典:`键=译文`,`//` 注释,`\\n` 换行、`\\=` 等号、`{0}` `{1}` 占位符原样保留——**等号左边一个字符都别动**(它是词典逐字匹配屏幕文字的键,改动就永远对不上)。第一段 `MCE_…=…` 是本模组界面词条(键为稳定 ID,只翻右边),之后的 `原文=译文` 由各模组交给 XUnity 使用。\n\n`_` 开头的文件不进下拉框;只读当前层的 `.txt`,子目录被忽略——备份请放进子目录。\n\n### 文件名规则:`语言码[-变体][_分包].txt`\n\n文件名自己决定它怎么进组、怎么显示,两种后缀各司其职:\n\n| 写法 | 含义 | 例子 |\n|---|---|---|\n| `语言码.txt` | 该语言的基础组 | `zh-cn.txt`、`en-us.txt` |\n| `语言码-变体.txt` | **同语言码的独立分组**:与基础组平起平坐,各自一套完整翻译,风格可以完全不同 | `zh-cn-old.txt`、`zh-cn-整活版.txt` |\n| `组名_分包.txt` | **组内分包**:并入前缀所指的组,按文件名排序追加加载、后者覆盖前者 | `zh-cn_补翻.txt`、`zh-cn-old_修正.txt` |\n\n- **语言码** = 文件名开头的 `xx` 或 `xx-yy`(`zh-cn-old` 的码是 `zh-cn`)。它只管两件事:XUnity 镜像目录(`Translation\\<码>`)和「跟随游戏语言」匹配。别名:`zh`=`zh-cn`、`en`=`en-us`。\n- **下拉框显示**:文件首行写了 `// display: 名字` 就显示「名字 (文件名)」,没写就显示文件名本身;组内多于一个文件时末尾带 `×数量`。例:`zh-cn-old.txt`(写了 `// display: 旧版翻译`)→ `旧版翻译 (zh-cn-old)`;`zh-cn.txt`(没写)→ `zh-cn`;`zh-cn-basic.txt`(`// display: 简体中文`)+ `zh-cn-basic_ModB.txt` 一组两个 → `简体中文 (zh-cn-basic) ×2`。\n- **说明框加载列表**:选中一组后按加载顺序列出每个文件和它自己的显示名,如 `zh-cn-basic.txt(简体中文)`、`zh-cn-basic_ModB.txt(Modb)`。\n- **注释强调**:`MCE_TIP_*` 悬停注释里,`` `…` `` 或 `“…”` 包住的文字用标题色强调(反引号本身不显示,弯引号保留)。\n- **变体组互不相关**:同码的各组是平等的独立翻译,补漏翻只统计当前组自己翻没翻过——就像 cn 与 tw 的区别,各算各的。\n- **跟随游戏语言**命中同码多组时,优先选组名恰等于语言码的组(`zh-cn`),没有再取第一个变体组。\n\n### 如何添加语言\n\n1. **导出** — 模组设置 → 左栏「导出翻译」,得到 `export\\` 下的待翻文件(先勾「仅导出已选」可去掉不需要的模组,本模组恒包含)。\n2. **翻译** — 按文件内说明规则,把译文填在对应键值 `=` 的右边;原文里的 `\\n` `\\=` 写法保持不变。\n3. **改名放入** — 以 UTF-8 编码保存 → 按上面的规则命名:新语言用 `小写语言码.txt`(`de-de.txt`、`ja-jp.txt`……),同一语言的另一套风格用 `语言码-变体.txt`,放进 `language\\`。想改下拉框里的显示名,首行写 `// display: 名字`。\n4. **启用** — 回游戏点「刷新」,在左侧语言下拉框选中它即自动加载;之后改文件点「重载翻译」生效。\n\n### 组内分包与补翻\n\n`组名_分包.txt` 并入前缀所指的组(基础文件先读,分包按文件名排序后读;文字排序而非数值,连续编号建议补零 `01`、`02`、`10`):\n\n```text\nzh-cn.txt             基础文件\nzh-cn_01_基本.txt      分包:追加\nzh-cn_20_补翻.txt      分包:覆盖同名键\nzh-cn-old_修正.txt     并进 zh-cn-old 组,不是 zh-cn 组\n```\n\n- 后读覆盖先读;同键同译文跳过;不同有效译文冲突记日志。\n- 空值、与原文相同的占位内容、未修改的 `MCE_` 英文不会覆盖已有译文。\n- 整组校验通过后才应用;格式错误(缺等号、空文件……)在说明面板用橙色带行号提示,修正后重载。\n\n补翻流程:保留旧文件 → 「补漏翻」→ 翻译 → 另存为本组的新 `_分包` 文件 → 「重载翻译」。补漏翻只统计当前组自己的覆盖情况;**不要用补翻文件替换原文件**;新增语言或新变体组点「刷新」后选择。\n\n### 选中语言后(无需重启)\n\n- 本模组界面立刻切换;说明面板按实际加载顺序列出全部文件名(带各自显示名)。\n- XUnity 同步切到该组的语言码:词典目录变为 `Translation\\<码>\\Text\\`,词条镜像为其中的 `ModConfigEnhance_<码>.txt`,`AutoTranslatorConfig.ini` 的 `Language=` 同步改写。本模组开关 `Switch XUnity language with the language file` 可关闭此联动。\n\n## 工具行\n\n| 按钮 | 作用 |\n|---|---|\n| 导出翻译 | 全部界面文本导出到 `export\\`(本模组 `MCE_` 块 + 各模组分块,含 manifest 简介) |\n| 补漏翻 | 只列 XUnity 词典未命中的条目(需 XUnityAutoTranslate) |\n| 仅导出已选 | 侧栏出现「导出」复选框列,只导出勾选模组(本模组恒包含) |\n| 显示原文/译文 | 全局原文/译文切换(=XUnityAutoTranslate Alt+T) |\n| 重载翻译 | 重读语言文件并刷新 XUnityAutoTranslate 词典 |\n| 打开目录 | 打开 `config\\ModConfigEnhance\\` |\n| 语言 ▾ / 刷新 | 按语言分组选择;新增语言点刷新,同语言新增分包点重载翻译 |\n\n## 手柄操作\n\n- **导航**:摇杆/十字键移动焦点;A 确认/进入;B 逐级返回(调值→编辑→捕获→右栏→左栏→退页)\n- **LB/RB**:切换模组\n- **滑条**:A 激活调值态,左右调值,再按 A 或 B 退出;步进为区间 0.5%,按住 1s 后 10 步/秒、3s 后 40 步/秒\n- **下拉框**:A 展开,上下选项,A 选定,B 关闭\n- **输入框**:A 进入编辑,B 退出。无屏幕键盘——打字靠实体键盘或平台 OSK(Deck 用 Steam+X)\n- **按键绑定**:A 进入捕获,按住目标键 1 秒写入;B 取消\n\n## 配置项\n\n`BepInEx\\config\\com.aiae.modconfigenhance.cfg`:\n\n| 分区 | 内容 |\n|---|---|\n| 1. Layout | 树形侧栏、说明面板开关(重启生效) |\n| 2. Localization | 界面本地化、隐藏本地化相关按钮(即时生效)、XUnityAutoTranslate 跟随切换、禁用 XUnityAutoTranslate 机翻(**默认开**,见上方提醒) |\n| 3. State | 语言文件、置顶、导出排除等运行状态(Hidden) |\n\n## 其他细节\n\n- **左栏渐入动效**:再次打开配置页时,选中模组行先出现,随后每拍向上、向下各显示一行;选在底部则向上显示,无有效选择则从顶部开始;关闭页面结束动画并恢复尚未出现的行。\n- **滚轮步幅**:左栏滚轮步幅约为原版三分之一,配约 0.1 秒短缓动;拖动滚动条或手柄定位会直接接管,其他滚动区域保持原行为。\n- **说明面板细节**:选中模组/分区时显示其名称、版本与 manifest 简介;悬停/选中具体选项时恢复该选项说明。\n\n## 问题反馈 · 投稿\n\n`[email protected]` / QQ 群 `1104320838` / GitHub https://github.com/AiAe-156/Peak-ModConfigEnhance;翻好的语言文件也欢迎寄给作者 AiAe,下个版本随包附带。\n";

		private const string ZhTw = "# ModConfig Enhance {VERSION}\n\nPEAK · ModConfig(PEAKLib.ModConfig)設定頁增強 · 作者 AiAe\n\n*本檔案由模組自動生成:每次啟動 / 切語言後按目前介面語言重寫,手動修改會被覆蓋。*\n\n> 你是否經常在一堆模組設定裡反覆來回捲動,就為了改某一個參數;是否因為想知道某個設定項是做什麼的而去 config 裡翻註解;想為整合包加入多語言支援……從現在開始,你可以利用該模組更加優雅地管理你的整合包!\n>\n> 模組列表樹形欄 - √\n> 一個能顯示模組名稱、版本號、設定項註解等資訊的說明框 - √\n> 一鍵匯出所有未本地化語言並自由發揮翻譯,支援多重語言 - √\n> 名稱排序與置頂功能 - √\n> 相容 TimeTheme 夜間幽紫主題 - √\n> 以及其他小改動……\n\n## 這個目錄放什麼\n\n| 路徑 | 用途 |\n|---|---|\n| `language\\xx-yy.txt` | 語言檔案:本模組介面詞條 + 所有模組的設定文字 |\n| `language\\en-us.txt` `zh-cn.txt` `zh-tw.txt` | 內建三種。只建不覆,可隨意改;刪掉即恢復預設 |\n| `export\\` | 「導出翻譯」「補漏翻」寫檔案的地方 |\n| `readme.md` | 本說明 |\n\n`_` 開頭的檔案不進下拉框;只讀 `language\\` 目前層級的 `.txt`,子目錄被忽略——備份請放進子目錄。\n\n## 功能\n\n| 功能 | 說明 |\n|---|---|\n| 樹形側欄 | 左欄顯示模組列表,選中模組會在其下方展開分類。可以置頂右側為選項。 |\n| | 支援搜尋、類型篩選、置頂選中列、僅匯出勾選列的翻譯文字。 |\n| | 篩選時無匹配項的行自動隱藏;單獨為按鍵設定加入了篩選按鈕。 |\n| 說明面板 | 右上方常駐面板:懸停/選中選項時顯示其說明、預設值、範圍或可選值; |\n| | 選中模組/分類時顯示該模組名稱、版本與簡介。可捲動 |\n| 介面本地化 | 全部介面文字走語言檔案,頁面內下拉即時切換語言 |\n| 翻譯工具 | 匯出全部待翻文字/匯出未翻條目、原文/譯文全域切換; |\n| | 支援即時重載詞典、為你的整合包加入多重語言! |\n| 手把支援 | 左欄↔右欄兩級導航,A 進入/確認、B 逐級返回、LB/RB 切模組; |\n| | 滑條按 A 啟用後調值;按鍵綁定按 A 後長按 1 秒寫入 |\n| 主題 | 手繪紙面面風格;裝 TimeTheme 後隨晝夜配色;還有適配原本風格的視覺風格與動效 |\n\n## 演示\n\n![Night-TimeTheme](https://raw.githubusercontent.com/AiAe-156/Peak-ModConfigEnhance/master/%E5%9B%BE%E7%89%87/%E5%A4%9C%E6%99%9A1.png)\n*夜晚主題(TimeTheme)*\n\n![Day](https://raw.githubusercontent.com/AiAe-156/Peak-ModConfigEnhance/master/%E5%9B%BE%E7%89%87/%E7%99%BD%E5%A4%A91.png)\n*白天樣式*\n\n![Demonstration](https://raw.githubusercontent.com/AiAe-156/Peak-ModConfigEnhance/master/%E5%9B%BE%E7%89%87/%E6%BC%94%E7%A4%BA%E8%A7%86%E9%A2%91main.gif)\n*演示圖片(可能需要時間載入)*\n\n## 依賴\n\n- **必須**:BepInEx 5、PEAKLib.Core、PEAKLib.UI、ModConfig 1.8.2\n- **掛在依賴裡,實際可選**:XUnity AutoTranslator——列進依賴只是讓模組管理器一起裝上;不裝也不會出問題,只是翻譯工具(補漏翻 / 顯示原文 / 詞典鏡像)置灰,其餘功能照常。注意下方提醒:本模組會改它的一項設定。\n- **可選**:TimeTheme(晝夜配色)\n\n## ⚠\ufe0f 本模組會改動 XUnity AutoTranslator 的一項設定\n\nXUnity AutoTranslator 保持出廠預設的 GoogleTranslateV2 端點時,會把**所有**介面文字(包括模組設定)丟去線上機翻,結果常常不知所云。因此裝有 XUnity 時,本模組的選項 `Disable XUnity machine translation`(**預設開啟**;`BepInEx\\config\\com.aiae.modconfigenhance.cfg` 的 `2. Localization` 分區)每次啟動會:\n\n- 清空 `AutoTranslatorConfig.ini` 的 `Endpoint` / `FallbackEndpoint`,讓 XUnity 只做詞典翻譯(本模組的語言檔案、你自己的詞典),不再機翻;\n- 清空各語言目錄下的機翻快取 `_AutoGeneratedTranslations*.txt`,每個檔案旁留一份 `.bak`(只留第一次的)。\n\n**依賴線上機翻的話,請在首次啟動前把這個選項改成 `false`**;事後想恢復也可以:關掉選項、把端點填回 `AutoTranslatorConfig.ini`、用 `.bak` 還原快取。\n\n\n## 語言檔案\n\n目錄:`BepInEx\\config\\ModConfigEnhance\\language\\`\n\n檔案格式同 XUnity 詞典:`鍵=譯文`,`//` 註解,`\\n` 換行、`\\=` 等號、`{0}` `{1}` 佔位符原樣保留——**等號左邊一個字元都別動**(它是詞典逐字比對螢幕文字的鍵,改動就永遠對不上)。第一段 `MCE_…=…` 是本模組介面詞條(鍵為穩定 ID,只翻右邊),之後的 `原文=譯文` 由各模組交給 XUnity 使用。\n\n`_` 開頭的檔案不進下拉框;只讀當前層的 `.txt`,子目錄被忽略——備份請放進子目錄。\n\n### 檔名規則:`語言碼[-變體][_分包].txt`\n\n檔名自己決定它怎麼進組、怎麼顯示,兩種後綴各司其職:\n\n| 寫法 | 含義 | 例子 |\n|---|---|---|\n| `語言碼.txt` | 該語言的基礎組 | `zh-cn.txt`、`zh-tw.txt` |\n| `語言碼-變體.txt` | **同語言碼的獨立分組**:與基礎組平起平坐,各自一套完整翻譯,風格可以完全不同 | `zh-tw-old.txt`、`zh-cn-整活版.txt` |\n| `組名_分包.txt` | **組內分包**:併入前綴所指的組,按檔名排序追加載入、後者覆蓋前者 | `zh-tw_補翻.txt`、`zh-cn-old_修正.txt` |\n\n- **語言碼** = 檔名開頭的 `xx` 或 `xx-yy`(`zh-cn-old` 的碼是 `zh-cn`)。它只管兩件事:XUnity 鏡像目錄(`Translation\\<碼>`)和「跟隨遊戲語言」匹