Decompiled source of REPO JP TranslationAndFont Updated v4.1.0

REPOJPTranslationAndFontUpdated.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using REPOJapaneseTranslation.Localization;
using REPOJapaneseTranslation.Patches;
using TMPro;
using UnityEngine;
using UnityEngine.TextCore;
using UnityEngine.TextCore.LowLevel;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("LocalBuild")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Japanese localization and Checkpoint Revenge font mod for R.E.P.O. v0.4.4.")]
[assembly: AssemblyFileVersion("4.1.0.0")]
[assembly: AssemblyInformationalVersion("4.1.0")]
[assembly: AssemblyProduct("REPO JP Translation and Font Updated")]
[assembly: AssemblyTitle("REPOJPTranslationAndFontUpdated")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace REPOJapaneseTranslation
{
	[BepInPlugin("local.REPOJPTranslationAndFontUpdated", "REPO JP Translation and Font Updated", "4.1.0")]
	[BepInProcess("REPO.exe")]
	public sealed class Plugin : BaseUnityPlugin
	{
		private readonly Harmony _harmony = new Harmony("local.REPOJPTranslationAndFontUpdated");

		internal static Plugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		internal static ConfigEntry<bool> EnableTranslation { get; private set; }

		internal static ConfigEntry<bool> EnableJapaneseFont { get; private set; }

		internal static ConfigEntry<float> FontSizeScale { get; private set; }

		internal static ConfigEntry<float> FontLineHeightScale { get; private set; }

		internal static ConfigEntry<bool> LogUntranslated { get; private set; }

		private void Awake()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Expected O, but got Unknown
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)((Component)this).gameObject);
			EnableTranslation = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableTranslation", true, "ゲーム内テキストを日本語へ翻訳します。");
			EnableJapaneseFont = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableJapaneseFont", true, "チェックポイント★リベンジをTextMeshProへ適用します。");
			FontSizeScale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "FontSizeScale", 0.72f, new ConfigDescription("日本語フォントの表示倍率。1.0がゲーム本来のフォントサイズです。", (AcceptableValueBase)new AcceptableValueRange<float>(0.5f, 1f), Array.Empty<object>()));
			FontLineHeightScale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "FontLineHeightScale", 1.35f, new ConfigDescription("複数行テキストの行高倍率。文字が重なる場合に大きくします。", (AcceptableValueBase)new AcceptableValueRange<float>(1f, 2f), Array.Empty<object>()));
			LogUntranslated = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "LogUntranslated", false, "未翻訳テキストをBepInExログへ出力します(翻訳追加作業用)。");
			TranslationManager.Initialize(((BaseUnityPlugin)this).Info.Location);
			FontManager.Initialize(((BaseUnityPlugin)this).Info.Location);
			_harmony.PatchAll(typeof(TMPTextTranslationPatch).Assembly);
			InstallTMPComponentHooks();
			InstallUGUITextHooks();
			Log.LogInfo((object)"REPO JP Translation and Font Updated v4.1.0 を読み込みました。");
			Log.LogInfo((object)$"翻訳エントリ: {TranslationManager.TranslationCount}件");
		}

		private void InstallTMPComponentHooks()
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(typeof(TMPComponentRefreshHook), "Postfix", (Type[])null, (Type[])null);
			Type[] obj = new Type[2]
			{
				typeof(TextMeshProUGUI),
				typeof(TextMeshPro)
			};
			int num = 0;
			Type[] array = obj;
			foreach (Type type in array)
			{
				MethodInfo methodInfo2 = AccessTools.Method(type, "OnEnable", (Type[])null, (Type[])null);
				if (methodInfo2 != null)
				{
					_harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					Log.LogInfo((object)("TMP表示対象をパッチしました: " + type.Name + ".OnEnable"));
					num++;
				}
			}
			Log.LogInfo((object)$"TMP表示パッチ数: {num}");
		}

		private void InstallUGUITextHooks()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(typeof(UGUITextRefreshHook), "Postfix", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(UGUITextSetterHook), "Prefix", (Type[])null, (Type[])null);
			MethodInfo methodInfo3 = AccessTools.Method(typeof(Text), "OnEnable", (Type[])null, (Type[])null);
			MethodInfo methodInfo4 = AccessTools.PropertySetter(typeof(Text), "text");
			int num = 0;
			if (methodInfo3 != null)
			{
				_harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Log.LogInfo((object)"UGUI表示対象をパッチしました: Text.OnEnable");
				num++;
			}
			if (methodInfo4 != null)
			{
				_harmony.Patch((MethodBase)methodInfo4, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Log.LogInfo((object)"UGUI表示対象をパッチしました: Text.text");
				num++;
			}
			Log.LogInfo((object)$"UGUI表示パッチ数: {num}");
		}

		private void OnDestroy()
		{
			_harmony.UnpatchSelf();
		}

		internal bool RefreshTextComponent(TMP_Text textComponent)
		{
			if (!FontManager.ShouldProcess(textComponent))
			{
				return false;
			}
			if (!EnableTranslation.Value || string.IsNullOrEmpty(textComponent.text))
			{
				return false;
			}
			string text = TranslationManager.Translate(textComponent.text);
			bool num = text != textComponent.text;
			if (num)
			{
				textComponent.text = text;
			}
			FontManager.AdjustTranslatedLayout(textComponent, text);
			return num;
		}

		internal bool RefreshTextComponent(Text textComponent)
		{
			if (!EnableTranslation.Value || string.IsNullOrEmpty(textComponent.text))
			{
				return false;
			}
			string text = TranslationManager.Translate(textComponent.text);
			bool num = text != textComponent.text;
			if (num)
			{
				textComponent.text = text;
			}
			FontManager.AdjustTranslatedLayout(textComponent, text);
			return num;
		}
	}
	internal static class PluginInfo
	{
		public const string PLUGIN_GUID = "local.REPOJPTranslationAndFontUpdated";

		public const string PLUGIN_NAME = "REPO JP Translation and Font Updated";

		public const string PLUGIN_VERSION = "4.1.0";
	}
}
namespace REPOJapaneseTranslation.Patches
{
	[HarmonyPatch(typeof(ItemAttributes), "GetItemNameLocalized")]
	internal static class ItemAttributesLocalizedNamePatch
	{
		[HarmonyPostfix]
		private static void Postfix(ItemAttributes __instance, ref string __result)
		{
			string text = __result;
			string text2 = (((Object)(object)__instance != (Object)null && (Object)(object)__instance.item != (Object)null) ? __instance.item.itemName : null);
			if (string.IsNullOrWhiteSpace(text))
			{
				text = text2;
			}
			if (!string.IsNullOrEmpty(text))
			{
				string text3 = TranslationManager.Translate(text, logUntranslated: false);
				if (string.IsNullOrWhiteSpace(text3))
				{
					text3 = text;
				}
				if (string.IsNullOrWhiteSpace(text3))
				{
					text3 = text2;
				}
				__result = NormalizeItemName(text3);
			}
		}

