Decompiled source of JevControllerKeyboard v1.0.1

JevControllerKeyboard.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using GUIFramework;
using HarmonyLib;
using JevControllerKeyboard.Config;
using JevControllerKeyboard.Features;
using JevControllerKeyboard.Infrastructure;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("JevControllerKeyboard")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+7f49fd50d18fe0b9a03cf16fa07279bd1aa27a74")]
[assembly: AssemblyProduct("JevControllerKeyboard")]
[assembly: AssemblyTitle("JevControllerKeyboard")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace JevControllerKeyboard
{
	[BepInPlugin("JevMods.JevControllerKeyboard", "JevControllerKeyboard", "1.0.1")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "JevMods.JevControllerKeyboard";

		public const string PluginName = "JevControllerKeyboard";

		private IFeature[] _features;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			PadInput padInput = (PadInput.Instance = new PadInput());
			GameAssets assets = new GameAssets();
			GameLanguage language = new GameLanguage();
			FocusedField focus = new FocusedField();
			FocusHint hint = new FocusHint(assets, language);
			NoFocusHint hint2 = new NoFocusHint();
			_features = new IFeature[7]
			{
				new OnscreenKeyboardFeature(padInput, focus, new KeyboardView(((Component)this).transform, assets, language), new ModSettings(((BaseUnityPlugin)this).Config), language, new LanguageLayouts(EmbeddedText.Read), new DialogPlacement(), new GameUiScale()),
				new FieldFocusFeature(new MainMenu(), "JoyRStick", focus, padInput, hint),
				new FieldFocusFeature(new ServerPassword(), "JoyRStick", focus, padInput, hint2),
				new FieldFocusFeature(new ServerFilter(), "JoyLStick", focus, padInput, hint2),
				new FieldFocusFeature(new TextDialog(), "JoyLStick", focus, padInput, hint),
				new FieldFocusFeature(new MapPin(), "JoyLStick", focus, padInput, hint),
				new FieldFocusFeature(new PopupEntry(), "JoyLStick", focus, padInput, hint)
			};
			IFeature[] features = _features;
			for (int i = 0; i < features.Length; i++)
			{
				features[i].Enable();
			}
			_harmony = new Harmony("JevMods.JevControllerKeyboard");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded");
		}

		private void Update()
		{
			IFeature[] features = _features;
			for (int i = 0; i < features.Length; i++)
			{
				features[i].Update();
			}
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			IFeature[] array = _features ?? Array.Empty<IFeature>();
			for (int i = 0; i < array.Length; i++)
			{
				array[i].Disable();
			}
			PadInput.Instance = null;
		}
	}
	internal static class BuildInfo
	{
		public const string Version = "1.0.1";
	}
}
namespace JevControllerKeyboard.Patches
{
	[HarmonyPatch(typeof(ZInput), "TryGetButtonState")]
	internal static class ZInputTryGetButtonStatePatch
	{
		private static bool Prefix(string name, ref bool __result)
		{
			if (PadInput.Instance == null || !PadInput.Instance.Blocks(name))
			{
				return true;
			}
			__result = false;
			return false;
		}
	}
}
namespace JevControllerKeyboard.Infrastructure
{
	public static class EmbeddedText
	{
		public static string Read(string name)
		{
			using Stream stream = typeof(EmbeddedText).Assembly.GetManifestResourceStream(name);
			using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
			return streamReader.ReadToEnd();
		}
	}
	public sealed class FocusedField : IFocusedField
	{
		public TMP_InputField Current
		{
			get
			{
				EventSystem current = EventSystem.current;
				if ((Object)(object)current == (Object)null || (Object)(object)current.currentSelectedGameObject == (Object)null)
				{
					return null;
				}
				GuiInputField component = current.currentSelectedGameObject.GetComponent<GuiInputField>();
				if (!((Object)(object)component != (Object)null) || !((TMP_InputField)component).isFocused || !((Behaviour)component).isActiveAndEnabled)
				{
					return null;
				}
				return (TMP_InputField)(object)component;
			}
		}

		public bool Navigation
		{
			get
			{
				if (!((Object)(object)EventSystem.current == (Object)null))
				{
					return EventSystem.current.sendNavigationEvents;
				}
				return true;
			}
			set
			{
				if ((Object)(object)EventSystem.current != (Object)null)
				{
					EventSystem.current.sendNavigationEvents = value;
				}
			}
		}
	}
	public sealed class GameAssets : IGameAssets
	{
		private readonly Dictionary<string, Object> _cache = new Dictionary<string, Object>();

		public Sprite Sprite(string name)
		{
			return Find<Sprite>(name);
		}

		public TMP_FontAsset Font(string name)
		{
			return Find<TMP_FontAsset>(name);
		}

		public Material Material(string name)
		{
			return Find<Material>(name);
		}

		private T Find<T>(string name) where T : Object
		{
			if (_cache.TryGetValue(name, out var value) && value != (Object)null)
			{
				return (T)(object)value;
			}
			T[] array = Resources.FindObjectsOfTypeAll<T>();
			foreach (T val in array)
			{
				if (((Object)val).name == name)
				{
					_cache[name] = (Object)(object)val;
					return val;
				}
			}
			return default(T);
		}
	}
	public sealed class GameLanguage : IGameLanguage
	{
		public string Current
		{
			get
			{
				Localization instance = Localization.instance;
				if (instance == null)
				{
					return null;
				}
				return instance.GetSelectedLanguage();
			}
		}

		public event Action Changed
		{
			add
			{
				Localization.OnLanguageChange = (Action)Delegate.Combine(Localization.OnLanguageChange, value);
			}
			remove
			{
				Localization.OnLanguageChange = (Action)Delegate.Remove(Localization.OnLanguageChange, value);
			}
		}

		public string Localize(string text)
		{
			if (Localization.instance == null)
			{
				return text;
			}
			return Localization.instance.Localize(text);
		}
	}
	public sealed class GameUiScale : IUiScale
	{
		public float Of(Transform element)
		{
			Canvas componentInParent = ((Component)element).GetComponentInParent<Canvas>();
			if (!((Object)(object)componentInParent != (Object)null))
			{
				return 1f;
			}
			return componentInParent.rootCanvas.scaleFactor;
		}
	}
	public interface IFieldSource
	{
		IReadOnlyList<GuiInputField> Fields { get; }
	}
	public interface IFocusedField
	{
		TMP_InputField Current { get; }

		bool Navigation { get; set; }
	}
	public interface IGameAssets
	{
		Sprite Sprite(string name);

		TMP_FontAsset Font(string name);

		Material Material(string name);
	}
	public interface IGameLanguage
	{
		string Current { get; }

		event Action Changed;

		string Localize(string text);
	}
	public interface IPadInput
	{
		bool IsActive { get; }

		bool Blocking { get; set; }

		bool Pressed(string button);

		bool Repeated(string button);
	}
	public interface IUiScale
	{
		float Of(Transform element);
	}
	public sealed class MainMenu : IFieldSource
	{
		public IReadOnlyList<GuiInputField> Fields
		{
			get
			{
				FejdStartup instance = FejdStartup.instance;
				if (!((Object)(object)instance != (Object)null) || !((Behaviour)instance.m_newWorldName).isActiveAndEnabled)
				{
					return Array.Empty<GuiInputField>();
				}
				return (IReadOnlyList<GuiInputField>)(object)new GuiInputField[2] { instance.m_newWorldName, instance.m_newWorldSeed };
			}
		}
	}
	public sealed class MapPin : IFieldSource
	{
		public IReadOnlyList<GuiInputField> Fields
		{
			get
			{
				Minimap instance = Minimap.instance;
				if (!((Object)(object)instance != (Object)null) || !((Component)instance.m_nameInput).gameObject.activeInHierarchy)
				{
					return Array.Empty<GuiInputField>();
				}
				return (IReadOnlyList<GuiInputField>)(object)new GuiInputField[1] { instance.m_nameInput };
			}
		}
	}
	public static class PadButton
	{
		public const string Prefix = "Joy";

		public const string A = "JoyButtonA";

		public const string B = "JoyButtonB";

		public const string X = "JoyButtonX";

		public const string Y = "JoyButtonY";

		public const string Start = "JoyStart";

		public const string LeftBumper = "JoyLBumper";

		public const string RightBumper = "JoyRBumper";

		public const string LeftTrigger = "JoyLTrigger";

		public const string LeftStick = "JoyLStick";

		public const string RightStick = "JoyRStick";

		public const string RightTrigger = "JoyRTrigger";

		public const string LeftStickLeft = "JoyLStickLeft";

		public const string LeftStickRight = "JoyLStickRight";

		public const string LeftStickUp = "JoyLStickUp";

		public const string LeftStickDown = "JoyLStickDown";

		public const string DPadLeft = "JoyDPadLeft";

		public const string DPadRight = "JoyDPadRight";

		public const string DPadUp = "JoyDPadUp";

		public const string DPadDown = "JoyDPadDown";
	}
	public sealed class PadInput : IPadInput
	{
		private const float RepeatDelay = 0.4f;

		private const float RepeatRate = 0.05f;

		private readonly Dictionary<string, float> _nextRepeat = new Dictionary<string, float>();

		private bool _reading;

		private bool _blocking;

		private int _releasedFrame = -1;

		internal static PadInput Instance { get; set; }

		public bool IsActive => ZInput.IsGamepadActive();

		public bool Blocking
		{
			get
			{
				return _blocking;
			}
			set
			{
				if (_blocking && !value)
				{
					_releasedFrame = Time.frameCount;
				}
				_blocking = value;
			}
		}

		public bool Pressed(string button)
		{
			return Read(() => ZInput.GetButtonDown(button));
		}

		public bool Repeated(string button)
		{
			float unscaledTime = Time.unscaledTime;
			if (Pressed(button))
			{
				_nextRepeat[button] = unscaledTime + 0.4f;
				return true;
			}
			if (!Read(() => ZInput.GetButton(button)) || !_nextRepeat.TryGetValue(button, out var value))
			{
				_nextRepeat.Remove(button);
				return false;
			}
			if (unscaledTime < value)
			{
				return false;
			}
			_nextRepeat[button] = unscaledTime + 0.05f;
			return true;
		}

		internal bool Blocks(string button)
		{
			if ((_blocking || _releasedFrame == Time.frameCount) && !_reading)
			{
				return button.StartsWith("Joy");
			}
			return false;
		}