		internal static string NormalizeItemName(string text)
		{
			if (string.IsNullOrEmpty(text))
			{
				return text;
			}
			return text.Replace("\r\n", " ").Replace('\r', ' ').Replace('\n', ' ')
				.Trim();
		}
	}
	[HarmonyPatch(typeof(StatsUI), "GetUpgradeDisplayName")]
	internal static class StatsUIUpgradeDisplayNamePatch
	{
		[HarmonyPostfix]
		private static void Postfix(ref string __result)
		{
			string text = __result;
			if (!string.IsNullOrWhiteSpace(text))
			{
				string text2 = TranslationManager.Translate(text, logUntranslated: false);
				if (string.IsNullOrWhiteSpace(text2))
				{
					text2 = text;
				}
				__result = ItemAttributesLocalizedNamePatch.NormalizeItemName(text2);
			}
		}
	}
	[HarmonyPatch(typeof(StatsUI), "Fetch")]
	internal static class StatsUIColumnLayoutPatch
	{
		[HarmonyPostfix]
		private static void Postfix(StatsUI __instance)
		{
			TextMeshProUGUI component = ((Component)__instance).GetComponent<TextMeshProUGUI>();
			Transform val = ((Component)__instance).transform.Find("StatsNumbers");
			TextMeshProUGUI val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<TextMeshProUGUI>() : null);
			if (!((Object)(object)component == (Object)null) && !((Object)(object)val2 == (Object)null))
			{
				((TMP_Text)val2).font = ((TMP_Text)component).font;
				((TMP_Text)val2).fontSize = ((TMP_Text)component).fontSize;
				((TMP_Text)val2).fontSizeMin = ((TMP_Text)component).fontSizeMin;
				((TMP_Text)val2).fontSizeMax = ((TMP_Text)component).fontSizeMax;
				((TMP_Text)val2).enableAutoSizing = false;
				((TMP_Text)val2).enableWordWrapping = false;
				((TMP_Text)val2).overflowMode = (TextOverflowModes)0;
				((TMP_Text)val2).lineSpacing = ((TMP_Text)component).lineSpacing;
			}
		}
	}
	[HarmonyPatch(typeof(ItemInfoUI), "ItemInfoText")]
	internal static class ItemInfoUITranslationPatch
	{
		[HarmonyPrefix]
		private static void Prefix(ref string message)
		{
			message = TranslationManager.Translate(message, logUntranslated: false);
		}
	}
	[HarmonyPatch(typeof(ItemInfoUI), "Update")]
	internal static class ItemInfoUIPositionPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ItemInfoUI __instance)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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)
			if (!((Object)(object)((SemiUI)__instance).textRectTransform == (Object)null))
			{
				Vector3 localPosition = ((SemiUI)__instance).textRectTransform.localPosition;
				localPosition.y += 3f;
				((SemiUI)__instance).textRectTransform.localPosition = localPosition;
			}
		}
	}
	[HarmonyPatch(typeof(ItemInfoExtraUI), "ItemInfoText")]
	internal static class ItemInfoExtraUITranslationPatch
	{
		[HarmonyPrefix]
		private static void Prefix(ref string message)
		{
			message = TranslationManager.Translate(message, logUntranslated: false);
		}
	}
	[HarmonyPatch(typeof(ArenaMessageUI), "ArenaText")]
	internal static class ArenaMessageUITranslationPatch
	{
		[HarmonyPrefix]
		private static void Prefix(ref string message)
		{
			message = TranslationManager.Translate(message, logUntranslated: false);
		}
	}
	[HarmonyPatch(typeof(ArenaMessageWinUI), "ArenaText")]
	internal static class ArenaMessageWinUITranslationPatch
	{
		[HarmonyPrefix]
		private static void Prefix(ref string message)
		{
			message = TranslationManager.Translate(message, logUntranslated: false);
		}
	}
	[HarmonyPatch(typeof(MenuButton), "Awake")]
	internal static class MenuButtonTranslationPatch
	{
		[HarmonyPrefix]
		private static void Prefix()
		{
			FontManager.SuppressTMPTranslation = true;
		}

		[HarmonyPostfix]
		private static void Postfix(MenuButton __instance)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			FontManager.SuppressTMPTranslation = false;
			if ((Object)__instance == (Object)null)
			{
				return;
			}
			TextMeshProUGUI componentInChildren = ((Component)__instance).GetComponentInChildren<TextMeshProUGUI>();
			if (string.Equals(__instance.buttonTextString, "BUTTON", StringComparison.Ordinal))
			{
				if (!((Object)componentInChildren == (Object)null) && string.Equals(((TMP_Text)componentInChildren).text, "BUTTON", StringComparison.Ordinal))
				{
					((TMP_Text)componentInChildren).text = string.Empty;
				}
			}
			else if (!string.IsNullOrEmpty(__instance.buttonTextString) && !((Object)componentInChildren == (Object)null))
			{
				string text = TranslationManager.Translate(__instance.buttonTextString);
				((TMP_Text)componentInChildren).text = text;
			}
		}

		[HarmonyFinalizer]
		private static Exception Finalizer(Exception __exception)
		{
			FontManager.SuppressTMPTranslation = false;
			return __exception;
		}
	}
	[HarmonyPatch(typeof(MenuButton), "RegisterHover")]
	internal static class LobbyButtonRowAlignmentPatch
	{
		[HarmonyPrefix]
		private static void Prefix(MenuButton __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)__instance == (Object)null)
			{
				return;
			}
			string text = TranslationManager.Translate(__instance.buttonTextString);
			string text2;
			if (text == "招待")
			{
				text2 = "カスタマイズ";
			}
			else
			{
				if (text != "はじめる")
				{
					return;
				}
				text2 = "退室";
			}
			MenuPage componentInParent = ((Component)__instance).GetComponentInParent<MenuPage>();
			if ((Object)componentInParent == (Object)null)
			{
				return;
			}
			MenuButton[] componentsInChildren = ((Component)componentInParent).GetComponentsInChildren<MenuButton>(true);
			foreach (MenuButton val in componentsInChildren)
			{
				if ((Object)val != (Object)null && TranslationManager.Translate(val.buttonTextString) == text2)
				{
					RectTransform component = ((Component)__instance).GetComponent<RectTransform>();
					RectTransform component2 = ((Component)val).GetComponent<RectTransform>();
					Vector3 position = ((Transform)component).position;
					position.y = ((Transform)component2).position.y;
					((Transform)component).position = position;
					break;
				}
			}
		}
	}
	[HarmonyPatch(typeof(MenuManager), "PageOpen", new Type[]
	{
		typeof(MenuPageIndex),
		typeof(bool)
	})]
	internal static class MenuPageOpenTranslationPatch
	{
		[HarmonyPostfix]
		private static void Postfix(MenuPage __result)
		{
			MenuPageTranslator.TranslatePage(__result);
		}
	}
	[HarmonyPatch(typeof(MenuPageSaves), "SaveFileSelected")]
	internal static class MenuPageSavesSaveFileSelectedPatch
	{
		[HarmonyPostfix]
		private static void Postfix(MenuPageSaves __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Expected O, but got Unknown
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Expected O, but got Unknown
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Expected O, but got Unknown
			//IL_0174: Expected O, but got Unknown
			if ((Object)__instance == (Object)null)
			{
				return;
			}
			string newValue = TranslationManager.Translate("Total Haul:", logUntranslated: false);
			string newValue2 = TranslationManager.Translate("Current Moon:", logUntranslated: false);
			TMP_Text[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text val in componentsInChildren)
			{
				if (!((Object)val == (Object)null) && !string.IsNullOrEmpty(val.text) && FontManager.ShouldProcess(val))
				{
					string text = val.text;
					string text2 = text.Replace("Total Haul:", newValue).Replace("Current Moon:", newValue2);
					if (text2 != text)
					{
						val.text = text2;
					}
					FontManager.AdjustTranslatedLayout(val, text2);
				}
			}
			if (!((Object)__instance.saveFileHeader != (Object)null))
			{
				return;
			}
			TextMeshProUGUI saveFileHeader = __instance.saveFileHeader;
			((TMP_Text)saveFileHeader).enableWordWrapping = false;
			((TMP_Text)saveFileHeader).overflowMode = (TextOverflowModes)0;
			((TMP_Text)saveFileHeader).maxVisibleCharacters = int.MaxValue;
			float targetWidth = ((TMP_Text)saveFileHeader).GetPreferredValues(((TMP_Text)saveFileHeader).text).x + 8f;
			ExpandKeepingLeft(((TMP_Text)saveFileHeader).rectTransform, targetWidth);
			if ((Object)__instance.saveFileRenameButton != (Object)null)
			{
				RectTransform component = __instance.saveFileRenameButton.GetComponent<RectTransform>();
				ExpandKeepingLeft(component, targetWidth);
				MenuButton component2 = __instance.saveFileRenameButton.GetComponent<MenuButton>();
				if ((Object)component2 != (Object)null && (Object)component2.rectTransformSelection != (Object)null && (Object)component2.rectTransformSelection != (Object)component)
				{
					ExpandKeepingLeft(component2.rectTransformSelection, targetWidth);
				}
			}
			((TMP_Text)saveFileHeader).ForceMeshUpdate(true, true);
		}

		private static void ExpandKeepingLeft(RectTransform rectTransform, float targetWidth)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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)
			if (!((Object)rectTransform == (Object)null))
			{
				Rect rect = rectTransform.rect;
				if (!(targetWidth <= ((Rect)(ref rect)).width))
				{
					rect = rectTransform.rect;
					float num = targetWidth - ((Rect)(ref rect)).width;
					Vector2 anchoredPosition = rectTransform.anchoredPosition;
					anchoredPosition.x += num * rectTransform.pivot.x;
					rectTransform.SetSizeWithCurrentAnchors((Axis)0, targetWidth);
					rectTransform.anchoredPosition = anchoredPosition;
				}
			}
		}
	}
	[HarmonyPatch(typeof(MenuPage), "Start")]
	internal static class MenuPageStartTranslationPatch
	{
		[HarmonyPostfix]
		private static void Postfix(MenuPage __instance)
		{
			MenuPageTranslator.TranslatePage(__instance);
		}
	}
	internal static class MenuPageTranslator
	{
		internal static void TranslatePage(MenuPage? menuPage)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if (!((Object)menuPage == (Object)null))
			{
				menuPage.menuHeaderName = TranslationManager.Translate(menuPage.menuHeaderName, logUntranslated: false);
				TMP_Text[] componentsInChildren = ((Component)menuPage).GetComponentsInChildren<TMP_Text>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					TranslateTextComponent(componentsInChildren[i]);
				}
			}
		}

		private static void TranslateTextComponent(TMP_Text text)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if (!((Object)text == (Object)null) && !string.IsNullOrEmpty(text.text) && FontManager.ShouldProcess(text))
			{
				string text2 = TranslationManager.Translate(text.text, logUntranslated: false);
				if (text2 != text.text)
				{
					text.text = text2;
				}
				FontManager.AdjustTranslatedLayout(text, text2);
			}
		}
	}
	[HarmonyPatch(typeof(MenuManager), "PagePopUp")]
	internal static class MenuPopUpTranslationPatch
	{
		[HarmonyPrefix]
		private static void Prefix(ref string headerText, ref string bodyText, ref string buttonText)
		{
			headerText = TranslationManager.Translate(headerText);
			bodyText = TranslationManager.Translate(bodyText);
			buttonText = TranslationManager.Translate(buttonText);
		}
	}
	[HarmonyPatch(typeof(MenuManager), "PagePopUpTwoOptions")]
	internal static class MenuTwoOptionPopUpTranslationPatch
	{
		[HarmonyPrefix]
		private static void Prefix(ref string popUpHeader, ref string popUpText, ref string option1Text, ref string option2Text)
		{
			popUpHeader = TranslationManager.Translate(popUpHeader);
			popUpText = TranslationManager.Translate(popUpText);
			option1Text = TranslationManager.Translate(option1Text);
			option2Text = TranslationManager.Translate(option2Text);
		}
	}
	internal static class SkipPromptInputTagResolver
	{
		internal static void Resolve(TMP_Text skipText)
		{
			if (!((Object)(object)skipText == (Object)null) && !((Object)(object)InputManager.instance == (Object)null) && !string.IsNullOrEmpty(skipText.text) && skipText.text.IndexOf("[menu]", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				string text = InputManager.instance.InputDisplayReplaceTags(skipText.text, "<color=#FF8500><u><b>", "</b></u></color>");
				if (!string.Equals(text, skipText.text, StringComparison.Ordinal))
				{
					skipText.text = text;
				}
			}
		}
	}
	[HarmonyPatch(typeof(MoonUI), "StateStart")]
	internal static class MoonUISkipPromptInputTagPatch
	{
		[HarmonyPostfix]
		private static void Postfix(MoonUI __instance)
		{
			SkipPromptInputTagResolver.Resolve((TMP_Text)(object)__instance.skipText);
		}
	}
	[HarmonyPatch(typeof(ResultScreenUI), "StateFadeIn")]
	internal static class ResultScreenUISkipPromptInputTagPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ResultScreenUI __instance)
		{
			SkipPromptInputTagResolver.Resolve((TMP_Text)(object)__instance.skipText);
		}
	}
	internal static class TMPComponentRefreshHook
	{
		private static bool s_loggedFirstComponent;

		internal static void Postfix(TMP_Text __instance)
		{
			if (!s_loggedFirstComponent)
			{
				s_loggedFirstComponent = true;
				Plugin.Log.LogInfo((object)("TMP表示コンポーネントを検出しました: " + ((object)__instance).GetType().Name));
			}
			Plugin.Instance.RefreshTextComponent(__instance);
		}
	}
	[HarmonyPatch]
	internal static class TMPFontPatch
	{
		[HarmonyPatch(typeof(RunManager), "Awake")]
		[HarmonyPostfix]
		private static void ApplyFontAfterSceneLoad()
		{
			FontManager.ApplyToAllTextComponents();
		}
	}
	[HarmonyPatch]
	internal static class TMPTextTranslationPatch
	{
		[HarmonyTargetMethods]
		private static IEnumerable<MethodBase> TargetMethods()
		{
			MethodInfo methodInfo = AccessTools.PropertySetter(typeof(TMP_Text), "text");
			if (methodInfo != null)
			{
				yield return methodInfo;
			}
			foreach (MethodInfo declaredMethod in AccessTools.GetDeclaredMethods(typeof(TMP_Text)))
			{
				if (!(declaredMethod.Name != "SetText"))
				{
					ParameterInfo[] parameters = declaredMethod.GetParameters();
					if (parameters.Length != 0 && !(parameters[0].ParameterType != typeof(string)))
					{
						yield return declaredMethod;
					}
				}
			}
		}

		[HarmonyPrefix]
		private static void TranslateText(TMP_Text __instance, ref string __0)
		{
			if (!FontManager.SuppressTMPTranslation && FontManager.ShouldProcess(__instance))
			{
				__0 = TranslationManager.Translate(__0);
				__0 = FontManager.NormalizeTranslatedMarkup(__instance, __0);
				FontManager.AdjustTranslatedLayout(__instance, __0);
			}
		}
	}
	[HarmonyPatch(typeof(TruckScreenText), "UpdateTaxmanNickname")]
	internal static class TruckScreenTextUpdateTaxmanNicknamePatch
	{
		[HarmonyPrefix]
		private static void Prefix(ref string newName)
		{
			newName = TranslationManager.Translate(newName, logUntranslated: false);
		}
	}
	[HarmonyPatch(typeof(TuckScreenLocked), "LockChatToggle")]
	internal static class TuckScreenLockedLockChatTogglePatch
	{
		[HarmonyPrefix]
		private static void Prefix(ref string _lockedText)
		{
			_lockedText = TranslationManager.Translate(_lockedText, logUntranslated: false);
		}
	}
	internal static class UGUITextRefreshHook
	{
		private static bool s_loggedFirstComponent;

		internal static void Postfix(Text __instance)
		{
			if (!s_loggedFirstComponent)
			{
				s_loggedFirstComponent = true;
				Plugin.Log.LogInfo((object)"UGUI Textコンポーネントを検出しました。");
			}
			Plugin.Instance.RefreshTextComponent(__instance);
		}
	}
	internal static class UGUITextSetterHook
	{
		internal static void Prefix(Text __instance, ref string __0)
		{
			__0 = TranslationManager.Translate(__0);
			FontManager.AdjustTranslatedLayout(__instance, __0);
		}
	}
}
namespace REPOJapaneseTranslation.Localization
{
	internal static class FontManager
	{
		private readonly struct LayoutProfile
		{
			internal float Scale { get; }

			internal float MinimumScale { get; }

			internal bool AllowWrapping { get; }

			internal bool AutoSizing { get; }

			internal float AdditionalLineSpacing { get; }

			internal bool ConstrainToBounds { get; }

			internal float AbsoluteSize { get; }

			internal LayoutProfile(float scale, float minimumScale, bool allowWrapping, bool autoSizing = true, float additionalLineSpacing = 0f, bool constrainToBounds = false, float absoluteSize = 0f)
			{
				Scale = scale;
				MinimumScale = minimumScale;
				AllowWrapping = allowWrapping;
				AutoSizing = autoSizing;
				AdditionalLineSpacing = additionalLineSpacing;
				ConstrainToBounds = constrainToBounds;
				AbsoluteSize = absoluteSize;
			}
		}