		private bool Read(Func<bool> read)
		{
			_reading = true;
			try
			{
				return read();
			}
			finally
			{
				_reading = false;
			}
		}
	}
	public sealed class PopupEntry : IFieldSource
	{
		public IReadOnlyList<GuiInputField> Fields
		{
			get
			{
				GuiInputField val = (UnifiedPopup.IsVisible() ? UnifiedPopup.instance.textEntryField : null);
				if (!((Object)(object)val != (Object)null) || !((Component)val).gameObject.activeInHierarchy)
				{
					return Array.Empty<GuiInputField>();
				}
				return (IReadOnlyList<GuiInputField>)(object)new GuiInputField[1] { val };
			}
		}
	}
	public sealed class ServerFilter : IFieldSource
	{
		public IReadOnlyList<GuiInputField> Fields
		{
			get
			{
				ServerListGui s_instance = ServerListGui.s_instance;
				if (!((Object)(object)s_instance != (Object)null) || !((Behaviour)s_instance.m_filterInputField).isActiveAndEnabled)
				{
					return Array.Empty<GuiInputField>();
				}
				return (IReadOnlyList<GuiInputField>)(object)new GuiInputField[1] { s_instance.m_filterInputField };
			}
		}
	}
	public sealed class ServerPassword : IFieldSource
	{
		public IReadOnlyList<GuiInputField> Fields
		{
			get
			{
				FejdStartup instance = FejdStartup.instance;
				if (!((Object)(object)instance != (Object)null) || ((Behaviour)instance.m_newWorldName).isActiveAndEnabled)
				{
					return Array.Empty<GuiInputField>();
				}
				return (IReadOnlyList<GuiInputField>)(object)new GuiInputField[1] { instance.m_serverPassword };
			}
		}
	}
	public sealed class TextDialog : IFieldSource
	{
		public IReadOnlyList<GuiInputField> Fields
		{
			get
			{
				TextInput instance = TextInput.instance;
				if (!((Object)(object)instance != (Object)null) || !TextInput.IsVisible())
				{
					return Array.Empty<GuiInputField>();
				}
				return (IReadOnlyList<GuiInputField>)(object)new GuiInputField[1] { instance.m_inputField };
			}
		}
	}
}
namespace JevControllerKeyboard.Features
{
	public abstract class CandidateInput : InputMethod
	{
		private readonly Func<CandidateTable> _table;

		private readonly int _maxLength;

		public override bool Choosing => Composition.Active;

		public override IReadOnlyList<char> Candidates
		{
			get
			{
				if (!Composition.Active)
				{
					return Array.Empty<char>();
				}
				return _table().Lookup(ReadingOf(Composition.Shown));
			}
		}

		protected Composition Composition { get; } = new Composition();

		protected CandidateInput(Func<CandidateTable> table, int maxLength)
		{
			_table = table;
			_maxLength = maxLength;
		}

		public override void Type(char character, ITextSurface text)
		{
			if (!Accepts(character))
			{
				Cancel();
				text.Insert(character.ToString());
				return;
			}
			Composition.Synchronize(text);
			if (Composition.Shown.Length >= _maxLength)
			{
				Composition.Cancel();
			}
			Composition.Show(text, Composition.Shown + character);
		}

		public override bool Backspace(ITextSurface text)
		{
			Composition.Synchronize(text);
			if (!Composition.Active)
			{
				return false;
			}
			string shown = Composition.Shown;
			Composition.Show(text, shown.Substring(0, shown.Length - 1));
			return true;
		}

		public override bool Space(ITextSurface text)
		{
			Composition.Synchronize(text);
			if (!Composition.Active)
			{
				return false;
			}
			IReadOnlyList<char> candidates = Candidates;
			if (candidates.Count > 0)
			{
				Composition.Complete(text, candidates[0].ToString());
			}
			else
			{
				Composition.Cancel();
			}
			return true;
		}

		public override void Choose(char candidate, ITextSurface text)
		{
			Composition.Complete(text, candidate.ToString());
		}

		public override void Cancel()
		{
			Composition.Cancel();
		}

		protected abstract bool Accepts(char character);

		protected virtual string ReadingOf(string shown)
		{
			return shown;
		}
	}
	public sealed class CandidateTable
	{
		private readonly Dictionary<string, char[]> _entries = new Dictionary<string, char[]>();

		public CandidateTable(string content)
		{
			string[] array = content.Split(new char[1] { '\n' });
			foreach (string text in array)
			{
				int num = text.IndexOf(' ');
				if (num > 0)
				{
					_entries[text.Substring(0, num)] = text.Substring(num + 1).Trim().ToCharArray();
				}
			}
		}

		public char[] Lookup(string reading)
		{
			if (!_entries.TryGetValue(reading, out var value))
			{
				return Array.Empty<char>();
			}
			return value;
		}
	}
	public sealed class Composition
	{
		private int _start;

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

		public bool Active => Shown.Length > 0;

		public void Synchronize(ITextSurface text)
		{
			if (Active)
			{
				int num = _start + Shown.Length;
				if (text.HasSelection || text.Caret != num || num > text.Text.Length || string.CompareOrdinal(text.Text, _start, Shown, 0, Shown.Length) != 0)
				{
					Cancel();
				}
			}
		}

		public bool Show(ITextSurface text, string shown)
		{
			Synchronize(text);
			if (shown.Length == 0)
			{
				Remove(text);
				return true;
			}
			if (!Active)
			{
				if (!text.Insert(shown))
				{
					return false;
				}
				_start = text.Caret - shown.Length;
			}
			else if (!text.Replace(_start, Shown.Length, shown))
			{
				return false;
			}
			Shown = shown;
			return true;
		}

		public bool Split(ITextSurface text, string kept, string next)
		{
			Synchronize(text);
			if (!Active || !text.Replace(_start, Shown.Length, kept + next))
			{
				return false;
			}
			_start += kept.Length;
			Shown = next;
			return true;
		}

		public void Complete(ITextSurface text, string result)
		{
			Synchronize(text);
			if (Active)
			{
				text.Replace(_start, Shown.Length, result);
			}
			else
			{
				text.Insert(result);
			}
			Cancel();
		}

		public void Cancel()
		{
			Shown = string.Empty;
		}

		private void Remove(ITextSurface text)
		{
			if (Active)
			{
				text.Replace(_start, Shown.Length, string.Empty);
			}
			Cancel();
		}
	}
	public sealed class DialogGeometry
	{
		private const float FullScreenShare = 0.9f;

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

		public RectTransform FindDialog(RectTransform field)
		{
			RectTransform result = field;
			Transform parent = ((Transform)field).parent;
			RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
			while ((Object)(object)val != (Object)null && !IsRoot(val))
			{
				result = val;
				Transform parent2 = ((Transform)val).parent;
				val = (RectTransform)(object)((parent2 is RectTransform) ? parent2 : null);
			}
			return result;
		}

		public Rect VisualBounds(RectTransform dialog)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			Rect result = ScreenBounds(dialog);
			foreach (RectTransform item in (Transform)dialog)
			{
				RectTransform val = item;
				if (IsBackground(val))
				{
					Rect val2 = ScreenBounds(val);
					result = Rect.MinMaxRect(Mathf.Min(((Rect)(ref result)).xMin, ((Rect)(ref val2)).xMin), Mathf.Min(((Rect)(ref result)).yMin, ((Rect)(ref val2)).yMin), Mathf.Max(((Rect)(ref result)).xMax, ((Rect)(ref val2)).xMax), Mathf.Max(((Rect)(ref result)).yMax, ((Rect)(ref val2)).yMax));
				}
			}
			return result;
		}

		public Rect ScreenBounds(RectTransform rect)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			rect.GetWorldCorners(_corners);
			Camera obj = CanvasCamera((Transform)(object)rect);
			Vector2 val = RectTransformUtility.WorldToScreenPoint(obj, _corners[0]);
			Vector2 val2 = RectTransformUtility.WorldToScreenPoint(obj, _corners[2]);
			return Rect.MinMaxRect(val.x, val.y, val2.x, val2.y);
		}

		public Vector3 WorldOffset(RectTransform rect, Vector2 screenOffset)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			Camera val = CanvasCamera((Transform)(object)rect);
			Rect val2 = ScreenBounds(rect);
			Vector2 center = ((Rect)(ref val2)).center;
			Transform parent = ((Transform)rect).parent;
			object obj = ((object)((parent is RectTransform) ? parent : null)) ?? ((object)rect);
			Vector3 val3 = default(Vector3);
			RectTransformUtility.ScreenPointToWorldPointInRectangle((RectTransform)obj, center, val, ref val3);
			Vector3 val4 = default(Vector3);
			RectTransformUtility.ScreenPointToWorldPointInRectangle((RectTransform)obj, center + screenOffset, val, ref val4);
			return val4 - val3;
		}

		private static Camera CanvasCamera(Transform transform)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Invalid comparison between Unknown and I4
			Canvas componentInParent = ((Component)transform).GetComponentInParent<Canvas>();
			if (!((Object)(object)componentInParent == (Object)null) && (int)componentInParent.rootCanvas.renderMode != 0)
			{
				return componentInParent.rootCanvas.worldCamera;
			}
			return null;
		}

		private static bool IsBackground(RectTransform child)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (child.anchorMin == Vector2.zero && child.anchorMax == Vector2.one && ((Component)child).gameObject.activeSelf)
			{
				return (Object)(object)((Component)child).GetComponent<Image>() != (Object)null;
			}
			return false;
		}

		private bool IsRoot(RectTransform rect)
		{
			if (!((Object)(object)((Component)rect).GetComponent<Canvas>() != (Object)null))
			{
				return IsFullScreen(rect);
			}
			return true;
		}

		private bool IsFullScreen(RectTransform rect)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			Rect val = ScreenBounds(rect);
			if (((Rect)(ref val)).width >= (float)Screen.width * 0.9f)
			{
				return ((Rect)(ref val)).height >= (float)Screen.height * 0.9f;
			}
			return false;
		}
	}
	public sealed class DialogPlacement : IDialogPlacement
	{
		private enum Slot
		{
			BelowDialog,
			AboveDialog,
			BelowField,
			AboveField,
			BelowFieldCorner,
			AboveFieldCorner,
			RightOfDialog,
			LeftOfDialog
		}

		private const float Margin = 8f;

		private const float ScreenMargin = 16f;

		private const float LargeShare = 0.5f;

		private const float SidePanelHeightShare = 0.5f;

		private const float SidePanelCenterShare = 0.4f;

		private static readonly Slot[] DialogSlots = new Slot[6]
		{
			Slot.BelowDialog,
			Slot.AboveDialog,
			Slot.BelowField,
			Slot.AboveField,
			Slot.RightOfDialog,
			Slot.LeftOfDialog
		};

		private static readonly Slot[] SideSlots = new Slot[5]
		{
			Slot.RightOfDialog,
			Slot.BelowDialog,
			Slot.AboveDialog,
			Slot.BelowField,
			Slot.AboveField
		};

		private static readonly Slot[] FieldSlots = new Slot[2]
		{
			Slot.BelowField,
			Slot.AboveField
		};

		private static readonly Slot[] CornerSlots = new Slot[2]
		{
			Slot.BelowFieldCorner,
			Slot.AboveFieldCorner
		};

		private readonly DialogGeometry _geometry = new DialogGeometry();

		private RectTransform _dialog;

		private Vector3 _originalPosition;

		public void Place(RectTransform field, IKeyboardView keyboard)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: 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_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			Restore();
			keyboard.ResetPosition();
			RectTransform dialog = _geometry.FindDialog(field);
			Rect val = _geometry.VisualBounds(dialog);
			Rect val2 = _geometry.ScreenBounds(field);
			Rect screenRect = keyboard.ScreenRect;
			Vector2 size = default(Vector2);
			((Vector2)(ref size))..ctor(((Rect)(ref screenRect)).width, Mathf.Max(((Rect)(ref screenRect)).height, keyboard.MaxHeight));
			bool flag = IsUsable(val);
			Vector2 val3 = (flag ? ShiftFor(val, val2, size) : ShiftForField(val, val2, size));
			if (val3 != Vector2.zero)
			{
				Shift(dialog, val3);
				val = Translate(val, val3);
				val2 = Translate(val2, val3);
			}
			Vector2 val4 = PositionOf(Choose(SlotsFor(val, flag), val, val2, size), val, val2, ((Rect)(ref screenRect)).size);
			float num = (float)Screen.height - 16f - ((Rect)(ref screenRect)).height;
			val4.y = Mathf.Clamp(val4.y, 16f, num);
			keyboard.MoveBy(val4 - ((Rect)(ref screenRect)).min);
		}

		public void Restore()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_dialog != (Object)null)
			{
				((Transform)_dialog).position = _originalPosition;
			}
			_dialog = null;
		}

		private static Vector2 ShiftFor(Rect dialog, Rect field, Vector2 size)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			if (IsSidePanel(dialog))
			{
				float num = ((Rect)(ref dialog)).xMax + 8f + size.x - ((float)Screen.width - 16f);
				float num2 = ((Rect)(ref dialog)).xMin - 16f;
				if (!(num > 0f) || !(num2 >= num))
				{
					return Vector2.zero;
				}
				return new Vector2(0f - num, 0f);
			}
			if (Fits(Slot.BelowDialog, dialog, field, size) || Fits(Slot.AboveDialog, dialog, field, size))
			{
				return Vector2.zero;
			}
			if (((Rect)(ref dialog)).height + 8f + size.y + 32f > (float)Screen.height)
			{
				return Vector2.zero;
			}
			float num3 = 16f - (((Rect)(ref dialog)).yMin - 8f - size.y);
			float num4 = ((Rect)(ref dialog)).yMax + 8f + size.y - ((float)Screen.height - 16f);
			if (!(num3 <= num4))
			{
				return new Vector2(0f, 0f - num4);
			}
			return new Vector2(0f, num3);
		}

		private static Vector2 ShiftForField(Rect dialog, Rect field, Vector2 size)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if (IsLarge(dialog) || Fits(Slot.BelowFieldCorner, dialog, field, size))
			{
				return Vector2.zero;
			}
			float num = 16f - (((Rect)(ref field)).yMin - 8f - size.y);
			if (!(((Rect)(ref dialog)).yMax + num <= (float)Screen.height))
			{
				return Vector2.zero;
			}
			return new Vector2(0f, num);
		}

		private static Slot[] SlotsFor(Rect dialog, bool usable)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			if (!usable)
			{
				if (!IsLarge(dialog))
				{
					return CornerSlots;
				}
				return FieldSlots;
			}
			if (!IsSidePanel(dialog))
			{
				return DialogSlots;
			}
			return SideSlots;
		}

		private static Slot Choose(Slot[] slots, Rect dialog, Rect field, Vector2 size)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			foreach (Slot slot in slots)
			{
				if (Fits(slot, dialog, field, size))
				{
					return slot;
				}
			}
			return Slot.BelowField;
		}

		private static bool Fits(Slot slot, Rect dialog, Rect field, Vector2 size)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = PositionOf(slot, dialog, field, size);
			if (val.x >= 16f && val.y >= 16f && val.x + size.x <= (float)Screen.width - 16f)
			{
				return val.y + size.y <= (float)Screen.height - 16f;
			}
			return false;
		}

		private static Vector2 PositionOf(Slot slot, Rect dialog, Rect field, Vector2 size)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			return (Vector2)(slot switch
			{
				Slot.BelowDialog => Below(dialog, size), 
				Slot.AboveDialog => Above(dialog, size), 
				Slot.BelowField => Below(field, size), 
				Slot.AboveField => Above(field, size), 
				Slot.BelowFieldCorner => new Vector2(CornerX(field, size), ((Rect)(ref field)).yMin - 8f - size.y), 
				Slot.AboveFieldCorner => new Vector2(CornerX(field, size), ((Rect)(ref field)).yMax + 8f), 
				Slot.RightOfDialog => new Vector2(((Rect)(ref dialog)).xMax + 8f, ((Rect)(ref dialog)).yMin), 
				_ => new Vector2(((Rect)(ref dialog)).xMin - 8f - size.x, ((Rect)(ref dialog)).yMin), 
			});
		}

		private static Vector2 Below(Rect anchor, Vector2 size)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			return new Vector2(CenterX(anchor, size), ((Rect)(ref anchor)).yMin - 8f - size.y);
		}

		private static Vector2 Above(Rect anchor, Vector2 size)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			return new Vector2(CenterX(anchor, size), ((Rect)(ref anchor)).yMax + 8f);
		}

		private static float CornerX(Rect anchor, Vector2 size)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			return Mathf.Clamp(((Rect)(ref anchor)).xMin, 16f, (float)Screen.width - 16f - size.x);
		}

		private static float CenterX(Rect anchor, Vector2 size)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			return Mathf.Clamp(((Rect)(ref anchor)).center.x - size.x / 2f, 16f, (float)Screen.width - 16f - size.x);
		}

		private static Rect Translate(Rect rect, Vector2 offset)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			return new Rect(((Rect)(ref rect)).position + offset, ((Rect)(ref rect)).size);
		}

		private static bool IsUsable(Rect bounds)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			bool flag = ((Rect)(ref bounds)).xMin >= 0f && ((Rect)(ref bounds)).yMin >= 0f && ((Rect)(ref bounds)).xMax <= (float)Screen.width && ((Rect)(ref bounds)).yMax <= (float)Screen.height;
			return !IsLarge(bounds) && flag;
		}

		private static bool IsLarge(Rect bounds)
		{
			return ((Rect)(ref bounds)).width * ((Rect)(ref bounds)).height > (float)(Screen.width * Screen.height) * 0.5f;
		}

		private static bool IsSidePanel(Rect bounds)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (((Rect)(ref bounds)).height > (float)Screen.height * 0.5f)
			{
				return ((Rect)(ref bounds)).center.x < (float)Screen.width * 0.4f;
			}
			return false;
		}

		private void Shift(RectTransform dialog, Vector2 offset)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			_dialog = dialog;
			_originalPosition = ((Transform)dialog).position;
			((Transform)dialog).position = ((Transform)dialog).position + _geometry.WorldOffset(dialog, offset);
		}
	}
	public sealed class FieldFocusFeature : IFeature
	{
		private readonly IFieldSource _source;

		private readonly string _button;

		private readonly IFocusedField _focus;

		private readonly IPadInput _pad;

		private readonly IFocusHint _hint;

		public FieldFocusFeature(IFieldSource source, string button, IFocusedField focus, IPadInput pad, IFocusHint hint)
		{
			_source = source;
			_button = button;
			_focus = focus;
			_pad = pad;
			_hint = hint;
		}

		public void Enable()
		{
		}

		public void Update()
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			IReadOnlyList<GuiInputField> fields = _source.Fields;
			if (fields.Count == 0)
			{
				return;
			}
			GuiInputField val = Target(fields);
			bool flag = (Object)(object)_focus.Current != (Object)null;
			foreach (GuiInputField item in fields)
			{
				bool visible = (Object)(object)item == (Object)(object)val && !flag && ((Selectable)item).interactable && _pad.IsActive;
				_hint.Show((RectTransform)((Component)item).transform, _button, visible);
			}
			bool flag2 = ((Behaviour)val).isActiveAndEnabled && ((Selectable)val).interactable;
			if (!flag && flag2 && _pad.Pressed(_button))
			{
				((Selectable)val).Select();
				val.ActivateInputField();
			}
		}

		public void Disable()
		{
		}

		private static GuiInputField Target(IReadOnlyList<GuiInputField> fields)
		{
			EventSystem current = EventSystem.current;
			GameObject val = (((Object)(object)current != (Object)null) ? current.currentSelectedGameObject : null);
			foreach (GuiInputField field in fields)
			{
				if ((Object)(object)((Component)field).gameObject == (Object)(object)val)
				{
					return field;
				}
			}
			return fields[0];
		}
	}
	public sealed class FocusHint : IFocusHint
	{
		private const string HintName = "JevFocusHint";

		private const float HintSize = 30f;

		private const float HintOffset = 4f;

		private const float GlyphFontSize = 20f;

		private readonly IGameAssets _assets;

		private readonly IGameLanguage _language;

		public FocusHint(IGameAssets assets, IGameLanguage language)
		{
			_assets = assets;
			_language = language;
		}

		public void Show(RectTransform field, string button, bool visible)
		{
			Transform val = ((Transform)field).Find("JevFocusHint");
			if ((Object)(object)val == (Object)null)
			{
				val = Create(field);
			}
			if (((Component)val).gameObject.activeSelf != visible)
			{
				((Component)val).gameObject.SetActive(visible);
			}
			TextMeshProUGUI componentInChildren = ((Component)val).GetComponentInChildren<TextMeshProUGUI>(true);
			string text = _language.Localize("$KEY_" + button);
			if (((TMP_Text)componentInChildren).text != text)
			{
				((TMP_Text)componentInChildren).text = text;
			}
		}

		private Transform Create(RectTransform field)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("JevFocusHint", new Type[2]
			{
				typeof(RectTransform),
				typeof(LayoutElement)
			});
			val.SetActive(false);
			val.GetComponent<LayoutElement>().ignoreLayout = true;
			RectTransform component = val.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)field, false);
			component.anchorMin = new Vector2(1f, 0.5f);
			component.anchorMax = new Vector2(1f, 0.5f);
			component.pivot = new Vector2(0f, 0.5f);
			component.anchoredPosition = new Vector2(4f, 0f);
			component.sizeDelta = new Vector2(30f, 30f);
			RectTransform component2 = new GameObject("Gamepad", new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>();
			((Transform)component2).SetParent((Transform)(object)component, false);
			component2.anchorMin = Vector2.zero;
			component2.anchorMax = Vector2.one;
			component2.sizeDelta = Vector2.zero;
			GameText.Create((Transform)(object)component2, _assets, "Valheim-AveriaSansLibre", "Valheim-AveriaSansLibre - Outline", 20f, 20f, Color.white, (TextAlignmentOptions)4098);
			return (Transform)(object)component;
		}
	}
	public static class GameStyle
	{
		public const string PanelSprite = "woodpanel_512x512";

		public const string PanelMaterial = "litpanel";

		public const string ButtonSprite = "button";

		public const string ButtonHighlightSprite = "button_highlight";

		public const string ButtonPressedSprite = "button_pressed";

		public const string SerifFont = "Valheim-AveriaSerifLibre";

		public const string SerifOutlineMaterial = "Valheim-AveriaSerifLibre - Outline";

		public const string SansFont = "Valheim-AveriaSansLibre";

		public const string SansOutlineMaterial = "Valheim-AveriaSansLibre - Outline";

		public static readonly Color ButtonText = new Color(1f, 0.63f, 0.24f, 1f);
	}
	public static class GameText
	{
		public static TextMeshProUGUI Create(Transform parent, IGameAssets assets, string font, string material, float size, float minSize, Color color, TextAlignmentOptions alignment)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Label", new Type[1] { typeof(RectTransform) });
			val.SetActive(false);
			val.AddComponent<TextMeshProUGUI>();
			val.transform.SetParent(parent, false);
			TextMeshProUGUI component = val.GetComponent<TextMeshProUGUI>();
			((TMP_Text)component).font = assets.Font(font) ?? ((TMP_Text)component).font;
			val.SetActive(true);
			Material val2 = assets.Material(material);
			if ((Object)(object)val2 != (Object)null)
			{
				((TMP_Text)component).fontSharedMaterial = val2;
			}
			((TMP_Text)component).fontSize = size;
			((TMP_Text)component).enableAutoSizing = minSize < size;
			((TMP_Text)component).fontSizeMin = minSize;
			((TMP_Text)component).fontSizeMax = size;
			((Graphic)component).color = color;
			((TMP_Text)component).alignment = alignment;
			((TMP_Text)component).textWrappingMode = (TextWrappingModes)0;
			((Graphic)component).raycastTarget = false;
			RectTransform rectTransform = ((TMP_Text)component).rectTransform;
			rectTransform.anchorMin = Vector2.zero;
			rectTransform.anchorMax = Vector2.one;
			rectTransform.sizeDelta = Vector2.zero;
			return component;
		}
	}
	public sealed class HangulInput : InputMethod
	{
		private const string Initials = "ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ";

		private const string Vowels = "ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ";

		private const string Finals = " ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ";

		private const int VowelCount = 21;

		private const int FinalCount = 28;

		private const char SyllableBase = '가';

		private static readonly Dictionary<string, char> CompoundVowels = new Dictionary<string, char>
		{
			{ "ㅗㅏ", 'ㅘ' },
			{ "ㅗㅐ", 'ㅙ' },
			{ "ㅗㅣ", 'ㅚ' },
			{ "ㅜㅓ", 'ㅝ' },
			{ "ㅜㅔ", 'ㅞ' },
			{ "ㅜㅣ", 'ㅟ' },
			{ "ㅡㅣ", 'ㅢ' }
		};

		private static readonly Dictionary<string, char> CompoundFinals = new Dictionary<string, char>
		{
			{ "ㄱㅅ", 'ㄳ' },
			{ "ㄴㅈ", 'ㄵ' },
			{ "ㄴㅎ", 'ㄶ' },
			{ "ㄹㄱ", 'ㄺ' },
			{ "ㄹㅁ", 'ㄻ' },
			{ "ㄹㅂ", 'ㄼ' },
			{ "ㄹㅅ", 'ㄽ' },
			{ "ㄹㅌ", 'ㄾ' },
			{ "ㄹㅍ", 'ㄿ' },
			{ "ㄹㅎ", 'ㅀ' },
			{ "ㅂㅅ", 'ㅄ' }
		};

		private readonly List<char> _jamo = new List<char>();

		private readonly Composition _composition = new Composition();

		public static bool TryCompose(IReadOnlyList<char> jamo, out char result, out bool hasFinal)
		{
			result = '\0';
			hasFinal = false;
			if (jamo.Count == 0)
			{
				return false;
			}
			int index = 0;
			int num = "ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ".IndexOf(jamo[0]);
			if (num >= 0)
			{
				index = 1;
			}
			else if (!IsVowel(jamo[0]))
			{
				return false;
			}
			int num2 = -1;
			int num3 = 0;
			if (index < jamo.Count && IsVowel(jamo[index]))
			{
				num2 = ReadVowel(jamo, ref index);
				if (num >= 0 && index < jamo.Count && IsFinal(jamo[index]))
				{
					num3 = ReadFinal(jamo, ref index);
				}
			}
			if (index != jamo.Count)
			{
				return false;
			}
			hasFinal = num3 > 0;
			result = ((num >= 0 && num2 >= 0) ? ((char)(44032 + (num * 21 + num2) * 28 + num3)) : ((num >= 0) ? "ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ"[num] : "ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ"[num2]));
			return true;
		}

		public override void Type(char character, ITextSurface text)
		{
			if (!IsJamo(character))
			{
				Cancel();
				text.Insert(character.ToString());
				return;
			}
			Synchronize(text);
			if (_jamo.Count <= 0 || !Extend(character, text))
			{
				Begin(character, text);
			}
		}

		public override bool Backspace(ITextSurface text)
		{
			Synchronize(text);
			if (_jamo.Count == 0)
			{
				return false;
			}
			_jamo.RemoveAt(_jamo.Count - 1);
			if (_jamo.Count == 0)
			{
				_composition.Show(text, string.Empty);
				return true;
			}
			TryCompose(_jamo, out var result, out var _);
			_composition.Show(text, result.ToString());
			return true;
		}

		public override bool Space(ITextSurface text)
		{
			Cancel();
			return false;
		}

		public override void Choose(char candidate, ITextSurface text)
		{
			Cancel();
			base.Choose(candidate, text);
		}

		public override void Cancel()
		{
			_jamo.Clear();
			_composition.Cancel();
		}

		private static bool IsVowel(char character)
		{
			return "ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ".IndexOf(character) >= 0;
		}

		private static bool IsFinal(char character)
		{
			return " ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ".IndexOf(character) > 0;
		}

		private static bool IsJamo(char character)
		{
			if ("ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ".IndexOf(character) < 0)
			{
				return IsVowel(character);
			}
			return true;
		}

		private static int ReadVowel(IReadOnlyList<char> jamo, ref int index)
		{
			char value = jamo[index++];
			if (index < jamo.Count && CompoundVowels.TryGetValue(value.ToString() + jamo[index], out var value2))
			{
				value = value2;
				index++;
			}
			return "ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ".IndexOf(value);
		}

		private static int ReadFinal(IReadOnlyList<char> jamo, ref int index)
		{
			char value = jamo[index++];
			if (index < jamo.Count && CompoundFinals.TryGetValue(value.ToString() + jamo[index], out var value2))
			{
				value = value2;
				index++;
			}
			return " ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ".IndexOf(value);
		}

		private void Synchronize(ITextSurface text)
		{
			_composition.Synchronize(text);
			if (!_composition.Active)
			{
				_jamo.Clear();
			}
		}

		private bool Extend(char character, ITextSurface text)
		{
			_jamo.Add(character);
			if (TryCompose(_jamo, out var result, out var _))
			{
				if (!_composition.Show(text, result.ToString()))
				{
					_jamo.RemoveAt(_jamo.Count - 1);
				}
				return true;
			}
			_jamo.RemoveAt(_jamo.Count - 1);
			TryCompose(_jamo, out var _, out var hasFinal2);
			if (!hasFinal2 || !IsVowel(character))
			{
				return false;
			}
			MoveFinal(character, text);
			return true;
		}

		private void Begin(char character, ITextSurface text)
		{
			Cancel();
			if (_composition.Show(text, character.ToString()))
			{
				_jamo.Add(character);
			}
		}

		private void MoveFinal(char vowel, ITextSurface text)
		{
			List<char> list = new List<char>(_jamo);
			char item = list[list.Count - 1];
			list.RemoveAt(list.Count - 1);
			List<char> list2 = new List<char> { item, vowel };
			TryCompose(list, out var result, out var hasFinal);
			TryCompose(list2, out var result2, out hasFinal);
			if (_composition.Split(text, result.ToString(), result2.ToString()))
			{
				_jamo.Clear();
				_jamo.AddRange(list2);
			}
		}
	}
	public interface IDialogPlacement
	{
		void Place(RectTransform field, IKeyboardView keyboard);

		void Restore();
	}
	public interface IFeature
	{
		void Enable();

		void Update();

		void Disable();
	}
	public interface IFocusHint
	{
		void Show(RectTransform field, string button, bool visible);
	}
	public interface IInputMethod
	{
		bool Choosing { get; }

		IReadOnlyList<char> Candidates { get; }

		void Type(char character, ITextSurface text);

		bool Backspace(ITextSurface text);

		bool Space(ITextSurface text);

		void Choose(char candidate, ITextSurface text);

		void Cancel();
	}
	public interface IKeyboardView
	{
		Rect ScreenRect { get; }

		float MaxHeight { get; }

		void Show(float scale);

		void Hide();

		void Refresh(KeyLayout layout);

		void MoveBy(Vector2 offset);

		void ResetPosition();
	}
	public interface ILayoutCatalog
	{
		LanguageLayout For(string language);
	}
	public sealed class InputFieldEditor : ITextEditor, ITextSurface
	{
		private readonly TMP_InputField _field;

		public string Text => _field.text;

		public int Caret => Mathf.Clamp(_field.selectionStringFocusPosition, 0, _field.text.Length);

		public bool HasSelection => _field.selectionStringAnchorPosition != _field.selectionStringFocusPosition;

		public InputFieldEditor(TMP_InputField field)
		{
			_field = field;
		}

		public bool Insert(string typed)
		{
			int position;
			string text = RemoveSelection(out position);
			bool result = false;
			foreach (char character in typed)
			{
				char c = Validate(text, position, character);
				if (c != 0 && !IsFull(text))
				{
					text = text.Insert(position, c.ToString());
					position++;
					result = true;
				}
			}
			SetText(text, position);
			return result;
		}

		public bool Replace(int start, int length, string replacement)
		{
			string text = _field.text;
			if (start < 0 || length < 0 || start + length > text.Length)
			{
				return false;
			}
			string text2 = text.Remove(start, length);
			int num = start;
			foreach (char character in replacement)
			{
				char c = Validate(text2, num, character);
				if (c == '\0' || IsFull(text2))
				{
					return false;
				}
				text2 = text2.Insert(num, c.ToString());
				num++;
			}
			SetText(text2, num);
			return true;
		}

		public void Backspace()
		{
			bool hasSelection = HasSelection;
			int position;
			string text = RemoveSelection(out position);
			if (!hasSelection && position > 0)
			{
				position--;
				text = text.Remove(position, 1);
			}
			SetText(text, position);
		}

		public void MoveCaret(int step)
		{
			int num = _field.selectionStringFocusPosition + step;
			_field.stringPosition = Mathf.Clamp(num, 0, _field.text.Length);
			ShowCaret();
		}

		public void Submit()
		{
			_field.SendOnSubmit();
			_field.DeactivateInputField(false);
		}

		private bool IsFull(string text)
		{
			if (_field.characterLimit > 0)
			{
				return text.Length >= _field.characterLimit;
			}
			return false;
		}

		private string RemoveSelection(out int position)
		{
			string text = _field.text;
			int num = Mathf.Clamp(_field.selectionStringAnchorPosition, 0, text.Length);
			int num2 = Mathf.Clamp(_field.selectionStringFocusPosition, 0, text.Length);
			position = Mathf.Min(num, num2);
			return text.Remove(position, Mathf.Abs(num2 - num));
		}

		private char Validate(string text, int position, char character)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (_field.onValidateInput != null)
			{
				return _field.onValidateInput.Invoke(text, position, character);
			}
			if ((int)_field.characterValidation != 0)
			{
				return _field.Validate(text, position, character);
			}
			return character;
		}

		private void SetText(string text, int position)
		{
			_field.text = text;
			_field.stringPosition = position;
			ShowCaret();
		}

		private void ShowCaret()
		{
			_field.UpdateLabel();
			_field.SetCaretVisible();
		}
	}
	public abstract class InputMethod : IInputMethod
	{
		public virtual bool Choosing => false;

		public virtual IReadOnlyList<char> Candidates => Array.Empty<char>();

		public abstract void Type(char character, ITextSurface text);

		public virtual bool Backspace(ITextSurface text)
		{
			return false;
		}

		public virtual bool Space(ITextSurface text)
		{
			return false;
		}

		public virtual void Choose(char candidate, ITextSurface text)
		{
			text.Insert(candidate.ToString());
		}

		public virtual void Cancel()
		{
		}
	}
	public interface ITextEditor : ITextSurface
	{
		void Backspace();

		void MoveCaret(int step);

		void Submit();
	}
	public interface ITextSurface
	{
		string Text { get; }

		int Caret { get; }

		bool HasSelection { get; }

		bool Insert(string text);

		bool Replace(int start, int length, string text);
	}
	public static class Kana
	{
		public const char Dakuten = '\u309b';

		public const char Handakuten = '\u309c';

		public const char Small = '小';

		public const char LongVowel = 'ー';

		private const int KatakanaOffset = 96;

		private const char FirstHiragana = 'ぁ';

		private const char LastHiragana = 'ゖ';

		private const string Plain = "かきくけこさしすせそたちつてとはひふへほう";

		private const string Voiced = "がぎぐげござじずぜぞだぢづでどばびぶべぼゔ";

		private const string HalfBase = "はひふへほ";

		private const string HalfVoiced = "ばびぶべぼ";

		private const string HalfVoiceless = "ぱぴぷぺぽ";

		private const string Big = "あいうえおつやゆよわかけ";

		private const string Reduced = "ぁぃぅぇぉっゃゅょゎゕゖ";

		public static bool IsMark(char character)
		{
			if (character != '\u309b' && character != '\u309c')
			{
				return character == '小';
			}
			return true;
		}

		public static bool IsKana(char character)
		{
			if (!IsHiragana(character) && !IsKatakana(character))
			{
				return character == 'ー';
			}
			return true;
		}

		public static string Katakana(string hiragana)
		{
			char[] array = hiragana.ToCharArray();
			for (int i = 0; i < array.Length; i++)
			{
				if (IsHiragana(array[i]))
				{
					array[i] = (char)(array[i] + 96);
				}
			}
			return new string(array);
		}

		public static string Hiragana(string kana)
		{
			char[] array = kana.ToCharArray();
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = Hiragana(array[i]);
			}
			return new string(array);
		}

		public static char Convert(char character, char mark)
		{
			char num = Hiragana(character);
			char c = ConvertHiragana(num, mark);
			if (num != character)
			{
				return (char)(c + 96);
			}
			return c;
		}

		private static bool IsHiragana(char character)
		{
			if (character >= 'ぁ')
			{
				return character <= 'ゖ';
			}
			return false;
		}

		private static bool IsKatakana(char character)
		{
			if (character >= 'ァ')
			{
				return character <= 'ヶ';
			}
			return false;
		}

		private static char Hiragana(char character)
		{
			if (!IsKatakana(character))
			{
				return character;
			}
			return (char)(character - 96);
		}

		private static char ConvertHiragana(char character, char mark)
		{
			return mark switch
			{
				'\u309b' => Pair(character, "かきくけこさしすせそたちつてとはひふへほう", "がぎぐげござじずぜぞだぢづでどばびぶべぼゔ") ?? Map(character, "ぱぴぷぺぽ", "ばびぶべぼ") ?? character, 
				'\u309c' => Pair(character, "はひふへほ", "ぱぴぷぺぽ") ?? Map(character, "ばびぶべぼ", "ぱぴぷぺぽ") ?? character, 
				_ => Pair(character, "あいうえおつやゆよわかけ", "ぁぃぅぇぉっゃゅょゎゕゖ") ?? character, 
			};
		}

		private static char? Pair(char character, string first, string second)
		{
			return Map(character, first, second) ?? Map(character, second, first);
		}

		private static char? Map(char character, string from, string to)
		{
			int num = from.IndexOf(character);
			if (num < 0)
			{
				return null;
			}
			return to[num];
		}
	}
	public sealed class KanaInput : CandidateInput
	{
		private const int MaxReadingLength = 8;

		public KanaInput(Func<CandidateTable> kanji)
			: base(kanji, 8)
		{
		}

		public override void Type(char character, ITextSurface text)
		{
			if (Kana.IsMark(character))
			{
				ApplyMark(character, text);
			}
			else
			{
				base.Type(character, text);
			}
		}

		protected override bool Accepts(char character)
		{
			return Kana.IsKana(character);
		}

		protected override string ReadingOf(string shown)
		{
			return Kana.Hiragana(shown);
		}

		private void ApplyMark(char mark, ITextSurface text)
		{
			base.Composition.Synchronize(text);
			int num = text.Caret - 1;
			if (text.HasSelection || num < 0)
			{
				return;
			}
			char c = text.Text[num];
			char c2 = Kana.Convert(c, mark);
			if (c2 != c)
			{
				if (base.Composition.Active)
				{
					string shown = base.Composition.Shown;
					base.Composition.Show(text, shown.Substring(0, shown.Length - 1) + c2);
				}
				else
				{
					text.Replace(num, 1, c2.ToString());
				}
			}
		}
	}
	public sealed class Key
	{
		public KeyAction Action { get; }

		public char Character { get; }

		public char ShiftCharacter { get; }

		public float X { get; }

		public float Width { get; }

		public float Center => X + Width / 2f;

		public Key(KeyAction action, char character, float x, float width)
			: this(action, character, character, x, width)
		{
		}

		public Key(KeyAction action, char character, char shiftCharacter, float x, float width)
		{
			Action = action;
			Character = character;
			ShiftCharacter = shiftCharacter;
			X = x;
			Width = width;
		}
	}
	public enum KeyAction
	{
		Character,
		Shift,
		Symbols,
		Language,
		Space,
		Backspace,
		Enter,
		Choice,
		NextPage
	}
	public sealed class KeyboardSession
	{
		private readonly KeyLayout _layout;

		private readonly ITextEditor _editor;

		public bool AccentsOpen { get; private set; }

		public KeyboardSession(KeyLayout layout, ITextEditor editor)
		{
			_layout = layout;
			_editor = editor;
		}

		public static bool Repeats(Key key)
		{
			if (key.Action != KeyAction.Choice)
			{
				return key.Action != KeyAction.NextPage;
			}
			return false;
		}

		public void Press(Key key)
		{
			switch (key.Action)
			{
			case KeyAction.Character:
				_layout.Input.Type(_layout.CharacterOf(key), _editor);
				Settle();
				break;
			case KeyAction.Choice:
				Choose(key.Character);
				break;
			case KeyAction.NextPage:
				_layout.NextChoicePage();
				break;
			case KeyAction.Shift:
				_layout.Shifted = !_layout.Shifted;
				break;
			case KeyAction.Symbols:
				Reset();
				_layout.ShowSymbols = !_layout.ShowSymbols;
				break;
			case KeyAction.Language:
				Reset();
				_layout.SwitchLanguage();
				break;
			case KeyAction.Space:
				Space();
				break;
			case KeyAction.Backspace:
				Backspace();
				break;
			default:
				Submit();
				break;
			}
		}

		public void Backspace()
		{
			if (!_layout.Input.Backspace(_editor))
			{
				_editor.Backspace();
			}
			Settle();
		}

		public void Space()
		{
			if (!_layout.Input.Space(_editor))
			{
				_editor.Insert(" ");
			}
			Settle();
		}

		public void MoveCaret(int step)
		{
			_editor.MoveCaret(step);
			_layout.Input.Cancel();
			Settle();
		}

		public void Submit()
		{
			_editor.Submit();
		}

		public void ToggleChoices()
		{
			if (_layout.ChoicesFocused)
			{
				LeaveChoices();
			}
			else if (_layout.ChoicesShown)
			{
				_layout.FocusChoices();
			}
			else
			{
				OpenAccents();
			}
		}

		public void CloseAccents()
		{
			AccentsOpen = false;
			_layout.ClearChoices();
			_layout.LeaveChoices(restore: true);
		}

		public void DismissAccentsOnNavigation()
		{
			if (AccentsOpen && _layout.Row != 0)
			{
				AccentsOpen = false;
				_layout.ClearChoices();
				_layout.LeaveChoices(restore: false);
			}
		}

		private void LeaveChoices()
		{
			if (AccentsOpen)
			{
				CloseAccents();
			}
			else
			{
				_layout.LeaveChoices(restore: true);
			}
		}

		private void OpenAccents()
		{
			Key selected = _layout.Selected;
			if (selected.Action == KeyAction.Character && !_layout.ShowSymbols)
			{
				string text = LetterVariants.Of(_layout.CharacterOf(selected));
				if (text.Length > 0)
				{
					AccentsOpen = true;
					_layout.ShowChoices(text.ToCharArray());
					_layout.FocusChoices();
				}
			}
		}

		private void Choose(char choice)
		{
			if (choice != 0)
			{
				if (_layout.Input.Choosing)
				{
					_layout.Input.Choose(choice, _editor);
				}
				else
				{
					_editor.Insert(choice.ToString());
				}
				AccentsOpen = false;
				Settle();
			}
		}

		private void Reset()
		{
			_layout.Input.Cancel();
			AccentsOpen = false;
		}

		private void Settle()
		{
			if (_layout.Input.Choosing)
			{
				_layout.ShowChoices(_layout.Input.Candidates);
			}
			else if (!AccentsOpen)
			{
				_layout.ClearChoices();
				_layout.LeaveChoices(restore: true);
			}
		}
	}
	public sealed class KeyboardView : IKeyboardView
	{
		private const float KeyWidth = 76f;

		private const float KeyHeight = 56f;

		private const float Gap = 6f;

		private const float Padding = 30f;

		private const float HintHeight = 36f;

		private const float BottomOffset = 24f;

		private const float KeyFontSize = 28f;

		private const float HintFontSize = 20f;

		private const float MinFontSize = 6f;

		private const float KeyTextMargin = 14f;

		private const string Hint = "$KEY_ButtonX $menu_remove      $KEY_ButtonY $button_space      $KEY_LTrigger Shift      $KEY_LBumper $KEY_RBumper $inventory_move      $KEY_RTrigger $menu_more      $KEY_Start $menu_ok      $KEY_ButtonB $menu_close";

		private readonly IGameAssets _assets;

		private readonly KeyCaption _captions;

		private readonly GameObject _canvas;

		private readonly RectTransform _panel;

		private readonly List<List<Image>> _keys = new List<List<Image>>();

		private readonly List<List<TextMeshProUGUI>> _labels = new List<List<TextMeshProUGUI>>();

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

		private TextMeshProUGUI _hint;

		private int _builtVersion = -1;

		private int _maxRows = 6;

		public Rect ScreenRect
		{
			get
			{
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				_panel.GetWorldCorners(_corners);
				return Rect.MinMaxRect(_corners[0].x, _corners[0].y, _corners[2].x, _corners[2].y);
			}
		}

		public float MaxHeight => HeightOf(_maxRows) * ((Transform)_panel).lossyScale.y;

		public KeyboardView(Transform parent, IGameAssets assets, IGameLanguage language)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			_assets = assets;
			_captions = new KeyCaption(language);
			_canvas = new GameObject("Canvas", new Type[1] { typeof(Canvas) });
			_canvas.transform.SetParent(parent, false);
			Canvas component = _canvas.GetComponent<Canvas>();
			component.renderMode = (RenderMode)0;
			component.sortingOrder = 32767;
			_panel = ((Graphic)CreateImage("Panel", _canvas.transform)).rectTransform;
			_panel.anchorMin = new Vector2(0.5f, 0f);
			_panel.anchorMax = new Vector2(0.5f, 0f);
			_panel.pivot = new Vector2(0.5f, 0f);
			_panel.anchoredPosition = new Vector2(0f, 24f);
			_canvas.SetActive(false);
		}

		public void MoveBy(Vector2 offset)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			RectTransform panel = _panel;
			((Transform)panel).position = ((Transform)panel).position + Vector2.op_Implicit(offset);
		}

		public void ResetPosition()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			_panel.anchoredPosition = new Vector2(0f, 24f);
		}

		public void Show(float scale)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_hint == (Object)null)
			{
				_hint = CreateHint();
			}
			Image component = ((Component)_panel).GetComponent<Image>();
			ApplySprite(component, "woodpanel_512x512");
			((Graphic)component).material = _assets.Material("litpanel");
			((Transform)_panel).localScale = new Vector3(scale, scale, 1f);
			ResetPosition();
			_builtVersion = -1;
			_canvas.SetActive(true);
		}

		public void Hide()
		{
			_canvas.SetActive(false);
		}

		public void Refresh(KeyLayout layout)
		{
			_maxRows = layout.MaxRows;
			if (_builtVersion != layout.Version)
			{
				Build(layout);
			}
			for (int i = 0; i < layout.Rows.Count; i++)
			{
				for (int j = 0; j < layout.Rows[i].Count; j++)
				{
					Key key = layout.Rows[i][j];
					bool selected = i == layout.Row && j == layout.Index;
					ApplySprite(_keys[i][j], KeySprite(layout, key, selected));
					((TMP_Text)_labels[i][j]).text = _captions.Of(layout, key);
				}
			}
		}

		private static float HeightOf(int rows)
		{
			return 60f + (float)rows * 62f + 36f;
		}

		private static string KeySprite(KeyLayout layout, Key key, bool selected)
		{
			if (selected)
			{
				return "button_highlight";
			}
			if ((key.Action != KeyAction.Shift || !layout.Shifted) && (key.Action != KeyAction.Symbols || !layout.ShowSymbols))
			{
				return "button";
			}
			return "button_pressed";
		}

		private static Image CreateImage(string name, Transform parent)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent(parent, false);
			Image component = val.GetComponent<Image>();
			((Graphic)component).raycastTarget = false;
			return component;
		}

		private void ApplySprite(Image image, string name)
		{
			image.sprite = _assets.Sprite(name);
			image.type = (Type)1;
		}

		private TextMeshProUGUI CreateHint()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Expected O, but got Unknown
			GameObject val = new GameObject("Hint", new Type[1] { typeof(RectTransform) });
			val.SetActive(false);
			RectTransform val2 = (RectTransform)val.transform;
			((Transform)val2).SetParent((Transform)(object)_panel, false);
			val2.anchorMin = new Vector2(0f, 0f);
			val2.anchorMax = new Vector2(1f, 0f);
			val2.pivot = new Vector2(0.5f, 0f);
			val2.anchoredPosition = new Vector2(0f, 24f);
			val2.sizeDelta = new Vector2(-60f, 36f);
			TextMeshProUGUI obj = GameText.Create((Transform)val2, _assets, "Valheim-AveriaSansLibre", "Valheim-AveriaSansLibre - Outline", 20f, 6f, Color.white, (TextAlignmentOptions)514);
			((TMP_Text)obj).text = "$KEY_ButtonX $menu_remove      $KEY_ButtonY $button_space      $KEY_LTrigger Shift      $KEY_LBumper $KEY_RBumper $inventory_move      $KEY_RTrigger $menu_more      $KEY_Start $menu_ok      $KEY_ButtonB $menu_close";
			val.AddComponent<Localize>();
			val.SetActive(true);
			return obj;
		}

		private void Build(KeyLayout layout)
		{
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			foreach (List<Image> key in _keys)
			{
				foreach (Image item in key)
				{
					Object.Destroy((Object)(object)((Component)item).gameObject);
				}
			}
			_keys.Clear();
			_labels.Clear();
			_panel.sizeDelta = new Vector2(60f + (float)layout.Width * 76f + (float)(layout.Width - 1) * 6f, HeightOf(layout.Rows.Count));
			for (int i = 0; i < layout.Rows.Count; i++)
			{
				List<Image> list = new List<Image>();
				List<TextMeshProUGUI> list2 = new List<TextMeshProUGUI>();
				foreach (Key item2 in layout.Rows[i])
				{
					Image val = CreateKey(i, item2);
					list.Add(val);
					list2.Add(((Component)val).GetComponentInChildren<TextMeshProUGUI>());
				}
				_keys.Add(list);
				_labels.Add(list2);
			}
			_builtVersion = layout.Version;
		}

		private Image CreateKey(int row, Key key)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			Image obj = CreateImage("Key", (Transform)(object)_panel);
			RectTransform rectTransform = ((Graphic)obj).rectTransform;
			rectTransform.anchorMin = new Vector2(0f, 1f);
			rectTransform.anchorMax = new Vector2(0f, 1f);
			rectTransform.pivot = new Vector2(0f, 1f);
			rectTransform.anchoredPosition = new Vector2(30f + key.X * 82f, 0f - (30f + (float)row * 62f));
			rectTransform.sizeDelta = new Vector2(key.Width * 76f + (key.Width - 1f) * 6f, 56f);
			TextMeshProUGUI obj2 = GameText.Create((Transform)(object)rectTransform, _assets, "Valheim-AveriaSerifLibre", "Valheim-AveriaSerifLibre - Outline", 28f, 6f, GameStyle.ButtonText, (TextAlignmentOptions)514);
			((TMP_Text)obj2).fontStyle = (FontStyles)1;
			((TMP_Text)obj2).margin = new Vector4(14f, 0f, 14f, 0f);
			return obj;
		}
	}
	public sealed class KeyCaption
	{
		private const char DottedCircle = '◌';

		private readonly IGameLanguage _language;

		public KeyCaption(IGameLanguage language)
		{
			_language = language;
		}

		public string Of(KeyLayout layout, Key key)
		{
			string text = layout.Label(key);
			switch (key.Action)
			{
			case KeyAction.Character:
			case KeyAction.Choice:
				return Printable(text);
			case KeyAction.NextPage:
				return text;
			default:
				return _language.Localize(text);
			}
		}

		private static string Printable(string label)
		{
			if (label.Length != 1)
			{
				return label;
			}
			UnicodeCategory unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(label[0]);
			if (unicodeCategory != UnicodeCategory.NonSpacingMark && unicodeCategory != UnicodeCategory.SpacingCombiningMark && unicodeCategory != UnicodeCategory.EnclosingMark)
			{
				return label;
			}
			return "◌" + label;
		}
	}
	public sealed class KeyChoices
	{
		public const int Slots = 10;

		public const char NextPageLabel = '»';

		private const int PagedSlots = 9;

		private IReadOnlyList<char> _items = Array.Empty<char>();

		private int _page;

		public bool Shown { get; private set; }

		public bool Focused { get; private set; }

		public int ReturnRow { get; private set; }

		public int ReturnIndex { get; private set; }

		public bool Show(IReadOnlyList<char> items)
		{
			if (Shown && _items.SequenceEqual(items))
			{
				return false;
			}
			_items = items;
			_page = 0;
			Shown = true;
			return true;
		}

		public void Clear()
		{
			_items = Array.Empty<char>();
			_page = 0;
			Shown = false;
		}

		public void NextPage()
		{
			int val = (_items.Count + 9 - 1) / 9;
			_page = (_page + 1) % Math.Max(val, 1);
		}

		public void Focus(int row, int index)
		{
			ReturnRow = row;
			ReturnIndex = index;
			Focused = true;
		}

		public void Release()
		{
			Focused = false;
		}

		public List<Key> Row(float offset)
		{
			bool flag = _items.Count > 10;
			int num = (flag ? 9 : 10);
			List<Key> list = new List<Key>();
			for (int i = 0; i < 10; i++)
			{
				float x = offset + (float)i;
				if (flag && i == 9)
				{
					list.Add(new Key(KeyAction.NextPage, '»', x, 1f));
					continue;
				}
				int num2 = _page * num + i;
				char character = ((num2 < _items.Count) ? _items[num2] : '\0');
				list.Add(new Key(KeyAction.Choice, character, x, 1f));
			}
			return list;
		}
	}
	public sealed class KeyLayout
	{
		public const int DefaultRows = 6;

		private readonly List<List<Key>> _rows = new List<List<Key>>();

		private readonly KeyChoices _choices = new KeyChoices();

		private LanguageLayout _native = LanguageLayouts.English;

		private LanguageLayout _language = LanguageLayouts.English;

		private List<Key> _digitRow = new List<Key>();

		private bool _showSymbols;

		private float _anchor;

		public IReadOnlyList<IReadOnlyList<Key>> Rows => _rows;

		public IInputMethod Input { get; private set; }

		public int Width { get; private set; }

		public int Version { get; private set; }

		public int Revision { get; private set; }

		public int Row { get; private set; }

		public int Index { get; private set; }

		public Key Selected => _rows[Row][Index];

		public bool Shifted { get; set; }

		public bool ChoicesShown => _choices.Shown;

		public bool ChoicesFocused => _choices.Focused;

		public bool ShowSymbols
		{
			get
			{
				return _showSymbols;
			}
			set
			{
				if (_showSymbols != value)
				{
					_showSymbols = value;
					Build();
				}
			}
		}

		public int MaxRows => Math.Max(KeyRowBuilder.RowsOf(_native), KeyRowBuilder.RowsOf(LanguageLayouts.English));

		public bool CanSwitchLanguage => _native != LanguageLayouts.English;

		private float ChoiceOffset => (float)(Width - 10) / 2f;

		public KeyLayout()
		{
			Reset(LanguageLayouts.English);
		}

		public void Reset(LanguageLayout language)
		{
			if (_native != language)
			{
				_native = language;
				_language = language;
			}
			Input = _language.CreateInput();
			_showSymbols = false;
			Shifted = false;
			Row = 0;
			Index = 0;
			Build();
		}

		public void SwitchLanguage()
		{
			_language = ((_language == _native) ? LanguageLayouts.English : _native);
			Input = _language.CreateInput();
			_showSymbols = false;
			Build();
		}

		public char CharacterOf(Key key)
		{
			if (!Shifted)
			{
				return key.Character;
			}
			return key.ShiftCharacter;
		}

		public string Label(Key key)
		{
			switch (key.Action)
			{
			case KeyAction.Character:
				return CharacterOf(key).ToString();
			case KeyAction.Choice:
			case KeyAction.NextPage:
				if (key.Character != 0)
				{
					return key.Character.ToString();
				}
				return string.Empty;
			case KeyAction.Shift:
				return "Shift";
			case KeyAction.Symbols:
				if (!_showSymbols)
				{
					return "#+=";
				}
				return _language.Label;
			case KeyAction.Language:
				return ((_language == _native) ? LanguageLayouts.English : _native).Label;
			case KeyAction.Space:
				return "$button_space";
			case KeyAction.Backspace:
				return "$menu_remove";
			default:
				return "$menu_ok";
			}
		}

		public void MoveHorizontal(int step)
		{
			int count = _rows[Row].Count;
			Index = (Index + step + count) % count;
			_anchor = Selected.Center;
		}

		public void MoveVertical(int step)
		{
			Row = (Row + step + _rows.Count) % _rows.Count;
			Index = NearestIndex(_rows[Row], _anchor);
		}

		public void ShowChoices(IReadOnlyList<char> items)
		{
			if (!_showSymbols && _choices.Show(items))
			{
				ReplaceTopRow(_choices.Row(ChoiceOffset));
			}
		}

		public void ClearChoices()
		{
			if (_choices.Shown)
			{
				_choices.Clear();
				ReplaceTopRow(_digitRow);
			}
		}

		public void NextChoicePage()
		{
			_choices.NextPage();
			ReplaceTopRow(_choices.Row(ChoiceOffset));
		}

		public void FocusChoices()
		{
			if (_choices.Shown && !_choices.Focused)
			{
				_choices.Focus(Row, Index);
				Row = 0;
				Index = 0;
				_anchor = Selected.Center;
			}
		}

		public void LeaveChoices(bool restore)
		{
			if (_choices.Focused)
			{
				_choices.Release();
				if (restore)
				{
					Row = Math.Min(_choices.ReturnRow, _rows.Count - 1);
					Index = Math.Min(_choices.ReturnIndex, _rows[Row].Count - 1);
					_anchor = Selected.Center;
				}
			}
		}

		private static int NearestIndex(List<Key> row, float x)
		{
			int num = 0;
			for (int i = 1; i < row.Count; i++)
			{
				if (Math.Abs(row[i].Center - x) < Math.Abs(row[num].Center - x))
				{
					num = i;
				}
			}
			return num;
		}

		private void Build()
		{
			bool flag = _rows.Count > 0 && Row == _rows.Count - 1;
			int width;
			List<List<Key>> collection = KeyRowBuilder.Build(_language, _showSymbols, CanSwitchLanguage, out width);
			Width = width;
			_rows.Clear();
			_rows.AddRange(collection);
			_digitRow = (_showSymbols ? new List<Key>() : _rows[0]);
			_choices.Clear();
			_choices.Release();
			Row = (flag ? (_rows.Count - 1) : Math.Min(Row, _rows.Count - 1));
			Index = NearestIndex(_rows[Row], _anchor);
			_anchor = Selected.Center;
			Version++;
		}

		private void ReplaceTopRow(List<Key> row)
		{
			_rows[0] = row;
			Revision++;
		}
	}
	public static class KeyRowBuilder
	{
		public const int ServiceRows = 2;

		private const int MinWidth = 11;

		private const int FixedSpecialWidth = 9;

		private const int MinSpaceWidth = 2;

		private const string Digits = "1234567890";

		private static readonly string[] SymbolRows = new string[3] { "!@#$%^&*()", "-_=+[]{}\\|", "/:;\"'<>?~`" };

		public static int RowsOf(LanguageLayout language)
		{
			return language.Rows.Length + 2;
		}

		public static List<List<Key>> Build(LanguageLayout language, bool symbols, bool canSwitchLanguage, out int width)
		{
			List<(string, string)> list = (symbols ? SymbolTexts() : LetterTexts(language));
			int num = 9 + (canSwitchLanguage ? 1 : 0);
			int rowWidth = Math.Max(11, num + 2);
			foreach (var item in list)
			{
				rowWidth = Math.Max(rowWidth, item.Item1.Length);
			}
			List<List<Key>> list2 = list.Select<(string, string), List<Key>>(((string Characters, string Shifted) text) => CharacterRow(text, rowWidth)).ToList();
			list2.Add(SpecialRow(language, symbols, canSwitchLanguage, rowWidth, num));
			width = rowWidth;
			return list2;
		}

		private static List<(string Characters, string Shifted)> SymbolTexts()
		{
			return SymbolRows.Select((string row) => (row, row)).ToList();
		}

		private static List<(string Characters, string Shifted)> LetterTexts(LanguageLayout language)
		{
			List<(string, string)> list = new List<(string, string)> { ("1234567890", "1234567890") };
			for (int i = 0; i < language.Rows.Length; i++)
			{
				list.Add((language.Rows[i], ShiftedRow(language, i)));
			}
			return list;
		}

		private static string ShiftedRow(LanguageLayout language, int row)
		{
			string text = language.Rows[row];
			char[] array = new char[text.Length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = ((text[i] == ' ') ? ' ' : language.ShiftedOf(row, i));
			}
			return new string(array);
		}

		private static List<Key> CharacterRow((string Characters, string Shifted) text, int width)
		{
			float num = (float)(width - text.Characters.Length) / 2f;
			List<Key> list = new List<Key>();
			for (int i = 0; i < text.Characters.Length; i++)
			{
				if (text.Characters[i] != ' ')
				{
					list.Add(new Key(KeyAction.Character, text.Characters[i], text.Shifted[i], num + (float)i, 1f));
				}
			}
			return list;
		}

		private static List<Key> SpecialRow(LanguageLayout language, bool symbols, bool canSwitchLanguage, int width, int specialWidth)
		{
			List<Key> list = new List<Key>();
			Append(list, KeyAction.Shift, '\0', 2f);
			Append(list, KeyAction.Symbols, '\0', 1f);
			if (canSwitchLanguage)
			{
				Append(list, KeyAction.Language, '\0', 1f);
			}
			Append(list, KeyAction.Character, symbols ? ',' : language.Comma, 1f);
			Append(list, KeyAction.Space, ' ', width - specialWidth);
			Append(list, KeyAction.Character, symbols ? '.' : language.Period, 1f);
			Append(list, KeyAction.Backspace, '\0', 2f);
			Append(list, KeyAction.Enter, '\0', 2f);
			return list;
		}

		private static void Append(List<Key> keys, KeyAction action, char character, float width)
		{
			float x = ((keys.Count == 0) ? 0f : (keys[keys.Count - 1].X + keys[keys.Count - 1].Width));
			keys.Add(new Key(action, character, x, width));
		}
	}
	public sealed class LanguageLayout
	{
		public const char Gap = ' ';

		private const int LabelLength = 3;

		private Func<IInputMethod> _input = () => new PlainInput();

		public CultureInfo Culture { get; }

		public string[] Rows { get; }

		public string[] ShiftRows { get; private set; }

		public string Label { get; private set; }

		public char Comma { get; private set; } = ',';

		public char Period { get; private set; } = '.';

		public LanguageLayout(params string[] rows)
			: this(CultureInfo.InvariantCulture, rows)
		{
		}

		public LanguageLayout(CultureInfo culture, params string[] rows)
		{
			Culture = culture;
			Rows = rows;
			Label = rows[0].Substring(0, Math.Min(3, rows[0].Length)).ToUpper(culture);
		}

		public LanguageLayout WithShift(params string[] rows)
		{
			LanguageLayout languageLayout = Copy();
			languageLayout.ShiftRows = rows;
			return languageLayout;
		}

		public LanguageLayout WithLabel(string label)
		{
			LanguageLayout languageLayout = Copy();
			languageLayout.Label = label;
			return languageLayout;
		}

		public LanguageLayout WithPunctuation(char comma, char period)
		{
			LanguageLayout languageLayout = Copy();
			languageLayout.Comma = comma;
			languageLayout.Period = period;
			return languageLayout;
		}

		public LanguageLayout WithInput(Func<IInputMethod> input)
		{
			LanguageLayout languageLayout = Copy();
			languageLayout._input = input;
			return languageLayout;
		}

		public IInputMethod CreateInput()
		{
			return _input();
		}

		public char ShiftedOf(int row, int index)
		{
			char c = Rows[row][index];
			if (ShiftRows == null)
			{
				return char.ToUpper(c, Culture);
			}
			return ShiftRows[row][index];
		}

		private LanguageLayout Copy()
		{
			return (LanguageLayout)MemberwiseClone();
		}
	}
	public sealed class LanguageLayouts : ILayoutCatalog
	{
		public static readonly LanguageLayout English = new LanguageLayout("qwertyuiop", "asdfghjkl", "zxcvbnm");

		private static readonly string[] Hiragana = new string[5] { "あかさたなはまやらわん", "いきしちにひみ りをー", "うくすつぬふむゆる々\u309b", "えけせてねへめ れ \u309c", "おこそとのほもよろ 小" };

		private readonly Dictionary<string, LanguageLayout> _layouts;

		public LanguageLayouts(Func<string, string> readResource)
		{
			Lazy<CandidateTable> simplified = Table(readResource, "PinyinSimplified.txt");
			Lazy<CandidateTable> traditional = Table(readResource, "PinyinTraditional.txt");
			Lazy<CandidateTable> kanji = Table(readResource, "KanjiReadings.txt");
			_layouts = new Dictionary<string, LanguageLayout>
			{
				{ "English", English },
				{
					"Russian",
					new LanguageLayout("йцукенгшщзхъ", "фывапролджэ", "ячсмитьбюё")
				},
				{
					"Ukrainian",
					new LanguageLayout("йцукенгшщзхї", "фівапролджє", "ячсмитьбюґ’")
				},
				{
					"Bulgarian",
					new LanguageLayout("уеишщксдзц", "ьяаожгтнвмч", "юйъфхпрлбѝ")
				},
				{
					"French",
					new LanguageLayout("azertyuiop", "qsdfghjklm", "wxcvbn", "éèêàâçùûôîëïœ")
				},
				{
					"German",
					new LanguageLayout("qwertzuiopü", "asdfghjklöä", "yxcvbnmß")
				},
				{
					"Spanish",
					new LanguageLayout("qwertyuiop", "asdfghjklñ", "zxcvbnm", "áéíóúü¿¡")
				},
				{
					"Portuguese_Brazilian",
					new LanguageLayout("qwertyuiop", "asdfghjklç", "zxcvbnm", "áàâãéêíóôõú")
				},
				{
					"Portuguese_European",
					new LanguageLayout("qwertyuiop", "asdfghjklç", "zxcvbnm", "áàâãéêíóôõú")
				},
				{
					"Italian",
					new LanguageLayout("qwertyuiop", "asdfghjkl", "zxcvbnm", "àèéìòù")
				},
				{
					"Dutch",
					new LanguageLayout("qwertyuiop", "asdfghjkl", "zxcvbnm", "éëïöü")
				},
				{
					"Swedish",
					new LanguageLayout("qwertyuiopå", "asdfghjklöä", "zxcvbnmé")
				},
				{
					"Finnish",
					new LanguageLayout("qwertyuiopå", "asdfghjklöä", "zxcvbnm")
				},
				{
					"Norwegian",
					new LanguageLayout("qwertyuiopå", "asdfghjkløæ", "zxcvbnmé")
				},
				{
					"Danish",
					new LanguageLayout("qwertyuiopå", "asdfghjklæø", "zxcvbnmé")
				},
				{
					"Icelandic",
					new LanguageLayout("qwertyuiopð", "asdfghjklæ", "zxcvbnmþ", "áéíóúýö")
				},
				{
					"Polish",
					new LanguageLayout("qwertyuiop", "asdfghjkl", "zxcvbnm", "ąćęłńóśźż")
				},
				{
					"Czech",
					new LanguageLayout("qwertzuiopú", "asdfghjklů", "yxcvbnm", "ěščřžýáíéťďň")
				},
				{
					"Slovak",
					new LanguageLayout("qwertzuiopú", "asdfghjklô", "yxcvbnmä", "ľščťžýáíéňóď")
				},
				{
					"Hungarian",
					new LanguageLayout("qwertzuiopőú", "asdfghjkléáű", "íyxcvbnmöüó")
				},
				{
					"Romanian",
					new LanguageLayout("qwertyuiop", "asdfghjkl", "zxcvbnm", "ăâîșț")
				},
				{
					"Croatian",
					new LanguageLayout("qwertzuiopš", "asdfghjklčćž", "yxcvbnmđ")
				},
				{
					"Turkish",
					new LanguageLayout(CultureInfo.GetCultureInfo("tr-TR"), "qwertyuıopğü", "asdfghjklşi", "zxcvbnmöç")
				},
				{
					"Latvian",
					new LanguageLayout("qwertyuiop", "asdfghjkl", "zxcvbnm", "āčēģīķļņšūž")
				},
				{
					"Lithuanian",
					new LanguageLayout("ąčęėįšųūž", "qwertyuiop", "asdfghjkl", "zxcvbnm")
				},
				{
					"Georgian",
					new LanguageLayout("ქწერტყუიოპ", "ასდფგჰჯკლ", "ზხცვბნმ", "ღთშჟძჩჭ")
				},
				{
					"Abenaki",
					new LanguageLayout("qwertyuiop", "asdfghjkl", "zxcvbnm", "àãèôòñ")
				},
				{
					"Thai",
					new LanguageLayout("ๆไำพะ\u0e31\u0e35รนยบลฃ", "ฟหกดเ\u0e49\u0e48าสวง", "ผปแอ\u0e34\u0e37ทมใฝ", "ๅภถ\u0e38\u0e36คตจขช").WithShift("๐\"ฎฑธ\u0e4d\u0e4aณฯญฐ,ฅ", "ฤฆฏโฌ\u0e47\u0e4bษศซ.", "()ฉฮ\u0e3a\u0e4c?ฒฬฦ", "+๓๔\u0e39฿๕๖๗๘๙").WithLabel("ไทย")
				},
				{
					"Korean",
					new LanguageLayout("ㅂㅈㄷㄱㅅㅛㅕㅑㅐㅔ", "ㅁㄴㅇㄹㅎㅗㅓㅏㅣ", "ㅋㅌㅊㅍㅠㅜㅡ").WithShift("ㅃㅉㄸㄲㅆㅛㅕㅑㅒㅖ", "ㅁㄴㅇㄹㅎㅗㅓㅏㅣ", "ㅋㅌㅊㅍㅠㅜㅡ").WithLabel("한").WithInput(() => new HangulInput())
				},
				{
					"Japanese",
					new LanguageLayout(Hiragana).WithShift(Array.ConvertAll(Hiragana, Kana.Katakana)).WithLabel("あ").WithPunctuation('、', '。')
						.WithInput(() => new KanaInput(() => kanji.Value))
				},
				{
					"Chinese",
					new LanguageLayout("qwertyuiop", "asdfghjkl", "zxcvbnm").WithLabel("拼音").WithPunctuation(',', '。').WithInput(() => new PinyinInput(() => simplified.Value))
				},
				{
					"Chinese_Trad",
					new LanguageLayout("qwertyuiop", "asdfghjkl", "zxcvbnm").WithLabel("拼音").WithPunctuation(',', '。').WithInput(() => new PinyinInput(() => traditional.Value))
				}
			};
		}

		public LanguageLayout For(string language)
		{
			if (language == null || !_layouts.TryGetValue(language, out var value))
			{
				return English;
			}
			return value;
		}

		private static Lazy<CandidateTable> Table(Func<string, string> readResource, string name)
		{
			return new Lazy<CandidateTable>(() => new CandidateTable(readResource(name)));
		}
	}
	public static class LetterVariants
	{
		private static readonly Dictionary<char, string> Variants = new Dictionary<char, string>
		{
			{ 'a', "áåäâàæãąāăǎª" },
			{ 'c', "čçćċ" },
			{ 'd', "ďðđ" },
			{ 'e', "éêèęēëėěĕẽ" },
			{ 'g', "ğģǧǥ" },
			{ 'h', "ȟħ" },
			{ 'i', "íîīìįïĭĩ" },
			{ 'k', "ķǩ" },
			{ 'l', "łľļĺ" },
			{ 'n', "ňñńņŋ" },
			{ 'o', "öóôøõòœőōŏº" },
			{ 'r', "řŕŗ" },
			{ 's', "šşßșśŝ" },
			{ 't', "ťțþţŧ" },
			{ 'u', "úüùūûųűůŭǔũ" },
			{ 'y', "ýÿ" },
			{ 'z', "žźżʒ" },
			{ 'е', "ёѐ" },
			{ 'и', "йѝ" },
			{ 'і', "ї" }
		};

		public static string Of(char letter)
		{
			char c = char.ToLowerInvariant(letter);
			if (!Variants.TryGetValue(c, out var value))
			{
				return string.Empty;
			}
			if (c != letter)
			{
				return value.ToUpperInvariant();
			}
			return value;
		}
	}
	public sealed class NoFocusHint : IFocusHint
	{
		public void Show(RectTransform field, string button, bool visible)
		{
		}
	}
	public sealed class OnscreenKeyboardFeature : IFeature
	{
		private const float BaseScale = 0.5f;

		private readonly IPadInput _gamepad;

		private readonly IFocusedField _focus;

		private readonly IKeyboardView _view;

		private readonly IModSettings _settings;

		private readonly IGameLanguage _language;

		private readonly ILayoutCatalog _layouts;

		private readonly IDialogPlacement _placement;

		private readonly IUiScale _uiScale;

		private readonly KeyLayout _layout = new KeyLayout();

		private TMP_InputField _field;

		private TMP_InputField _dismissed;

		private KeyboardSession _session;

		private bool _savedNavigation;

		private bool _languageChanged;

		public OnscreenKeyboardFeature(IPadInput gamepad, IFocusedField focus, IKeyboardView view, IModSettings settings, IGameLanguage language, ILayoutCatalog layouts, IDialogPlacement placement, IUiScale uiScale)
		{
			_gamepad = gamepad;
			_focus = focus;
			_view = view;
			_settings = settings;
			_language = language;
			_layouts = layouts;
			_placement = placement;
			_uiScale = uiScale;
		}

		public void Enable()
		{
			_language.Changed += OnLanguageChanged;
		}

		public void Update()
		{
			TMP_InputField current = _focus.Current;
			if ((Object)(object)current != (Object)(object)_dismissed || _gamepad.Pressed("JoyButtonA"))
			{
				_dismissed = null;
			}
			if ((Object)(object)current == (Object)null || (Object)(object)current == (Object)(object)_dismissed || !_gamepad.IsActive)
			{
				Close();
				return;
			}
			if ((Object)(object)current != (Object)(object)_field || _languageChanged)
			{
				Open(current);
			}
			_focus.Navigation = false;
			HandleInput();
		}

		public void Disable()
		{
			_language.Changed -= OnLanguageChanged;
			Close();
		}

		private void OnLanguageChanged()
		{
			_languageChanged = true;
		}

		private void Open(TMP_InputField field)
		{
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			if ((Object)(object)_field == (Object)null)
			{
				_savedNavigation = _focus.Navigation;
			}
			_field = field;
			_languageChanged = false;
			_session = new KeyboardSession(_layout, new InputFieldEditor(field));
			_gamepad.Blocking = true;
			_layout.Reset(_layouts.For(_language.Current));
			_view.Show(_settings.Scale * 0.5f * _uiScale.Of(((Component)field).transform));
			_view.Refresh(_layout);
			_placement.Place((RectTransform)((Component)field).transform, _view);
		}

		private void Close()
		{
			if (!((Object)(object)_field == (Object)null))
			{
				_focus.Navigation = _savedNavigation;
				_field = null;
				_session = null;
				_gamepad.Blocking = false;
				_placement.Restore();
				_view.Hide();
			}
		}

		private void HandleInput()
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			if (_gamepad.Pressed("JoyButtonB"))
			{
				Cancel();
				return;
			}
			int version = _layout.Version;
			(int, int, bool, int, int) tuple = State();
			Navigate();
			Edit();
			(int, int, bool, int, int) tuple2 = tuple;
			(int, int, bool, int, int) tuple3 = State();
			if (tuple2.Item1 != tuple3.Item1 || tuple2.Item2 != tuple3.Item2 || tuple2.Item3 != tuple3.Item3 || tuple2.Item4 != tuple3.Item4 || tuple2.Item5 != tuple3.Item5)
			{
				_view.Refresh(_layout);
			}
			if (version != _layout.Version)
			{
				_placement.Place((RectTransform)((Component)_field).transform, _view);
			}
		}

		private void Cancel()
		{
			if (_session.AccentsOpen)
			{
				_session.CloseAccents();
				_view.Refresh(_layout);
			}
			else
			{
				_dismissed = _field;
				_field.DeactivateInputField(false);
				Close();
			}
		}

		private (int, int, bool, int, int) State()
		{
			return (_layout.Row, _layout.Index, _layout.Shifted, _layout.Version, _layout.Revision);
		}

		private void Navigate()
		{
			if (Moved("JoyDPadLeft", "JoyLStickLeft"))
			{
				_layout.MoveHorizontal(-1);
			}
			if (Moved("JoyDPadRight", "JoyLStickRight"))
			{
				_layout.MoveHorizontal(1);
			}
			if (Moved("JoyDPadUp", "JoyLStickUp"))
			{
				_layout.MoveVertical(-1);
			}
			if (Moved("JoyDPadDown", "JoyLStickDown"))
			{
				_layout.MoveVertical(1);
			}
			_session.DismissAccentsOnNavigation();
		}

		private bool Moved(string dpad, string stick)
		{
			if (!_gamepad.Repeated(dpad))
			{
				return _gamepad.Repeated(stick);
			}
			return true;
		}

		private void Edit()
		{
			if (_gamepad.Pressed("JoyLTrigger"))
			{
				_layout.Shifted = !_layout.Shifted;
			}
			if (_gamepad.Pressed("JoyRTrigger"))
			{
				_session.ToggleChoices();
			}
			if (_gamepad.Repeated("JoyButtonX"))
			{
				_session.B