		private readonly struct TMPFontState
		{
			private WeakReference<TMP_Text> Owner { get; }

			internal TMP_FontAsset Font { get; }

			internal float FontSize { get; }

			internal float FontSizeMin { get; }

			internal float FontSizeMax { get; }

			internal bool AutoSizing { get; }

			internal bool WordWrapping { get; }

			internal TextOverflowModes Overflow { get; }

			internal float LineSpacing { get; }

			internal TMPFontState(TMP_Text component)
			{
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				Owner = new WeakReference<TMP_Text>(component);
				Font = component.font;
				FontSize = component.fontSize;
				FontSizeMin = component.fontSizeMin;
				FontSizeMax = component.fontSizeMax;
				AutoSizing = component.enableAutoSizing;
				WordWrapping = component.enableWordWrapping;
				Overflow = component.overflowMode;
				LineSpacing = component.lineSpacing;
			}

			internal bool Matches(TMP_Text component)
			{
				if (Owner.TryGetTarget(out TMP_Text target))
				{
					return (Object)(object)target == (Object)(object)component;
				}
				return false;
			}

			internal void Restore(TMP_Text component)
			{
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				component.font = Font;
				component.fontSize = FontSize;
				component.fontSizeMin = FontSizeMin;
				component.fontSizeMax = FontSizeMax;
				component.enableAutoSizing = AutoSizing;
				component.enableWordWrapping = WordWrapping;
				component.overflowMode = Overflow;
				component.lineSpacing = LineSpacing;
			}
		}

		private readonly struct UGUIFontState
		{
			private WeakReference<Text> Owner { get; }

			internal Font Font { get; }

			internal int FontSize { get; }

			internal int MinSize { get; }

			internal int MaxSize { get; }

			internal bool BestFit { get; }

			internal HorizontalWrapMode Overflow { get; }

			internal UGUIFontState(Text component)
			{
				//IL_004a: 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)
				Owner = new WeakReference<Text>(component);
				Font = component.font;
				FontSize = component.fontSize;
				MinSize = component.resizeTextMinSize;
				MaxSize = component.resizeTextMaxSize;
				BestFit = component.resizeTextForBestFit;
				Overflow = component.horizontalOverflow;
			}

			internal bool Matches(Text component)
			{
				if (Owner.TryGetTarget(out Text target))
				{
					return (Object)(object)target == (Object)(object)component;
				}
				return false;
			}

			internal void Restore(Text component)
			{
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				component.font = Font;
				component.fontSize = FontSize;
				component.resizeTextMinSize = MinSize;
				component.resizeTextMaxSize = MaxSize;
				component.resizeTextForBestFit = BestFit;
				component.horizontalOverflow = Overflow;
			}
		}

		private const string FontResourceName = "REPOJapaneseTranslation.fonts.CP_Revenge.ttf";

		private const string FontEnginePatchId = "local.REPOJPTranslationAndFontUpdated.FontEngine";

		private static readonly Dictionary<Font, byte[]> s_fontBytesByDummyFont = new Dictionary<Font, byte[]>();

		private static readonly Dictionary<int, TMPFontState> s_originalTMPStates = new Dictionary<int, TMPFontState>();

		private static readonly Dictionary<int, UGUIFontState> s_originalUGUIStates = new Dictionary<int, UGUIFontState>();

		private static readonly HashSet<string> s_compactTitles = new HashSet<string>(StringComparer.Ordinal)
		{
			"ゲームプレイ", "グラフィックス", "オーディオ", "コントロール", "パスワード", "ロビー", "メインメニュー", "警告", "自爆", "ランダム",
			"プリセット", "セーブをロード", "ゲームをホストする", "設定を初期化", "デフォルト設定にリセット"
		};

		private static readonly HashSet<string> s_dialogButtons = new HashSet<string>(StringComparer.Ordinal) { "はい", "はい!", "いいえ", "いいえ…", "戻る", "続ける", "スキップ", "わかりました", "セーブをロード", "セーブを削除" };

		private static readonly HashSet<string> s_uniformMenuItems = new HashSet<string>(StringComparer.Ordinal)
		{
			"プライベート", "パブリック", "プライベートゲーム", "パブリックゲーム", "フレンドに参加", "シングルプレイ", "シングルプレイモード", "チュートリアル", "続ける", "カスタマイズ",
			"変更", "設定", "はじめる", "閉じる", "自爆", "メインメニュー", "タイトルに戻る", "ゲームを終わる", "ゲームを終了する"
		};

		private static readonly HashSet<string> s_settingsRows = new HashSet<string>(StringComparer.Ordinal)
		{
			"ヒント", "プレイヤー名", "光感受性", "光過敏症設定", "クモ恐怖症", "照準感度", "エイム感度", "カメラスムージング", "カメラの滑らかさ", "カメラシェイク",
			"カメラの揺れ", "シャドウ距離", "モーションブラー", "レンズ歪み", "ブルーム", "色収差", "グレイン", "グリッチループ", "ピクセル化", "すべての音量",
			"音楽音量", "BGM", "効果音", "効果音音量", "近接音声", "近接ボイス音量", "読み上げ", "マイク音量", "プッシュトゥトーク", "掴む",
			"回転", "押す", "引く", "ウィンドウモード", "垂直同期", "ガンマ", "最大FPS", "ライト距離", "シャドウ品質", "シャドウ距離",
			"マスター音量", "テキスト読み上げ音量", "オン", "オフ", "デフォルト", "フルスクリーン", "ウィンドウ", "ボーダーレス", "低", "中",
			"高", "最高"
		};

		private static readonly HashSet<string> s_extractionStatusLabels = new HashSet<string>(StringComparer.Ordinal) { "アクティブ", "準備完了", "未準備", "回収中", "完了", "回収ポイントが起動した", "回収ポイント完了" };

		private static readonly HashSet<string> s_settingsNavigationItems = new HashSet<string>(StringComparer.Ordinal) { "ゲームプレイ", "グラフィック", "グラフィックス", "音声", "オーディオ", "コントロール", "操作", "戻る" };

		private static readonly HashSet<string> s_settingsPageTitles = new HashSet<string>(StringComparer.Ordinal) { "ゲームプレイ", "グラフィック", "グラフィックス", "音声", "オーディオ", "コントロール", "操作" };

		private static readonly HashSet<string> s_controlSectionTitles = new HashSet<string>(StringComparer.Ordinal) { "移動", "掴み動作", "その他", "プレイヤー表情" };

		private static readonly HashSet<string> s_controlRows = new HashSet<string>(StringComparer.Ordinal)
		{
			"前", "前進", "左", "後", "後退", "右", "右移動", "ジャンプ", "しゃがむ", "スプリント",
			"転がる", "掴み", "回転", "押す", "引く", "引っぱる", "インベントリ1", "インベントリ2", "インベントリ3", "マップ",
			"インタラクト", "チャット", "次の観戦", "前の観戦", "プッシュトゥトーク", "表情 - 目を閉じる", "表情 - 怪しむ", "表情 - 悲しみ", "表情 - 怒り", "表情 - クレイジー",
			"表情 - 幸せ"
		};

		private static TMP_FontAsset? s_checkpointFont;

		private static Font? s_checkpointUnityFont;

		private static bool s_initialized;

		private static bool s_fontEnginePatched;

		internal static bool SuppressTMPTranslation { get; set; }

		internal static void Initialize(string pluginLocation)
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			if (s_initialized)
			{
				return;
			}
			s_initialized = true;
			if (!Plugin.EnableJapaneseFont.Value)
			{
				return;
			}
			try
			{
				using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("REPOJapaneseTranslation.fonts.CP_Revenge.ttf");
				if (stream == null)
				{
					Plugin.Log.LogError((object)"埋め込みフォントが見つかりません: REPOJapaneseTranslation.fonts.CP_Revenge.ttf");
					return;
				}
				byte[] array = new byte[stream.Length];
				int num;
				for (int i = 0; i < array.Length; i += num)
				{
					num = stream.Read(array, i, array.Length - i);
					if (num == 0)
					{
						throw new EndOfStreamException("埋め込みフォントを最後まで読み取れませんでした。");
					}
				}
				PatchFontEngine();
				s_checkpointFont = CreateFontAsset(array);
				if ((Object)s_checkpointFont == (Object)null)
				{
					Plugin.Log.LogError((object)"チェックポイント★リベンジのTMPフォント生成に失敗しました。");
					return;
				}
				ApplyToAllTextComponents();
				Plugin.Log.LogInfo((object)$"チェックポイント★リベンジを読み込みました (埋め込み未改変TTF ({array.Length:N0} bytes))。");
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"フォント初期化に失敗しました: {arg}");
			}
		}

		internal static void ApplyToText(TMP_Text? textComponent)
		{
			if (ShouldProcess(textComponent) && ContainsJapanese(textComponent.text))
			{
				AdjustTranslatedLayout(textComponent, textComponent.text);
			}
		}

		internal static bool ShouldProcess(TMP_Text? textComponent)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)textComponent == (Object)null)
			{
				return false;
			}
			if (IsPlayerNameText(textComponent))
			{
				return false;
			}
			string text = GetHierarchyPath(textComponent.transform).ToLowerInvariant();
			return !text.Contains("monitor") && !text.Contains("truckscreen") && (!text.Contains("truck") || !text.Contains("screen"));
		}

		private static bool IsPlayerNameText(TMP_Text component)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_001b: 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_002b: Expected O, but got Unknown
			//IL_002b: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_005a: Expected O, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_0089: Expected O, but got Unknown
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			//IL_00cd: Expected O, but got Unknown
			//IL_00ef: 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_00ff: Expected O, but got Unknown
			//IL_00ff: Expected O, but got Unknown
			MenuPlayerListed componentInParent = ((Component)component).GetComponentInParent<MenuPlayerListed>();
			if ((Object)componentInParent != (Object)null && (Object)componentInParent.playerName == (Object)component)
			{
				return true;
			}
			WorldSpaceUIPlayerName componentInParent2 = ((Component)component).GetComponentInParent<WorldSpaceUIPlayerName>();
			if ((Object)componentInParent2 != (Object)null && (Object)componentInParent2.text == (Object)component)
			{
				return true;
			}
			LobbyChatUI componentInParent3 = ((Component)component).GetComponentInParent<LobbyChatUI>();
			if ((Object)componentInParent3 != (Object)null && (Object)componentInParent3.spectateName == (Object)component)
			{
				return true;
			}
			if ((Object)((Component)component).GetComponentInParent<SpectateNameUI>() != (Object)null)
			{
				return true;
			}
			PlayerListDisplay componentInParent4 = ((Component)component).GetComponentInParent<PlayerListDisplay>();
			if ((Object)componentInParent4 != (Object)null && (Object)componentInParent4.playerListText == (Object)component)
			{
				return true;
			}
			MenuPageSaves componentInParent5 = ((Component)component).GetComponentInParent<MenuPageSaves>();
			if ((Object)componentInParent5 != (Object)null)
			{
				return (Object)componentInParent5.saveFileInfoRow3 == (Object)component;
			}
			return false;
		}

		internal static void ApplyToText(Text? textComponent)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)textComponent != (Object)null && ContainsJapanese(textComponent.text))
			{
				AdjustTranslatedLayout(textComponent, textComponent.text);
			}
		}

		internal static void ApplyToAllTextComponents()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			if ((Object)s_checkpointFont == (Object)null)
			{
				return;
			}
			TMP_Text[] array = Object.FindObjectsOfType<TMP_Text>(true);
			TMP_Text[] array2 = array;
			foreach (TMP_Text textComponent in array2)
			{
				if (ShouldProcess(textComponent))
				{
					ApplyToText(textComponent);
				}
			}
			Plugin.Log.LogDebug((object)$"{array.Length}個のTMPテキストを確認しました。");
		}

		internal static void AdjustTranslatedLayout(TMP_Text textComponent, string translatedText)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			if (!Plugin.EnableJapaneseFont.Value || (Object)s_checkpointFont == (Object)null || !ShouldProcess(textComponent))
			{
				return;
			}
			int instanceID = ((Object)textComponent).GetInstanceID();
			if (!s_originalTMPStates.TryGetValue(instanceID, out var value) || !value.Matches(textComponent))
			{
				value = new TMPFontState(textComponent);
				s_originalTMPStates[instanceID] = value;
			}
			if (!ContainsJapanese(translatedText))
			{
				value.Restore(textComponent);
				if (IsSettingsHierarchy(GetHierarchyPath(textComponent.transform)) && ContainsDigit(translatedText))
				{
					ApplyOriginalFontScale(textComponent, value, 0.78f);
				}
				return;
			}
			LayoutProfile layoutProfile = ResolveProfile(textComponent, translatedText);
			textComponent.font = s_checkpointFont;
			textComponent.enableAutoSizing = layoutProfile.AutoSizing;
			float val = ((layoutProfile.AbsoluteSize > 0f) ? layoutProfile.AbsoluteSize : (value.FontSize * layoutProfile.Scale));
			float val2 = ((layoutProfile.AbsoluteSize > 0f) ? layoutProfile.AbsoluteSize : (value.FontSizeMax * layoutProfile.Scale));
			float val3 = ((layoutProfile.AbsoluteSize > 0f) ? (layoutProfile.AbsoluteSize * layoutProfile.MinimumScale) : (value.FontSizeMax * layoutProfile.MinimumScale));
			textComponent.fontSize = Math.Max(1f, val);
			textComponent.fontSizeMax = Math.Max(1f, val2);
			textComponent.fontSizeMin = Math.Max(1f, val3);
			textComponent.enableWordWrapping = layoutProfile.AllowWrapping;
			textComponent.overflowMode = (TextOverflowModes)layoutProfile.ConstrainToBounds;
			textComponent.lineSpacing = value.LineSpacing + layoutProfile.AdditionalLineSpacing;
		}

		internal static void AdjustTranslatedLayout(Text textComponent, string translatedText)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			if (Plugin.EnableJapaneseFont.Value && !((Object)s_checkpointUnityFont == (Object)null) && !((Object)textComponent == (Object)null))
			{
				int instanceID = ((Object)textComponent).GetInstanceID();
				if (!s_originalUGUIStates.TryGetValue(instanceID, out var value) || !value.Matches(textComponent))
				{
					value = new UGUIFontState(textComponent);
					s_originalUGUIStates[instanceID] = value;
				}
				if (!ContainsJapanese(translatedText))
				{
					value.Restore(textComponent);
					return;
				}
				float num = ResolveUGUIScale(translatedText);
				textComponent.font = s_checkpointUnityFont;
				textComponent.fontSize = Math.Max(1, (int)Math.Round((float)value.FontSize * num));
				textComponent.resizeTextForBestFit = true;
				textComponent.resizeTextMinSize = Math.Max(1, (int)Math.Round((float)value.MaxSize * 0.28f));
				textComponent.resizeTextMaxSize = Math.Max(1, (int)Math.Round((float)value.MaxSize * num));
				textComponent.horizontalOverflow = (HorizontalWrapMode)(!translatedText.Contains('\n'));
			}
		}

		private static LayoutProfile ResolveProfile(TMP_Text component, string text)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_0038: 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_004d: Expected O, but got Unknown
			//IL_004d: Expected O, but got Unknown
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			//IL_009c: Expected O, but got Unknown
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Expected O, but got Unknown
			//IL_00d9: 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_00e9: Expected O, but got Unknown
			//IL_00e9: Expected O, but got Unknown
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Expected O, but got Unknown
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Expected O, but got Unknown
			//IL_0136: Expected O, but got Unknown
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Expected O, but got Unknown
			//IL_0183: Expected O, but got Unknown
			string text2 = RemoveSimpleRichText(text).Trim();
			string text3 = GetHierarchyPath(component.transform).ToLowerInvariant();
			ItemInfoUI componentInParent = ((Component)component).GetComponentInParent<ItemInfoUI>();
			if ((Object)componentInParent != (Object)null && (Object)component.transform == (Object)((Component)componentInParent).transform)
			{
				return new LayoutProfile(1f, 0.72f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 15f);
			}
			StatsUI componentInParent2 = ((Component)component).GetComponentInParent<StatsUI>();
			if ((Object)componentInParent2 != (Object)null && (Object)component.transform == (Object)((Component)componentInParent2).transform)
			{
				return new LayoutProfile(1f, 0.72f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 20f);
			}
			MoonAttributeUI componentInParent3 = ((Component)component).GetComponentInParent<MoonAttributeUI>();
			if ((Object)componentInParent3 != (Object)null && (Object)componentInParent3.text == (Object)component)
			{
				return new LayoutProfile(1f, 0.45f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: false, 10f);
			}
			MenuElementMoonAttribute componentInParent4 = ((Component)component).GetComponentInParent<MenuElementMoonAttribute>();
			if ((Object)componentInParent4 != (Object)null && (Object)componentInParent4.text == (Object)component)
			{
				return new LayoutProfile(1f, 0.45f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 10f);
			}
			ExtractionPoint componentInParent5 = ((Component)component).GetComponentInParent<ExtractionPoint>();
			if ((Object)componentInParent5 != (Object)null && (Object)componentInParent5.tubeScreenText == (Object)component)
			{
				return new LayoutProfile(0.55f, 0.42f, allowWrapping: false, autoSizing: false);
			}
			if (text2 == "モード: 強" || text2 == "モード: 弱")
			{
				return new LayoutProfile(1f, 0.78f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 10f);
			}
			if (IsExtractionHierarchy(text3) && s_extractionStatusLabels.Contains(text2))
			{
				return new LayoutProfile(0.36f, 0.28f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true);
			}
			bool flag = IsSettingsHierarchy(text3);
			bool flag2 = IsLeftSideOfScreen(component);
			bool flag3 = text3.Contains("lobby");
			bool flag4 = IsLowerHalfOfScreen(component);
			if (s_settingsNavigationItems.Contains(text2) && flag2 && (flag || text2 == "操作"))
			{
				return new LayoutProfile(1f, 0.78f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 15f);
			}
			if (s_settingsPageTitles.Contains(text2) && flag && !flag2)
			{
				return new LayoutProfile(1f, 0.78f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 15f);
			}
			if (text2 == "設定" && !flag3 && flag4)
			{
				return new LayoutProfile(1f, 0.78f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 18f);
			}
			if (text2 == "設定" && flag && !flag3)
			{
				return new LayoutProfile(1f, 0.78f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 14f);
			}
			if (text2 == "デフォルト設定にリセット" && flag)
			{
				return new LayoutProfile(1f, 0.78f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 15f);
			}
			if (flag3 && text2 == "Tを押してチャット")
			{
				return new LayoutProfile(1f, 0.72f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 8f);
			}
			if (text2 == "地域")
			{
				return new LayoutProfile(1f, 0.72f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 18f);
			}
			if (text2 == "最適な地域を選択する")
			{
				return new LayoutProfile(1f, 0.72f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 11f);
			}
			if (flag3)
			{
				switch (text2)
				{
				case "カスタマイズ":
				case "退室":
				case "設定":
				case "招待":
				case "はじめる":
					return new LayoutProfile(1f, 0.72f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 18f);
				}
			}
			if (IsFocusMissionHudText(text3, text2))
			{
				return new LayoutProfile(1f, 0.78f, allowWrapping: true, autoSizing: false, 2f, constrainToBounds: false, 10f);
			}
			switch (text2)
			{
			case "パスワード":
				return new LayoutProfile(1f, 0.72f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 24f);
			case "ロビー":
				return new LayoutProfile(0.46f, 0.23f, allowWrapping: false);
			case "セーブをロード":
				return new LayoutProfile(0.52f, 0.26f, allowWrapping: false);
			case "光敏感性発作についての警告":
			case "光過敏症の警告":
				return new LayoutProfile(0.62f, 0.52f, allowWrapping: true, autoSizing: false, 12f);
			case "サーバー一覧":
				return new LayoutProfile(1f, 0.72f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 15f);
			default:
				if (text2.StartsWith("このゲームには点滅する光が含まれています。", StringComparison.Ordinal) || text2.StartsWith("<このゲームには光の点滅表現が含まれています>", StringComparison.Ordinal))
				{
					return new LayoutProfile(0.65f, 0.54f, allowWrapping: true, autoSizing: false, 14f);
				}
				if (text2.StartsWith("一部の方は、光のパターンや点滅する光", StringComparison.Ordinal) || text2.StartsWith("一部の人は光や点滅や模様に晒されると", StringComparison.Ordinal))
				{
					return new LayoutProfile(0.58f, 0.46f, allowWrapping: true, autoSizing: false, 24f);
				}
				if (text2 == "メニュー")
				{
					return new LayoutProfile(0.4f, 0.28f, allowWrapping: false);
				}
				if (s_uniformMenuItems.Contains(text2))
				{
					return new LayoutProfile(1f, 0.78f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 20f);
				}
				if (text2.StartsWith("総回収額:", StringComparison.Ordinal) || text2.StartsWith("現在の月:", StringComparison.Ordinal))
				{
					return new LayoutProfile(0.68f, 0.48f, allowWrapping: false);
				}
				switch (text2)
				{
				case "(クリックして名前変更)":
					return new LayoutProfile(0.52f, 0.36f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true);
				case "シングルプレイモード":
					return new LayoutProfile(0.44f, 0.3f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true);
				case "ウィンドウモード":
					return new LayoutProfile(0.23f, 0.16f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true);
				case "モーションブラー":
					return new LayoutProfile(0.24f, 0.16f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true);
				case "カメラの滑らかさ":
				case "カメラスムージング":
					return new LayoutProfile(0.22f, 0.15f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true);
				case "カメラアニメーション":
				case "カメラの動き":
					return new LayoutProfile(0.22f, 0.15f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true);
				case "アンチエイリアシング":
					return new LayoutProfile(0.22f, 0.15f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true);
				case "リッチプレゼンス":
					return new LayoutProfile(0.22f, 0.15f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true);
				case "アイテム自動装備":
					return new LayoutProfile(0.22f, 0.15f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true);
				case "オフ":
				case "オン":
					return new LayoutProfile(0.48f, 0.34f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true);
				default:
				{
					if (s_controlSectionTitles.Contains(text2))
					{
						return new LayoutProfile(1f, 0.72f, allowWrapping: false, autoSizing: false, 0f, constrainToBounds: false, 14f);
					}
					if (s_settingsRows.Contains(text2) || s_controlRows.Contains(text2))
					{
						return new LayoutProfile(1f, 0.72f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true, 10f);
					}
					if (IsControlHierarchy(text3))
					{
						return new LayoutProfile(1f, 0.58f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true, 10f);
					}
					if (text2 == "プリセット")
					{
						return new LayoutProfile(0.82f, 0.58f, allowWrapping: false);
					}
					if (text2 == "確認")
					{
						return new LayoutProfile(0.95f, 0.66f, allowWrapping: false);
					}
					if (text2.StartsWith("マイク", StringComparison.Ordinal))
					{
						return new LayoutProfile(1f, 0.5f, allowWrapping: false, autoSizing: true, 0f, constrainToBounds: true, 9f);
					}
					if (s_dialogButtons.Contains(text2))
					{
						return new LayoutProfile(0.58f, 0.3f, allowWrapping: false);
					}
					if (s_compactTitles.Contains(text2))
					{
						return new LayoutProfile(0.52f, 0.25f, allowWrapping: false);
					}
					bool flag5 = text3.Contains("popup") || text3.Contains("dialog") || text3.Contains("confirm") || text3.Contains("warning");
					bool flag6 = flag;
					bool num = text3.Contains("password");
					bool flag7 = text3.Contains("lobby");
					bool flag8 = text3.Contains("save");
					if (num)
					{
						return new LayoutProfile(0.5f, 0.24f, text.Contains('\n'));
					}
					if (flag7)
					{
						return new LayoutProfile(0.5f, 0.24f, text.Contains('\n'));
					}
					if (flag8)
					{
						return new LayoutProfile(0.62f, 0.34f, text.Length > 18 || text.Contains('\n'));
					}
					if (flag6)
					{
						return new LayoutProfile(0.24f, 0.14f, text.Length > 20 || text.Contains('\n'), autoSizing: true, 0f, constrainToBounds: true);
					}
					if (flag5)
					{
						return new LayoutProfile(0.45f, 0.2f, allowWrapping: true, autoSizing: true, 0f, constrainToBounds: true);
					}
					if (text.Contains('\n') || text2.Length >= 18)
					{
						return new LayoutProfile(0.46f, 0.2f, allowWrapping: true, autoSizing: true, 0f, constrainToBounds: true);
					}
					return new LayoutProfile(Plugin.FontSizeScale.Value, 0.28f, allowWrapping: false);
				}
				}
			}
		}

		private static float ResolveUGUIScale(string text)
		{
			string text2 = RemoveSimpleRichText(text).Trim();
			if (s_dialogButtons.Contains(text2))
			{
				return 0.58f;
			}
			if (s_settingsRows.Contains(text2))
			{
				return 0.47f;
			}
			if (s_compactTitles.Contains(text2))
			{
				return 0.52f;
			}
			if (text2.Length < 18 && !text.Contains('\n'))
			{
				return Plugin.FontSizeScale.Value;
			}
			return 0.46f;
		}

		private static bool ContainsJapanese(string? text)
		{
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			foreach (char c in text)
			{
				if ((c >= '\u3040' && c <= 'ヿ') || (c >= '㐀' && c <= '鿿') || (c >= '豈' && c <= '\ufaff') || (c >= 'ヲ' && c <= '゚'))
				{
					return true;
				}
			}
			return false;
		}

		private static bool ContainsDigit(string? text)
		{
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			for (int i = 0; i < text.Length; i++)
			{
				if (char.IsDigit(text[i]))
				{
					return true;
				}
			}
			return false;
		}

		private static bool IsSettingsHierarchy(string hierarchy)
		{
			string text = hierarchy.ToLowerInvariant();
			if (!text.Contains("setting") && !text.Contains("graphic") && !text.Contains("audio") && !text.Contains("control"))
			{
				return text.Contains("gameplay");
			}
			return true;
		}

		private static bool IsControlHierarchy(string hierarchy)
		{
			string text = hierarchy.ToLowerInvariant();
			if (!text.Contains("control") && !text.Contains("keybind"))
			{
				return text.Contains("input");
			}
			return true;
		}

		private static bool IsExtractionHierarchy(string hierarchy)
		{
			string text = hierarchy.ToLowerInvariant();
			if (!text.Contains("extraction") && !text.Contains("extractpoint"))
			{
				return text.Contains("extractionpoint");
			}
			return true;
		}

		private static bool IsLeftSideOfScreen(TMP_Text component)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_0020: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			if (Screen.width <= 0)
			{
				return false;
			}
			Canvas componentInParent = ((Component)component).GetComponentInParent<Canvas>();
			return RectTransformUtility.WorldToScreenPoint(((Object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) ? componentInParent.worldCamera : null, ((Transform)component.rectTransform).position).x <= (float)Screen.width * 0.48f;
		}

		private static bool IsLowerHalfOfScreen(TMP_Text component)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_0020: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			if (Screen.height <= 0)
			{
				return false;
			}
			Canvas componentInParent = ((Component)component).GetComponentInParent<Canvas>();
			return RectTransformUtility.WorldToScreenPoint(((Object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) ? componentInParent.worldCamera : null, ((Transform)component.rectTransform).position).y <= (float)Screen.height * 0.5f;
		}

		internal static string NormalizeTranslatedMarkup(TMP_Text component, string text)
		{
			string hierarchy = GetHierarchyPath(component.transform).ToLowerInvariant();
			string text2 = RemoveSimpleRichText(text).Trim();
			if (text2 == "パスワード")
			{
				return "<voffset=0.65em>パスワード</voffset>";
			}
			if (text2 == "サーバー一覧")
			{
				return "<voffset=-0.15em>サーバー一覧</voffset>";
			}
			if (s_controlSectionTitles.Contains(text2))
			{
				return text2;
			}
			if (!ShouldProcess(component) || !IsFocusMissionHudText(hierarchy, text2))
			{
				return text;
			}
			return RemoveSizeTags(text);
		}

		private static bool IsFocusMissionHudText(string hierarchy, string text)
		{
			if (hierarchy.Contains("uifocustext") || hierarchy.Contains("localizedfocustext") || hierarchy.Contains("focustext"))
			{
				return true;
			}
			if (!text.StartsWith("FOCUS >", StringComparison.OrdinalIgnoreCase) && !text.StartsWith("FOCUS>", StringComparison.OrdinalIgnoreCase) && !text.StartsWith("目標 >", StringComparison.Ordinal) && !text.StartsWith("目標>", StringComparison.Ordinal) && !text.StartsWith("ミッション >", StringComparison.Ordinal) && !text.StartsWith("ミッション>", StringComparison.Ordinal) && !text.StartsWith("注目 >", StringComparison.Ordinal))
			{
				return text.StartsWith("注目>", StringComparison.Ordinal);
			}
			return true;
		}

		private static string RemoveSizeTags(string text)
		{
			StringBuilder stringBuilder = new StringBuilder(text.Length);
			for (int i = 0; i < text.Length; i++)
			{
				if (text[i] == '<' && (text.AsSpan(i).StartsWith("<size=", StringComparison.OrdinalIgnoreCase) || text.AsSpan(i).StartsWith("</size>", StringComparison.OrdinalIgnoreCase)))
				{
					int num = text.IndexOf('>', i);
					if (num >= 0)
					{
						i = num;
						continue;
					}
				}
				stringBuilder.Append(text[i]);
			}
			return stringBuilder.ToString();
		}

		private static void ApplyOriginalFontScale(TMP_Text component, TMPFontState original, float scale)
		{
			component.enableAutoSizing = false;
			component.fontSize = Math.Max(1f, original.FontSize * scale);
			component.fontSizeMax = Math.Max(1f, original.FontSizeMax * scale);
			component.fontSizeMin = Math.Max(1f, original.FontSizeMax * scale * 0.65f);
			component.overflowMode = (TextOverflowModes)0;
		}

		private static string GetHierarchyPath(Transform? transform)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			if ((Object)transform == (Object)null)
			{
				return string.Empty;
			}
			string text = ((Object)transform).name;
			Transform parent = transform.parent;
			int num = 0;
			while ((Object)parent != (Object)null && num++ < 12)
			{
				text = ((Object)parent).name + "/" + text;
				parent = parent.parent;
			}
			return text;
		}

		private static string RemoveSimpleRichText(string text)
		{
			StringBuilder stringBuilder = new StringBuilder(text.Length);
			bool flag = false;
			foreach (char c in text)
			{
				if (c == '<')
				{
					flag = true;
				}
				else if (c == '>' && flag)
				{
					flag = false;
				}
				else if (!flag)
				{
					stringBuilder.Append(c);
				}
			}
			return stringBuilder.ToString();
		}

		private static TMP_FontAsset? CreateFontAsset(byte[] fontBytes)
		{
			//IL_0000: 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_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_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_003c: Expected O, but got Unknown
			//IL_003d: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_00af: 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_007b: Expected O, but got Unknown
			FontEngine.InitializeFontEngine();
			FontEngineError val = FontEngine.LoadFontFace(fontBytes);
			if ((int)val != 0)
			{
				Plugin.Log.LogError((object)$"TTFの検証に失敗しました: {val}");
				return null;
			}
			Font val2 = new Font("CP_Revenge");
			s_checkpointUnityFont = val2;
			Font val3 = val2;
			s_fontBytesByDummyFont[val3] = fontBytes;
			TMP_FontAsset val4 = TMP_FontAsset.CreateFontAsset(val3);
			if ((Object)val4 == (Object)null)
			{
				s_fontBytesByDummyFont.Remove(val3);
				s_checkpointUnityFont = null;
				Object.Destroy((Object)val3);
				return null;
			}
			((Object)val4).name = "Checkpoint Revenge Dynamic";
			val4.atlasPopulationMode = (AtlasPopulationMode)1;
			FaceInfo faceInfo = val4.faceInfo;
			((FaceInfo)(ref faceInfo)).lineHeight = ((FaceInfo)(ref faceInfo)).lineHeight * Plugin.FontLineHeightScale.Value;
			val4.faceInfo = faceInfo;
			ConfigureTextMeshProMaterial(val4);
			return val4;
		}

		private static void ConfigureTextMeshProMaterial(TMP_FontAsset fontAsset)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			Shader val = Shader.Find("TextMeshPro/Distance Field");
			if ((Object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)"TextMeshPro/Distance Fieldシェーダーが見つかりません。");
				return;
			}
			Material material = ((TMP_Asset)fontAsset).material;
			material.shader = val;
			if (material.HasProperty("_GlowColor"))
			{
				material.SetColor("_GlowColor", Color.clear);
			}
			if (material.HasProperty("_GlowPower"))
			{
				material.SetFloat("_GlowPower", 0f);
			}
		}

		private static void PatchFontEngine()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			if (!s_fontEnginePatched)
			{
				MethodInfo method = typeof(FontEngine).GetMethod("LoadFontFace", BindingFlags.Static | BindingFlags.Public, null, new Type[2]
				{
					typeof(Font),
					typeof(int)
				}, null);
				MethodInfo method2 = typeof(FontManager).GetMethod("LoadFontFacePrefix", BindingFlags.Static | BindingFlags.NonPublic);
				if (method == null || method2 == null)
				{
					throw new MissingMethodException("FontEngine.LoadFontFace(Font, int) が見つかりません。");
				}
				new Harmony("local.REPOJPTranslationAndFontUpdated.FontEngine").Patch((MethodBase)method, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				s_fontEnginePatched = true;
			}
		}

		private static bool LoadFontFacePrefix(Font font, int pointSize, ref FontEngineError __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected I4, but got Unknown
			if ((Object)font == (Object)null || !s_fontBytesByDummyFont.TryGetValue(font, out byte[] value))
			{
				return true;
			}
			__result = (FontEngineError)(int)FontEngine.LoadFontFace(value, pointSize);
			return false;
		}
	}
	internal static class TranslationManager
	{
		private sealed class TranslationTemplate
		{
			private readonly Regex _pattern;

			private readonly string _translatedTemplate;

			private readonly string[] _placeholderTokens;

			internal int SourceLength { get; }

			private TranslationTemplate(Regex pattern, string translatedTemplate, string[] placeholderTokens, int sourceLength)
			{
				_pattern = pattern;
				_translatedTemplate = translatedTemplate;
				_placeholderTokens = placeholderTokens;
				SourceLength = sourceLength;
			}

			internal static TranslationTemplate Create(string sourceTemplate, string translatedTemplate)
			{
				MatchCollection matchCollection = s_placeholderTokenRegex.Matches(sourceTemplate);
				StringBuilder stringBuilder = new StringBuilder();
				string[] array = new string[matchCollection.Count];
				stringBuilder.Append('^');
				int num = 0;
				int num2;
				for (int i = 0; i < matchCollection.Count; i++)
				{
					Match match = matchCollection[i];
					num2 = num;
					stringBuilder.Append(Regex.Escape(sourceTemplate.Substring(num2, match.Index - num2)));
					stringBuilder.Append($"(?<p{i}>.+?)");
					array[i] = match.Value;
					num = match.Index + match.Length;
				}
				num2 = num;
				stringBuilder.Append(Regex.Escape(sourceTemplate.Substring(num2, sourceTemplate.Length - num2)));
				stringBuilder.Append('$');
				return new TranslationTemplate(new Regex(stringBuilder.ToString(), RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant), translatedTemplate, array, sourceTemplate.Length);
			}

			internal bool TryTranslate(string text, out string result)
			{
				Match match = _pattern.Match(text);
				if (!match.Success)
				{
					result = text;
					return false;
				}
				Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal);
				for (int i = 0; i < _placeholderTokens.Length; i++)
				{
					string key = _placeholderTokens[i];
					if (!dictionary.ContainsKey(key))
					{
						dictionary[key] = match.Groups[$"p{i}"].Value;
					}
				}
				result = _translatedTemplate;
				foreach (KeyValuePair<string, string> item in dictionary)
				{
					item.Deconstruct(out var key2, out var value);
					string oldValue = key2;
					string newValue = value;
					result = result.Replace(oldValue, newValue, StringComparison.Ordinal);
				}
				return true;
			}
		}

		private static readonly string[] s_originalTranslationResources = new string[4] { "REPOJapaneseTranslation.original.TranslationJP_Main.txt", "REPOJapaneseTranslation.original.TranslationJP_MOD.txt", "REPOJapaneseTranslation.original.TranslationJP_Other.txt", "REPOJapaneseTranslation.original.TranslationJP_Upgrade.txt" };

		private static readonly Regex s_placeholderTokenRegex = new Regex("\\{[^{}]+\\}|\\[[^\\[\\]]+\\]", RegexOptions.Compiled | RegexOptions.CultureInvariant);

		private static readonly Regex s_actionSuffixRegex = new Regex("^(?<body>.+?)(?<suffix>\\s*(?:<[^>]+>)*\\[[^\\[\\]]+\\](?:</[^>]+>)*\\s*)$", RegexOptions.Compiled | RegexOptions.CultureInvariant);

		private static readonly Regex s_richTextSuffixRegex = new Regex("^(?<body>.+?)(?<suffix>\\s*(?:<[^>]+>)+\\s*)$", RegexOptions.Compiled | RegexOptions.CultureInvariant);

		private static readonly Regex s_labeledPrefixRegex = new Regex("^(?<leadingTags>(?:<[^>]+>)*)(?<label>[^<>]+?)(?<separator>\\s*>\\s*)(?<trailingTags>(?:</[^>]+>)*)(?<body>.+)$", RegexOptions.Compiled | RegexOptions.CultureInvariant);

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

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

		private static readonly List<TranslationTemplate> s_templates = new List<TranslationTemplate>();

		private static readonly HashSet<string> s_loggedUntranslated = new HashSet<string>(StringComparer.Ordinal);

		private static bool s_initialized;

		internal static int TranslationCount => s_translations.Count;

		internal static void Initialize(string pluginLocation)
		{
			if (s_initialized)
			{
				return;
			}
			s_initialized = true;
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			using Stream stream = executingAssembly.GetManifestResourceStream("REPOJapaneseTranslation.translations.ja.json");
			if (stream == null)
			{
				Plugin.Log.LogError((object)"埋め込みリソース 'REPOJapaneseTranslation.translations.ja.json' が見つかりません。");
				return;
			}
			using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
			LoadJson(streamReader.ReadToEnd());
			string[] array = s_originalTranslationResources;
			foreach (string resourceName in array)
			{
				LoadXUnityResource(executingAssembly, resourceName);
			}
			string path = Path.Combine(Path.GetDirectoryName(pluginLocation) ?? string.Empty, "translations.custom.json");
			if (File.Exists(path))
			{
				LoadJson(File.ReadAllText(path, Encoding.UTF8));
				Plugin.Log.LogInfo((object)"translations.custom.jsonを追加読み込みしました。");
			}
			RebuildTemplates();
			Plugin.Log.LogInfo((object)$"翻訳辞書を読み込みました: {s_translations.Count} 件");
		}

		private static void LoadXUnityResource(Assembly assembly, string resourceName)
		{
			using Stream stream = assembly.GetManifestResourceStream(resourceName);
			if (stream == null)
			{
				Plugin.Log.LogWarning((object)("原版翻訳リソースが見つかりません: " + resourceName));
				return;
			}
			using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8);
			LoadXUnityText(streamReader.ReadToEnd());
		}

		private static void LoadXUnityText(string contents)
		{
			using StringReader stringReader = new StringReader(contents);
			string text;
			while ((text = stringReader.ReadLine()) != null)
			{
				string text2 = text.TrimStart();
				if (text2.Length != 0 && !text2.StartsWith("//", StringComparison.Ordinal))
				{
					int num = FindUnescapedSeparator(text);
					if (num > 0)
					{
						string source = UnescapeXUnity(text.Substring(0, num).Trim());
						string translated = UnescapeXUnity(text.Substring(num + 1));
						AddTranslation(source, translated);
					}
				}
			}
		}

		private static int FindUnescapedSeparator(string line)
		{
			for (int i = 0; i < line.Length; i++)
			{
				if (line[i] == '=' && (i == 0 || line[i - 1] != '\\'))
				{
					return i;
				}
			}
			return -1;
		}

		private static string UnescapeXUnity(string text)
		{
			StringBuilder stringBuilder = new StringBuilder(text.Length);
			for (int i = 0; i < text.Length; i++)
			{
				char c = text[i];
				if (c != '\\' || i + 1 >= text.Length)
				{
					stringBuilder.Append(c);
					continue;
				}
				char c2 = text[++i];
				switch (c2)
				{
				case 'n':
					stringBuilder.Append('\n');
					break;
				case 'r':
					stringBuilder.Append('\r');
					break;
				case 't':
					stringBuilder.Append('\t');
					break;
				case '=':
				case '\\':
					stringBuilder.Append(c2);
					break;
				default:
					stringBuilder.Append('\\').Append(c2);
					break;
				}
			}
			return stringBuilder.ToString();
		}

		private static void LoadJson(string json)
		{
			//IL_0077: Expected O, but got Unknown
			try
			{
				Dictionary<string, string> dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
				if (dictionary == null)
				{
					return;
				}
				foreach (var (text3, translated) in dictionary)
				{
					if (!string.IsNullOrEmpty(text3) && text3[0] != '_' && !text3.StartsWith("//", StringComparison.Ordinal))
					{
						AddTranslation(text3, translated);
					}
				}
			}
			catch (JsonException ex)
			{
				JsonException ex2 = ex;
				Plugin.Log.LogError((object)("翻訳JSONのパースに失敗しました: " + ((Exception)(object)ex2).Message));
			}
		}

		private static void AddTranslation(string source, string translated)
		{
			if (!string.IsNullOrEmpty(source))
			{
				string text = NormalizeKey(source);
				string value = NormalizeTranslationValue(translated);
				s_translations[text] = value;
				s_translationsUpper[text.ToUpperInvariant()] = value;
			}
		}

		private static void RebuildTemplates()
		{
			s_templates.Clear();
			foreach (KeyValuePair<string, string> s_translation in s_translations)
			{
				if (s_placeholderTokenRegex.IsMatch(s_translation.Key))
				{
					s_templates.Add(TranslationTemplate.Create(s_translation.Key, s_translation.Value));
				}
			}
			s_templates.Sort((TranslationTemplate left, TranslationTemplate right) => right.SourceLength.CompareTo(left.SourceLength));
		}

		internal static string Translate(string text, bool logUntranslated = true)
		{
			if (!Plugin.EnableTranslation.Value || string.IsNullOrEmpty(text))
			{
				return text;
			}
			SplitOuterWhitespace(text, out string leadingWhitespace, out string coreText, out string trailingWhitespace);
			if (coreText.Length == 0)
			{
				return text;
			}
			if (TryTranslateCore(coreText, out string result))
			{
				return leadingWhitespace + result + trailingWhitespace;
			}
			if (logUntranslated && Plugin.LogUntranslated.Value && s_loggedUntranslated.Add(text))
			{
				Plugin.Log.LogInfo((object)("[未翻訳] \"" + text.Replace("\n", "\\n") + "\""));
			}
			return text;
		}

		private static bool TryTranslateCore(string text, out string result)
		{
			if (TryTranslateInlineText(text, out result))
			{
				return true;
			}
			if (TryTranslateMultilineBlock(text, out result))
			{
				return true;
			}
			result = text;
			return false;
		}

		private static bool TryTranslateInlineText(string text, out string result)
		{
			if (TryTranslateLookup(text, out result))
			{
				return true;
			}
			if (TryTranslateTemplate(text, out result))
			{
				return true;
			}
			if (TryTranslateLabeledPrefix(text, out result))
			{
				return true;
			}
			if (TryTranslateRichTextSuffix(text, out result))
			{
				return true;
			}
			if (TryTranslateActionSuffix(text, out result))
			{
				return true;
			}
			if (TryTranslatePhraseSequence(text, out result))
			{
				return true;
			}
			result = text;
			return false;
		}

		private static bool TryTranslateLookup(string text, out string result)
		{
			if (s_translations.TryGetValue(text, out result))
			{
				return true;
			}
			string text2 = NormalizeKey(text);
			if (text2 != text && s_translations.TryGetValue(text2, out result))
			{
				return true;
			}
			string key = text2.ToUpperInvariant();
			if (s_translationsUpper.TryGetValue(key, out result))
			{
				return true;
			}
			result = text;
			return false;
		}

		private static bool TryTranslateTemplate(string text, out string result)
		{
			string text2 = NormalizeKey(text);
			foreach (TranslationTemplate s_template in s_templates)
			{
				if (s_template.TryTranslate(text2, out result))
				{
					return true;
				}
			}
			result = text;
			return false;
		}

		private static bool TryTranslateLabeledPrefix(string text, out string result)
		{
			Match match = s_labeledPrefixRegex.Match(text);
			if (!match.Success)
			{
				result = text;
				return false;
			}
			string value = match.Groups["leadingTags"].Value;
			string value2 = match.Groups["label"].Value;
			string value3 = match.Groups["separator"].Value;
			string value4 = match.Groups["trailingTags"].Value;
			if (!TryTranslateCore(match.Groups["body"].Value, out string result2))
			{
				result = text;
				return false;
			}
			string result3;
			string text2 = (TryTranslateLookup(value2, out result3) ? result3 : value2);
			result = value + text2 + value3 + value4 + result2;
			return true;
		}

		private static bool TryTranslateActionSuffix(string text, out string result)
		{
			Match match = s_actionSuffixRegex.Match(text);
			if (!match.Success)
			{
				result = text;
				return false;
			}
			string value = match.Groups["body"].Value;
			string value2 = match.Groups["suffix"].Value;
			if (!TryTranslateLookup(value, out string result2) && !TryTranslateTemplate(value, out result2) && !TryTranslatePhraseSequence(value, out result2))
			{
				result = text;
				return false;
			}
			result = result2 + value2;
			return true;
		}

		private static bool TryTranslateRichTextSuffix(string text, out string result)
		{
			Match match = s_richTextSuffixRegex.Match(text);
			if (!match.Success)
			{
				result = text;
				return false;
			}
			string value = match.Groups["body"].Value;
			string value2 = match.Groups["suffix"].Value;
			if (!TryTranslateLookup(value, out string result2) && !TryTranslateTemplate(value, out result2) && !TryTranslatePhraseSequence(value, out result2))
			{
				result = text;
				return false;
			}
			result = result2 + value2;
			return true;
		}

		private static bool TryTranslateMultilineBlock(string text, out string result)
		{
			if (!text.Contains('\n'))
			{
				result = text;
				return false;
			}
			string[] array = text.Split('\n');
			bool flag = false;
			for (int i = 0; i < array.Length; i++)
			{
				string text2 = array[i];
				if (string.IsNullOrWhiteSpace(text2))
				{
					continue;
				}
				SplitOuterWhitespace(text2, out string leadingWhitespace, out string coreText, out string trailingWhitespace);
				if (coreText.Length != 0 && TryTranslateInlineText(coreText, out string result2))
				{
					string text3 = leadingWhitespace + result2 + trailingWhitespace;
					if (!(text3 == text2))
					{
						array[i] = text3;
						flag = true;
					}
				}
			}
			result = (flag ? string.Join("\n", array) : text);
			return flag;
		}

		private static bool TryTranslatePhraseSequence(string text, out string result)
		{
			result = text;
			if (!CanUsePhraseSegmentation(text))
			{
				return false;
			}
			SplitNumericPrefix(text, out string prefix, out string body);
			if (body.Length == 0)
			{
				return false;
			}
			string[] array = body.Split(' ', StringSplitOptions.RemoveEmptyEntries);
			if (array.Length < 2)
			{
				return false;
			}
			List<string> list = new List<string>();
			int matchedTokenCount;
			for (int i = 0; i < array.Length; i += matchedTokenCount)
			{
				if (!TryMatchLongestPhrase(array, i, out matchedTokenCount, out string translatedFragment))
				{
					return false;
				}
				list.Add(translatedFragment);
			}
			if (list.Count < 2)
			{
				return false;
			}
			result = prefix + string.Join("\n", list);
			return true;
		}

		private static bool TryMatchLongestPhrase(IReadOnlyList<string> tokens, int startIndex, out int matchedTokenCount, out string translatedFragment)
		{
			int val = tokens.Count - startIndex;
			for (int num = Math.Min(5, val); num >= 1; num--)
			{
				if (TryTranslateLookup(string.Join(" ", tokens, startIndex, num), out translatedFragment))
				{
					matchedTokenCount = num;
					return true;
				}
			}
			matchedTokenCount = 0;
			translatedFragment = string.Empty;
			return false;
		}

		private static bool CanUsePhraseSegmentation(string text)
		{
			bool result = false;
			foreach (char c in text)
			{
				if (char.IsLetter(c))
				{
					result = true;
				}
				else if (!char.IsDigit(c) && !char.IsWhiteSpace(c) && c != '\'' && c != '-' && c != '(' && c != ')' && c != '&')
				{
					return false;
				}
			}
			return result;
		}

		private static void SplitNumericPrefix(string text, out string prefix, out string body)
		{
			int i;
			for (i = 0; i < text.Length && char.IsDigit(text[i]); i++)
			{
			}
			if (i == 0 || i >= text.Length || !char.IsWhiteSpace(text[i]))
			{
				prefix = string.Empty;
				body = text;
				return;
			}
			for (; i < text.Length && char.IsWhiteSpace(text[i]); i++)
			{
			}
			prefix = text.Substring(0, i);
			int num = i;
			body = text.Substring(num, text.Length - num);
		}

		private static void SplitOuterWhitespace(string text, out string leadingWhitespace, out string coreText, out string trailingWhitespace)
		{
			int i;
			for (i = 0; i < text.Length && char.IsWhiteSpace(text[i]); i++)
			{
			}
			int num = text.Length - 1;
			while (num >= i && char.IsWhiteSpace(text[num]))
			{
				num--;
			}
			leadingWhitespace = text.Substring(0, i);
			string text2;
			if (i > num)
			{
				text2 = string.Empty;
			}
			else
			{
				int num2 = i;
				text2 = text.Substring(num2, num + 1 - num2);
			}
			coreText = text2;
			string text3;
			if (num + 1 >= text.Length)
			{
				text3 = string.Empty;
			}
			else
			{
				int num3 = num + 1;
				text3 = text.Substring(num3, text.Length - num3);
			}
			trailingWhitespace = text3;
		}

		private static string NormalizeKey(string text)
		{
			return text.Replace("\r\n", "\n").Trim();
		}

		private static string NormalizeTranslationValue(string text)
		{
			return text.TrimStart(' ', '\t', '\u3000');
		}
	}
}