plugins/RiskofThunder-R2API_Language/R2API.Language/R2API.Language.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Timers;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using On.RoR2;
using On.RoR2.UI;
using RoR2;
using RoR2.ConVar;
using RoR2.UI;
using SimpleJSON;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("R2API.Language")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("R2API.Language")]
[assembly: AssemblyTitle("R2API.Language")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.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 R2API
{
	internal static class ConsoleCommands
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_InitConVarsCoroutine <0>__OnConsoleInit;
		}

		private static bool _registered;

		internal static void Init()
		{
			//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_001b: Expected O, but got Unknown
			object obj = <>O.<0>__OnConsoleInit;
			if (obj == null)
			{
				hook_InitConVarsCoroutine val = OnConsoleInit;
				<>O.<0>__OnConsoleInit = val;
				obj = (object)val;
			}
			Console.InitConVarsCoroutine += (hook_InitConVarsCoroutine)obj;
		}

		internal static void Cleanup()
		{
			//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_001b: Expected O, but got Unknown
			object obj = <>O.<0>__OnConsoleInit;
			if (obj == null)
			{
				hook_InitConVarsCoroutine val = OnConsoleInit;
				<>O.<0>__OnConsoleInit = val;
				obj = (object)val;
			}
			Console.InitConVarsCoroutine -= (hook_InitConVarsCoroutine)obj;
		}

		private static IEnumerator OnConsoleInit(orig_InitConVarsCoroutine orig, Console self)
		{
			yield return orig.Invoke(self);
			RegisterCommands();
		}

		private static void RegisterCommands()
		{
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			if (_registered)
			{
				return;
			}
			_registered = true;
			Console instance = Console.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			FieldInfo field = typeof(Console).GetField("concommandCatalog", BindingFlags.Instance | BindingFlags.NonPublic);
			if (field == null)
			{
				ManualLogSource logger = LanguagePlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)"concommandCatalog field not found via reflection");
				}
				return;
			}
			Type nestedType = typeof(Console).GetNestedType("ConCommand", BindingFlags.NonPublic);
			if (nestedType == null)
			{
				ManualLogSource logger2 = LanguagePlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogWarning((object)"ConCommand nested type not found");
				}
				return;
			}
			if (!(field.GetValue(instance) is IDictionary dictionary))
			{
				ManualLogSource logger3 = LanguagePlugin.Logger;
				if (logger3 != null)
				{
					logger3.LogWarning((object)"concommandCatalog is null");
				}
				return;
			}
			FieldInfo field2 = nestedType.GetField("flags");
			FieldInfo field3 = nestedType.GetField("helpText");
			FieldInfo field4 = nestedType.GetField("action", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field4 == null)
			{
				ManualLogSource logger4 = LanguagePlugin.Logger;
				if (logger4 != null)
				{
					logger4.LogWarning((object)"ConCommand.action field not found");
				}
				return;
			}
			Type fieldType = field4.FieldType;
			int num = 0;
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			for (int i = 0; i < types.Length; i++)
			{
				MethodInfo[] methods = types[i].GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					ConCommandAttribute customAttribute = ((MemberInfo)methodInfo).GetCustomAttribute<ConCommandAttribute>();
					if (customAttribute == null)
					{
						continue;
					}
					try
					{
						object obj = Activator.CreateInstance(nestedType);
						field2?.SetValue(obj, customAttribute.flags);
						field3?.SetValue(obj, customAttribute.helpText);
						field4.SetValue(obj, Delegate.CreateDelegate(fieldType, methodInfo));
						dictionary[customAttribute.commandName.ToLower()] = obj;
						num++;
					}
					catch (Exception ex)
					{
						ManualLogSource logger5 = LanguagePlugin.Logger;
						if (logger5 != null)
						{
							logger5.LogWarning((object)("Falha ao registrar comando '" + customAttribute.commandName + "': " + ex.Message));
						}
					}
				}
			}
			if (num > 0)
			{
				ManualLogSource logger6 = LanguagePlugin.Logger;
				if (logger6 != null)
				{
					logger6.LogInfo((object)$"Console commands registered ({num}): /reloadlang, /langdebug, /langstatus");
				}
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CC_ReloadLang(ConCommandArgs args)
		{
			LanguageAPI.InvalidateDiskCache();
			LanguageAPI.ReloadAllLanguageFiles(Paths.PluginPath);
			LanguagePlugin.ReloadPeleJsonFiles();
			Debug.Log((object)"[R2API.Language] /reloadlang: todos os arquivos recarregados.");
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CC_LangDebug(ConCommandArgs args)
		{
			if (!LanguagePlugin.EnableDebugMenu)
			{
				Debug.Log((object)"[R2API.Language] /langdebug: EnableDebugMenu=false no config.");
				return;
			}
			LanguageDebugUI.Toggle();
			Debug.Log((object)"[R2API.Language] /langdebug: janela de debug alternada.");
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CC_LangStatus(ConCommandArgs args)
		{
			string text = string.Join(", ", LanguagePlugin.GetRegisteredCustomLangs());
			string text2 = string.Join(", ", LanguagePlugin.GetFallbackLangs());
			string currentLanguageName = Language.currentLanguageName;
			int totalCustomTokens = LanguageAPI.GetTotalCustomTokens();
			int languageFileCount = LanguageAPI.GetLanguageFileCount();
			int peleJsonFileCount = LanguageAPI.GetPeleJsonFileCount();
			string text3 = string.Join(", ", LanguageAPI.GetPeleLanguageFolders());
			string text4 = (LanguageAPI.IsHotReloadEnabled ? "ativo" : "inativo");
			Debug.Log((object)"[R2API.Language] === Status ===");
			Debug.Log((object)("  Current language: " + currentLanguageName));
			Debug.Log((object)("  Custom langs: " + text));
			Debug.Log((object)("  Fallback (en): " + text2));
			Debug.Log((object)("  Hot-Reload: " + text4));
			Debug.Log((object)$"  .language files: {languageFileCount}");
			Debug.Log((object)$"  PELE JSON files: {peleJsonFileCount}");
			Debug.Log((object)("  PELE language folders: " + text3));
			Debug.Log((object)$"  API tokens: {totalCustomTokens}");
			Debug.Log((object)"[R2API.Language] ===============");
		}
	}
	internal static class CustomLanguageRegistration
	{
		private static readonly string[] CustomLangs = new string[3] { "la", "eo", "uk" };

		private static readonly string[] CultureFallbackLangs = new string[2] { "la", "eo" };

		internal static string[] GetRegisteredCustomLangs()
		{
			return (string[])CustomLangs.Clone();
		}

		internal static string[] GetFallbackLangs()
		{
			return (string[])CultureFallbackLangs.Clone();
		}

		internal static string FixCultureName(string name)
		{
			if (Array.IndexOf(CultureFallbackLangs, name) >= 0)
			{
				return "en";
			}
			return name;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Language), "FindLanguageByName")]
		private static void FindLanguageByNamePostfix(string __0, ref Language __result)
		{
			if (__result != null || Array.IndexOf(CustomLangs, __0) < 0)
			{
				return;
			}
			Dictionary<string, Language> languagesByName = GetLanguagesByName();
			if (languagesByName == null)
			{
				return;
			}
			if (languagesByName.TryGetValue(__0, out var value))
			{
				__result = value;
				return;
			}
			Language val = CreateLanguage(__0);
			if (val != null)
			{
				languagesByName[__0] = val;
				__result = val;
				LanguagePlugin.LogVerbose("Lazy-registrado: " + __0);
			}
		}

		private static Dictionary<string, Language> GetLanguagesByName()
		{
			return (Dictionary<string, Language>)(typeof(Language).GetField("languagesByName", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null));
		}

		private static Language CreateLanguage(string lang)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			try
			{
				ConstructorInfo constructor = typeof(Language).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null);
				if (constructor == null)
				{
					ManualLogSource logger = LanguagePlugin.Logger;
					if (logger != null)
					{
						logger.LogError((object)("CreateLanguage: Construtor Language(string) nao encontrado para " + lang));
					}
					return null;
				}
				Language val = (Language)constructor.Invoke(new object[1] { lang });
				FieldInfo fieldInfo = typeof(Language).GetField("name", BindingFlags.Instance | BindingFlags.Public) ?? typeof(Language).GetField("_name", BindingFlags.Instance | BindingFlags.NonPublic) ?? typeof(Language).GetField("name", BindingFlags.Instance | BindingFlags.NonPublic) ?? typeof(Language).GetField("<name>k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic);
				if (fieldInfo == null)
				{
					FieldInfo[] fields = typeof(Language).GetFields(BindingFlags.Instance | BindingFlags.NonPublic);
					foreach (FieldInfo fieldInfo2 in fields)
					{
						if (!(fieldInfo2.FieldType != typeof(string)) && (string)fieldInfo2.GetValue(val) == lang)
						{
							fieldInfo = fieldInfo2;
							break;
						}
					}
				}
				fieldInfo?.SetValue(val, lang);
				MethodInfo method = typeof(Language).GetMethod("SetFolders", BindingFlags.Instance | BindingFlags.NonPublic);
				string text = Path.Combine(PelePaths.LanguageRoot(Paths.PluginPath), lang);
				if (Directory.Exists(text))
				{
					method?.Invoke(val, new object[1] { new string[1] { text } });
				}
				string text2 = ((fieldInfo != null) ? ((string)fieldInfo.GetValue(val)) : "(field not found)");
				LanguagePlugin.LogVerbose("CreateLanguage: '" + lang + "' ok (nameField='" + text2 + "')");
				return val;
			}
			catch (Exception ex)
			{
				ManualLogSource logger2 = LanguagePlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)("CreateLanguage falhou para " + lang + ": " + (ex.InnerException?.Message ?? ex.Message)));
				}
				ManualLogSource logger3 = LanguagePlugin.Logger;
				if (logger3 != null)
				{
					logger3.LogError((object)("  Stack: " + (ex.InnerException?.StackTrace ?? ex.StackTrace)));
				}
				return null;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Language), "SetCurrentLanguage")]
		private static bool SetCurrentLanguagePrefix(string newCurrentLanguageName)
		{
			if (Array.IndexOf(CustomLangs, newCurrentLanguageName) < 0)
			{
				return true;
			}
			try
			{
				Language val = Language.FindLanguageByName(newCurrentLanguageName);
				if (val == null)
				{
					return true;
				}
				if (Language.currentLanguage != null && Language.currentLanguage != Language.english)
				{
					Language.currentLanguage.UnloadStrings();
				}
				(typeof(Language).GetField("<currentLanguageName>k__BackingField", BindingFlags.Static | BindingFlags.NonPublic) ?? typeof(Language).GetField("currentLanguageName", BindingFlags.Static | BindingFlags.NonPublic) ?? typeof(Language).GetField("_currentLanguageName", BindingFlags.Static | BindingFlags.NonPublic))?.SetValue(null, newCurrentLanguageName);
				(typeof(Language).GetField("<currentLanguage>k__BackingField", BindingFlags.Static | BindingFlags.NonPublic) ?? typeof(Language).GetField("currentLanguage", BindingFlags.Static | BindingFlags.NonPublic) ?? typeof(Language).GetField("_currentLanguage", BindingFlags.Static | BindingFlags.NonPublic) ?? typeof(Language).GetField("currentLanguage", BindingFlags.Static | BindingFlags.Public))?.SetValue(null, val);
				CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo(FixCultureName(val.name));
				val.LoadStrings();
				(typeof(Language).GetField("onCurrentLanguageChanged", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null) as Action)?.Invoke();
				LanguagePlugin.LogVerbose("SetCurrentLanguage interceptado: '" + newCurrentLanguageName + "' (CultureInfo='" + CultureInfo.CurrentCulture.Name + "')");
			}
			catch (Exception ex)
			{
				ManualLogSource logger = LanguagePlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)("SetCurrentLanguagePrefix falhou: " + (ex.InnerException?.Message ?? ex.Message)));
				}
				return true;
			}
			return false;
		}
	}
	internal static class CyrillicFontSupport
	{
		private static TMP_FontAsset _cachedEmbeddedFont;

		private static AssetBundle _cachedEmbeddedFontBundle;

		private static TMP_FontAsset _vanillaDefaultFont;

		private static TMP_FontAsset _cyrillicFont;

		private static TMP_FontAsset _bombardierDefaultFont;

		private static AssetBundle _cyrillicFontBundle;

		private static bool _cyrillicFontProbeDone;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(HGTextMeshProUGUI), "OnCurrentLanguageChanged")]
		private static void OnLanguageChanged()
		{
			if (_vanillaDefaultFont == null)
			{
				_vanillaDefaultFont = HGTextMeshProUGUI.defaultLanguageFont;
			}
			HGTextMeshProUGUI.defaultLanguageFont = GetCustomFontForCurrentLanguage() ?? _vanillaDefaultFont;
			ApplyCurrentFontToActiveText();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(TextMeshProUGUI), "LoadFontAsset")]
		private static void TextMeshProUGUI_LoadFontAsset_Postfix(TextMeshProUGUI __instance)
		{
			TMP_FontAsset cyrillicFont = GetCyrillicFont();
			if ((Object)(object)cyrillicFont == (Object)null || (Object)(object)__instance == (Object)null)
			{
				return;
			}
			TMP_FontAsset font = ((TMP_Text)__instance).font;
			if (!((Object)(object)font == (Object)null))
			{
				TMP_FontAsset val = _bombardierDefaultFont ?? _vanillaDefaultFont;
				if ((Object)(object)font == (Object)(object)val || ((Object)font).name.IndexOf("Bomb", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					((TMP_Text)__instance).font = cyrillicFont;
				}
			}
		}

		internal static TMP_FontAsset GetCyrillicFont()
		{
			if (_cyrillicFontProbeDone)
			{
				return _cyrillicFont;
			}
			_cyrillicFontProbeDone = true;
			_cyrillicFont = TryLoadCyrillicFontBundle() ?? TryGetExternalCyrillicFont() ?? TryLoadEmbeddedFont("ukrainianfont");
			if ((Object)(object)_cyrillicFont != (Object)null)
			{
				ManualLogSource logger = LanguagePlugin.Logger;
				if (logger != null)
				{
					logger.LogInfo((object)"Fonte cirilica do PELE ativa.");
				}
			}
			else
			{
				ManualLogSource logger2 = LanguagePlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogWarning((object)"Nenhuma fonte cirilica encontrada; caracteres ucranianos podem aparecer como '?'.");
				}
			}
			return _cyrillicFont;
		}

		private static TMP_FontAsset GetCustomFontForCurrentLanguage()
		{
			string currentLanguageName = Language.currentLanguageName;
			if (currentLanguageName == null)
			{
				return null;
			}
			if (!"uk".Equals(currentLanguageName, StringComparison.OrdinalIgnoreCase))
			{
				return null;
			}
			return GetCyrillicFont();
		}

		private static TMP_FontAsset TryGetExternalCyrillicFont()
		{
			try
			{
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				for (int i = 0; i < assemblies.Length; i++)
				{
					Type type = assemblies[i].GetType("AnotherOneCyrillicFont.AnotherOneCyrillicFont", throwOnError: false);
					if (!(type == null))
					{
						FieldInfo field = type.GetField("fontBomb", BindingFlags.Static | BindingFlags.Public);
						FieldInfo? field2 = type.GetField("fontBombDefault", BindingFlags.Static | BindingFlags.Public);
						object? obj = field?.GetValue(null);
						TMP_FontAsset val = (TMP_FontAsset)((obj is TMP_FontAsset) ? obj : null);
						object? obj2 = field2?.GetValue(null);
						TMP_FontAsset val2 = (TMP_FontAsset)((obj2 is TMP_FontAsset) ? obj2 : null);
						if ((Object)(object)val2 != (Object)null)
						{
							_bombardierDefaultFont = val2;
						}
						if ((Object)(object)val != (Object)null)
						{
							return val;
						}
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger = LanguagePlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)("TryGetExternalCyrillicFont falhou: " + ex.Message));
				}
			}
			return null;
		}

		private static TMP_FontAsset TryLoadCyrillicFontBundle()
		{
			try
			{
				string text = FindCyrillicFontBundlePath();
				if (text == null)
				{
					return null;
				}
				_cyrillicFontBundle = AssetBundle.LoadFromFile(text);
				if ((Object)(object)_cyrillicFontBundle == (Object)null)
				{
					ManualLogSource logger = LanguagePlugin.Logger;
					if (logger != null)
					{
						logger.LogWarning((object)"TryLoadCyrillicFontBundle: AssetBundle retornou null.");
					}
					return null;
				}
				TMP_FontAsset obj = _cyrillicFontBundle.LoadAsset<TMP_FontAsset>("Assets/CyrillicFont/tmpBombDropshadow.asset") ?? _cyrillicFontBundle.LoadAllAssets<TMP_FontAsset>().FirstOrDefault();
				if ((Object)(object)obj != (Object)null)
				{
					ManualLogSource logger2 = LanguagePlugin.Logger;
					if (logger2 != null)
					{
						logger2.LogInfo((object)"Fonte cirilica carregada de bundle PELE.");
					}
				}
				return obj;
			}
			catch (Exception ex)
			{
				ManualLogSource logger3 = LanguagePlugin.Logger;
				if (logger3 != null)
				{
					logger3.LogWarning((object)("TryLoadCyrillicFontBundle falhou: " + ex.Message));
				}
				return null;
			}
		}

		private static string FindCyrillicFontBundlePath()
		{
			string[] array = new string[2]
			{
				PelePaths.CyrillicFont(Paths.PluginPath),
				Path.Combine(Paths.PluginPath, "PELE", "cyrillicfont")
			};
			foreach (string text in array)
			{
				if (File.Exists(text))
				{
					return text;
				}
			}
			return Directory.GetFiles(Paths.PluginPath, "cyrillicfont", SearchOption.AllDirectories).FirstOrDefault();
		}

		private static TMP_FontAsset TryLoadEmbeddedFont(string resourceName)
		{
			if ((Object)(object)_cachedEmbeddedFont != (Object)null)
			{
				return _cachedEmbeddedFont;
			}
			try
			{
				if ((Object)(object)_cachedEmbeddedFontBundle == (Object)null)
				{
					Stream stream = TryGetResourceStream(resourceName);
					if (stream == null)
					{
						ManualLogSource logger = LanguagePlugin.Logger;
						if (logger != null)
						{
							logger.LogWarning((object)("TryLoadEmbeddedFont: recurso embutido nao encontrado: " + resourceName));
						}
						return null;
					}
					using (stream)
					{
						_cachedEmbeddedFontBundle = AssetBundle.LoadFromStream(stream);
					}
					if ((Object)(object)_cachedEmbeddedFontBundle == (Object)null)
					{
						ManualLogSource logger2 = LanguagePlugin.Logger;
						if (logger2 != null)
						{
							logger2.LogWarning((object)("TryLoadEmbeddedFont: AssetBundle retornou null: " + resourceName));
						}
						return null;
					}
				}
				TMP_FontAsset val = _cachedEmbeddedFontBundle.LoadAsset<TMP_FontAsset>("Assets/PELE-Font.asset") ?? _cachedEmbeddedFontBundle.LoadAsset<TMP_FontAsset>("PELE-Font") ?? _cachedEmbeddedFontBundle.LoadAsset<TMP_FontAsset>("ukrainianfont") ?? _cachedEmbeddedFontBundle.LoadAllAssets<TMP_FontAsset>().FirstOrDefault();
				if ((Object)(object)val == (Object)null)
				{
					ManualLogSource logger3 = LanguagePlugin.Logger;
					if (logger3 != null)
					{
						logger3.LogWarning((object)("TryLoadEmbeddedFont: TMP_FontAsset nao encontrado no bundle '" + resourceName + "'"));
					}
					return null;
				}
				_cachedEmbeddedFont = val;
				ManualLogSource logger4 = LanguagePlugin.Logger;
				if (logger4 != null)
				{
					logger4.LogInfo((object)"Fonte cirilica embutida carregada.");
				}
				return _cachedEmbeddedFont;
			}
			catch (Exception ex)
			{
				ManualLogSource logger5 = LanguagePlugin.Logger;
				if (logger5 != null)
				{
					logger5.LogWarning((object)("TryLoadEmbeddedFont falhou: " + ex.Message));
				}
				return null;
			}
		}

		private static void ApplyCurrentFontToActiveText()
		{
			//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)
			TMP_FontAsset defaultLanguageFont = HGTextMeshProUGUI.defaultLanguageFont;
			if ((Object)(object)defaultLanguageFont == (Object)null)
			{
				return;
			}
			HGTextMeshProUGUI[] array = Resources.FindObjectsOfTypeAll<HGTextMeshProUGUI>();
			foreach (HGTextMeshProUGUI val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					Scene scene = ((Component)val).gameObject.scene;
					if (((Scene)(ref scene)).IsValid())
					{
						((TMP_Text)val).font = defaultLanguageFont;
						((Graphic)val).SetAllDirty();
					}
				}
			}
		}

		private static Stream TryGetResourceStream(string resourceName)
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			return executingAssembly.GetManifestResourceStream("R2API.Language." + resourceName) ?? executingAssembly.GetManifestResourceStream("PELE." + resourceName);
		}
	}
	public class DuplicateTokenDetector
	{
		public List<DuplicateEntry> FindDuplicateTokens(string directory)
		{
			string[] languageFiles;
			try
			{
				languageFiles = LanguageFileHelper.GetLanguageFiles(directory);
			}
			catch (DirectoryNotFoundException)
			{
				return new List<DuplicateEntry>();
			}
			Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
			string[] array = languageFiles;
			foreach (string text in array)
			{
				Dictionary<string, Dictionary<string, string>> dictionary2;
				try
				{
					dictionary2 = LanguageFileHelper.ParseTokensFromFile(text);
				}
				catch
				{
					continue;
				}
				string fileName = Path.GetFileName(text);
				foreach (KeyValuePair<string, Dictionary<string, string>> item in dictionary2)
				{
					string key = item.Key;
					foreach (string key3 in item.Value.Keys)
					{
						string key2 = key + ":" + key3;
						if (!dictionary.TryGetValue(key2, out var value))
						{
							value = (dictionary[key2] = new List<string>());
						}
						if (!value.Contains<string>(fileName, StringComparer.OrdinalIgnoreCase))
						{
							value.Add(fileName);
						}
					}
				}
			}
			return (from d in dictionary.Where((KeyValuePair<string, List<string>> kvp) => kvp.Value.Count > 1).Select(delegate(KeyValuePair<string, List<string>> kvp)
				{
					string[] array2 = kvp.Key.Split(new char[1] { ':' }, 2);
					return new DuplicateEntry
					{
						Language = ((array2.Length > 1) ? array2[0] : ""),
						TokenName = ((array2.Length > 1) ? array2[1] : kvp.Key),
						Files = kvp.Value,
						Count = kvp.Value.Count
					};
				})
				orderby d.Count descending
				select d).ToList();
		}

		public bool HasDuplicates(string tokenName, string directory)
		{
			return FindDuplicateTokens(directory).Any((DuplicateEntry d) => d.TokenName.Equals(tokenName, StringComparison.OrdinalIgnoreCase));
		}
	}
	public class DuplicateEntry
	{
		public string TokenName { get; set; }

		public string Language { get; set; }

		public List<string> Files { get; set; }

		public int Count { get; set; }
	}
	public static class LanguageAPI
	{
		public class LanguageOverlay
		{
			private readonly List<OverlayTokenData> _overlayTokenDatas;

			public readonly ReadOnlyCollection<OverlayTokenData> readOnlyOverlays;

			internal LanguageOverlay(List<OverlayTokenData> data)
			{
				_overlayTokenDatas = data;
				readOnlyOverlays = data.AsReadOnly();
				Apply();
				temporaryOverlays.Add(this);
			}

			private void Apply()
			{
				_rwLock.EnterWriteLock();
				try
				{
					ApplyUnderLock();
				}
				finally
				{
					_rwLock.ExitWriteLock();
				}
			}

			private void ApplyUnderLock()
			{
				foreach (OverlayTokenData readOnlyOverlay in readOnlyOverlays)
				{
					if (!OverlayLanguage.TryGetValue(readOnlyOverlay.lang, out Dictionary<string, string> value))
					{
						value = new Dictionary<string, string>();
						OverlayLanguage[readOnlyOverlay.lang] = value;
					}
					value[readOnlyOverlay.key] = readOnlyOverlay.value;
				}
			}

			public void Remove()
			{
				SetHooks();
				temporaryOverlays.Remove(this);
				_rwLock.EnterWriteLock();
				try
				{
					OverlayLanguage.Clear();
					foreach (LanguageOverlay temporaryOverlay in temporaryOverlays)
					{
						temporaryOverlay.ApplyUnderLock();
					}
				}
				finally
				{
					_rwLock.ExitWriteLock();
				}
			}
		}

		public struct OverlayTokenData
		{
			public string key;

			public string value;

			public string lang;

			public bool isGeneric;

			internal OverlayTokenData(string _key, string _value, string _lang)
			{
				key = _key;
				value = _value;
				lang = _lang;
				isGeneric = _lang == "generic";
			}

			internal OverlayTokenData(string _key, string _value)
			{
				key = _key;
				value = _value;
				lang = "generic";
				isGeneric = true;
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_GetLocalizedStringByToken <0>__Language_GetLocalizedStringByToken;

			public static hook_TokenIsRegistered <1>__Language_TokenIsRegistered;

			public static Func<string, string> <2>__GetFileName;
		}

		public const string PluginGUID = "com.bepis.r2api.language";

		public const string PluginName = "R2API.Language (Jaosnake fork)";

		public const string PluginVersion = "2.0.0";

		private static readonly Dictionary<string, Dictionary<string, string>> CustomLanguage = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<string, Dictionary<string, string>> OverlayLanguage = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);

		private static readonly List<LanguageOverlay> temporaryOverlays = new List<LanguageOverlay>();

		private static readonly ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);

		private static LanguageHotReload _hotReload;

		private static Dictionary<string, int> _peleTokenCountCache;

		private static DateTime _peleTokenCacheTime = DateTime.MinValue;

		private static int _cachedLanguageFileCount;

		private static int _cachedPeleJsonFileCount;

		private static string[] _cachedPeleFolders;

		private static Dictionary<string, List<string>> _cachedModFiles;

		private static DateTime _diskCacheTime = DateTime.MinValue;

		private const string GenericLanguage = "generic";

		private const string GenericLegacyName = "strings";

		private static bool _hooksEnabled = false;

		public static bool Loaded => true;

		internal static ManualLogSource Log { get; set; }

		internal static bool IsHotReloadEnabled => _hotReload?.IsEnabled ?? false;

		internal static void SetHooks()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0043: 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_004e: Expected O, but got Unknown
			if (!_hooksEnabled)
			{
				_hooksEnabled = true;
				LoadLanguageFilesFromPluginFolder();
				object obj = <>O.<0>__Language_GetLocalizedStringByToken;
				if (obj == null)
				{
					hook_GetLocalizedStringByToken val = Language_GetLocalizedStringByToken;
					<>O.<0>__Language_GetLocalizedStringByToken = val;
					obj = (object)val;
				}
				Language.GetLocalizedStringByToken += (hook_GetLocalizedStringByToken)obj;
				object obj2 = <>O.<1>__Language_TokenIsRegistered;
				if (obj2 == null)
				{
					hook_TokenIsRegistered val2 = Language_TokenIsRegistered;
					<>O.<1>__Language_TokenIsRegistered = val2;
					obj2 = (object)val2;
				}
				Language.TokenIsRegistered += (hook_TokenIsRegistered)obj2;
			}
		}

		private static void LoadLanguageFilesFromPluginFolder()
		{
			string[] files = Directory.GetFiles(Paths.PluginPath, "*.language", SearchOption.AllDirectories);
			for (int i = 0; i < files.Length; i++)
			{
				AddPath(files[i]);
			}
		}

		internal static void UnsetHooks()
		{
			//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_001b: Expected O, but got Unknown
			//IL_0030: 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_003b: Expected O, but got Unknown
			object obj = <>O.<0>__Language_GetLocalizedStringByToken;
			if (obj == null)
			{
				hook_GetLocalizedStringByToken val = Language_GetLocalizedStringByToken;
				<>O.<0>__Language_GetLocalizedStringByToken = val;
				obj = (object)val;
			}
			Language.GetLocalizedStringByToken -= (hook_GetLocalizedStringByToken)obj;
			object obj2 = <>O.<1>__Language_TokenIsRegistered;
			if (obj2 == null)
			{
				hook_TokenIsRegistered val2 = Language_TokenIsRegistered;
				<>O.<1>__Language_TokenIsRegistered = val2;
				obj2 = (object)val2;
			}
			Language.TokenIsRegistered -= (hook_TokenIsRegistered)obj2;
			_hooksEnabled = false;
		}

		internal static void DisposeLock()
		{
		}

		private static bool TryGetToken(Dictionary<string, Dictionary<string, string>> dict, string lang, string token, out string value)
		{
			_rwLock.EnterReadLock();
			try
			{
				if (dict.TryGetValue(lang, out Dictionary<string, string> value2) && value2.TryGetValue(token, out value))
				{
					return true;
				}
				string text = PelePaths.LanguageAlias(lang);
				if (text != null && dict.TryGetValue(text, out Dictionary<string, string> value3) && value3.TryGetValue(token, out value))
				{
					return true;
				}
				if (dict.TryGetValue("generic", out Dictionary<string, string> value4) && value4.TryGetValue(token, out value))
				{
					return true;
				}
				value = null;
				return false;
			}
			finally
			{
				_rwLock.ExitReadLock();
			}
		}

		private static bool TokenExists(Dictionary<string, Dictionary<string, string>> dict, string lang, string token)
		{
			_rwLock.EnterReadLock();
			try
			{
				string text = PelePaths.LanguageAlias(lang);
				Dictionary<string, string> value;
				Dictionary<string, string> value2;
				Dictionary<string, string> value3;
				return (dict.TryGetValue(lang, out value) && value.ContainsKey(token)) || (text != null && dict.TryGetValue(text, out value2) && value2.ContainsKey(token)) || (dict.TryGetValue("generic", out value3) && value3.ContainsKey(token));
			}
			finally
			{
				_rwLock.ExitReadLock();
			}
		}

		private static bool Language_TokenIsRegistered(orig_TokenIsRegistered orig, Language self, string token)
		{
			string name = self.name;
			if (TokenExists(OverlayLanguage, name, token))
			{
				return true;
			}
			if (TokenExists(CustomLanguage, name, token))
			{
				return true;
			}
			return orig.Invoke(self, token);
		}

		private static string Language_GetLocalizedStringByToken(orig_GetLocalizedStringByToken orig, Language self, string token)
		{
			string name = self.name;
			if (TryGetToken(OverlayLanguage, name, token, out string value))
			{
				return value;
			}
			if (TryGetToken(CustomLanguage, name, token, out value))
			{
				return value;
			}
			return orig.Invoke(self, token);
		}

		private static Dictionary<string, Dictionary<string, string>> LoadFile(string fileContent)
		{
			Dictionary<string, Dictionary<string, string>> dictionary = new Dictionary<string, Dictionary<string, string>>();
			try
			{
				JSONNode val = JSON.Parse(fileContent);
				if (val == (object)null)
				{
					return null;
				}
				foreach (string key2 in val.Keys)
				{
					JSONNode val2 = val[key2];
					if (val2 == (object)null)
					{
						continue;
					}
					string key = ((key2 == "strings") ? "generic" : key2);
					if (!dictionary.TryGetValue(key, out var value))
					{
						value = (dictionary[key] = new Dictionary<string, string>());
					}
					foreach (string key3 in val2.Keys)
					{
						value[key3] = val2[key3].Value;
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogFormat("Parsing error in language file, Error: {0}", new object[1] { ex });
				return null;
			}
			if (dictionary.Count <= 0)
			{
				return null;
			}
			return dictionary;
		}

		public static void Add(string key, string value)
		{
			SetHooks();
			Add(key, value, "generic");
		}

		public static void Add(string key, string value, string language)
		{
			SetHooks();
			if (key == null)
			{
				throw new ArgumentNullException("key");
			}
			if (value == null)
			{
				throw new ArgumentNullException("value");
			}
			if (language == null)
			{
				throw new ArgumentNullException("language");
			}
			_rwLock.EnterWriteLock();
			try
			{
				if (!CustomLanguage.TryGetValue(language, out Dictionary<string, string> value2))
				{
					value2 = new Dictionary<string, string>();
					CustomLanguage[language] = value2;
				}
				if (!value2.ContainsKey(key))
				{
					value2[key] = value;
				}
			}
			finally
			{
				_rwLock.ExitWriteLock();
			}
		}

		public static void AddPath(string path)
		{
			SetHooks();
			if (path == null)
			{
				throw new ArgumentNullException("path");
			}
			Add(File.ReadAllText(path));
		}

		public static void Add(string file)
		{
			SetHooks();
			if (file == null)
			{
				throw new ArgumentNullException("file");
			}
			Dictionary<string, Dictionary<string, string>> dictionary = LoadFile(file);
			if (dictionary != null)
			{
				Add(dictionary);
			}
		}

		public static void Add(Dictionary<string, string> tokenDictionary)
		{
			SetHooks();
			Add(tokenDictionary, "generic");
		}

		public static void Add(Dictionary<string, string> tokenDictionary, string language)
		{
			SetHooks();
			if (tokenDictionary == null)
			{
				throw new ArgumentNullException("tokenDictionary");
			}
			foreach (KeyValuePair<string, string> item in tokenDictionary)
			{
				if (item.Value != null)
				{
					Add(item.Key, item.Value, language);
				}
			}
		}

		public static void Add(Dictionary<string, Dictionary<string, string>> languageDictionary)
		{
			SetHooks();
			if (languageDictionary == null)
			{
				throw new ArgumentNullException("languageDictionary");
			}
			foreach (KeyValuePair<string, Dictionary<string, string>> item in languageDictionary)
			{
				if (item.Value != null)
				{
					Add(item.Value, item.Key);
				}
			}
		}

		public static void AddOrUpdateToken(string key, string value)
		{
			SetHooks();
			AddOrUpdateToken(key, value, "generic");
		}

		public static void AddOrUpdateToken(string key, string value, string language)
		{
			SetHooks();
			if (string.IsNullOrEmpty(key))
			{
				throw new ArgumentNullException("key");
			}
			if (value == null)
			{
				throw new ArgumentNullException("value");
			}
			if (string.IsNullOrEmpty(language))
			{
				language = "generic";
			}
			_rwLock.EnterWriteLock();
			try
			{
				if (!CustomLanguage.TryGetValue(language, out Dictionary<string, string> value2))
				{
					value2 = new Dictionary<string, string>();
					CustomLanguage[language] = value2;
				}
				value2[key] = value;
			}
			finally
			{
				_rwLock.ExitWriteLock();
			}
		}

		public static void RemoveToken(string key, string language = null)
		{
			SetHooks();
			if (string.IsNullOrEmpty(key))
			{
				return;
			}
			string key2 = language ?? "generic";
			_rwLock.EnterWriteLock();
			try
			{
				if (CustomLanguage.TryGetValue(key2, out Dictionary<string, string> value))
				{
					value.Remove(key);
				}
			}
			finally
			{
				_rwLock.ExitWriteLock();
			}
		}

		public static void ClearAllTokens()
		{
			SetHooks();
			_rwLock.EnterWriteLock();
			try
			{
				CustomLanguage.Clear();
			}
			finally
			{
				_rwLock.ExitWriteLock();
			}
		}

		public static void EnableHotReload(string directory)
		{
			SetHooks();
			if (_hotReload == null)
			{
				_hotReload = LanguageHotReload.Instance;
			}
			_hotReload.Enable(directory);
		}

		public static void DisableHotReload()
		{
			_hotReload?.Disable();
		}

		public static void ReloadAllLanguageFiles(string directory)
		{
			SetHooks();
			ClearAllTokens();
			string[] languageFiles = LanguageFileHelper.GetLanguageFiles(directory);
			foreach (string text in languageFiles)
			{
				try
				{
					foreach (KeyValuePair<string, Dictionary<string, string>> item in LanguageFileHelper.ParseTokensFromFile(text))
					{
						foreach (KeyValuePair<string, string> item2 in item.Value)
						{
							AddOrUpdateToken(item2.Key, item2.Value, item.Key);
						}
					}
				}
				catch (Exception ex)
				{
					Debug.LogError((object)("[LanguageAPI] Erro ao recarregar " + text + ": " + ex.Message));
				}
			}
		}

		public static ValidationResult ValidateLanguageFile(string filePath)
		{
			SetHooks();
			return new LanguageFileValidator().ValidateFile(filePath);
		}

		public static List<DuplicateEntry> FindDuplicateTokens(string directory)
		{
			SetHooks();
			return new DuplicateTokenDetector().FindDuplicateTokens(directory);
		}

		public static List<string> FindUnusedTokens(string directory)
		{
			SetHooks();
			return new TokenUsageAnalyzer().FindUnusedTokens(directory);
		}

		public static void CompileLanguageFiles(string sourceDirectory, string outputDirectory)
		{
			SetHooks();
			new LanguageFileCompiler().CompileLanguageFiles(sourceDirectory, outputDirectory);
		}

		public static LanguageOverlay AddOverlay(string key, string value)
		{
			SetHooks();
			return AddOverlay(key, value, "generic");
		}

		public static LanguageOverlay AddOverlay(string key, string value, string lang)
		{
			SetHooks();
			if (key == null)
			{
				throw new ArgumentNullException("key");
			}
			if (value == null)
			{
				throw new ArgumentNullException("value");
			}
			if (lang == null)
			{
				throw new ArgumentNullException("lang");
			}
			return new LanguageOverlay(new List<OverlayTokenData>(1)
			{
				new OverlayTokenData(key, value, lang)
			});
		}

		public static LanguageOverlay AddOverlayPath(string path)
		{
			SetHooks();
			if (path == null)
			{
				throw new ArgumentNullException("path");
			}
			return AddOverlay(File.ReadAllText(path));
		}

		public static LanguageOverlay AddOverlay(string file)
		{
			SetHooks();
			if (file == null)
			{
				throw new ArgumentNullException("file");
			}
			Dictionary<string, Dictionary<string, string>> dictionary = LoadFile(file);
			if (dictionary == null)
			{
				return null;
			}
			return AddOverlay(dictionary);
		}

		public static LanguageOverlay AddOverlay(Dictionary<string, string> tokenDictionary)
		{
			SetHooks();
			return AddOverlay(tokenDictionary, "generic");
		}

		public static LanguageOverlay AddOverlay(Dictionary<string, string> tokenDictionary, string language)
		{
			SetHooks();
			if (tokenDictionary == null)
			{
				throw new ArgumentNullException("tokenDictionary");
			}
			if (language == null)
			{
				throw new ArgumentNullException("language");
			}
			List<OverlayTokenData> list = new List<OverlayTokenData>(tokenDictionary.Count);
			foreach (KeyValuePair<string, string> item in tokenDictionary)
			{
				if (item.Value != null)
				{
					list.Add(new OverlayTokenData(item.Key, item.Value, language));
				}
			}
			return new LanguageOverlay(list);
		}

		public static LanguageOverlay AddOverlay(Dictionary<string, Dictionary<string, string>> languageDictionary)
		{
			SetHooks();
			if (languageDictionary == null)
			{
				throw new ArgumentNullException("languageDictionary");
			}
			List<OverlayTokenData> list = new List<OverlayTokenData>();
			foreach (KeyValuePair<string, Dictionary<string, string>> item in languageDictionary)
			{
				item.Deconstruct(out var key, out var value);
				string lang = key;
				Dictionary<string, string> dictionary = value;
				if (dictionary == null)
				{
					continue;
				}
				foreach (KeyValuePair<string, string> item2 in dictionary)
				{
					item2.Deconstruct(out key, out var value2);
					string key2 = key;
					string text = value2;
					if (text != null)
					{
						list.Add(new OverlayTokenData(key2, text, lang));
					}
				}
			}
			return new LanguageOverlay(list);
		}

		internal static Dictionary<string, int> GetCustomTokenCounts()
		{
			_rwLock.EnterReadLock();
			try
			{
				Dictionary<string, int> dictionary = new Dictionary<string, int>();
				foreach (KeyValuePair<string, Dictionary<string, string>> item in CustomLanguage)
				{
					dictionary[item.Key] = item.Value.Count;
				}
				foreach (KeyValuePair<string, Dictionary<string, string>> item2 in OverlayLanguage)
				{
					dictionary[item2.Key] = dictionary.GetValueOrDefault(item2.Key) + item2.Value.Count;
				}
				return dictionary;
			}
			finally
			{
				_rwLock.ExitReadLock();
			}
		}

		internal static int GetTotalCustomTokens()
		{
			_rwLock.EnterReadLock();
			try
			{
				return CustomLanguage.Sum<KeyValuePair<string, Dictionary<string, string>>>((KeyValuePair<string, Dictionary<string, string>> kvp) => kvp.Value.Count) + OverlayLanguage.Sum<KeyValuePair<string, Dictionary<string, string>>>((KeyValuePair<string, Dictionary<string, string>> kvp) => kvp.Value.Count);
			}
			finally
			{
				_rwLock.ExitReadLock();
			}
		}

		internal static IEnumerable<string> GetCustomLanguages()
		{
			_rwLock.EnterReadLock();
			try
			{
				return (from x in CustomLanguage.Keys.Union(OverlayLanguage.Keys).Distinct<string>(StringComparer.OrdinalIgnoreCase)
					orderby x
					select x).ToList();
			}
			finally
			{
				_rwLock.ExitReadLock();
			}
		}

		internal static void InvalidateDiskCache()
		{
			_diskCacheTime = DateTime.MinValue;
			_peleTokenCacheTime = DateTime.MinValue;
		}

		internal static void RefreshDiskCache()
		{
			_diskCacheTime = DateTime.UtcNow;
			try
			{
				_cachedLanguageFileCount = Directory.GetFiles(Paths.PluginPath, "*.language", SearchOption.AllDirectories).Length;
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)("GetLanguageFileCount: " + ex.Message));
				}
				_cachedLanguageFileCount = 0;
			}
			string path = PelePaths.LanguageRoot(Paths.PluginPath);
			try
			{
				_cachedPeleJsonFileCount = (Directory.Exists(path) ? Directory.GetFiles(path, "*.json", SearchOption.AllDirectories).Length : 0);
			}
			catch (Exception ex2)
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogWarning((object)("GetPeleJsonFileCount: " + ex2.Message));
				}
				_cachedPeleJsonFileCount = 0;
			}
			try
			{
				_cachedPeleFolders = (Directory.Exists(path) ? Directory.GetDirectories(path).Select(Path.GetFileName).ToArray() : Array.Empty<string>());
			}
			catch (Exception ex3)
			{
				ManualLogSource log3 = Log;
				if (log3 != null)
				{
					log3.LogWarning((object)("GetPeleLanguageFolders: " + ex3.Message));
				}
				_cachedPeleFolders = Array.Empty<string>();
			}
			try
			{
				_cachedModFiles = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);
				string[] files = Directory.GetFiles(Paths.PluginPath, "*.language", SearchOption.AllDirectories);
				foreach (string text in files)
				{
					DirectoryInfo directoryInfo = new DirectoryInfo(Path.GetDirectoryName(text));
					string key = directoryInfo.Parent?.Name ?? directoryInfo.Name;
					if (!_cachedModFiles.TryGetValue(key, out List<string> value))
					{
						value = new List<string>();
						_cachedModFiles[key] = value;
					}
					value.Add(text);
				}
			}
			catch (Exception ex4)
			{
				ManualLogSource log4 = Log;
				if (log4 != null)
				{
					log4.LogWarning((object)("GetModFiles: " + ex4.Message));
				}
				if (_cachedModFiles == null)
				{
					_cachedModFiles = new Dictionary<string, List<string>>();
				}
			}
		}

		internal static int GetLanguageFileCount()
		{
			if (_diskCacheTime < DateTime.UtcNow.AddSeconds(-5.0))
			{
				RefreshDiskCache();
			}
			return _cachedLanguageFileCount;
		}

		internal static int GetPeleJsonFileCount()
		{
			if (_diskCacheTime < DateTime.UtcNow.AddSeconds(-5.0))
			{
				RefreshDiskCache();
			}
			return _cachedPeleJsonFileCount;
		}

		internal static string[] GetPeleLanguageFolders()
		{
			if (_diskCacheTime < DateTime.UtcNow.AddSeconds(-5.0))
			{
				RefreshDiskCache();
			}
			return _cachedPeleFolders ?? Array.Empty<string>();
		}

		internal static Dictionary<string, List<string>> GetModFileGroups()
		{
			if (_diskCacheTime < DateTime.UtcNow.AddSeconds(-5.0))
			{
				RefreshDiskCache();
			}
			return _cachedModFiles ?? new Dictionary<string, List<string>>();
		}

		internal static Dictionary<string, int> GetPeleTokenCounts()
		{
			if (_peleTokenCacheTime > DateTime.UtcNow.AddSeconds(-5.0))
			{
				return _peleTokenCountCache ?? new Dictionary<string, int>();
			}
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			try
			{
				string path = PelePaths.LanguageRoot(Paths.PluginPath);
				if (!Directory.Exists(path))
				{
					return dictionary;
				}
				string[] directories = Directory.GetDirectories(path);
				foreach (string path2 in directories)
				{
					string fileName = Path.GetFileName(path2);
					int num = 0;
					string[] files = Directory.GetFiles(path2, "*.json");
					foreach (string text in files)
					{
						try
						{
							JSONNode val = JSON.Parse(File.ReadAllText(text));
							if (val != (object)null)
							{
								num += CountPeleJsonTokens(val);
							}
						}
						catch (Exception ex)
						{
							ManualLogSource log = Log;
							if (log != null)
							{
								log.LogWarning((object)("Erro ao ler " + text + ": " + ex.Message));
							}
						}
					}
					if (num > 0)
					{
						dictionary[fileName] = num;
					}
				}
			}
			catch (Exception ex2)
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogWarning((object)("GetPeleTokenCounts: " + ex2.Message));
				}
			}
			_peleTokenCountCache = dictionary;
			_peleTokenCacheTime = DateTime.UtcNow;
			return dictionary;
		}

		private static int CountPeleJsonTokens(JSONNode json)
		{
			if (json == (object)null)
			{
				return 0;
			}
			JSONNode val = json["strings"];
			if (val != (object)null && val.Count > 0)
			{
				return CountTokenObject(val);
			}
			return CountTokenObject(json, skipManifestKeys: true);
		}

		private static int CountTokenObject(JSONNode node, bool skipManifestKeys = false)
		{
			int num = 0;
			foreach (string key in node.Keys)
			{
				if ((!skipManifestKeys || !string.Equals(key, "language", StringComparison.OrdinalIgnoreCase)) && (!skipManifestKeys || !string.Equals(key, "strings", StringComparison.OrdinalIgnoreCase)) && !key.StartsWith("_", StringComparison.Ordinal) && node[key] != (object)null && node[key].Count == 0)
				{
					num++;
				}
			}
			return num;
		}
	}
	internal class LanguageDebugUI : MonoBehaviour
	{
		private static LanguageDebugUI _instance;

		private bool _visible;

		private Rect _windowRect;

		private int _activeTab;

		private Vector2 _scrollPos;

		private readonly string[] _tabs = new string[5] { "Linguas", "PELE", "Mods", "Status", "Duplicatas" };

		private const string PrefsKeyX = "R2APILang_DebugX";

		private const string PrefsKeyY = "R2APILang_DebugY";

		private const string PrefsKeyW = "R2APILang_DebugW";

		private const string PrefsKeyH = "R2APILang_DebugH";

		private List<DuplicateEntry> _duplicates;

		private bool _duplicatesDirty = true;

		private bool _scanning;

		private readonly Queue<Action> _mainThreadQueue = new Queue<Action>();

		private int _errorCount = -1;

		private static MethodInfo _setCurrentLanguageMethod;

		internal static void Create()
		{
			//IL_0026: 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_0031: Expected O, but got Unknown
			if (!((Object)(object)_instance != (Object)null))
			{
				GameObject val = new GameObject("LanguageDebugUI", new Type[1] { typeof(LanguageDebugUI) });
				Object.DontDestroyOnLoad((Object)val);
				_instance = val.GetComponent<LanguageDebugUI>();
				_setCurrentLanguageMethod = typeof(Language).GetMethod("SetCurrentLanguage", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			}
		}

		internal static void DestroyInstance()
		{
			if ((Object)(object)_instance != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_instance).gameObject);
				_instance = null;
			}
		}

		internal static void Toggle()
		{
			if ((Object)(object)_instance != (Object)null)
			{
				_instance._visible = !_instance._visible;
			}
		}

		private void Awake()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			_windowRect = new Rect(PlayerPrefs.GetFloat("R2APILang_DebugX", 50f), PlayerPrefs.GetFloat("R2APILang_DebugY", 50f), PlayerPrefs.GetFloat("R2APILang_DebugW", 600f), PlayerPrefs.GetFloat("R2APILang_DebugH", 400f));
		}

		private void Update()
		{
			if (Input.GetKeyDown((KeyCode)287))
			{
				_visible = !_visible;
			}
			ProcessMainThreadQueue();
		}

		private void OnGUI()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_0046: 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)
			if (_visible)
			{
				_windowRect = GUILayout.Window(999, _windowRect, new WindowFunction(DrawWindow), "R2API.Language Debug", (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.MinWidth(400f),
					GUILayout.MinHeight(200f)
				});
			}
		}

		private void DrawWindow(int _)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Invalid comparison between Unknown and I4
			_activeTab = GUILayout.Toolbar(_activeTab, _tabs, Array.Empty<GUILayoutOption>());
			_scrollPos = GUILayout.BeginScrollView(_scrollPos, Array.Empty<GUILayoutOption>());
			switch (_activeTab)
			{
			case 0:
				DrawLanguagesTab();
				break;
			case 1:
				DrawPeleTab();
				break;
			case 2:
				DrawModsTab();
				break;
			case 3:
				DrawStatusTab();
				break;
			case 4:
				DrawDuplicatesTab();
				break;
			}
			GUILayout.EndScrollView();
			if ((int)Event.current.type == 1)
			{
				SaveWindowRect();
			}
			GUI.DragWindow();
		}

		private void SaveWindowRect()
		{
			PlayerPrefs.SetFloat("R2APILang_DebugX", ((Rect)(ref _windowRect)).x);
			PlayerPrefs.SetFloat("R2APILang_DebugY", ((Rect)(ref _windowRect)).y);
			PlayerPrefs.SetFloat("R2APILang_DebugW", ((Rect)(ref _windowRect)).width);
			PlayerPrefs.SetFloat("R2APILang_DebugH", ((Rect)(ref _windowRect)).height);
			PlayerPrefs.Save();
		}

		private void InvokeSetCurrentLanguage(string lang)
		{
			if (_setCurrentLanguageMethod == null)
			{
				ManualLogSource logger = LanguagePlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)"SetCurrentLanguage method not found");
				}
				return;
			}
			try
			{
				_setCurrentLanguageMethod.Invoke(null, new object[1] { lang });
			}
			catch (Exception ex)
			{
				ManualLogSource logger2 = LanguagePlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)("Falha ao trocar lingua: " + (ex.InnerException?.Message ?? ex.Message)));
				}
			}
		}

		private void DrawLanguagesTab()
		{
			GUILayout.Label("Linguas registradas no jogo — clique Ativar para trocar:", GUI.skin.label, Array.Empty<GUILayoutOption>());
			string currentLanguageName = Language.currentLanguageName;
			List<string> availableLanguages = LanguageNames.GetAvailableLanguages();
			if (availableLanguages.Count == 0)
			{
				GUILayout.Label("  (nenhuma)", Array.Empty<GUILayoutOption>());
			}
			else
			{
				foreach (string item in availableLanguages)
				{
					string friendlyName = LanguageNames.GetFriendlyName(item);
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					GUILayout.Label("  " + item + " - " + friendlyName, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(250f) });
					if (item == currentLanguageName)
					{
						GUILayout.Label("[ATIVO]", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) });
					}
					else if (GUILayout.Button("Ativar", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }))
					{
						InvokeSetCurrentLanguage(item);
					}
					GUILayout.EndHorizontal();
				}
			}
			GUILayout.Space(10f);
			GUILayout.Label("Tokens customizados por lingua (API):", GUI.skin.label, Array.Empty<GUILayoutOption>());
			Dictionary<string, int> customTokenCounts = LanguageAPI.GetCustomTokenCounts();
			if (customTokenCounts.Count == 0)
			{
				GUILayout.Label("  (nenhum)", Array.Empty<GUILayoutOption>());
			}
			else
			{
				foreach (KeyValuePair<string, int> item2 in customTokenCounts.OrderBy((KeyValuePair<string, int> x) => x.Key))
				{
					GUILayout.Label($"  {item2.Key}: {item2.Value} tokens", Array.Empty<GUILayoutOption>());
				}
			}
			GUILayout.Space(5f);
			GUILayout.Label("Total de tokens via API: " + LanguageAPI.GetTotalCustomTokens(), Array.Empty<GUILayoutOption>());
		}

		private void DrawPeleTab()
		{
			string[] peleLanguageFolders = LanguageAPI.GetPeleLanguageFolders();
			if (peleLanguageFolders.Length == 0)
			{
				GUILayout.Label("Pasta PELE/Language/ nao encontrada.", Array.Empty<GUILayoutOption>());
				return;
			}
			GUILayout.Label("Pastas de idioma encontradas:", GUI.skin.label, Array.Empty<GUILayoutOption>());
			string[] array = peleLanguageFolders;
			foreach (string text in array)
			{
				GUILayout.Label("  " + text, Array.Empty<GUILayoutOption>());
			}
			GUILayout.Space(5f);
			GUILayout.Label("Arquivos JSON: " + LanguageAPI.GetPeleJsonFileCount(), Array.Empty<GUILayoutOption>());
			GUILayout.Space(5f);
			GUILayout.Label("Tokens por lingua (PELE JSONs):", GUI.skin.label, Array.Empty<GUILayoutOption>());
			Dictionary<string, int> peleTokenCounts = LanguageAPI.GetPeleTokenCounts();
			if (peleTokenCounts.Count == 0)
			{
				GUILayout.Label("  (nenhum token)", Array.Empty<GUILayoutOption>());
				return;
			}
			foreach (KeyValuePair<string, int> item in peleTokenCounts.OrderBy((KeyValuePair<string, int> x) => x.Key))
			{
				GUILayout.Label($"  {item.Key}: {item.Value} tokens", Array.Empty<GUILayoutOption>());
			}
		}

		private void DrawModsTab()
		{
			GUILayout.Label("Mods com arquivos .language:", GUI.skin.label, Array.Empty<GUILayoutOption>());
			Dictionary<string, List<string>> modFileGroups = LanguageAPI.GetModFileGroups();
			if (modFileGroups.Count == 0)
			{
				GUILayout.Label("  (nenhum encontrado)", Array.Empty<GUILayoutOption>());
				return;
			}
			foreach (KeyValuePair<string, List<string>> item in modFileGroups.OrderBy((KeyValuePair<string, List<string>> x) => x.Key))
			{
				GUILayout.Label($"  {item.Key}: {item.Value.Count} arquivo(s)", Array.Empty<GUILayoutOption>());
				foreach (string item2 in item.Value.Take(5))
				{
					GUILayout.Label("      " + Path.GetFileName(item2), Array.Empty<GUILayoutOption>());
				}
				if (item.Value.Count > 5)
				{
					GUILayout.Label($"      ... e mais {item.Value.Count - 5}", Array.Empty<GUILayoutOption>());
				}
			}
		}

		private void DrawStatusTab()
		{
			GUILayout.Label("Status do Plugin", GUI.skin.label, Array.Empty<GUILayoutOption>());
			GUILayout.Label("  DLL: com.bepis.r2api.language v2.0.0", Array.Empty<GUILayoutOption>());
			GUILayout.Label("  Hot-Reload: " + (LanguageAPI.IsHotReloadEnabled ? "ATIVO" : "INATIVO"), Array.Empty<GUILayoutOption>());
			GUILayout.Space(5f);
			GUILayout.Label("Diretorios monitorados:", GUI.skin.label, Array.Empty<GUILayoutOption>());
			GUILayout.Label("  *.language: " + Paths.PluginPath, Array.Empty<GUILayoutOption>());
			GUILayout.Label("  *.json:     " + PelePaths.LanguageRoot(Paths.PluginPath), Array.Empty<GUILayoutOption>());
			GUILayout.Space(5f);
			GUILayout.Label("Arquivos carregados:", GUI.skin.label, Array.Empty<GUILayoutOption>());
			GUILayout.Label($"  .language: {LanguageAPI.GetLanguageFileCount()}", Array.Empty<GUILayoutOption>());
			GUILayout.Label($"  .json:     {LanguageAPI.GetPeleJsonFileCount()}", Array.Empty<GUILayoutOption>());
			GUILayout.Label($"  Tokens:    {LanguageAPI.GetTotalCustomTokens()}", Array.Empty<GUILayoutOption>());
			GUILayout.Label("  Erros de sintaxe: " + ((_errorCount >= 0) ? _errorCount.ToString() : "?"), Array.Empty<GUILayoutOption>());
			GUILayout.Space(5f);
			GUILayout.Label("Custom langs:", GUI.skin.label, Array.Empty<GUILayoutOption>());
			GUILayout.Label("  " + string.Join(", ", LanguagePlugin.GetRegisteredCustomLangs()), Array.Empty<GUILayoutOption>());
			GUILayout.Label("  Com fallback: " + string.Join(", ", LanguagePlugin.GetFallbackLangs()), Array.Empty<GUILayoutOption>());
			GUILayout.Space(10f);
			if (GUILayout.Button("Refresh cache", Array.Empty<GUILayoutOption>()))
			{
				LanguageAPI.InvalidateDiskCache();
				LanguageAPI.RefreshDiskCache();
				_errorCount = CountFileErrors();
				_duplicatesDirty = true;
			}
			if (GUILayout.Button("Recarregar tudo (F5)", Array.Empty<GUILayoutOption>()))
			{
				LanguageAPI.InvalidateDiskCache();
				LanguageAPI.ReloadAllLanguageFiles(Paths.PluginPath);
				LanguagePlugin.ReloadPeleJsonFiles();
				_errorCount = CountFileErrors();
				_duplicatesDirty = true;
			}
			GUILayout.Space(5f);
			GUILayout.Label("F6 - Alternar esta janela", GUI.skin.label, Array.Empty<GUILayoutOption>());
		}

		private void DrawDuplicatesTab()
		{
			if (_duplicatesDirty && !_scanning)
			{
				_scanning = true;
				_duplicates = null;
				ThreadPool.QueueUserWorkItem(delegate
				{
					try
					{
						List<DuplicateEntry> result = new DuplicateTokenDetector().FindDuplicateTokens(Paths.PluginPath);
						_mainThreadQueue.Enqueue(delegate
						{
							_duplicates = result;
							_duplicatesDirty = false;
							_scanning = false;
						});
					}
					catch (Exception ex)
					{
						Exception ex2 = ex;
						Exception ex3 = ex2;
						_mainThreadQueue.Enqueue(delegate
						{
							_duplicates = new List<DuplicateEntry>();
							_duplicatesDirty = false;
							_scanning = false;
							Debug.LogError((object)("Erro ao escanear duplicatas: " + ex3.Message));
						});
					}
				});
			}
			if (_scanning)
			{
				GUILayout.Label("Escaneando arquivos .language...", Array.Empty<GUILayoutOption>());
				return;
			}
			if (_duplicates == null || _duplicates.Count == 0)
			{
				GUILayout.Label("Nenhum token duplicado encontrado.", Array.Empty<GUILayoutOption>());
				return;
			}
			GUILayout.Label($"{_duplicates.Count} token(s) duplicado(s):", GUI.skin.label, Array.Empty<GUILayoutOption>());
			GUILayout.Space(5f);
			int count = Math.Min(_duplicates.Count, 50);
			foreach (DuplicateEntry item in _duplicates.OrderByDescending((DuplicateEntry d) => d.Count).Take(count))
			{
				string arg = (string.IsNullOrEmpty(item.Language) ? "" : ("[" + item.Language + "] "));
				GUILayout.Label($"  {arg}{item.TokenName} ({item.Count}x)", Array.Empty<GUILayoutOption>());
				foreach (string file in item.Files)
				{
					GUILayout.Label("      " + file, Array.Empty<GUILayoutOption>());
				}
				GUILayout.Space(3f);
			}
			if (_duplicates.Count > 50)
			{
				GUILayout.Label($"  ... e mais {_duplicates.Count - 50} token(s)", Array.Empty<GUILayoutOption>());
			}
		}

		private void ProcessMainThreadQueue()
		{
			while (_mainThreadQueue.Count > 0)
			{
				try
				{
					_mainThreadQueue.Dequeue()?.Invoke();
				}
				catch (Exception ex)
				{
					Debug.LogError((object)("Error processing main thread queue: " + ex.Message));
				}
			}
		}

		private static int CountFileErrors()
		{
			int num = 0;
			try
			{
				LanguageFileValidator languageFileValidator = new LanguageFileValidator();
				string[] files = Directory.GetFiles(Paths.PluginPath, "*.language", SearchOption.AllDirectories);
				foreach (string filePath in files)
				{
					ValidationResult validationResult = languageFileValidator.ValidateFile(filePath);
					if (!validationResult.IsValid)
					{
						num += validationResult.Errors.Count;
					}
				}
			}
			catch
			{
			}
			return num;
		}
	}
	public class LanguageFileCompiler
	{
		public void CompileLanguageFiles(string sourceDir, string outputDir)
		{
			if (!Directory.Exists(sourceDir))
			{
				throw new DirectoryNotFoundException("Origem nao encontrada: " + sourceDir);
			}
			if (!Directory.Exists(outputDir))
			{
				Directory.CreateDirectory(outputDir);
			}
			string[] languageFiles = LanguageFileHelper.GetLanguageFiles(sourceDir);
			List<string> list = new List<string>();
			string[] array = languageFiles;
			foreach (string text in array)
			{
				try
				{
					string contents = CompileFile(text);
					string relativePath = Path.GetRelativePath(sourceDir, text);
					string path = Path.Combine(outputDir, relativePath + ".compiled");
					string directoryName = Path.GetDirectoryName(path);
					if (!Directory.Exists(directoryName))
					{
						Directory.CreateDirectory(directoryName);
					}
					File.WriteAllText(path, contents, Encoding.UTF8);
				}
				catch (Exception ex)
				{
					list.Add(Path.GetFileName(text) + ": " + ex.Message);
				}
			}
			if (list.Count > 0)
			{
				throw new AggregateException("Erros na compilacao:", list.Select((string e) => new Exception(e)));
			}
		}

		private static string CompileFile(string filePath)
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("// COMPILED");
			stringBuilder.AppendLine("// " + Path.GetFileName(filePath));
			stringBuilder.AppendLine();
			foreach (KeyValuePair<string, Dictionary<string, string>> item in LanguageFileHelper.ParseTokensFromFile(filePath))
			{
				string key = item.Key;
				foreach (KeyValuePair<string, string> item2 in item.Value)
				{
					stringBuilder.AppendLine(key + "." + item2.Key + "=" + item2.Value);
				}
			}
			return stringBuilder.ToString().TrimEnd();
		}
	}
	internal static class LanguageFileHelper
	{
		public static string[] GetLanguageFiles(string directory)
		{
			if (!Directory.Exists(directory))
			{
				throw new DirectoryNotFoundException("Diretorio nao encontrado: " + directory);
			}
			return Directory.GetFiles(directory, "*.language", SearchOption.AllDirectories);
		}

		public static Dictionary<string, Dictionary<string, string>> ParseTokensFromFile(string filePath)
		{
			string text = File.ReadAllText(filePath).TrimStart();
			if (text.StartsWith("{"))
			{
				return ParseJsonTokens(text);
			}
			return ParseSimpleTokens(text, DetectLanguageFromFileName(filePath));
		}

		private static Dictionary<string, Dictionary<string, string>> ParseJsonTokens(string content)
		{
			Dictionary<string, Dictionary<string, string>> dictionary = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);
			JSONNode val = JSON.Parse(content);
			if (val == (object)null)
			{
				return dictionary;
			}
			foreach (string key2 in val.Keys)
			{
				JSONNode val2 = val[key2];
				if (val2 == (object)null)
				{
					continue;
				}
				string key = (key2.Equals("strings", StringComparison.OrdinalIgnoreCase) ? "generic" : key2);
				Dictionary<string, string> dictionary2 = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
				foreach (string key3 in val2.Keys)
				{
					dictionary2[key3] = val2[key3].Value;
				}
				dictionary[key] = dictionary2;
			}
			return dictionary;
		}

		private static Dictionary<string, Dictionary<string, string>> ParseSimpleTokens(string content, string language)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
			string[] array = content.Split('\n');
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (string.IsNullOrWhiteSpace(text) || text.StartsWith("//") || text.StartsWith("@"))
				{
					continue;
				}
				int num = text.IndexOf('=');
				if (num >= 1)
				{
					string text2 = text.Substring(0, num).Trim();
					string text3 = text.Substring(num + 1).Trim();
					if (text3.StartsWith("\"") && text3.EndsWith("\"") && text3.Length >= 2)
					{
						text3 = text3.Substring(1, text3.Length - 2);
					}
					if (!string.IsNullOrEmpty(text2))
					{
						dictionary[text2] = text3;
					}
				}
			}
			return new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase) { { language, dictionary } };
		}

		internal static string DetectLanguageFromFileName(string filePath)
		{
			string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath);
			if (fileNameWithoutExtension == null)
			{
				return "generic";
			}
			if (fileNameWithoutExtension.EndsWith("_eo", StringComparison.OrdinalIgnoreCase))
			{
				return "eo";
			}
			if (fileNameWithoutExtension.EndsWith("_la", StringComparison.OrdinalIgnoreCase))
			{
				return "la";
			}
			if (fileNameWithoutExtension.EndsWith("_ua", StringComparison.OrdinalIgnoreCase))
			{
				return "uk";
			}
			if (fileNameWithoutExtension.EndsWith("_uk", StringComparison.OrdinalIgnoreCase))
			{
				return "uk";
			}
			if (fileNameWithoutExtension.EndsWith("_pt-BR", StringComparison.OrdinalIgnoreCase))
			{
				return "pt-BR";
			}
			if (fileNameWithoutExtension.EndsWith("_en", StringComparison.OrdinalIgnoreCase))
			{
				return "en";
			}
			if (fileNameWithoutExtension.EndsWith("_de", StringComparison.OrdinalIgnoreCase))
			{
				return "de";
			}
			if (fileNameWithoutExtension.EndsWith("_fr", StringComparison.OrdinalIgnoreCase))
			{
				return "fr";
			}
			if (fileNameWithoutExtension.EndsWith("_es", StringComparison.OrdinalIgnoreCase))
			{
				return "es-ES";
			}
			if (fileNameWithoutExtension.EndsWith("_ru", StringComparison.OrdinalIgnoreCase))
			{
				return "ru";
			}
			if (fileNameWithoutExtension.EndsWith("_ja", StringComparison.OrdinalIgnoreCase))
			{
				return "ja";
			}
			if (fileNameWithoutExtension.EndsWith("_ko", StringComparison.OrdinalIgnoreCase))
			{
				return "ko";
			}
			if (fileNameWithoutExtension.EndsWith("_zh", StringComparison.OrdinalIgnoreCase))
			{
				return "zh-CN";
			}
			if (fileNameWithoutExtension.EndsWith("_tr", StringComparison.OrdinalIgnoreCase))
			{
				return "tr";
			}
			if (fileNameWithoutExtension.EndsWith("_it", StringComparison.OrdinalIgnoreCase))
			{
				return "it";
			}
			return "generic";
		}

		public static string[] GetCodeFiles(string directory)
		{
			if (!Directory.Exists(directory))
			{
				return Array.Empty<string>();
			}
			return Directory.GetFiles(directory, "*.cs", SearchOption.AllDirectories);
		}
	}
	public class LanguageFileValidator
	{
		private static readonly Regex TokenPattern = new Regex("^[A-Za-z0-9_.]+\\s*=", RegexOptions.Compiled);

		private static readonly Regex CommentPattern = new Regex("^\\s*//", RegexOptions.Compiled);

		private static readonly Regex TokenNameRegex = new Regex("^[A-Za-z0-9_.]+$", RegexOptions.Compiled);

		public ValidationResult ValidateFile(string filePath)
		{
			if (!File.Exists(filePath))
			{
				return ValidationResult.Error("Arquivo nao encontrado: " + filePath);
			}
			string[] array = File.ReadAllLines(filePath);
			List<string> list = new List<string>();
			List<string> list2 = new List<string>();
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i];
				int num = i + 1;
				if (string.IsNullOrWhiteSpace(text) || CommentPattern.IsMatch(text))
				{
					continue;
				}
				string text2 = text.Trim();
				if (!(text2 == "{") && !(text2 == "}"))
				{
					if (!TokenPattern.IsMatch(text2))
					{
						list.Add($"Linha {num}: Sintaxe invalida: '{text}'");
					}
					if (HasPotentialIssues(text))
					{
						list2.Add($"Linha {num}: Possivel problema de espacos: '{text}'");
					}
				}
			}
			return new ValidationResult
			{
				IsValid = (list.Count == 0),
				Errors = list,
				Warnings = list2,
				FilePath = filePath
			};
		}

		public bool ValidateTokenSyntax(string token)
		{
			if (string.IsNullOrWhiteSpace(token))
			{
				return false;
			}
			int num = token.IndexOf('=');
			if (num < 1)
			{
				return false;
			}
			string text = token.Substring(0, num).Trim();
			string value = token.Substring(num + 1).Trim();
			if (!string.IsNullOrWhiteSpace(text) && !string.IsNullOrWhiteSpace(value))
			{
				return IsValidTokenName(text);
			}
			return false;
		}

		private static bool IsValidTokenName(string tokenName)
		{
			if (TokenNameRegex.IsMatch(tokenName))
			{
				return !tokenName.StartsWith("//");
			}
			return false;
		}

		private static bool HasPotentialIssues(string line)
		{
			if (!line.Contains("  ") && !line.StartsWith(" "))
			{
				return line.EndsWith(" ");
			}
			return true;
		}
	}
	public class ValidationResult
	{
		public bool IsValid { get; set; }

		public List<string> Errors { get; set; } = new List<string>();

		public List<string> Warnings { get; set; } = new List<string>();

		public string FilePath { get; set; }

		public static ValidationResult Error(string message)
		{
			return new ValidationResult
			{
				IsValid = false,
				Errors = new List<string> { message }
			};
		}
	}
	public class LanguageHotReload : IDisposable
	{
		private static LanguageHotReload _instance;

		private FileSystemWatcher _languageWatcher;

		private FileSystemWatcher _jsonWatcher;

		private readonly Dictionary<string, DateTime> _lastModified = new Dictionary<string, DateTime>();

		private readonly Queue<string> _pending = new Queue<string>();

		private readonly object _pendingLock = new object();

		private System.Timers.Timer _debounceTimer;

		private SynchronizationContext _unityContext;

		public static LanguageHotReload Instance => _instance ?? (_instance = new LanguageHotReload());

		public bool IsEnabled { get; private set; }

		public string WatchDirectory { get; private set; }

		public event Action<string, string> OnTokenReloaded;

		public event Action<string> OnFileReloaded;

		public event Action<IEnumerable<string>> OnBatchReloaded;

		public event Action OnBeforeReload;

		public event Action OnAfterReload;

		public void Enable(string directory)
		{
			if (IsEnabled)
			{
				Disable();
			}
			if (!Directory.Exists(directory))
			{
				Debug.LogError((object)("[LanguageAPI] Diretorio nao encontrado: " + directory));
				return;
			}
			_unityContext = SynchronizationContext.Current;
			WatchDirectory = directory;
			try
			{
				_languageWatcher = new FileSystemWatcher(directory)
				{
					Filter = "*.language",
					IncludeSubdirectories = true,
					NotifyFilter = (NotifyFilters.FileName | NotifyFilters.LastWrite)
				};
				_languageWatcher.Changed += OnChanged;
				_languageWatcher.Created += OnChanged;
				_languageWatcher.Deleted += OnChanged;
				_languageWatcher.EnableRaisingEvents = true;
				string path = PelePaths.LanguageRoot(directory);
				if (Directory.Exists(path))
				{
					_jsonWatcher = new FileSystemWatcher(path)
					{
						Filter = "*.json",
						IncludeSubdirectories = true,
						NotifyFilter = (NotifyFilters.FileName | NotifyFilters.LastWrite)
					};
					_jsonWatcher.Changed += OnChanged;
					_jsonWatcher.Created += OnChanged;
					_jsonWatcher.Deleted += OnChanged;
					_jsonWatcher.EnableRaisingEvents = true;
				}
				_debounceTimer = new System.Timers.Timer(500.0)
				{
					AutoReset = false
				};
				_debounceTimer.Elapsed += delegate
				{
					ProcessPending();
				};
				IsEnabled = true;
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[LanguageAPI] Erro ao iniciar FileSystemWatcher: " + ex.Message));
			}
		}

		public void Disable()
		{
			IsEnabled = false;
			if (_languageWatcher != null)
			{
				_languageWatcher.EnableRaisingEvents = false;
				_languageWatcher.Changed -= OnChanged;
				_languageWatcher.Created -= OnChanged;
				_languageWatcher.Deleted -= OnChanged;
				_languageWatcher.Dispose();
				_languageWatcher = null;
			}
			if (_jsonWatcher != null)
			{
				_jsonWatcher.EnableRaisingEvents = false;
				_jsonWatcher.Changed -= OnChanged;
				_jsonWatcher.Created -= OnChanged;
				_jsonWatcher.Deleted -= OnChanged;
				_jsonWatcher.Dispose();
				_jsonWatcher = null;
			}
			_debounceTimer?.Stop();
			_debounceTimer?.Dispose();
			_debounceTimer = null;
			lock (_pendingLock)
			{
				_pending.Clear();
				_lastModified.Clear();
			}
		}

		public void Dispose()
		{
			Disable();
		}

		private void OnChanged(object sender, FileSystemEventArgs e)
		{
			lock (_pendingLock)
			{
				try
				{
					DateTime lastWriteTime = File.GetLastWriteTime(e.FullPath);
					if (_lastModified.TryGetValue(e.FullPath, out var value) && value == lastWriteTime)
					{
						return;
					}
					_lastModified[e.FullPath] = lastWriteTime;
				}
				catch
				{
					return;
				}
				if (!_pending.Contains(e.FullPath))
				{
					_pending.Enqueue(e.FullPath);
				}
				_debounceTimer?.Stop();
				_debounceTimer?.Start();
			}
		}

		private void ProcessPending()
		{
			if (!IsEnabled)
			{
				return;
			}
			List<string> files;
			lock (_pendingLock)
			{
				files = new List<string>(_pending);
				_pending.Clear();
			}
			if (files.Count == 0)
			{
				return;
			}
			SynchronizationContext unityContext = _unityContext;
			if (unityContext != null)
			{
				unityContext.Post(delegate
				{
					FireEvents();
				}, null);
			}
			else
			{
				FireEvents();
			}
			void FireEvents()
			{
				try
				{
					this.OnBeforeReload?.Invoke();
				}
				catch (Exception ex)
				{
					Debug.LogError((object)("[LanguageAPI] OnBeforeReload: " + ex.Message));
				}
				LanguageAPI.ClearAllTokens();
				string[] languageFiles = LanguageFileHelper.GetLanguageFiles(WatchDirectory);
				foreach (string text in languageFiles)
				{
					try
					{
						foreach (KeyValuePair<string, Dictionary<string, string>> item in LanguageFileHelper.ParseTokensFromFile(text))
						{
							foreach (KeyValuePair<string, string> item2 in item.Value)
							{
								LanguageAPI.AddOrUpdateToken(item2.Key, item2.Value, item.Key);
								try
								{
									this.OnTokenReloaded?.Invoke(item.Key, item2.Key);
								}
								catch (Exception ex2)
								{
									Debug.LogError((object)("[LanguageAPI] OnTokenReloaded: " + ex2.Message));
								}
							}
						}
						try
						{
							this.OnFileReloaded?.Invoke(text);
						}
						catch (Exception ex3)
						{
							Debug.LogError((object)("[LanguageAPI] OnFileReloaded: " + ex3.Message));
						}
					}
					catch (Exception ex4)
					{
						Debug.LogError((object)("[LanguageAPI] Erro ao recarregar " + text + ": " + ex4.Message));
					}
				}
				try
				{
					this.OnAfterReload?.Invoke();
				}
				catch (Exception ex5)
				{
					Debug.LogError((object)("[LanguageAPI] OnAfterReload: " + ex5.Message));
				}
				try
				{
					this.OnBatchReloaded?.Invoke(files);
				}
				catch (Exception ex6)
				{
					Debug.LogError((object)("[LanguageAPI] OnBatchReloaded: " + ex6.Message));
				}
			}
		}
	}
	internal static class LanguageNames
	{
		private static readonly Dictionary<string, string> Map = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
		{
			{ "en", "English" },
			{ "pt-BR", "Portuguese (Brazil)" },
			{ "es-ES", "Spanish (Spain)" },
			{ "de", "German" },
			{ "fr", "French" },
			{ "it", "Italian" },
			{ "ja", "Japanese" },
			{ "ko", "Korean" },
			{ "ru", "Russian" },
			{ "tr", "Turkish" },
			{ "uk", "Ukrainian" },
			{ "zh-CN", "Chinese (Simplified)" },
			{ "es-419", "Spanish (Latin America)" },
			{ "la", "Latin" },
			{ "eo", "Esperanto" }
		};

		internal static string GetFriendlyName(string langCode)
		{
			if (!Map.TryGetValue(langCode, out string value))
			{
				return langCode;
			}
			return value;
		}

		internal static List<string> GetAvailableLanguages(bool includeCustom = true)
		{
			try
			{
				if (typeof(Language).GetField("languagesByName", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null) is Dictionary<string, Language> dictionary)
				{
					HashSet<string> hashSet = new HashSet<string>(dictionary.Keys, StringComparer.OrdinalIgnoreCase);
					if (includeCustom)
					{
						string[] array = new string[3] { "uk", "la", "eo" };
						foreach (string text in array)
						{
							if (!hashSet.Contains(text))
							{
								Language.FindLanguageByName(text);
								hashSet.Add(text);
							}
						}
					}
					return hashSet.OrderBy<string, string>((string x) => x, StringComparer.OrdinalIgnoreCase).ToList();
				}
			}
			catch
			{
			}
			return new List<string>();
		}
	}
	internal static class LanguagePauseMenu
	{
		private class LanguageDialogCloseWatcher : MonoBehaviour
		{
			private float _delay = 0.4f;

			public SimpleDialogBox dialog;

			private bool _closing;

			private void Update()
			{
				if (!_closing)
				{
					_delay -= Time.unscaledDeltaTime;
					if (!(_delay > 0f) && (Input.GetKeyDown((KeyCode)27) || Input.GetKeyDown((KeyCode)331)))
					{
						_closing = true;
						CloseDialog(dialog);
					}
				}
			}
		}

		private class LanguageInputLegendController : MonoBehaviour
		{
			public MPEventSystem eventSystem;

			public InputBindingDisplayController applyGlyph;

			public InputBindingDisplayController cancelGlyph;

			private void Update()
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Invalid comparison between Unknown and I4
				bool visible = (Object)(object)eventSystem != (Object)null && (int)eventSystem.currentInputSource == 1;
				SetGlyphVisible(applyGlyph, visible);
				SetGlyphVisible(cancelGlyph, visible);
			}

			private static void SetGlyphVisible(InputBindingDisplayController glyph, bool visible)
			{
				if (!((Object)(object)glyph == (Object)null))
				{
					HGTextMeshProUGUI component = ((Component)glyph).GetComponent<HGTextMeshProUGUI>();
					if ((Object)(object)component != (Object)null)
					{
						((Behaviour)component).enabled = visible;
					}
					Transform val = ((Component)glyph).transform.parent.Find("KeyFallback");
					if ((Object)(object)val != (Object)null)
					{
						((Component)val).gameObject.SetActive(!visible);
					}
				}
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__OnPauseAwake;
		}

		private static bool _hooksActive;

		private static MethodInfo _setCurrentLanguageMethod;

		internal static void Init()
		{
			//IL_0039: 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: Expected O, but got Unknown
			if (!_hooksActive)
			{
				_hooksActive = true;
				_setCurrentLanguageMethod = typeof(Language).GetMethod("SetCurrentLanguage", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				object obj = <>O.<0>__OnPauseAwake;
				if (obj == null)
				{
					hook_Awake val = OnPauseAwake;
					<>O.<0>__OnPauseAwake = val;
					obj = (object)val;
				}
				PauseScreenController.Awake += (hook_Awake)obj;
			}
		}

		internal static void Cleanup()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			if (_hooksActive)
			{
				_hooksActive = false;
				object obj = <>O.<0>__OnPauseAwake;
				if (obj == null)
				{
					hook_Awake val = OnPauseAwake;
					<>O.<0>__OnPauseAwake = val;
					obj = (object)val;
				}
				PauseScreenController.Awake -= (hook_Awake)obj;
			}
		}

		private static void OnPauseAwake(orig_Awake orig, PauseScreenController self)
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			orig.Invoke(self);
			try
			{
				RegisterUiTokens();
				RectTransform mainPanel = self.mainPanel;
				if ((Object)(object)mainPanel == (Object)null || ((Transform)mainPanel).childCount == 0)
				{
					return;
				}
				Transform child = ((Transform)mainPanel).GetChild(0).GetChild(1);
				if (!((Object)(object)child == (Object)null))
				{
					Transform obj = Object.Instantiate<Transform>(child, ((Transform)mainPanel).GetChild(0));
					((Object)obj).name = "LanguageSwitcherButton";
					LanguageTextMeshController componentInChildren = ((Component)obj).GetComponentInChildren<LanguageTextMeshController>();
					if ((Object)(object)componentInChildren != (Object)null)
					{
						componentInChildren.token = "PELE_LANGUAGE_BUTTON";
					}
					HGTextMeshProUGUI componentInChildren2 = ((Component)obj).GetComponentInChildren<HGTextMeshProUGUI>();
					if ((Object)(object)componentInChildren2 != (Object)null)
					{
						((TMP_Text)componentInChildren2).text = Language.GetString("PELE_LANGUAGE_BUTTON");
					}
					HGButton component = ((Component)obj).GetComponent<HGButton>();
					((Button)component).onClick = new ButtonClickedEvent();
					((UnityEvent)((Button)component).onClick).AddListener((UnityAction)delegate
					{
						ShowLanguageDialog(self);
					});
					((Component)obj).transform.SetAsLastSibling();
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger = LanguagePlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)("Falha no botao de idiomas: " + ex.Message));
				}
			}
		}

		private static void RegisterUiTokens()
		{
			LanguageAPI.AddOrUpdateToken("PELE_LANGUAGE_BUTTON", "Language");
			LanguageAPI.AddOrUpdateToken("PELE_LANGUAGE_BUTTON", "Idioma", "pt-BR");
			LanguageAPI.AddOrUpdateToken("PELE_LANGUAGE_BUTTON", "Lingua", "la");
			LanguageAPI.AddOrUpdateToken("PELE_LANGUAGE_BUTTON", "Lingvo", "eo");
			LanguageAPI.AddOrUpdateToken("PELE_LANGUAGE_BUTTON", "Мова", "uk");
			LanguageAPI.AddOrUpdateToken("PELE_LANGUAGE_BUTTON", "Sprache", "de");
			LanguageAPI.AddOrUpdateToken("PELE_LANGUAGE_BUTTON", "Idioma", "es-ES");
			LanguageAPI.AddOrUpdateToken("PELE_LANGUAGE_BUTTON", "Idioma", "es-419");
			LanguageAPI.AddOrUpdateToken("PELE_LANGUAGE_BUTTON", "Langue", "fr");
			LanguageAPI.AddOrUpdateToken("PELE_LANGUAGE_BUTTON", "Lingua", "it");
			LanguageAPI.AddOrUpdateToken("PELE_LANGUAGE_BUTTON", "言語", "ja");
			LanguageAPI.AddOrUpdateToken("PELE_LANGUAGE_BUTTON", "언어", "ko");
			LanguageAPI.AddOrUpdateToken("PELE_LANGUAGE_BUTTON", "Язык", "ru");
			LanguageAPI.AddOrUpdateToken("PELE_LANGUAGE_BUTTON", "Dil", "tr");
			LanguageAPI.AddOrUpdateToken("PELE_LANGUAGE_BUTTON", "语言", "zh-CN");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_TITLE", "Select Language");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_TITLE", "Selecionar idioma", "pt-BR");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_TITLE", "Elige linguam", "la");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_TITLE", "Elekti lingvon", "eo");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_TITLE", "Вибрати мову", "uk");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_DESC", "Choose a language below. The change applies immediately.");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_DESC", "Escolha um idioma abaixo. A troca e aplicada imediatamente.", "pt-BR");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_DESC", "Elige linguam infra. Mutatio statim fit.", "la");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_DESC", "Elektu lingvon sube. La sxangxo validas tuj.", "eo");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_DESC", "Оберіть мову нижче. Зміна застосовується одразу.", "uk");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_CANCEL", "Cancel");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_CANCEL", "Cancelar", "pt-BR");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_CANCEL", "Abrogare", "la");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_CANCEL", "Nuligi", "eo");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_CANCEL", "Скасувати", "uk");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_APPLY_HINT", "Apply");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_APPLY_HINT", "Aplicar", "pt-BR");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_APPLY_HINT", "Applicare", "la");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_APPLY_HINT", "Apliki", "eo");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_APPLY_HINT", "Застосувати", "uk");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_CANCEL_HINT", "Cancel");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_CANCEL_HINT", "Cancelar", "pt-BR");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_CANCEL_HINT", "Abrogare", "la");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_CANCEL_HINT", "Nuligi", "eo");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_CANCEL_HINT", "Скасувати", "uk");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_MOUSE_APPLY_HINT", "Left click");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_MOUSE_APPLY_HINT", "Clique esquerdo", "pt-BR");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_MOUSE_APPLY_HINT", "Clic sinistro", "la");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_MOUSE_APPLY_HINT", "Maldekstra klako", "eo");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_MOUSE_APPLY_HINT", "Ліва кнопка", "uk");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_ESC_HINT", "Esc");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_ESC_HINT", "Esc", "pt-BR");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_ESC_HINT", "Esc", "la");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_ESC_HINT", "Esc", "eo");
			LanguageAPI.AddOrUpdateToken("SWITCH_LANGUAGE_ESC_HINT", "Esc", "uk");
		}

		private static void SetLanguage(string lang)
		{
			if (_setCurrentLanguageMethod == null)
			{
				ManualLogSource logger = LanguagePlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)"SetCurrentLanguage method not found via reflection");
				}
				return;
			}
			try
			{
				if (LanguageConVar.instance != null)
				{
					((BaseConVar)LanguageConVar.instance).SetString(lang);
					return;
				}
				_setCurrentLanguageMethod.Invoke(null, new object[1] { lang });
			}
			catch (Exception ex)
			{
				string text = ex.InnerException?.Message ?? ex.Message;
				string text2 = ex.InnerException?.StackTrace ?? ex.StackTrace;
				ManualLogSource logger2 = LanguagePlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)("Falha ao trocar lingua para '" + lang + "': " + text));
				}
				ManualLogSource logger3 = LanguagePlugin.Logger;
				if (logger3 != null)
				{
					logger3.LogError((object)("  Stack: " + text2));
				}
			}
		}

		private static void ShowLanguageDialog(PauseScreenController pause)
		{
			//IL_006c: 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_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_00e8: Expected O, but got Unknown
			RegisterUiTokens();
			List<string> availableLanguages = LanguageNames.GetAvailableLanguages();
			foreach (string item in availableLanguages)
			{
				LanguageAPI.AddOrUpdateToken("LANG_SEL_" + item, LanguageNames.GetFriendlyName(item));
			}
			EventSystem current2 = EventSystem.current;
			SimpleDialogBox val = SimpleDialogBox.Create((MPEventSystem)(object)((current2 is MPEventSystem) ? current2 : null));
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			val.headerToken = new TokenParamsPair
			{
				token = "SWITCH_LANGUAGE_TITLE"
			};
			val.descriptionToken = new TokenParamsPair
			{
				token = "SWITCH_LANGUAGE_DESC"
			};
			foreach (string item2 in availableLanguages)
			{
				string captured = item2;
				val.AddActionButton((UnityAction)delegate
				{
					SetLanguage(captured);
				}, "LANG_SEL_" + item2, true, Array.Empty<object>());
			}
			(((Object)(object)val.rootObject != (Object)null) ? val.rootObject : ((Component)val).gameObject).AddComponent<LanguageDialogCloseWatcher>().dialog = val;
			MonoBehaviour component = ((Component)pause).GetComponent<MonoBehaviour>();
			if ((Object)(object)component != (Object)null)
			{
				component.StartCoroutine(DelayedGridLayout(val));
			}
			else
			{
				ApplyGridLayout(val);
			}
		}

		private static void CloseDialog(SimpleDialogBox dialog)
		{
			if (!((Object)(object)dialog == (Object)null))
			{
				Object.Destroy((Object)(object)(((Object)(object)dialog.rootObject != (Object)null) ? dialog.rootObject : ((Component)dialog).gameObject));
			}
		}

		private static IEnumerator DelayedGridLayout(SimpleDialogBox dialog)
		{
			yield return null;
			ApplyGridLayout(dialog);
		}

		private static void ApplyGridLayout(SimpleDialogBox dialog)
		{
			//IL_0073: 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)
			try
			{
				RectTransform buttonContainer = dialog.buttonContainer;
				if ((Object)(object)buttonContainer == (Object)null)
				{
					ManualLogSource logger = LanguagePlugin.Logger;
					if (logger != null)
					{
						logger.LogWarning((object)"ApplyGridLayout: buttonContainer e null");
					}
					return;
				}
				LayoutGroup[] components = ((Component)buttonContainer).GetComponents<LayoutGroup>();
				foreach (LayoutGroup obj in components)
				{
					((Behaviour)obj).enabled = false;
					Object.DestroyImmediate((Object)(object)obj, true);
				}
				GridLayoutGroup obj2 = ((Component)buttonContainer).gameObject.AddComponent<GridLayoutGroup>();
				obj2.constraint = (Constraint)1;
				obj2.constraintCount = 3;
				obj2.cellSize = new Vector2(200f, 40f);
				obj2.spacing = new Vector2(8f, 6f);
				obj2.startAxis = (Axis)0;
				ContentSizeFitter obj3 = ((Component)buttonContainer).GetComponent<ContentSizeFitter>() ?? ((Component)buttonContainer).gameObject.AddComponent<ContentSizeFitter>();
				obj3.verticalFit = (FitMode)2;
				obj3.horizontalFit = (FitMode)2;
				AddInputLegend(dialog);
				LayoutRebuilder.ForceRebuildLayoutImmediate(buttonContainer);
				WrapGridNavigation(buttonContainer);
				LanguagePlugin.LogVerbose($"ApplyGridLayout: grid aplicado com {((Transform)buttonContainer).childCount} botoes");
			}
			catch (Exception ex)
			{
				ManualLogSource logger2 = LanguagePlugin.Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)("Falha ao aplicar grid layout: " + ex.Message));
				}
			}
		}

		private static void WrapGridNavigation(RectTransform container)
		{
			//IL_0069: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			List<MPButton> list = new List<MPButton>();
			MPButton[] componentsInChildren = ((Component)container).GetComponentsInChildren<MPButton>();
			foreach (MPButton val in componentsInChildren)
			{
				if (!((Object)(object)((Component)val).GetComponentInParent<LanguageInputLegendController>() != (Object)null))
				{
					list.Add(val);
				}
			}
			if (list.Count == 0)
			{
				return;
			}
			int num = Mathf.Min(3, list.Count);
			int num2 = (list.Count + num - 1) / num;
			for (int j = 0; j < list.Count; j++)
			{
				Navigation val2 = default(Navigation);
				((Navigation)(ref val2)).mode = (Mode)4;
				Navigation navigation = val2;
				int num3 = j % num;
				int num4 = j / num;
				int num5 = ((num3 > 0) ? (j - 1) : (j + num - 1));
				int num6 = ((num3 < num - 1) ? (j + 1) : (j - num3));
				int num7 = ((num4 > 0) ? (j - num) : ((num2 - 1) * num + Mathf.Min(num3, list.Count - (num2 - 1) * num - 1)));
				int num8 = ((num4 < num2 - 1) ? Mathf.Min(j + num, list.Count - 1) : num3);
				if (num5 >= 0 && num5 < list.Count)
				{
					((Navigation)(ref navigation)).selectOnLeft = (Selectable)(object)list[num5];
				}
				if (num6 >= 0 && num6 < list.Count)
				{
					((Navigation)(ref navigation)).selectOnRight = (Selectable)(object)list[num6];
				}
				if (num7 >= 0 && num7 < list.Count)
				{
					((Navigation)(ref navigation)).selectOnUp = (Selectable)(object)list[num7];
				}
				if (num8 >= 0 && num8 < list.Count)
				{
					((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)list[num8];
				}
				((Selectable)list[j]).navigation = navigation;
			}
		}

		private static void AddInputLegend(SimpleDialogBox dialog)
		{
			//IL_005d: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected O, but got Unknown
			RectTransform val = dialog?.buttonContainer;
			if (!((Object)(object)val == (Object)null) && !((Object)(object)((Transform)val).Find("PELELanguageInputLegend") != (Object)null))
			{
				GameObject val2 = new GameObject("PELELanguageInputLegend", new Type[3]
				{
					typeof(RectTransform),
					typeof(HorizontalLayoutGroup),
					typeof(LanguageInputLegendController)
				});
				RectTransform component = val2.GetComponent<RectTransform>();
				((Transform)component).SetParent((Transform)(object)val, false);
				component.sizeDelta = new Vector2(616f, 42f);
				LayoutElement obj = val2.AddComponent<LayoutElement>();
				obj.minWidth = 616f;
				obj.preferredWidth = 616f;
				obj.minHeight = 42f;
				obj.preferredHeight = 42f;
				obj.flexibleWidth = 0f;
				obj.flexibleHeight = 0f;
				HorizontalLayoutGroup component2 = val2.GetComponent<HorizontalLayoutGroup>();
				((HorizontalOrVerticalLayoutGroup)component2).spacing = 58f;
				((LayoutGroup)component2).padding = new RectOffset(8, 0, 8, 0);
				((HorizontalOrVerticalLayoutGroup)component2).childForceExpandHeight = false;
				((HorizontalOrVerticalLayoutGroup)component2).childForceExpandWidth = false;
				LanguageInputLegendController component3 = val2.GetComponent<LanguageInputLegendController>();
				ref MPEventSystem eventSystem = ref component3.eventSystem;
				EventSystem current = EventSystem.current;
				eventSystem = (MPEventSystem)(object)((current is MPEventSystem) ? current : null);
				component3.applyGlyph = AddLegendItem(component, "UISubmit", "SWITCH_LANGUAGE_MOUSE_APPLY_HINT", "SWITCH_LANGUAGE_APPLY_HINT");
				component3.cancelGlyph = AddLegendItem(component, "UICancel", "SWITCH_LANGUAGE_ESC_HINT", "SWITCH_LANGUAGE_CANCEL_HINT");
			}
		}

		private static InputBindingDisplayController AddLegendItem(RectTransform parent, string actionName, string keyToken, string textToken)
		{
			//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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_00c6: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(actionName + "Legend", new Type[2]
			{
				typeof(RectTransform),
				typeof(HorizontalLayoutGroup)
			});
			RectTransform component = val.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)parent, false);
			component.sizeDelta = new Vector2(270f, 30f);
			HorizontalLayoutGroup component2 = val.GetComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)component2).spacing = 7f;
			((HorizontalOrVerticalLayoutGroup)component2).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)component2).childForceExpandWidth = false;
			LayoutElement obj = val.AddComponent<LayoutElement>();
			obj.minWidth = 270f;
			obj.preferredWidth = 270f;
			obj.minHeight = 30f;
			obj.preferredHeight = 30f;
			GameObject val2 = new GameObject("Glyph", new Type[1] { typeof(RectTransform) });
			val2.SetActive(false);
			RectTransform component3 = val2.GetComponent<RectTransform>();
			((Transform)component3).SetParent((Transform)(object)component, false);
			component3.sizeDelta = new Vector2(28f, 28f);
			HGTextMeshProUGUI obj2 = val2.AddComponent<HGTextMeshProUGUI>();
			((TMP_Text)obj2).fontSize = 18f;
			((TMP_Text)obj2).alignment = (TextAlignmentOptions)514;
			InputBindingDisplayController val3 = val2.AddComponent<InputBindingDisplayController>();
			val3.actionName = actionName;
			val3.useExplicitInputSource = true;
			val3.explicitInputSource = (InputSource)1;
			val2.SetActive(true);
			GameObject val4 = new GameObject("KeyFallback", new Type[1] { typeof(RectTransform) });
			val4.SetActive(false);
			RectTransform component4 = val4.GetComponent<RectTransform>();
			((Transform)component4).SetParent((Transform)(object)component, false);
			component4.sizeDelta = new Vector2(158f, 28f);
			HGTextMeshProUGUI obj3 = val4.AddComponent<HGTextMeshProUGUI>();
			((TMP

plugins/PELE/PELE.KingDBZFix.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using NS_KingModUtilities;
using RoR2;
using RoR2.UI;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PELE.KingDBZFix")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1757dcd61239f8763a6fee2fd8d61a758edf3b91")]
[assembly: AssemblyProduct("PELE.KingDBZFix")]
[assembly: AssemblyTitle("PELE.KingDBZFix")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PELE.KingDBZFix
{
	public static class DBZLocalizationDictionary
	{
		private static readonly Dictionary<string, Dictionary<string, string>> _languages = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase)
		{
			["pt-BR"] = new Dictionary<string, string>
			{
				["Transformations"] = "Transformações",
				["KINGMOD_REMOVE"] = "REMOVER",
				["KINGMOD_TOGGLE_EXTRA"] = "ALTERNAR EXTRAS",
				["KINGMOD_COSTS_PREFIX"] = "Custa ",
				["KINGMOD_TOTAL_MASTERY_REQUIRED"] = "Níveis de Maestria Totais Necessários: ",
				["KINGMOD_TOTAL_MASTERY_LEVELS"] = "Níveis de Maestria Totais",
				["KINGMOD_KI_DRAIN"] = "Dreno de Ki: ",
				["KINGMOD_PER_SECOND"] = " Por Segundo",
				["KINGMOD_CHARGE_POWER"] = "Poder de Carga: ",
				["KINGMOD_STAT_DAMAGE"] = "Dano: ",
				["KINGMOD_STAT_ARMOR"] = "Armadura: ",
				["KINGMOD_STAT_HEALTH_REGEN"] = "Regeneração de Vida: ",
				["KINGMOD_STAT_ATTACK_SPEED"] = "Velocidade de Ataque: ",
				["KINGMOD_STAT_MOVE_SPEED"] = "Velocidade de Movimento: ",
				["KINGMOD_STAT_MAX_HEALTH"] = "Vida Máxima: ",
				["KINGMOD_MASTERED"] = "Dominado ",
				["KINGMOD_POWER_LEVEL"] = "Nível de Poder: ",
				["KINGMOD_NO_STAT_BOOSTS"] = " não possui bônus de atributos...",
				["KINGMOD_ALL_FORMS_UNLOCKED"] = "Todas as Formas desbloqueadas?",
				["KINGMOD_UNTIL_NEXT_UNLOCK"] = " nível(is) de Maestria até o próximo desbloqueio",
				["KINGMOD_COSTS_KI_FORMAT"] = "Custa <color=#03bcff>{0} de Ki</color>",
				["KINGMOD_DAMAGE_FORMAT"] = "<color=#E5C962>{0}% de Dano</color>",
				["KINGMOD_STAT_NAME_DAMAGE"] = "Dano",
				["KINGMOD_STAT_NAME_ARMOR"] = "Armadura",
				["KINGMOD_STAT_NAME_ATTACKSPEED"] = "Velocidade de Ataque",
				["KINGMOD_STAT_NAME_MOVESPEED"] = "Velocidade de Movimento",
				["KINGMOD_STAT_NAME_REGEN"] = "Regeneração de Vida",
				["KINGMOD_STAT_NAME_MAXHEALTH"] = "Vida Máxima",
				["KINGMOD_TUTORIAL_F1"] = "Ativar/Desativar Tutoriais pressionando F1",
				["KINGMOD_TUTORIAL_FORM_MASTERY"] = "Com a Maestria de Forma, ganhe Experiência com o tempo ou causando dano a inimigos. Subir o nível da forma concede o seguinte:\n- Um aumento no bônus de atributos da transformação.\n- Uma redução no dreno de Ki da transformação.\n- Um aumento na regeneração geral de Ki.\nNa Forma Base, regeneração de Ki e Ki máximo são aumentados.",
				["KINGMOD_TUTORIAL_TRANSFORM_TRIGGER"] = "Quando seu nível de maestria for alto o suficiente, ative uma Transformação Principal tocando no botão de transformação (Padrão 'C') e reverta pressionando (Padrão 'X'). Ao desbloquear mais Transformações, pressione o botão novamente para ascender ainda mais além!",
				["KINGMOD_TUTORIAL_ULTIMATE_SKILL"] = "Enquanto transformado, você tem acesso a uma Habilidade Suprema. Ative-a pressionando a tecla vinculada abaixo.",
				["KINGMOD_TUTORIAL_KI_RESOURCE"] = "Ki é um recurso que suas habilidades utilizam. Recupere Ki atingindo inimigos com sua habilidade primária.",
				["KINGMOD_TUTORIAL_ZENKAI"] = "Ganhe Zenkais morrendo ou ficando abaixo de 20% de vida por 30 segundos. Concede atributos bônus permanentes.",
				["KINGMOD_TUTORIAL_LIGHT_CHARGE"] = "Ganhe Carga de Luz atingindo inimigos com sua espada. Quando cheia, ative-a segurando o Botão de Transformação. Concede Dano e Chance Crítica bônus enquanto ativa.",
				["KINGMOD_TUTORIALS_ENABLED"] = "Tutoriais Ativados",
				["KINGMOD_TUTORIALS_DISABLED"] = "Tutoriais Desativados"
			},
			["tr"] = new Dictionary<string, string>
			{
				["Transformations"] = "Dönüşümler",
				["KINGMOD_REMOVE"] = "KALDIR",
				["KINGMOD_TOGGLE_EXTRA"] = "EKSTRALARI AÇ/KAPAT",
				["KINGMOD_COSTS_PREFIX"] = "Gereken: ",
				["KINGMOD_TOTAL_MASTERY_REQUIRED"] = "Gereken Toplam Ustalık Seviyesi: ",
				["KINGMOD_TOTAL_MASTERY_LEVELS"] = "Toplam Ustalık Seviyeleri",
				["KINGMOD_KI_DRAIN"] = "Ki Tüketimi: ",
				["KINGMOD_PER_SECOND"] = " Saniye Başına",
				["KINGMOD_CHARGE_POWER"] = "Şarj Gücü: ",
				["KINGMOD_STAT_DAMAGE"] = "Hasar: ",
				["KINGMOD_STAT_ARMOR"] = "Zırh: ",
				["KINGMOD_STAT_HEALTH_REGEN"] = "Can Yenilenmesi: ",
				["KINGMOD_STAT_ATTACK_SPEED"] = "Saldırı Hızı: ",
				["KINGMOD_STAT_MOVE_SPEED"] = "Hareket Hızı: ",
				["KINGMOD_STAT_MAX_HEALTH"] = "Maksimum Can: ",
				["KINGMOD_MASTERED"] = "Ustalık Kazanıldı ",
				["KINGMOD_POWER_LEVEL"] = "Güç Seviyesi: ",
				["KINGMOD_NO_STAT_BOOSTS"] = " özellik takviyesi yok...",
				["KINGMOD_ALL_FORMS_UNLOCKED"] = "Tüm Formlar açıldı mı?",
				["KINGMOD_UNTIL_NEXT_UNLOCK"] = " Ustalık seviyesi sonraki açılışa kadar",
				["KINGMOD_COSTS_KI_FORMAT"] = "<color=#03bcff>{0} Ki</color> Harcar",
				["KINGMOD_DAMAGE_FORMAT"] = "<color=#E5C962>%{0} Hasar</color>",
				["KINGMOD_STAT_NAME_DAMAGE"] = "Hasar",
				["KINGMOD_STAT_NAME_ARMOR"] = "Zırh",
				["KINGMOD_STAT_NAME_ATTACKSPEED"] = "Saldırı Hızı",
				["KINGMOD_STAT_NAME_MOVESPEED"] = "Hareket Hızı",
				["KINGMOD_STAT_NAME_REGEN"] = "Can Yenilenmesi",
				["KINGMOD_STAT_NAME_MAXHEALTH"] = "Maksimum Can",
				["KINGMOD_TUTORIAL_F1"] = "F1 tuşuna basarak Öğreticileri Aç/Kapat",
				["KINGMOD_TUTORIAL_FORM_MASTERY"] = "Form Ustalığı ile zamanla veya düşmanlara hasar vererek Deneyim kazanın. Form seviyesini yükseltmek şunları sağlar:\n- Dönüşümünüzün özellik takviyesinde artış.\n- Dönüşümünüzün Ki tüketiminde azalma.\n- Genel Ki yenilenmenizde artış.\nTemel Formda Ki yenilenmesi ve maksimum Ki kazanılır.",
				["KINGMOD_TUTORIAL_TRANSFORM_TRIGGER"] = "Ustalık seviyeniz yeterince yükseldiğinde, dönüşüm düğmesine (Varsayılan 'C') dokunarak bir Ana Dönüşümü etkinleştirin ve (Varsayılan 'X') basarak Gücü Azaltın. Daha fazla Dönüşüm açıldığında, daha da öteye yükselmek için dönüşüm düğmesine tekrar basın!",
				["KINGMOD_TUTORIAL_ULTIMATE_SKILL"] = "Dönüşmüş durumdayken bir Nihai Yeteneğe erişiminiz olur. Aşağıda atanan tuşa basarak etkinleştirin.",
				["KINGMOD_TUTORIAL_KI_RESOURCE"] = "Ki, yeteneklerinizin kullandığı bir kaynaktır. Birincil yeteneğinizle düşmanlara vurarak bir kısmını geri kazanın.",
				["KINGMOD_TUTORIAL_ZENKAI"] = "Ölerek veya 30 saniye boyunca %20 canın altında kalarak Zenkai kazanın. Kalıcı bonus özellikler sağlar.",
				["KINGMOD_TUTORIAL_LIGHT_CHARGE"] = "Kılıcınızla düşmanlara vurarak Işık Şarjı kazanın. Dolduğunda, Dönüşüm Düğmesini basılı tutarak etkinleştirin. Aktifken bonus Hasar ve Kritik Şansı sağlar.",
				["KINGMOD_TUTORIALS_ENABLED"] = "Öğreticiler Etkinleştirildi",
				["KINGMOD_TUTORIALS_DISABLED"] = "Öğreticiler Devre Dışı"
			},
			["en"] = new Dictionary<string, string>
			{
				["Transformations"] = "Transformations",
				["KINGMOD_REMOVE"] = "REMOVE",
				["KINGMOD_TOGGLE_EXTRA"] = "TOGGLE EXTRA",
				["KINGMOD_COSTS_PREFIX"] = "Costs ",
				["KINGMOD_TOTAL_MASTERY_REQUIRED"] = "Total Mastery Levels Required: ",
				["KINGMOD_TOTAL_MASTERY_LEVELS"] = "Total Mastery levels",
				["KINGMOD_KI_DRAIN"] = "Ki Drain: ",
				["KINGMOD_PER_SECOND"] = " Per Second",
				["KINGMOD_CHARGE_POWER"] = "Charge Power: ",
				["KINGMOD_STAT_DAMAGE"] = "Damage: ",
				["KINGMOD_STAT_ARMOR"] = "Armor: ",
				["KINGMOD_STAT_HEALTH_REGEN"] = "Health Regen: ",
				["KINGMOD_STAT_ATTACK_SPEED"] = "Attack Speed: ",
				["KINGMOD_STAT_MOVE_SPEED"] = "Movement Speed: ",
				["KINGMOD_STAT_MAX_HEALTH"] = "Max Health: ",
				["KINGMOD_MASTERED"] = "Mastered ",
				["KINGMOD_POWER_LEVEL"] = "Power Level: ",
				["KINGMOD_NO_STAT_BOOSTS"] = " has no stat boosts...",
				["KINGMOD_ALL_FORMS_UNLOCKED"] = "All Forms unlocked?",
				["KINGMOD_UNTIL_NEXT_UNLOCK"] = " Mastery level(s) until next unlock",
				["KINGMOD_COSTS_KI_FORMAT"] = "Costs <color=#03bcff>{0} Ki</color>",
				["KINGMOD_DAMAGE_FORMAT"] = "<color=#E5C962>{0}% Damage</color>",
				["KINGMOD_STAT_NAME_DAMAGE"] = "Damage",
				["KINGMOD_STAT_NAME_ARMOR"] = "Armor",
				["KINGMOD_STAT_NAME_ATTACKSPEED"] = "Attack Speed",
				["KINGMOD_STAT_NAME_MOVESPEED"] = "Movement Speed",
				["KINGMOD_STAT_NAME_REGEN"] = "Health Regen",
				["KINGMOD_STAT_NAME_MAXHEALTH"] = "Max Health",
				["KINGMOD_TUTORIAL_F1"] = "Enable/Disable Tutorials by pressing F1",
				["KINGMOD_TUTORIAL_FORM_MASTERY"] = "With Form Mastery, gain Experience over time or by damaging enemies. Levelling up the form grants the following:\n- An increase to your transformation's stat boost.\n- A reduction to the Ki drain of your transformation\n- An increase to your overall Ki regen.\nIn Base Form, Ki regen & max Ki is gained.",
				["KINGMOD_TUTORIAL_TRANSFORM_TRIGGER"] = "Once your mastery level is high enough, activate a Main Transformation by tapping the transformation button (Default 'C') and Power Down by pressing (Default 'X'). When more Transformations unlock, press the transformation button again to ascend further beyond!",
				["KINGMOD_TUTORIAL_ULTIMATE_SKILL"] = "While transformed, you have access to an Ultimate Skill. Activate it by pressing the key binded below.",
				["KINGMOD_TUTORIAL_KI_RESOURCE"] = "Ki is a resource that your skills use. Gain some back by hitting enemies with your primary skill.",
				["KINGMOD_TUTORIAL_ZENKAI"] = "Gain Zenkai's by dying or staying below 20% health for 30 seconds. Grants permanent bonus stats.",
				["KINGMOD_TUTORIAL_LIGHT_CHARGE"] = "Gain Light Charge by hitting enemies with your sword. Once full, activate it by holding the Transformation Button. Grants bonus Damage and Crit Chance while active.",
				["KINGMOD_TUTORIALS_ENABLED"] = "Tutorials Enabled",
				["KINGMOD_TUTORIALS_DISABLED"] = "Tutorials Disabled"
			}
		};

		public static Dictionary<string, string> GetDictionaryForLanguage(string lang)
		{
			if (string.IsNullOrEmpty(lang))
			{
				return _languages["en"];
			}
			if (_languages.TryGetValue(lang, out Dictionary<string, string> value))
			{
				return value;
			}
			if (lang.StartsWith("pt", StringComparison.OrdinalIgnoreCase))
			{
				return _languages["pt-BR"];
			}
			if (lang.StartsWith("tr", StringComparison.OrdinalIgnoreCase))
			{
				return _languages["tr"];
			}
			return _languages["en"];
		}
	}
	[BepInPlugin("jaosnake.pele.kingdbzfix", "PELE - KingModUtilities Localization Fix", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class KingDBZFixPlugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			if (!Chainloader.PluginInfos.ContainsKey("com.Kingpinush.KingModUtilities"))
			{
				Log.LogInfo((object)"KingModUtilities não detectado. Patch de localização DBZ ignorado.");
				return;
			}
			try
			{
				_harmony = new Harmony("jaosnake.pele.kingdbzfix");
				PatchGroup(typeof(TransformationsMenuPatches));
				PatchGroup(typeof(FormattingPatches));
				PatchGroup(typeof(MenuHudPatches));
				PatchGroup(typeof(TutorialPatches));
				Language.onCurrentLanguageChanged += OnLanguageChanged;
				InjectFallbackTokens();
				Log.LogInfo((object)"PELE - KingModUtilities Localization Fix (Goku, Vegeta, Trunks) carregado com sucesso!");
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Erro ao aplicar patch no KingModUtilities: " + ex));
			}
		}

		private void PatchGroup(Type patchType)
		{
			try
			{
				_harmony.PatchAll(patchType);
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogError((object)("Falha ao aplicar " + patchType.Name + ": " + ex));
				}
			}
		}

		private void OnDestroy()
		{
			Language.onCurrentLanguageChanged -= OnLanguageChanged;
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private static void OnLanguageChanged()
		{
			InjectFallbackTokens();
		}

		public static void InjectFallbackTokens()
		{
			try
			{
				Language currentLanguage = Language.currentLanguage;
				if (currentLanguage == null)
				{
					return;
				}
				string text = currentLanguage.name;
				if (string.IsNullOrEmpty(text))
				{
					text = "en";
				}
				Dictionary<string, string> dictionaryForLanguage = DBZLocalizationDictionary.GetDictionaryForLanguage(text);
				if (dictionaryForLanguage == null)
				{
					return;
				}
				foreach (KeyValuePair<string, string> item in dictionaryForLanguage)
				{
					if (!currentLanguage.TokenIsRegistered(item.Key) || currentLanguage.GetLocalizedStringByToken(item.Key) == item.Key)
					{
						currentLanguage.SetStringByToken(item.Key, item.Value);
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)("Erro ao injetar tokens de fallback: " + ex.Message));
				}
			}
		}

		public static string SafeGetString(string token, string fallback = null)
		{
			if (string.IsNullOrEmpty(token))
			{
				return fallback ?? "";
			}
			if (token == "Transformations")
			{
				token = "KINGMOD_TRANSFORMATIONS";
			}
			if (MenuTranslations.TryGet(Language.currentLanguageName, token, out string value))
			{
				return value;
			}
			if (token.StartsWith("KINGMOD_TUTORIAL_", StringComparison.Ordinal) || token == "KINGMOD_POPUP_ADDED_FORMAT" || token == "KINGMOD_ULTIMATE_SKILL_TITLE")
			{
				if (TutorialTranslations.TryGet(Language.currentLanguageName, token, out string value2))
				{
					return value2;
				}
				return fallback ?? token;
			}
			try
			{
				Language currentLanguage = Language.currentLanguage;
				if (currentLanguage != null && currentLanguage.TokenIsRegistered(token))
				{
					string localizedStringByToken = currentLanguage.GetLocalizedStringByToken(token);
					if (!string.IsNullOrEmpty(localizedStringByToken) && localizedStringByToken != token)
					{
						return localizedStringByToken;
					}
				}
				else
				{
					string text = Language.GetString(token);
					if (!string.IsNullOrEmpty(text) && text != token)
					{
						return text;
					}
				}
			}
			catch
			{
			}
			try
			{
				string text2 = Language.currentLanguageName;
				if (string.IsNullOrEmpty(text2))
				{
					text2 = "en";
				}
				Dictionary<string, string> dictionaryForLanguage = DBZLocalizationDictionary.GetDictionaryForLanguage(text2);
				if (dictionaryForLanguage != null && dictionaryForLanguage.TryGetValue(token, out var value3))
				{
					return value3;
				}
			}
			catch
			{
			}
			return fallback ?? token;
		}
	}
	public static class TransformationsMenuPatches
	{
		private static readonly FieldInfo _fTransName = typeof(UI_TransformationsMenu).GetField("m_mainToolTipTransformationNameText", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo _fSkillName = typeof(UI_TransformationsMenu).GetField("m_mainToolTipSkillNameText", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo _fSkillText = typeof(UI_TransformationsMenu).GetField("m_mainToolTipSkillText", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo _fMainTooltipText = typeof(UI_TransformationsMenu).GetField("m_mainTooltipText", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo _fRemoveBtn = typeof(UI_TransformationsMenu).GetField("m_removeTransformationButton", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo _fShowExtraBtn = typeof(UI_TransformationsMenu).GetField("m_showExtraTransformationButton", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		[HarmonyPatch(typeof(UI_TransformationsMenu), "UpdateTooltip")]
		[HarmonyPostfix]
		public static void Postfix_UpdateTooltip(UI_TransformationsMenu __instance)
		{
			try
			{
				if (__instance == null)
				{
					return;
				}
				object? obj = _fSkillName?.GetValue(__instance);
				Text val = (Text)((obj is Text) ? obj : null);
				Transform val2 = (((Object)(object)val != (Object)null) ? ((Component)val).transform.root : null);
				Text[] array = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponentsInChildren<Text>(true) : Array.Empty<Text>());
				foreach (Text val3 in array)
				{
					if (!((Object)(object)val3 == (Object)null))
					{
						string text = null;
						if (((Object)((Component)val3).gameObject).name == "Tooltip_main_skill_title_text")
						{
							text = KingDBZFixPlugin.SafeGetString("KINGMOD_ULTIMATE_SKILL_TITLE", "ULTIMATE SKILL");
						}
						else if (((Object)((Component)val3).gameObject).name == "Tooltip_main_transformation_title_text")
						{
							text = KingDBZFixPlugin.SafeGetString("KINGMOD_TRANSFORMATION", "TRANSFORMATION");
						}
						if (text != null && val3.text != text)
						{
							val3.text = text;
						}
					}
				}
				object? obj2 = _fTransName?.GetValue(__instance);
				Text val4 = (Text)((obj2 is Text) ? obj2 : null);
				if ((Object)(object)val4 != (Object)null && !string.IsNullOrEmpty(val4.text))
				{
					val4.text = KingDBZFixPlugin.SafeGetString(val4.text, val4.text);
				}
				object? obj3 = _fSkillName?.GetValue(__instance);
				Text val5 = (Text)((obj3 is Text) ? obj3 : null);
				if ((Object)(object)val5 != (Object)null && !string.IsNullOrEmpty(val5.text))
				{
					val5.text = KingDBZFixPlugin.SafeGetString(val5.text, val5.text);
				}
				object? obj4 = _fSkillText?.GetValue(__instance);
				Text val6 = (Text)((obj4 is Text) ? obj4 : null);
				if ((Object)(object)val6 != (Object)null && !string.IsNullOrEmpty(val6.text))
				{
					val6.text = LocalizeSkillDescription(val6.text);
				}
				object? obj5 = _fMainTooltipText?.GetValue(__instance);
				Text val7 = (Text)((obj5 is Text) ? obj5 : null);
				if ((Object)(object)val7 != (Object)null && !string.IsNullOrEmpty(val7.text))
				{
					val7.text = LocalizeStatsText(val7.text);
				}
				object? obj6 = _fRemoveBtn?.GetValue(__instance);
				Button val8 = (Button)((obj6 is Button) ? obj6 : null);
				if ((Object)(object)val8 != (Object)null)
				{
					Text componentInChildren = ((Component)val8).GetComponentInChildren<Text>();
					if ((Object)(object)componentInChildren != (Object)null)
					{
						string text2 = KingDBZFixPlugin.SafeGetString("KINGMOD_REMOVE", "REMOVE");
						if (componentInChildren.text != text2)
						{
							componentInChildren.text = text2;
						}
					}
				}
				object? obj7 = _fShowExtraBtn?.GetValue(__instance);
				Button val9 = (Button)((obj7 is Button) ? obj7 : null);
				if (!((Object)(object)val9 != (Object)null))
				{
					return;
				}
				Text componentInChildren2 = ((Component)val9).GetComponentInChildren<Text>();
				if ((Object)(object)componentInChildren2 != (Object)null)
				{
					string text3 = KingDBZFixPlugin.SafeGetString("KINGMOD_TOGGLE_EXTRA", "TOGGLE EXTRA");
					if (componentInChildren2.text != text3)
					{
						componentInChildren2.text = text3;
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = KingDBZFixPlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("Erro em Postfix_UpdateTooltip: " + ex.Message));
				}
			}
		}

		[HarmonyPatch(typeof(UI_TransformationsMenu), "CreateTransformationElement")]
		[HarmonyPostfix]
		public static void Postfix_CreateTransformationElement(ref DynamicArray<GameObject> __0, MainTransformationState __3)
		{
			try
			{
				if (__3 == null)
				{
					return;
				}
				int count = __0.GetCount();
				if (count <= 0)
				{
					return;
				}
				GameObject val = __0.AccessElement(count - 1);
				if (!((Object)(object)val != (Object)null))
				{
					return;
				}
				Text[] componentsInChildren = val.GetComponentsInChildren<Text>(true);
				foreach (Text val2 in componentsInChildren)
				{
					if ((Object)(object)val2 != (Object)null && !string.IsNullOrEmpty(val2.text) && val2.text == ((TransformationState)__3).GetDisplayName())
					{
						val2.text = KingDBZFixPlugin.SafeGetString(val2.text, val2.text);
					}
				}
			}
			catch
			{
			}
		}

		public static string LocalizeSkillDescription(string text)
		{
			if (string.IsNullOrEmpty(text))
			{
				return text;
			}
			string text2 = KingDBZFixPlugin.SafeGetString(text);
			if (!string.IsNullOrEmpty(text2) && text2 != text)
			{
				return text2;
			}
			Match match = Regex.Match(text, "^Costs\\s+(<color=[^>]+>\\d+\\s*Ki</color>)\\s*\\n([\\s\\S]*)$", RegexOptions.IgnoreCase);
			if (match.Success)
			{
				string value = match.Groups[1].Value;
				string text3 = match.Groups[2].Value.Trim();
				string text4 = KingDBZFixPlugin.SafeGetString("KINGMOD_COSTS_PREFIX", "Costs ");
				string text5 = KingDBZFixPlugin.SafeGetString(text3, text3);
				return text4 + value + "\n" + text5;
			}
			return text;
		}

		public static string LocalizeStatsText(string text)
		{
			if (string.IsNullOrEmpty(text))
			{
				return text;
			}
			text = SafeReplace(text, "Total Mastery Levels Required: ", "KINGMOD_TOTAL_MASTERY_REQUIRED", "Total Mastery Levels Required: ");
			text = SafeReplace(text, "Total Mastery levels", "KINGMOD_TOTAL_MASTERY_LEVELS", "Total Mastery levels");
			text = SafeReplace(text, "Ki Drain: ", "KINGMOD_KI_DRAIN", "Ki Drain: ");
			text = SafeReplace(text, " Per Second", "KINGMOD_PER_SECOND", " Per Second");
			text = SafeReplace(text, "Charge Power: ", "KINGMOD_CHARGE_POWER", "Charge Power: ");
			text = SafeReplace(text, "Damage: ", "KINGMOD_STAT_DAMAGE", "Damage: ");
			text = SafeReplace(text, "Armor: ", "KINGMOD_STAT_ARMOR", "Armor: ");
			text = SafeReplace(text, "Health Regen: ", "KINGMOD_STAT_HEALTH_REGEN", "Health Regen: ");
			text = SafeReplace(text, "Attack Speed: ", "KINGMOD_STAT_ATTACK_SPEED", "Attack Speed: ");
			text = SafeReplace(text, "Movement Speed: ", "KINGMOD_STAT_MOVE_SPEED", "Movement Speed: ");
			text = SafeReplace(text, "Max Health: ", "KINGMOD_STAT_MAX_HEALTH", "Max Health: ");
			text = SafeReplace(text, "Mastered ", "KINGMOD_MASTERED", "Mastered ");
			text = SafeReplace(text, "Power Level: ", "KINGMOD_POWER_LEVEL", "Power Level: ");
			text = SafeReplace(text, " has no stat boosts...", "KINGMOD_NO_STAT_BOOSTS", " has no stat boosts...");
			text = SafeReplace(text, "All Forms unlocked?", "KINGMOD_ALL_FORMS_UNLOCKED", "All Forms unlocked?");
			text = SafeReplace(text, " Mastery level(s) until next unlock", "KINGMOD_UNTIL_NEXT_UNLOCK", " Mastery level(s) until next unlock");
			return text;
		}

		private static string SafeReplace(string text, string target, string token, string fallback)
		{
			if (!text.Contains(target))
			{
				return text;
			}
			string text2 = KingDBZFixPlugin.SafeGetString(token, fallback);
			if (target.EndsWith(" ") && !text2.EndsWith(" "))
			{
				text2 += " ";
			}
			if (target.StartsWith(" ") && !text2.StartsWith(" "))
			{
				text2 = " " + text2;
			}
			return text.Replace(target, text2);
		}
	}
	public static class FormattingPatches
	{
		[HarmonyPatch(typeof(MainPlugin), "CreateKiCostDescription")]
		[HarmonyPostfix]
		public static void Postfix_CreateKiCostDescription(string numValue, ref string __result)
		{
			string text = KingDBZFixPlugin.SafeGetString("KINGMOD_COSTS_KI_FORMAT");
			if (!string.IsNullOrEmpty(text))
			{
				try
				{
					__result = string.Format(text, numValue);
				}
				catch
				{
				}
			}
		}

		[HarmonyPatch(typeof(MainPlugin), "CreateDamageDescription")]
		[HarmonyPostfix]
		public static void Postfix_CreateDamageDescription(string numValue, ref string __result)
		{
			string text = KingDBZFixPlugin.SafeGetString("KINGMOD_DAMAGE_FORMAT");
			if (!string.IsNullOrEmpty(text))
			{
				try
				{
					__result = string.Format(text, numValue);
				}
				catch
				{
				}
			}
		}
	}
	public static class TutorialPatches
	{
		private sealed class TutorialSnapshot
		{
			internal string Source;

			internal string Last;
		}

		private static float _nextHudCheckTime = 0f;

		private static readonly ConditionalWeakTable<Object, TutorialSnapshot> Sources = new ConditionalWeakTable<Object, TutorialSnapshot>();

		private static string TranslateComponent(Object component, string current)
		{
			if (component == (Object)null || string.IsNullOrEmpty(current))
			{
				return current;
			}
			Sources.TryGetValue(component, out TutorialSnapshot value);
			string text = ((value != null && (current == value.Last || current == value.Source)) ? value.Source : current);
			string text2 = TutorialMatcher.FindToken(text);
			if (text2 == null)
			{
				return current;
			}
			string currentLanguageName = Language.currentLanguageName;
			bool num = string.Equals(currentLanguageName, "en", StringComparison.OrdinalIgnoreCase);
			string text3 = (num ? text : KingDBZFixPlugin.SafeGetString(text2, text));
			if (!num && text3 != text)
			{
				text3 = TutorialHighlight.Apply(currentLanguageName, text2, text3);
			}
			if (value == null)
			{
				value = Sources.GetValue(component, (Object _) => new TutorialSnapshot());
			}
			value.Source = text;
			value.Last = text3;
			return text3;
		}

		[HarmonyPatch(typeof(PopUpTextHandler), "AddNewPopUpText")]
		[HarmonyPrefix]
		public static void Prefix_AddNewPopUpText(ref string newText)
		{
			if (string.IsNullOrEmpty(newText))
			{
				return;
			}
			if (newText.StartsWith("Added ", StringComparison.Ordinal) && newText.EndsWith("!", StringComparison.Ordinal) && newText.Length > 7)
			{
				string arg = newText.Substring(6, newText.Length - 7);
				string format = KingDBZFixPlugin.SafeGetString("KINGMOD_POPUP_ADDED_FORMAT", "Added {0}!");
				try
				{
					newText = string.Format(format, arg);
					return;
				}
				catch (FormatException)
				{
					return;
				}
			}
			if (newText == "Tutorials Enabled")
			{
				newText = KingDBZFixPlugin.SafeGetString("KINGMOD_TUTORIALS_ENABLED", "Tutorials Enabled");
			}
			else if (newText == "Tutorials Disabled")
			{
				newText = KingDBZFixPlugin.SafeGetString("KINGMOD_TUTORIALS_DISABLED", "Tutorials Disabled");
			}
			else
			{
				newText = KingDBZFixPlugin.SafeGetString(newText, newText);
			}
		}

		[HarmonyPatch(typeof(UI_Element), "RefreshTutorialUI")]
		[HarmonyPostfix]
		public static void Postfix_RefreshTutorialUI(UI_Element __instance)
		{
			if (__instance == null)
			{
				return;
			}
			try
			{
				Traverse obj = Traverse.Create((object)__instance);
				Traverse obj2 = obj.Field("m_tutorial");
				object obj3 = ((obj2 != null) ? obj2.GetValue() : null);
				GameObject val = (GameObject)((obj3 is GameObject) ? obj3 : null);
				if ((Object)(object)val != (Object)null)
				{
					LocalizeTutorialUI(val);
				}
				Traverse obj4 = obj.Field("m_uiGO");
				object obj5 = ((obj4 != null) ? obj4.GetValue() : null);
				GameObject val2 = (GameObject)((obj5 is GameObject) ? obj5 : null);
				if ((Object)(object)val2 != (Object)null)
				{
					LocalizeTutorialUI(val2);
				}
			}
			catch
			{
			}
		}

		[HarmonyPatch(typeof(UIManager), "SetupHUD")]
		[HarmonyPostfix]
		public static void Postfix_SetupHUD(Transform selfTransform)
		{
			if ((Object)(object)selfTransform != (Object)null)
			{
				try
				{
					LocalizeTutorialUI(((Component)selfTransform).gameObject);
				}
				catch
				{
				}
			}
		}

		[HarmonyPatch(typeof(UIManager), "RefreshAllTutorialUI")]
		[HarmonyPostfix]
		public static void Postfix_RefreshAllTutorialUI(UIManager __instance)
		{
			try
			{
				if (HUD.readOnlyInstanceList == null)
				{
					return;
				}
				foreach (HUD readOnlyInstance in HUD.readOnlyInstanceList)
				{
					if ((Object)(object)readOnlyInstance != (Object)null)
					{
						LocalizeTutorialUI(((Component)readOnlyInstance).gameObject);
					}
				}
			}
			catch
			{
			}
		}

		[HarmonyPatch(typeof(HUD), "Update")]
		[HarmonyPostfix]
		public static void Postfix_HUD_Update(HUD __instance)
		{
			if ((Object)(object)__instance == (Object)null || !(Time.unscaledTime > _nextHudCheckTime))
			{
				return;
			}
			_nextHudCheckTime = Time.unscaledTime + 1f;
			try
			{
				LocalizeTutorialUI(((Component)__instance).gameObject);
			}
			catch
			{
			}
		}

		public static void LocalizeTutorialUI(GameObject root)
		{
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			Text[] componentsInChildren = root.GetComponentsInChildren<Text>(true);
			if (componentsInChildren != null)
			{
				Text[] array = componentsInChildren;
				foreach (Text val in array)
				{
					if ((Object)(object)val != (Object)null && !string.IsNullOrEmpty(val.text))
					{
						string text = TranslateComponent((Object)(object)val, val.text);
						if (text != val.text)
						{
							val.text = text;
						}
					}
				}
			}
			TextMeshProUGUI[] componentsInChildren2 = root.GetComponentsInChildren<TextMeshProUGUI>(true);
			if (componentsInChildren2 == null)
			{
				return;
			}
			TextMeshProUGUI[] array2 = componentsInChildren2;
			foreach (TextMeshProUGUI val2 in array2)
			{
				if ((Object)(object)val2 != (Object)null && !string.IsNullOrEmpty(((TMP_Text)val2).text))
				{
					string text2 = TranslateComponent((Object)(object)val2, ((TMP_Text)val2).text);
					if (text2 != ((TMP_Text)val2).text)
					{
						((TMP_Text)val2).text = text2;
					}
				}
			}
		}

		public static string LocalizeTutorialString(string text)
		{
			if (string.IsNullOrEmpty(text))
			{
				return text;
			}
			string text2 = TutorialMatcher.FindToken(text);
			if (text2 != null)
			{
				return KingDBZFixPlugin.SafeGetString(text2, text);
			}
			return text;
		}
	}
	internal static class MenuHudPatches
	{
		private sealed class LabelSnapshot
		{
			internal string Source;

			internal string Last;
		}

		private static readonly FieldInfo OverviewField = typeof(TrainingMenuUI).GetField("m_overviewButtonText", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo TransformationField = typeof(UI_TransformationDisplay).GetField("m_transformationText", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo PowerField = typeof(UI_TransformationDisplay).GetField("m_powerLevelText", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo MasteryField = typeof(UI_TransformationDisplay).GetField("m_masteryLevelSection", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly ConditionalWeakTable<Text, LabelSnapshot> Sources = new ConditionalWeakTable<Text, LabelSnapshot>();

		[HarmonyPatch(typeof(TrainingMenuUI), "OnCharacterSelected")]
		[HarmonyPostfix]
		private static void OnCharacterSelected(TrainingMenuUI __instance)
		{
			try
			{
				object? obj = OverviewField?.GetValue(__instance);
				HGTextMeshProUGUI val = (HGTextMeshProUGUI)((obj is HGTextMeshProUGUI) ? obj : null);
				if (!((Object)(object)val == (Object)null))
				{
					string text = KingDBZFixPlugin.SafeGetString("KINGMOD_TRANSFORMATIONS", "Transformations");
					if (((TMP_Text)val).text != text)
					{
						((TMP_Text)val).text = text;
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = KingDBZFixPlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("Erro ao localizar aba de transformacoes: " + ex.Message));
				}
			}
		}

		[HarmonyPatch(typeof(UI_TransformationDisplay), "DrawElement")]
		[HarmonyPostfix]
		private static void DrawElement(UI_TransformationDisplay __instance)
		{
			try
			{
				object? obj = TransformationField?.GetValue(__instance);
				Text val = (Text)((obj is Text) ? obj : null);
				if ((Object)(object)val != (Object)null)
				{
					Sources.TryGetValue(val, out LabelSnapshot value);
					if (val.text == "Base Form" || (value != null && val.text == value.Last))
					{
						string text = KingDBZFixPlugin.SafeGetString("KINGMOD_BASE_FORM", "Base Form");
						if (value == null)
						{
							value = Sources.GetValue(val, (Text _) => new LabelSnapshot());
						}
						value.Source = "Base Form";
						value.Last = text;
						if (val.text != text)
						{
							val.text = text;
						}
					}
				}
				object? obj2 = PowerField?.GetValue(__instance);
				Text val2 = (Text)((obj2 is Text) ? obj2 : null);
				if ((Object)(object)val2 != (Object)null && !string.IsNullOrEmpty(val2.text))
				{
					Sources.TryGetValue(val2, out LabelSnapshot value2);
					string text2 = ((value2 != null && val2.text == value2.Last) ? value2.Source : val2.text);
					string text3 = TransformationsMenuPatches.LocalizeStatsText(text2);
					if (text3 != text2 || (value2 != null && val2.text == value2.Last))
					{
						if (value2 == null)
						{
							value2 = Sources.GetValue(val2, (Text _) => new LabelSnapshot());
						}
						value2.Source = text2;
						value2.Last = text3;
						if (val2.text != text3)
						{
							val2.text = text3;
						}
					}
				}
				object? obj3 = MasteryField?.GetValue(__instance);
				Transform val3 = (Transform)((obj3 is Transform) ? obj3 : null);
				if (!((Object)(object)val3 != (Object)null))
				{
					return;
				}
				Text[] componentsInChildren = ((Component)val3).GetComponentsInChildren<Text>(true);
				foreach (Text val4 in componentsInChildren)
				{
					if ((Object)(object)val4 != (Object)null && ((Object)((Component)val4).gameObject).name == "MasteryLevel_TitleText")
					{
						string text4 = KingDBZFixPlugin.SafeGetString("KINGMOD_LEVEL", "Level");
						if (val4.text != text4)
						{
							val4.text = text4;
						}
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = KingDBZFixPlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("Erro ao localizar HUD de transformacoes: " + ex.Message));
				}
			}
		}
	}
	internal static class MenuTranslations
	{
		private static readonly Dictionary<string, string[]> Data = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase)
		{
			["de"] = new string[25]
			{
				"Transformationen", "Transformation", "Grundform", "Stufe", "ENTFERNEN", "EXTRAS UMSCHALTEN", "Benötigte Meisterschaftsstufen insgesamt: ", "Meisterschaftsstufen insgesamt", "Ki-Verbrauch: ", " pro Sekunde",
				"Ladeleistung: ", "Schaden: ", "Rüstung: ", "Gesundheitsregeneration: ", "Angriffsgeschwindigkeit: ", "Bewegungsgeschwindigkeit: ", "Maximale Gesundheit: ", "Gemeistert ", "Kampfkraft: ", " hat keine Attributsboni...",
				"Alle Formen freigeschaltet?", " Meisterschaftsstufen bis zur nächsten Freischaltung", "Kostet ", "Kostet <color=#03bcff>{0} Ki</color>", "<color=#E5C962>{0}% Schaden</color>"
			},
			["es-ES"] = new string[25]
			{
				"Transformaciones", "Transformación", "Forma base", "Nivel", "QUITAR", "ALTERNAR EXTRAS", "Niveles de dominio totales requeridos: ", "Niveles de dominio total", "Consumo de Ki: ", " Por segundo",
				"Potencia de carga: ", "Daño: ", "armadura: ", "regeneración de salud: ", "Velocidad de ataque: ", "Velocidad de movimiento: ", "Salud máxima: ", "dominado ", "Nivel de poder: ", " no tiene aumentos de estadísticas...",
				"¿Todas las formas desbloqueadas?", " Niveles de dominio hasta el próximo desbloqueo.", "Cuesta ", "Cuesta <color=#03bcff>{0} Ki</color>", "<color=#E5C962>{0}% de daño</color>"
			},
			["es-419"] = new string[25]
			{
				"Transformaciones", "Transformación", "Forma base", "Nivel", "QUITAR", "ALTERNAR EXTRAS", "Niveles de dominio totales requeridos: ", "Niveles de dominio total", "Consumo de Ki: ", " Por segundo",
				"Potencia de carga: ", "Daño: ", "armadura: ", "regeneración de salud: ", "Velocidad de ataque: ", "Velocidad de movimiento: ", "Salud máxima: ", "dominado ", "Nivel de poder: ", " no tiene aumentos de estadísticas...",
				"¿Todas las formas desbloqueadas?", " Niveles de dominio hasta el próximo desbloqueo.", "Cuesta ", "Cuesta <color=#03bcff>{0} Ki</color>", "<color=#E5C962>{0}% de daño</color>"
			},
			["FR"] = new string[25]
			{
				"Transformations", "Transformation", "Forme de base", "Niveau", "RETIRER", "BASCULER EXTRAS", "Niveaux de maîtrise totaux requis: ", "Niveaux de maîtrise totaux", "Consommation de Ki: ", " Par seconde",
				"Puissance de charge: ", "Dégâts: ", "Armure: ", "Régénération de la santé: ", "Vitesse d'attaque: ", "Vitesse de déplacement: ", "Santé maximale: ", "Maîtrisé ", "Niveau de puissance: ", " n'a pas d'amélioration de statistiques...",
				"Toutes les formes débloquées ?", " Niveaux de maîtrise jusqu'au prochain déverrouillage", "Coûte ", "Coûte <color=#03bcff>{0} Ki</color>", "<color=#E5C962>{0}% de dégâts</color>"
			},
			["ja"] = new string[25]
			{
				"変身", "変身", "基本形態", "レベル", "解除", "追加形態を切替", "必要な合計マスタリーレベル: ", "合計マスタリーレベル", "気の消費: ", " 毎秒",
				"チャージ力: ", "ダメージ: ", "防御力: ", "体力再生: ", "攻撃速度: ", "移動速度: ", "最大体力: ", "マスター済み ", "戦闘力: ", " ステータスブーストはありません...",
				"全形態を解放済み?", " 次のロックが解除されるまでのマスタリーレベル", "消費: ", "消費: <color=#03bcff>{0} Ki</color>", "<color=#E5C962>{0}% ダメージ</color>"
			},
			["IT"] = new string[25]
			{
				"Trasformazioni", "Trasformazione", "Forma base", "Livello", "RIMUOVI", "MOSTRA/NASCONDI EXTRA", "Livelli di padronanza totali richiesti: ", "Livelli di padronanza totali", "Consumo di Ki: ", " Al secondo",
				"Potenza di carica: ", "Danno: ", "Armatura: ", "Rigenerazione della salute: ", "Velocità d'attacco: ", "Velocità di movimento: ", "Salute massima: ", "Padroneggiato ", "Livello di potenza: ", " non ha aumenti delle statistiche...",
				"Tutte le forme sbloccate?", " Livelli di maestria fino al prossimo sblocco", "Costa ", "Costa <color=#03bcff>{0} Ki</color>", "<color=#E5C962>{0}% di danno</color>"
			},
			["ko"] = new string[25]
			{
				"변신", "변신", "기본 형태", "레벨", "제거", "추가 형태 전환", "필요한 총 숙련도 레벨: ", "총 숙련도 레벨", "기 소모: ", " 초당",
				"충전력: ", "피해: ", "방어력: ", "체력 재생: ", "공격 속도: ", "이동 속도: ", "최대 체력: ", "마스터 ", "전투력: ", " 스텟 부스트가 없습니다...",
				"모든 형태를 해제했습니까?", " 다음 잠금 해제까지의 마스터리 레벨", "소모: ", "소모: <color=#03bcff>{0} Ki</color>", "<color=#E5C962>{0}% 피해</color>"
			},
			["RU"] = new string[25]
			{
				"Превращения", "Превращение", "Базовая форма", "Уровень", "УБРАТЬ", "ДОПОЛНИТЕЛЬНЫЕ ФОРМЫ", "Общее количество требуемых уровней мастерства: ", "Всего уровней мастерства", "Расход Ки: ", " в секунду",
				"Мощность заряда: ", "Урон: ", "Броня: ", "Регенерация здоровья: ", "Скорость атаки: ", "Скорость движения: ", "Максимальное здоровье: ", "Освоен ", "Уровень силы: ", " не имеет повышения характеристик...",
				"Все формы разблокированы?", " Уровни мастерства до следующей разблокировки", "Стоимость: ", "Стоимость: <color=#03bcff>{0} Ki</color>", "<color=#E5C962>{0}% урона</color>"
			},
			["zh-CN"] = new string[25]
			{
				"变身", "变身", "基础形态", "等级", "移除", "切换额外形态", "所需总精通等级: ", "总精通等级", "气消耗: ", " 每秒",
				"蓄力强度: ", "伤害: ", "护甲: ", "生命回复: ", "攻击速度: ", "移动速度: ", "最大生命值: ", "已精通 ", "战斗力: ", " 没有属性加成...",
				"所有形态均已解锁?", " 距离下次解锁所需精通等级", "消耗:", "消耗:<color=#03bcff>{0} Ki</color>", "<color=#E5C962>{0}% 伤害</color>"
			},
			["UA"] = new string[25]
			{
				"Перетворення", "Перетворення", "Базова форма", "Рівень", "ПРИБРАТИ", "ДОДАТКОВІ ФОРМИ", "Необхідні загальні рівні майстерності: ", "Загальні рівні майстерності", "Витрата Кі: ", " За секунду",
				"Потужність заряду: ", "Шкода: ", "Броня: ", "Регенерація здоров'я: ", "Швидкість атаки: ", "Швидкість руху: ", "Максимальне здоров'я: ", "Опанував ", "Рівень сили: ", " не має підвищення характеристик...",
				"Усі форми розблоковано?", " Рівні майстерності до наступного розблокування", "Вартість: ", "Вартість: <color=#03bcff>{0} Ki</color>", "<color=#E5C962>{0}% шкоди</color>"
			},
			["tr"] = new string[25]
			{
				"Dönüşümler", "Dönüşüm", "Temel Form", "Seviye", "KALDIR", "EKSTRALARI AÇ/KAPAT", "Gerekli Toplam Ustalık Seviyesi: ", "Toplam Ustalık Seviyesi", "Ki Tüketimi: ", " Saniyede",
				"Şarj Gücü: ", "Hasar: ", "Zırh: ", "Sağlık Yenilenmesi: ", "Saldırı Hızı: ", "Hareket Hızı: ", "Maksimum Sağlık: ", "Ustalaşmış ", "Güç Seviyesi: ", " istatistik artışı yok...",
				"Tüm Formların kilidi açıldı mı?", " Bir sonraki kilidi açana kadar ustalık seviyeleri", "Bedel: ", "Bedel: <color=#03bcff>{0} Ki</color>", "<color=#E5C962>{0}% hasar</color>"
			},
			["eo"] = new string[25]
			{
				"Transformoj", "Transformo", "Baza Formo", "Nivelo", "FORIGI", "SXALTI EKSTRAJN", "Bezonataj totalaj majstraj niveloj: ", "Totalaj majstraj niveloj", "Ki-konsumo: ", " sekunde",
				"Sxargxa potenco: ", "Damagxo: ", "Kiraso: ", "Sanregenerado: ", "Atakrapido: ", "Movrapido: ", "Maksimuma sano: ", "Majstrita ", "Potenca nivelo: ", " ne havas atributajn gratifikojn...",
				"Cxu cxiuj formoj estas malxsxlositaj?", " Majstraj niveloj gxis la sekva malxsxloso", "Kostas ", "Kostas <color=#03bcff>{0} Ki</color>", "<color=#E5C962>{0}% da damagxo</color>"
			},
			["la"] = new string[25]
			{
				"Transformationes", "Transformatio", "Forma fundamentalis", "Gradus", "REMOVE", "EXTRA MUTA", "Gradus peritiae totales necessarii: ", "Gradus peritiae totales", "Consumptio Ki: ", " per secundum",
				"Potentia onerandi: ", "Damnum: ", "Lorica: ", "Regeneratio salutis: ", "Celeritas impetus: ", "Celeritas motus: ", "Salus maxima: ", "Perfecta ", "Gradus potentiae: ", " nulla incrementa attributorum habet...",
				"Omnes formae reseratae?", " Gradus peritiae usque ad proximam reserationem", "Constat ", "Constat <color=#03bcff>{0} Ki</color>", "<color=#E5C962>{0}% damni</color>"
			},
			["en"] = new string[25]
			{
				"Transformations", "Transformation", "Base Form", "Level", "REMOVE", "TOGGLE EXTRA", "Total Mastery Levels Required: ", "Total Mastery Levels", "Ki Drain: ", " Per Second",
				"Charge Power: ", "Damage: ", "Armor: ", "Health Regen: ", "Attack Speed: ", "Movement Speed: ", "Max Health: ", "Mastered ", "Power Level: ", " has no stat boosts...",
				"All Forms unlocked?", " Mastery levels until next unlock", "Costs ", "Costs <color=#03bcff>{0} Ki</color>", "<color=#E5C962>{0}% Damage</color>"
			},
			["pt-BR"] = new string[25]
			{
				"Transformações", "Transformação", "Forma Base", "Nível", "REMOVER", "ALTERNAR EXTRAS", "Níveis de Maestria Totais Necessários: ", "Níveis de Maestria Totais", "Dreno de Ki: ", " Por Segundo",
				"Poder de Carga: ", "Dano: ", "Armadura: ", "Regeneração de Vida: ", "Velocidade de Ataque: ", "Velocidade de Movimento: ", "Vida Máxima: ", "Dominado ", "Nível de Poder: ", " não possui bônus de atributos...",
				"Todas as formas desbloqueadas?", " Níveis de maestria até o próximo desbloqueio", "Custa ", "Custa <color=#03bcff>{0} Ki</color>", "<color=#E5C962>{0}% de dano</color>"
			}
		};

		private static readonly string[] Keys = new string[25]
		{
			"KINGMOD_TRANSFORMATIONS", "KINGMOD_TRANSFORMATION", "KINGMOD_BASE_FORM", "KINGMOD_LEVEL", "KINGMOD_REMOVE", "KINGMOD_TOGGLE_EXTRA", "KINGMOD_TOTAL_MASTERY_REQUIRED", "KINGMOD_TOTAL_MASTERY_LEVELS", "KINGMOD_KI_DRAIN", "KINGMOD_PER_SECOND",
			"KINGMOD_CHARGE_POWER", "KINGMOD_STAT_DAMAGE", "KINGMOD_STAT_ARMOR", "KINGMOD_STAT_HEALTH_REGEN", "KINGMOD_STAT_ATTACK_SPEED", "KINGMOD_STAT_MOVE_SPEED", "KINGMOD_STAT_MAX_HEALTH", "KINGMOD_MASTERED", "KINGMOD_POWER_LEVEL", "KINGMOD_NO_STAT_BOOSTS",
			"KINGMOD_ALL_FORMS_UNLOCKED", "KINGMOD_UNTIL_NEXT_UNLOCK", "KINGMOD_COSTS_PREFIX", "KINGMOD_COSTS_KI_FORMAT", "KINGMOD_DAMAGE_FORMAT"
		};

		internal static bool TryGet(string language, string key, out string value)
		{
			if (string.Equals(language, "uk", StringComparison.OrdinalIgnoreCase))
			{
				language = "UA";
			}
			int num = Array.IndexOf(Keys, key);
			if (num >= 0 && language != null && Data.TryGetValue(language, out string[] value2))
			{
				value = value2[num];
				return true;
			}
			value = null;
			return false;
		}
	}
	internal static class TutorialHighlight
	{
		private static readonly Dictionary<string, Dictionary<string, string>> Terms = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase)
		{
			["en"] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
			{
				["Form Mastery"] = "#FF5400",
				["Main Transformations"] = "#FF5400",
				["Main Transformation"] = "#FF5400",
				["Transformations"] = "#FF5400",
				["transformation"] = "#FF5400",
				["transformed"] = "#FF5400",
				["Base Form"] = "#FF5400",
				["Kaioken"] = "#FF5400",
				["Zenkai"] = "#FF5400",
				["Ki regen"] = "#03bcff",
				["Ki drain"] = "#03bcff",
				["max Ki"] = "#03bcff",
				["Ki"] = "#03bcff",
				["Experience"] = "#E5C962",
				["Damage"] = "#E5C962",
				["Crit Chance"] = "#E5C962",
				["stunned"] = "#E5C962",
				["20% health"] = "#00FF00",
				["Strain"] = "#FF0000",
				["Light Charge"] = "#097CFF"
			},
			["pt-BR"] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
			{
				["Maestria de Forma"] = "#FF5400",
				["Transformações Principais"] = "#FF5400",
				["Transformação Principal"] = "#FF5400",
				["Transformações"] = "#FF5400",
				["transformação"] = "#FF5400",
				["transformado"] = "#FF5400",
				["Forma Base"] = "#FF5400",
				["Kaioken"] = "#FF5400",
				["Zenkais"] = "#FF5400",
				["Zenkai"] = "#FF5400",
				["regeneração geral de Ki"] = "#03bcff",
				["regeneração de Ki"] = "#03bcff",
				["dreno de Ki"] = "#03bcff",
				["Ki máximo"] = "#03bcff",
				["Ki"] = "#03bcff",
				["Experiência"] = "#E5C962",
				["Dano"] = "#E5C962",
				["Chance Crítica"] = "#E5C962",
				["atordoado"] = "#E5C962",
				["20% de vida"] = "#00FF00",
				["esforço"] = "#FF0000",
				["Carga de Luz"] = "#097CFF"
			},
			["de"] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
			{
				["Formbeherrschung"] = "#FF5400",
				["Haupttransformationen"] = "#FF5400",
				["Haupttransformation"] = "#FF5400",
				["Transformationen"] = "#FF5400",
				["Transformation"] = "#FF5400",
				["verwandelt"] = "#FF5400",
				["Grundform"] = "#FF5400",
				["Kaioken"] = "#FF5400",
				["Zenkais"] = "#FF5400",
				["Ki-Regeneration"] = "#03bcff",
				["Ki-Verbrauch"] = "#03bcff",
				["maximales Ki"] = "#03bcff",
				["Ki"] = "#03bcff",
				["Erfahrung"] = "#E5C962",
				["Schaden"] = "#E5C962",
				["kritische Trefferchance"] = "#E5C962",
				["betäubt"] = "#E5C962",
				["20 % deiner Gesundheit"] = "#00FF00",
				["belastet"] = "#FF0000",
				["Belastung"] = "#FF0000",
				["leichte Ladung"] = "#097CFF"
			},
			["es-419"] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
			{
				["Maestría de forma"] = "#FF5400",
				["Transformaciones Principales"] = "#FF5400",
				["Transformación Principal"] = "#FF5400",
				["transformaciones"] = "#FF5400",
				["transformación"] = "#FF5400",
				["transformado"] = "#FF5400",
				["Forma Base"] = "#FF5400",
				["Kaioken"] = "#FF5400",
				["Zenkai"] = "#FF5400",
				["regeneración general de Ki"] = "#03bcff",
				["consumo de Ki"] = "#03bcff",
				["Ki máximo"] = "#03bcff",
				["Ki"] = "#03bcff",
				["experiencia"] = "#E5C962",
				["daño"] = "#E5C962",
				["probabilidad de crítico"] = "#E5C962",
				["aturdido"] = "#E5C962",
				["20% de salud"] = "#00FF00",
				["esfuerzo"] = "#FF0000",
				["carga ligera"] = "#097CFF"
			},
			["es-ES"] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
			{
				["Maestría de forma"] = "#FF5400",
				["Transformaciones Principales"] = "#FF5400",
				["Transformación Principal"] = "#FF5400",
				["transformaciones"] = "#FF5400",
				["transformación"] = "#FF5400",
				["transformado"] = "#FF5400",
				["Forma Base"] = "#FF5400",
				["Kaioken"] = "#FF5400",
				["Zenkai"] = "#FF5400",
				["regeneración general de Ki"] = "#03bcff",
				["consumo de Ki"] = "#03bcff",
				["Ki máximo"] = "#03bcff",
				["Ki"] = "#03bcff",
				["experiencia"] = "#E5C962",
				["daño"] = "#E5C962",
				["probabilidad de crítico"] = "#E5C962",
				["aturdido"] = "#E5C962",
				["20% de salud"] = "#00FF00",
				["esfuerzo"] = "#FF0000",
				["carga ligera"] = "#097CFF"
			},
			["FR"] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
			{
				["maîtrise des formes"] = "#FF5400",
				["transformations principales"] = "#FF5400",
				["transformation principale"] = "#FF5400",
				["transformations"] = "#FF5400",
				["transformation"] = "#FF5400",
				["forme de base"] = "#FF5400",
				["Kaioken"] = "#FF5400",
				["Zenkai"] = "#FF5400",
				["consommation de Ki"] = "#03bcff",
				["régénération générale du Ki"] = "#03bcff",
				["Ki maximal"] = "#03bcff",
				["Ki"] = "#03bcff",
				["expérience"] = "#E5C962",
				["dégâts"] = "#E5C962",
				["chances de coup critique"] = "#E5C962",
				["étourdi"] = "#E5C962",
				["20% de santé"] = "#00FF00",
				["tension"] = "#FF0000",
				["charge légère"] = "#097CFF"
			},
			["IT"] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
			{
				["maestria delle forme"] = "#FF5400",
				["Trasformazioni Principali"] = "#FF5400",
				["Trasformazione Principale"] = "#FF5400",
				["trasformazioni"] = "#FF5400",
				["trasformazione"] = "#FF5400",
				["trasformato"] = "#FF5400",
				["forma base"] = "#FF5400",
				["Kaioken"] = "#FF5400",
				["Zenkai"] = "#FF5400",
				["consumo di Ki"] = "#03bcff",
				["rigenerazione complessiva del Ki"] = "#03bcff",
				["Ki massimo"] = "#03bcff",
				["Ki"] = "#03bcff",
				["esperienza"] = "#E5C962",
				["danni"] = "#E5C962",
				["probabilità critica"] = "#E5C962",
				["stordito"] = "#E5C962",
				["20% di salute"] = "#00FF00",
				["sforzo"] = "#FF0000",
				["Carica leggera"] = "#097CFF"
			},
			["ja"] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
			{
				["形態熟練度"] = "#FF5400",
				["メイン変身"] = "#FF5400",
				["基本形態"] = "#FF5400",
				["変身"] = "#FF5400",
				["界王拳"] = "#FF5400",
				["ゼンカイ"] = "#FF5400",
				["気の回復量"] = "#03bcff",
				["気の消費"] = "#03bcff",
				["最大気力"] = "#03bcff",
				["気"] = "#03bcff",
				["経験値"] = "#E5C962",
				["ダメージ"] = "#E5C962",
				["クリティカル率"] = "#E5C962",
				["気絶"] = "#E5C962",
				["20%未満"] = "#00FF00",
				["負担"] = "#FF0000",
				["ライトチャージ"] = "#097CFF"
			},
			["ko"] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
			{
				["형태 숙련도"] = "#FF5400",
				["주 변신"] = "#FF5400",
				["기본 형태"] = "#FF5400",
				["변신"] = "#FF5400",
				["계왕권"] = "#FF5400",
				["Zenkai"] = "#FF5400",
				["기 회복량"] = "#03bcff",
				["기 회복"] = "#03bcff",
				["기 소모"] = "#03bcff",
				["최대 기"] = "#03bcff",
				["기"] = "#03bcff",
				["경험치"] = "#E5C962",
				["피해"] = "#E5C962",
				["치명타 확률"] = "#E5C962",
				["기절"] = "#E5C962",
				["20% 미만"] = "#00FF00",
				["부담"] = "#FF0000",
				["빛 충전"] = "#097CFF"
			},
			["RU"] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
			{
				["Мастерство формы"] = "#FF5400",
				["основным трансформациям"] = "#FF5400",
				["основную форму"] = "#FF5400",
				["трансформации"] = "#FF5400",
				["трансформаций"] = "#FF5400",
				["трансформация"] = "#FF5400",
				["базовой форме"] = "#FF5400",
				["базовой формы"] = "#FF5400",
				["Kaioken"] = "#FF5400",
				["Зенкай"] = "#FF5400",
				["восстановления Ки"] = "#03bcff",
				["утечки Ки"] = "#03bcff",
				["количество Ки"] = "#03bcff",
				["Ки"] = "#03bcff",
				["опыт"] = "#E5C962",
				["урон"] = "#E5C962",
				["шанс критического удара"] = "#E5C962",
				["оглушения"] = "#E5C962",
				["здоровьем ниже 20%"] = "#00FF00",
				["нагрузку"] = "#FF0000",
				["нагрузки"] = "#FF0000",
				["легкий заряд"] = "#097CFF"
			},
			["UA"] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
			{
				["майстерності форми"] = "#FF5400",
				["основним формам"] = "#FF5400",
				["основну форму"] = "#FF5400",
				["трансформації"] = "#FF5400",
				["трансформація"] = "#FF5400",
				["трансформованому"] = "#FF5400",
				["базовій формі"] = "#FF5400",
				["базової форми"] = "#FF5400",
				["Kaioken"] = "#FF5400",
				["Zenkai"] = "#FF5400",
				["витрати Кі"] = "#03bcff",
				["відновлення Кі"] = "#03bcff",
				["запас Кі"] = "#03bcff",
				["Кі"] = "#03bcff",
				["досвід"] = "#E5C962",
				["шкода"] = "#E5C962",
				["шкоди"] = "#E5C962",
				["шанс критичного удару"] = "#E5C962",
				["оглушення"] = "#E5C962",
				["здоров’ям нижче 20%"] = "#00FF00",
				["навантаження"] = "#FF0000",
				["світловий заряд"] = "#097CFF"
			},
			["zh-CN"] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
			{
				["形态精通"] = "#FF5400",
				["主要变身"] = "#FF5400",
				["基础形态"] = "#FF5400",
				["变身"] = "#FF5400",
				["界王拳"] = "#FF5400",
				["Zenkai"] = "#FF5400",
				["气恢复速度"] = "#03bcff",
				["气消耗"] = "#03bcff",
				["气上限"] = "#03bcff",
				["气"] = "#03bcff",
				["经验"] = "#E5C962",
				["伤害"] = "#E5C962",
				["暴击率"] = "#E5C962",
				["眩晕"] = "#E5C962",
				["生命值低于 20%"] = "#00FF00",
				["负担"] = "#FF0000",
				["光之充能"] = "#097CFF"
			},
			["tr"] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
			{
				["Form Ustalığı"] = "#FF5400",
				["Ana Dönüşümlerin"] = "#FF5400",
				["Ana Dönüşümü"] = "#FF5400",
				["Dönüşümler"] = "#FF5400",
				["Dönüşüm"] = "#FF5400",
				["Dönüşmüş"] = "#FF5400",
				["Temel Formunun"] = "#FF5400",
				["Temel Formda"] = "#FF5400",
				["Kaioken"] = "#FF5400",
				["Zenkai"] = "#FF5400",
				["Ki yenilenmesi"] = "#03bcff",
				["Ki tüketimi"] = "#03bcff",
				["Ki"] = "#03bcff",
				["Deneyim"] = "#E5C962",
				["Hasar"] = "#E5C962",
				["Kritik Şansı"] = "#E5C962",
				["sersemleme"] = "#E5C962",
				["%20 canın"] = "#00FF00",
				["zorlanma"] = "#FF0000",
				["zorlanmaya"] = "#FF0000",
				["Işık Şarjı"] = "#097CFF"
			},
			["eo"] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
			{
				["forma majstreco"] = "#FF5400",
				["Cxefaj transformoj"] = "#FF5400",
				["cxefan transformon"] = "#FF5400",
				["transformoj"] = "#FF5400",
				["transformon"] = "#FF5400",
				["transformo"] = "#FF5400",
				["transformiteco"] = "#FF5400",
				["baza formo"] = "#FF5400",
				["Kaioken"] = "#FF5400",
				["Zenkai"] = "#FF5400",
				["Ki-regenerado"] = "#03bcff",
				["Ki-regeneradon"] = "#03bcff",
				["Ki-elfluon"] = "#03bcff",
				["Ki"] = "#03bcff",
				["sperton"] = "#E5C962",
				["damagxon"] = "#E5C962",
				["kritikan sxancon"] = "#E5C962",
				["miregigxos"] = "#E5C962",
				["20% da sano"] = "#00FF00",
				["strecxigxas"] = "#FF0000",
				["strecxigxo"] = "#FF0000",
				["lumsxargon"] = "#097CFF"
			},
			["la"] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
			{
				["peritiam formae"] = "#FF5400",
				["Transformationes principales"] = "#FF5400",
				["transformationem principalem"] = "#FF5400",
				["transformationis"] = "#FF5400",
				["transformationem"] = "#FF5400",
				["transformatus"] = "#FF5400",
				["forma fundamentali"] = "#FF5400",
				["formae fundamentalis"] = "#FF5400",
				["Kaioken"] = "#FF5400",
				["Zenkai"] = "#FF5400",
				["regenerationem Ki"] = "#03bcff",
				["consumptionem Ki"] = "#03bcff",
				["Ki maximum"] = "#03bcff",
				["Ki"] = "#03bcff",
				["experientiam"] = "#E5C962",
				["damnum"] = "#E5C962",
				["probabilitatem ictus critici"] = "#E5C962",
				["stuporis"] = "#E5C962",
				["20% salutis"] = "#00FF00",
				["fatigatur"] = "#FF0000",
				["fatigatio"] = "#FF0000",
				["Lucis cumulum"] = "#097CFF"
			}
		};

		private static readonly Dictionary<string, Regex> Patterns = new Dictionary<string, Regex>(StringComparer.OrdinalIgnoreCase);

		private static readonly object PatternLock = new object();

		internal static string Apply(string language, string token, string text)
		{
			if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(language))
			{
				return text;
			}
			if (string.Equals(language, "uk", StringComparison.OrdinalIgnoreCase))
			{
				language = "UA";
			}
			if (!Terms.TryGetValue(language, out Dictionary<string, string> terms))
			{
				return text;
			}
			Regex value;
			lock (PatternLock)
			{
				if (!Patterns.TryGetValue(language, out value))
				{
					IEnumerable<string> values = terms.Keys.OrderByDescending((string x) => x.Length).Select(delegate(string x)
					{
						string text2 = Regex.Escape(x);
						return (x.Length > 2 || !Regex.IsMatch(x, "^[A-Za-zА-Яа-яІіЇїЄє]+$")) ? text2 : ("(?<![\\p{L}\\p{N}])" + text2 + "(?![\\p{L}\\p{N}])");
					});
					value = new Regex(string.Join("|", values), RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
					Patterns[language] = value;
				}
			}
			string[] array = value.Replace(text, (Match match) => "<color=" + terms[match.Value] + ">" + match.Value + "</color>").Split('\n');
			if (token == "KINGMOD_TUTORIAL_FORM_MASTERY" && array.Length > 1)
			{
				array[^1] = "<color=#aaaaaa>" + array[^1] + "</color>";
			}
			if (token == "KINGMOD_TUTORIAL_KAIOKEN" && array.Length >= 8)
			{
				for (int num = array.Length - 3; num < array.Length; num++)
				{
					array[num] = "<color=#aaaaaa>" + array[num] + "</color>";
				}
			}
			return string.Join("\n", array);
		}
	}
	internal static class TutorialMatcher
	{
		internal static string FindToken(string text)
		{
			if (string.IsNullOrEmpty(text))
			{
				return null;
			}
			string text2 = Regex.Replace(Regex.Replace(text, "<[^>]*>", ""), "\\s+", " ").Trim();
			if (text2.Contains("Enable/Disable Tutorials"))
			{
				return "KINGMOD_TUTORIAL_F1";
			}
			if (text2.Contains("With Form Mastery"))
			{
				return "KINGMOD_TUTORIAL_FORM_MASTERY";
			}
			if (text2.Contains("Once your mastery level is high enough"))
			{
				return "KINGMOD_TUTORIAL_TRANSFORM_TRIGGER";
			}
			if (text2.Contains("While transformed") && text2.Contains("Ultimate Skill"))
			{
				return "KINGMOD_TUTORIAL_ULTIMATE_SKILL";
			}
			if (text2.Contains("Ki is a resource that your skills use"))
			{
				return "KINGMOD_TUTORIAL_KI_RESOURCE";
			}
			if (text2.Contains("Gain Zenkai"))
			{
				return "KINGMOD_TUTORIAL_ZENKAI";
			}
			if (text2.Contains("Gain Light Charge"))
			{
				return "KINGMOD_TUTORIAL_LIGHT_CHARGE";
			}
			if (text2.Contains("Unlock Kaioken forms") || text2.Contains("Kaioken Meter"))
			{
				return "KINGMOD_TUTORIAL_KAIOKEN";
			}
			return null;
		}
	}
	internal static class TutorialTranslations
	{
		private static readonly Dictionary<string, Dictionary<string, string>> Data = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase)
		{
			["en"] = new Dictionary<string, string>(StringComparer.Ordinal)
			{
				["KINGMOD_TUTORIAL_F1"] = "Enable/Disable Tutorials by pressing F1",
				["KINGMOD_TUTORIAL_FORM_MASTERY"] = "With Form Mastery, gain Experience over time or by damaging enemies. Levelling up the form grants the following:\n- An increase to your transformation's stat boost.\n- A reduction to the Ki drain of your transformation\n- An increase to your overall Ki regen.\nIn Base Form, Ki regen & max Ki is gained.",
				["KINGMOD_TUTORIAL_TRANSFORM_TRIGGER"] = "Once your mastery level is high enough, activate a Main Transformation by tapping the transformation button (Default 'C') and Power Down by pressing (Default 'X'). When more Transformations unlock, press the transformation button again to ascend further beyond!",
				["KINGMOD_TUTORIAL_ULTIMATE_SKILL"] = "While transformed, you have access to an Ultimate Skill. Activate it by pressing the key binded below.",
				["KINGMOD_TUTORIAL_KI_RESOURCE"] = "Ki is a resource that your skills use. Gain some back by hitting enemies with your primary skill.",
				["KINGMOD_TUTORIAL_ZENKAI"] = "Gain Zenkai's by dying or staying below 20% health for 30 seconds. Grants permanent bonus stats.",
				["KINGMOD_TUTORIAL_LIGHT_CHARGE"] = "Gain Light Charge by hitting enemies with your sword. Once full, activate it by holding the Transformation Button. Grants bonus Damage and Crit Chance while active.",
				["KINGMOD_TUTORIAL_KAIOKEN"] = "Unlock Kaioken forms by levelling up your Base Form.\nArrows will display above the Kaioken Meter when Kaioken is available.\nTransform into Kaioken by holding the transformation button.\nWhile active, your body begins to Strain and fills the meter.\nIf the meter is full, you have a high chance of being stunned.\nLevelling up your Base Form increases your strain limit.\nHigher strain rates increase stun duration.\nMain Transformations require mastery to handle Kaioken.",
				["KINGMOD_POPUP_ADDED_FORMAT"] = "Added {0}!",
				["KINGMOD_ULTIMATE_SKILL_TITLE"] = "ULTIMATE SKILL"
			},
			["de"] = new Dictionary<string, string>(StringComparer.Ordinal)
			{
				["KINGMOD_TUTORIAL_KI_RESOURCE"] = "Ki ist eine Ressource, die Ihre Fähigkeiten nutzen. Gewinnen Sie etwas zurück, indem Sie Feinde mit Ihrer Primärfähigkeit treffen.",
				["KINGMOD_TUTORIAL_FORM_MASTERY"] = "Mit Formbeherrschung erhältst du mit der Zeit oder durch Schaden an Gegnern Erfahrung. Ein höheres Formlevel gewährt:\n- Einen höheren Attributbonus deiner Transformation.\n- Einen geringeren Ki-Verbrauch deiner Transformation.\n- Eine höhere allgemeine Ki-Regeneration.\nIn der Grundform steigen Ki-Regeneration und maximales Ki.",
				["KINGMOD_TUTORIAL_ZENKAI"] = "Erhalte Zenkais, indem du stirbst oder 30 Sekunden lang unter 20 % deiner Gesundheit bleibst. Gewährt dauerhafte Bonusstatistiken.",
				["KINGMOD_TUTORIAL_LIGHT_CHARGE"] = "Erhalte leichte Ladung, indem du Feinde mit deinem Schwert triffst. Sobald es voll ist, aktivieren Sie es, indem Sie die Transformationstaste gedrückt halten. Gewährt zusätzlichen Schaden und kritische Trefferchance, solange es aktiv ist.",
				["KINGMOD_TUTORIAL_TRANSFORM_TRIGGER"] = "Ist dein Meisterschaftslevel hoch genug, tippe auf die Transformationstaste (standardmäßig C), um eine Haupttransformation zu aktivieren; mit X kehrst du zu einer niedrigeren Form zurück. Sind weitere Transformationen freigeschaltet, drücke die Taste erneut, um weiter aufzusteigen!",
				["KINGMOD_TUTORIAL_F1"] = "Aktivieren/deaktivieren Sie Tutorials, indem Sie F1 drücken",
				["KINGMOD_TUTORIAL_KAIOKEN"] = "Schalte Kaioken-Formen frei, indem du deine Grundform aufwertest.\nIst Kaioken verfügbar, erscheinen Pfeile über der Kaioken-Anzeige.\nHalte die Transformationstaste gedrückt, um Kaioken zu aktivieren.\nWährenddessen wird dein Körper belastet und die Anzeige füllt sich.\nIst sie voll, wirst du mit hoher Wahrscheinlichkeit betäubt.\nEin höheres Level der Grundform erhöht deine Belastungsgrenze.\nEine schnellere Belastung verlängert die Betäubung.\nHaupttransformationen benötigen Meisterschaft, um Kaioken standzuhalten.",
				["KINGMOD_TUTORIAL_ULTIMATE_SKILL"] = "Während du verwandelt bist, hast du Zugang zu einer ultimativen Fähigkeit. Aktivieren Sie es, indem Sie die unten zugeordnete Taste drücken.",
				["KINGMOD_POPUP_ADDED_FORMAT"] = "{0} hinzugefügt!",
				["KINGMOD_ULTIMATE_SKILL_TITLE"] = "ULTIMATIVE FÄHIGKEIT"
			},
			["es-419"] = new Dictionary<string, string>(StringComparer.Ordinal)
			{
				["KINGMOD_TUTORIAL_ULTIMATE_SKILL"] = "Mientras estás transformado, tienes acceso a una habilidad definitiva. Actívelo presionando la tecla adjunta a continuación.",
				["KINGMOD_TUTORIAL_KI_RESOURCE"] = "Ki es un recurso que utilizan tus habilidades. Recupera algo golpeando a los enemigos con tu habilidad principal.",
				["KINGMOD_TUTORIAL_FORM_MASTERY"] = "Con Maestría de forma, ganas experiencia con el tiempo o al dañar enemigos. Subir de nivel la forma otorga:\n- Mayor bonificación de atributos de la transformación.\n- Menor consumo de Ki de la transformación.\n- Mayor regeneración general de Ki.\nEn la Forma Base aumentan la regeneración y el Ki máximo.",
				["KINGMOD_TUTORIAL_F1"] = "Activar/desactivar tutoriales pulsando F1",
				["KINGMOD_TUTORIAL_TRANSFORM_TRIGGER"] = "Cuando tu nivel de maestría sea suficiente, pulsa el botón de transformación (C por defecto) para activar una Transformación Principal y X por defecto para reducir tu poder. Al desbloquear más transformaciones, vuelve a pulsar el botón para ascender aún más.",
				["KINGMOD_TUTORIAL_ZENKAI"] = "Gana Zenkai muriendo o manteniéndote por debajo del 20% de salud durante 30 segundos. Otorga estadísticas de bonificación permanentes.",
				["KINGMOD_TUTORIAL_KAIOKEN"] = "Desbloquea formas de Kaioken subiendo de nivel la Forma Base.\nCuando Kaioken esté disponible, aparecerán flechas sobre su medidor.\nMantén pulsado el botón de transformación para activarlo.\nMientras esté activo, tu cuerpo acumula esfuerzo y llena el medidor.\nSi se llena, tienes una alta probabilidad de quedar aturdido.\nSubir de nivel la Forma Base aumenta tu límite de esfuerzo.\nUna mayor acumulación de esfuerzo aumenta la duración del aturdimiento.\nLas Transformaciones Principales necesitan maestría para soportar Kaioken.",
				["KINGMOD_TUTORIAL_LIGHT_CHARGE"] = "Obtén carga ligera golpeando a los enemigos con tu espada. Una vez lleno, actívalo manteniendo presionado el botón de transformación. Otorga daño adicional y probabilidad de crítico mientras está activo.",
				["KINGMOD_POPUP_ADDED_FORMAT"] = "¡{0} añadido!",
				["KINGMOD_ULTIMATE_SKILL_TITLE"] = "HABILIDAD DEFINITIVA"
			},
			["es-ES"] = new Dictionary<string, string>(StringComparer.Ordinal)
			{
				["KINGMOD_TUTORIAL_F1"] = "Activar/desactivar tutoriales pulsando F1",
				["KINGMOD_TUTORIAL_FORM_MASTERY"] = "Con Maestría de forma, ganas experiencia con el tiempo o al dañar enemigos. Subir de nivel la forma otorga:\n- Mayor bonificación de atributos de la transformación.\n- Menor consumo de Ki de la transformación.\n- Mayor regeneración general de Ki.\nEn la Forma Base aumentan la regeneración y el Ki máximo.",
				["KINGMOD_TUTORIAL_ULTIMATE_SKILL"] = "Mientras estás transformado, tienes acceso a una habilidad definitiva. Actívelo presionando la tecla adjunta a continuación.",
				["KINGMOD_TUTORIAL_KI_RESOURCE"] = "Ki es un recurso que utilizan tus habilidades. Recupera algo golpeando a los enemigos con tu habilidad principal.",
				["KINGMOD_TUTORIAL_LIGHT_CHARGE"] = "Obtén carga ligera golpeando a los enemigos con tu espada. Una vez lleno, actívalo manteniendo presionado el botón de transformación. Otorga daño adicional y probabilidad de crítico mientras está activo.",
				["KINGMOD_TUTORIAL_TRANSFORM_TRIGGER"] = "Cuando tu nivel de maestría sea suficiente, pulsa el botón de transformación (C por defecto) para activar una Transformación Principal y X por defecto para reducir tu poder. Al desbloquear más transformaciones, vuelve a pulsar el botón para ascender aún más.",
				["KINGMOD_TUTORIAL_KAIOKEN"] = "Desbloquea formas de Kaioken subiendo de nivel la Forma Base.\nCuando Kaioken esté disponible, aparecerán flechas sobre su medidor.\nMantén pulsado el botón de transformación para activarlo.\nMientras esté activo, tu cuerpo acumula esfuerzo y llena el medidor.\nSi se llena, tienes una alta probabilidad de quedar aturdido.\nSubir de nivel la Forma Base aumenta tu límite de esfuerzo.\nUna mayor acumulación de esfuerzo aumenta la duración del aturdimiento.\nLas Transformaciones Principales necesitan maestría para soportar Kaioken.",
				["KINGMOD_TUTORIAL_ZENKAI"] = "Gana Zenkai muriendo o manteniéndote por debajo del 20% de salud durante 30 segundos. Otorga estadísticas de bonificación permanentes.",
				["KINGMOD_POPUP_ADDED_FORMAT"] = "¡{0} añadido!",
				["KINGMOD_ULTIMATE_SKILL_TITLE"] = "HABILIDAD DEFINITIVA"
			},
			["FR"] = new Dictionary<string, string>(StringComparer.Ordinal)
			{
				["KINGMOD_TUTORIAL_F1"] = "Activer/Désactiver les didacticiels en appuyant sur F1",
				["KINGMOD_TUTORIAL_FORM_MASTERY"] = "Avec la maîtrise des formes, gagnez de l'expérience au fil du temps ou en blessant des ennemis. Augmenter le niveau d'une forme donne :\n- Un meilleur bonus de caractéristiques de la transformation.\n- Une réduction de sa consommation de Ki.\n- Une meilleure régénération générale du Ki.\nEn forme de base, la régénération et le Ki maximal augmentent.",
				["KINGMOD_TUTORIAL_TRANSFORM_TRIGGER"] = "Lorsque votre niveau de maîtrise est suffisant, appuyez sur le bouton de transformation (C par défaut) pour activer une transformation principale, et sur X par défaut pour revenir à une forme inférieure. Une fois d'autres transformations débloquées, appuyez à nouveau pour atteindre un niveau supérieur !",
				["KINGMOD_TUTORIAL_ULTIMATE_SKILL"] = "Pendant votre transformation, vous avez accès à une compétence ultime. Activez-le en appuyant sur la touche liée ci-dessous.",
				["KINGMOD_TUTORIAL_KAIOKEN"] = "Débloquez les formes Kaioken en augmentant le niveau de votre forme de base.\nDes flèches apparaissent au-dessus de la jauge lorsque Kaioken est disponible.\nMaintenez le bouton de transformation pour l'activer.\nPendant son activation, votre corps accumule de la tension et la jauge se remplit.\nSi elle est pleine, vous risquez fortement d'être étourdi.\nAugmenter le niveau de la forme de base élève votre limite de tension.\nUne accumulation plus rapide prolonge l'étourdissement.\nLes transformations principales exigent de la maîtrise pour supporter Kaioken.",
				["KINGMOD_TUTORIAL_ZENKAI"] = "Gagnez Zenkai en mourant ou en restant en dessous de 20% de santé pendant 30 secondes. Accorde des statistiques bonus permanentes.",
				["KINGMOD_TUTORIAL_LIGHT_CHARGE"] = "Gagnez une charge légère en frappant les ennemis avec votre épée. Une fois plein, activez-le en maintenant le bouton Transformation enfoncé. Accorde un bonus de dégâts et de chances de coup critique lorsqu'il est actif.",
				["KINGMOD_TUTORIAL_KI_RESOURCE"] = "Ki est une ressource que vos compétences utilisent. Récupérez-en en frappant les ennemis avec votre compétence principale.",
				["KINGMOD_POPUP_ADDED_FORMAT"] = "{0} ajouté !",
				["KINGMOD_ULTIMATE_SKILL_TITLE"] = "COMPÉTENCE ULTIME"
			},
			["IT"] = new Dictionary<string, string>(StringComparer.Ordinal)
			{
				["KINGMOD_TUTORIAL_ZENKAI"] = "Ottieni Zenkai morendo o rimanendo al di sotto del 20% di salute per 30 secondi. Concede statistiche bonus permanenti.",
				["KINGMOD_TUTORIAL_ULTIMATE_SKILL"] = "Mentre sei trasformato, hai accesso a un'abilità suprema. Attivalo premendo il tasto associato di seguito.",
				["KINGMOD_TUTORIAL_F1"] = "Abilita/Disabilita i tutorial premendo F1",
				["KINGMOD_TUTORIAL_KI_RESOURCE"] = "Il Ki è una risorsa utilizzata dalle tue abilità. Guadagnane un po' colpendo i nemici con la tua abilità principale.",
				["KINGMOD_TUTORIAL_FORM_MASTERY"] = "Con la maestria delle forme, ottieni esperienza nel tempo o danneggiando i nemici. Aumentare il livello della forma concede:\n- Un maggior bonus alle statistiche della trasformazione.\n- Un minor consumo di Ki della trasformazione.\n- Una maggiore rigenerazione complessiva del Ki.\nNella forma base aumentano la rigenerazione e il Ki massimo.",
				["KINGMOD_TUTORIAL_TRANSFORM_TRIGGER"] = "Quando il livello di maestria è sufficiente, premi il pulsante di trasformazione (C per impostazione predefinita) per attivare una Trasformazione Principale e X per tornare a una forma inferiore. Quando sblocchi altre trasformazioni, premi di nuovo il pulsante per ascendere ancora!",
				["KINGMOD_TUTORIAL_LIGHT_CHARGE"] = "Ottieni Carica leggera colpendo i nemici con la tua spada. Una volta pieno, attivalo tenendo premuto il pulsante di trasformazione. Concede danni bonus e probabilità critica mentre è attivo.",
				["KINGMOD_TUTORIAL_KAIOKEN"] = "Sblocca le forme Kaioken aumentando il livello della Forma Base.\nQuando Kaioken è disponibile, sopra l'indicatore appaiono delle frecce.\nTieni premuto il pulsante di trasformazione per attivarlo.\nMentre è attivo, il corpo accumula sforzo e l'indicatore si riempie.\nSe è pieno, hai un'alta probabilità di essere stordito.\nAumentare il livello della Forma Base alza il limite di sforzo.\nUn accumulo di sforzo più rapido aumenta la durata dello stordimento.\nLe Trasformazioni Principali richiedono maestria per sostenere Kaioken.",
				["KINGMOD_POPUP_ADDED_FORMAT"] = "{0} aggiunto!",
				["KINGMOD_ULTIMATE_SKILL_TITLE"] = "ABILITÀ SUPREMA"
			},
			["ja"] = new Dictionary<string, string>(StringComparer.Ordinal)
			{
				["KINGMOD_TUTORIAL_F1"] = "F1キーでチュートリアルを表示・非表示にします。",
				["KINGMOD_TUTORIAL_FORM_MASTERY"] = "形態熟練度により、時間の経過または敵へのダメージで経験値を獲得します。形態のレベルを上げると:\n- 変身による能力値ボーナスが増加します。\n- 変身中の気の消費が減少します。\n- 全体の気の回復量が増加します。\n基本形態では気の回復量と最大気力が増加します。",
				["KINGMOD_TUTORIAL_ULTIMATE_SKILL"] = "変身中は究極技を使用できます。下に割り当てられたキーを押して発動します。",
				["KINGMOD_TUTORIAL_TRANSFORM_TRIGGER"] = "熟練度が十分に上がると、変身ボタン(初期設定 C)を押してメイン変身を発動し、パワーダウン(初期設定 X)で下位の形態に戻れます。さらに変身を解放したら、変身ボタンをもう一度押して上位形態へ!",
				["KINGMOD_TUTORIAL_KAIOKEN"] = "基本形態のレベルを上げると界王拳の形態が解放されます。\n界王拳が使用可能になると、ゲージの上に矢印が表示されます。\n変身ボタンを長押しして界王拳を発動します。\n発動中は体への負担が増え、ゲージが溜まります。\nゲージが満タンになると高確率で気絶します。\n基本形態のレベルを上げると負担の上限が上がります。\n負担の蓄積速度が高いほど気絶時間が長くなります。\nメイン変身で界王拳に耐えるには熟練度が必要です。",
				["KINGMOD_TUTORIAL_KI_RESOURCE"] = "気はスキルが消費する資源です。メインスキルで敵を攻撃すると一部回復します。",
				["KINGMOD_TUTORIAL_LIGHT_CHARGE"] = "剣で敵を攻撃するとライトチャージが蓄積します。満タンになったら変身ボタンを長押しして発動。発動中はダメージとクリティカル率が上昇します。",
				["KINGMOD_TUTORIAL_ZENKAI"] = "死亡するか、体力が20%未満の状態で30秒間耐えると、ゼンカイを獲得し、能力値が恒久的に上昇します。",
				["KINGMOD_POPUP_ADDED_FORMAT"] = "{0}を追加!",
				["KINGMOD_ULTIMATE_SKILL_TITLE"] = "究極技"
			},
			["ko"] = new Dictionary<string, string>(StringComparer.Ordinal)
			{
				["KINGMOD_TUTORIAL_F1"] = "F1을 눌러 튜토리얼을 켜거나 끕니다.",
				["KINGMOD_TUTORIAL_FORM_MASTERY"] = "형태 숙련도를 통해 시간이 지나거나 적에게 피해를 주면 경험치를 얻습니다. 형태의 레벨을 올리면:\n- 변신의 능력치 보너스가 증가합니다.\n- 변신 중 기 소모가 감소합니다.\n- 전체 기 회복량이 증가합니다.\n기본 형태에서는 기 회복과 최대 기가 증가합니다.",
				["KINGMOD_TUTORIAL_TRANSFORM_TRIGGER"] = "숙련도 레벨이 충분하면 변신 버튼(기본 C)을 눌러 주 변신을 활성화하고, 단계 하강 버튼(기본 X)을 눌러 낮은 형태로 돌아갑니다. 추가 변신을 해제한 뒤 변신 버튼을 다시 누르면 더 높은 형태로 올라갑니다!",
				["KINGMOD_TUTORIAL_LIGHT_CHARGE"] = "검으로 적을 맞혀 빛 충전을 모읍니다. 가득 차면 변신 버튼을 길게 눌러 활성화하세요. 활성화 중에는 피해와 치명타 확률이 증가합니다.",
				["KINGMOD_TUTORIAL_ULTIMATE_SKILL"] = "변신 중에는 궁극기를 사용할 수 있습니다. 아래에 지정된 키를 눌러 발동하세요.",
				["KINGMOD_TUTORIAL_KI_RESOURCE"] = "기는 스킬에 사용하는 자원입니다. 기본 스킬로 적을 맞히면 일부 회복합니다.",
				["KINGMOD_TUTORIAL_KAIOKEN"] = "기본 형태의 레벨을 올려 계왕권 형태를 해제하세요.\n계왕권을 사용할 수 있으면 계량기 위에 화살표가 표시됩니다.\n변신 버튼을 길게 눌러 계왕권을 활성화하세요.\n활성화 중에는 몸에 부담이 쌓이며 계량기가 찹니다.\n계량기가 가득 차면 높은 확률로 기절합니다.\n기본 형태의 레벨을 올리면 부담 한도가 늘어납니다.\n부담이 더 빠르게 쌓일수록 기절 시간이 길어집니다.\n주 변신 상태에서 계왕권을 버티려면 숙련도가 필요합니다.",
				["KINGMOD_TUTORIAL_ZENKAI"] = "죽거나 체력이 20% 미만인 상태로 30초를 버티면 Zenkai를 얻어 능력치가 영구적으로 증가합니다.",
				["KINGMOD_POPUP_ADDED_FORMAT"] = "{0} 추가!",
				["KINGMOD_ULTIMATE_SKILL_TITLE"] = "궁극기"
			},
			["RU"] = new Dictionary<string, string>(StringComparer.Ordinal)
			{
				["KINGMOD_TUTORIAL_FORM_MASTERY"] = "Используя «Мастерство формы», вы получаете опыт с течением времени или нанося урон врагам. Повышение уровня формы дает следующее:\n- Увеличение повышения характеристик вашей трансформации.\n- Уменьшение утечки Ки в вашей трансформации.\n- Увеличение общего восстановления Ки.\nВ базовой форме достигается регенерация Ки и максимальное количество Ки.",
				["KINGMOD_TUTORIAL_F1"] = "Включите/отключите учебные пособия, нажав F1.",
				["KINGMOD_TUTORIAL_TRANSFORM_TRIGGER"] = "Когда уровень мастерства достаточен, нажмите кнопку трансформации (по умолчанию C), чтобы активировать основную форму, и кнопку снижения силы (по умолчанию X), чтобы вернуться к более низкой. После открытия новых трансформаций нажмите кнопку ещё раз, чтобы подняться выше!",
				["KINGMOD_TUTORIAL_LIGHT_CHARGE"] = "Получите легкий заряд, поражая врагов мечом. Когда он заполнится, активируйте его, удерживая кнопку трансформации. Пока активно, дает дополнительный урон и шанс критического удара.",
				["KINGMOD_TUTORIAL_ULTIMATE_SKILL"] = "Во время трансформации у вас есть доступ к Высшему Навыку. Активируйте его, нажав клавишу, указанную ниже.",
				["KINGMOD_TUTORIAL_ZENKAI"] = "Получите Зенкай, умерев или оставаясь со здоровьем ниже 20% в течение 30 секунд. Предоставляет постоянный бонус к характеристикам.",
				["KINGMOD_TUTORIAL_KI_RESOURCE"] = "Ки — это ресурс, который используют ваши навыки. Получите немного обратно, поражая врагов своим основным навыком.",
				["KINGMOD_TUTORIAL_KAIOKEN"] = "Повышайте уровень базовой формы, чтобы открыть формы Kaioken.\nКогда Kaioken доступен, над его шкалой появляются стрелки.\nУдерживайте кнопку трансформации, чтобы активировать Kaioken.\nПока он действует, тело накапливает нагрузку, заполняя шкалу.\nКогда шкала полна, высока вероятность оглушения.\nПовышение уровня базовой формы увеличивает предел нагрузки.\nБолее быстрое накопление нагрузки продлевает оглушение.\nОсновным трансформациям нужно мастерство, чтобы выдерживать Kaioken.",
				["KINGMOD_POPUP_ADDED_FORMAT"] = "{0} добавлено!",
				["KINGMOD_ULTIMATE_SKILL_TITLE"] = "УЛЬТИМАТИВНЫЙ НАВЫК"
			},
			["UA"] = new Dictionary<string, string>(StringComparer.Ordinal)
			{
				["KINGMOD_TUTORIAL_TRANSFORM_TRIGGER"] = "Коли рівень майстерності достатній, натисніть кнопку трансформації (типово C), щоб активувати основну форму, а кнопку зниження сили (типово X) — щоб повернутися до нижчої. Розблокувавши інші трансформації, натисніть кнопку знову, щоб піднятися вище!",
				["KINGMOD_TUTORIAL_F1"] = "Натисніть F1, щоб увімкнути або вимкнути навчання.",
				["KINGMOD_TUTORIAL_LIGHT_CHARGE"] = "Накопичуйте світловий заряд, влучаючи мечем по ворогах. Коли він заповниться, утримуйте кнопку трансформації для активації. Під час дії зростають шкода й шанс критичного удару.",
				["KINGMOD_TUTORIAL_KI_RESOURCE"] = "Кі — ресурс, який використовують ваші навички. Влучайте по ворогах основною навичкою, щоб частково його відновити.",
				["KINGMOD_TUTORIAL_ZENKAI"] = "Отримуйте Zenkai після смерті або перебування зі здоров’ям нижче 20% протягом 30 секунд. Він назавжди підвищує характеристики.",
				["KINGMOD_TUTORIAL_FORM_MASTERY"] = "Завдяки майстерності форми здобувайте досвід з часом або завдаючи шкоди ворогам. Підвищення рівня форми дає:\n- Більший бонус характеристик трансформації.\n- Менші витрати Кі під час трансформації.\n- Краще загальне відновлення Кі.\nУ базовій формі зростають відновлення та максимальний запас Кі.",
				["KINGMOD_TUTORIAL_ULTIMATE_SKILL"] = "У трансформованому стані вам доступна ультимативна навичка. Активуйте її призначеною нижче клавішею.",
				["KINGMOD_TUTORIAL_KAIOKEN"] = "Підвищуйте рівень базової форми, щоб розблокувати форми Kaioken.\nКоли Kaioken доступний, над його шкалою з’являються стрілки.\nУтримуйте кнопку трансформації, щоб активувати Kaioken.\nПоки він діє, тіло накопичує навантаження, а шкала заповнюється.\nКоли шкала повна, є високий шанс оглушення.\nПідвищення рівня базової форми збільшує межу навантаження.\nШвидше накопичення навантаження збільшує тривалість оглушення.\nОсновним формам потрібна майстерність, щоб витримати Kaioken.",
				["KINGMOD_POPUP_ADDED_FORMAT"] = "{0} додано!",
				["KINGMOD_ULTIMATE_SKILL_TITLE"] = "УЛЬТИМАТИВНА НАВИЧКА"
			},
			["zh-CN"] = new Dictionary<string, string>(StringComparer.Ordinal)
			{
				["KINGMOD_TUTORIAL_FORM_MASTERY"] = "通过形态精通,随时间推移或伤害敌人可获得经验。提升形态等级可获得:\n- 提高变身带来的属性加成。\n- 降低变身时的气消耗。\n- 提高整体气恢复速度。\n在基础形态下,气恢复速度和气上限会提高。",
				["KINGMOD_TUTORIAL_LIGHT_CHARGE"] = "用剑击中敌人可积累光之充能。充满后长按变身键激活;激活期间提高伤害和暴击率。",
				["KINGMOD_TUTORIAL_TRANSFORM_TRIGGER"] = "精通等级足够高后,轻按变身键(默认 C)激活主要变身,按降阶键(默认 X)降低形态。解锁更多变身后,再次按下变身键即可继续提升!",
				["KINGMOD_TUTORIAL_ZENKAI"] = "死亡或生命值低于 20% 持续 30 秒可获得Zenkai,永久提高属性。",
				["KINGMOD_TUTORIAL_ULTIMATE_SKILL"] = "变身后可使用终极技能。按下方绑定的按键即可发动。",
				["KINGMOD_TUTORIAL_KI_RESOURCE"] = "气是技能使用的资源。用主技能击中敌人可以恢复一部分气。",
				["KINGMOD_TUTORIAL_KAIOKEN"] = "提升基础形态等级可解锁界王拳形态。\n界王拳可用时,计量条上方会显示箭头。\n长按变身键可激活界王拳。\n激活期间身体逐渐承受负担,计量条随之填充。\n计量条满时,你很可能被眩晕。\n提升基础形态等级可提高负担上限。\n负担积累越快,眩晕持续时间越长。\n主要变身需要足够的精通才能承受界王拳。",
				["KINGMOD_TUTORIAL_F1"] = "按 F1 启用或关闭教程。",
				["KINGMOD_POPUP_ADDED_FORMAT"] = "已添加 {0}!",
				["KINGMOD_ULTIMATE_SKILL_TITLE"] = "终极技能"
			},
			["pt-BR"] = new Dictionary<string, string>(StringComparer.Ordinal)
			{
				["KINGMOD_TUTORIAL_F1"] = "Ativar/Desativar Tutoriais pressionando F1",
				["KINGMOD_TUTORIAL_FORM_MASTERY"] = "Com a Maestria de Forma, ganhe Experiência com o tempo ou causando dano a inimigos. Subir o nível da forma concede o seguinte:\n- Um aumento no bônus de atributos da transformação.\n- Uma redução no dreno de Ki da transformação.\n- Um aumento na regeneração geral de Ki.\nNa Forma Base, regeneração de Ki e Ki máximo são aumentados.",
				["KINGMOD_TUTORIAL_TRANSFORM_TRIGGER"] = "Quando seu nível de maestria for alto o suficiente, ative uma Transformação Principal tocando no botão de transformação (Padrão 'C') e reverta pressionando (Padrão 'X'). Ao desbloquear mais Transformações, pressione o botão novamente para ascender ainda mais além!",
				["KINGMOD_TUTORIAL_ULTIMATE_SKILL"] = "Enquanto transformado, você tem acesso a uma Habilidade Suprema. Ative-a pressionando a tecla vinculada abaixo.",
				["KINGMOD_TUTORIAL_KI_RESOURCE"] = "Ki é um recurso que suas habilidades utilizam. Recupere Ki atingindo inimigos com sua habilidade primária.",
				["KINGMOD_TUTORIAL_ZENKAI"] = "Ganhe Zenkais morrendo ou ficando abaixo de 20% de vida por 30 segundos. Concede atributos bônus permanentes.",
				["KINGMOD_TUTORIAL_LIGHT_CHARGE"] = "Ganhe Carga de Luz atingindo inimigos com sua espada. Quando cheia, ative-a segurando o Botão de Transformação. Concede Dano e Chance Crítica bônus enquanto ativa.",
				["KINGMOD_TUTORIAL_KAIOKEN"] = "Desbloqueie formas de Kaioken aumentando o nível da Forma Base.\nSetas aparecem acima do medidor de Kaioken quando ele está disponível.\nSegure o botão de transformação para ativá-lo.\nEnquanto estiver ativo, seu corpo acumula esforço e enche o medidor.\nCom o medidor cheio, há grande chance de ficar atordoado.\nAumentar o nível da Forma Base eleva seu limite de esforço.\nTaxas maiores de esforço aumentam a duração do atordoamento.\nAs Transformações Principais exigem maestria para suportar Kaioken.",
				["KINGMOD_POPUP_ADDED_FORMAT"] = "{0} adicionado!",
				["KINGMOD_ULTIMATE_SKILL_TITLE"] = "HABILIDADE SUPREMA"
			},
			["tr"] = new Dictionary<string, string>(StringComparer.Ordinal)
			{
				["KINGMOD_TUTORIAL_F1"] = "F1 tuşuna basarak Öğreticileri Aç/Kapat",
				["KINGMOD_TUTORIAL_FORM_MASTERY"] = "Form Ustalığı ile zamanla veya düşmanlara hasar vererek Deneyim kazanın. Form seviyesini yükseltmek şunları sağlar:\n- Dönüşümünüzün özellik takviyesinde artış.\n- Dönüşümünüzün Ki tüketiminde azalma.\n- Genel Ki yenilenmenizde artış.\nTemel Formda Ki yenilenmesi ve maksimum Ki kazanılır.",
				["KINGMOD_TUTORIAL_TRANSFORM_TRIGGER"] = "Ustalık seviyeniz yeterince yükseldiğinde, dönüşüm düğmesine (Varsayılan 'C') dokunarak bir Ana Dönüşümü etkinleştirin ve (Varsayılan 'X') basarak Gücü Azaltın. Daha fazla Dönüşüm açıldığında, daha da öteye yükselmek için dönüşüm düğmesine tekrar basın!",
				["KINGMOD_TUTORIAL_ULTIMATE_SKILL"] = "Dönüşmüş durumdayken bir Nihai Yeteneğe erişiminiz olur. Aşağıda atanan tuşa basarak etkinleştirin.",
				["KINGMOD_TUTORIAL_KI_RESOURCE"] = "Ki, yeteneklerinizin kullandığı bir kaynaktır. Birincil yeteneğinizle düşmanlara vurarak bir kısmını geri kazanın.",
				["KINGMOD_TUTORIAL_ZENKAI"] = "Ölerek veya 30 saniye boyunca %20 canın altında kalarak Zenkai kazanın. Kalıcı bonus özellikler sağlar.",
				["KINGMOD_TUTORIAL_LIGHT_CHARGE"] = "Kılıcınızla düşmanlara vurarak Işık Şarjı kazanın. Dolduğunda, Dönüşüm Düğmesini basılı tutarak etkinleştirin. Aktifken bonus Hasar ve Kritik Şansı sağlar.",
				["KINGMOD_TUTORIAL_KAIOKEN"] = "Temel Formunun seviyesini yükselterek Kaioken formlarını aç.\nKaioken kullanılabilir olduğunda göstergenin üzerinde oklar görünür.\nDönüşüm düğmesini basılı tutarak Kaioken'i etkinleştir.\nAktifken bedenin zorlanmaya başlar ve gösterge dolar.\nGösterge dolarsa sersemleme olasılığın yüksektir.\nTemel Formunun seviyesini yükseltmek zorlanma sınırını artırır.\nDaha yüksek zorlanma hızı sersemleme süresini uzatır.\nAna Dönüşümlerin Kaioken'i taşıyabilmesi için ustalık gerekir.",
				["KINGMOD_POPUP_ADDED_FORMAT"] = "{0} eklendi!",
				["KINGMOD_ULTIMATE_SKILL_TITLE"] = "NİHAİ YETENEK"
			},
			["eo"] = new Dictionary<string, string>(StringComparer.Ordinal)
			{
				["KINGMOD_TUTORIAL_F1"] = "Sxaltu/malsxaltu lernilojn per F1",
				["KINGMOD_TUTORIAL_FORM_MASTERY"] = "Kun forma majstreco, akiru sperton dum tempo pasas aux kiam vi damagxas malamikojn. Altigi la nivelon de la formo donas:\n- Pli grandan atributan gratifikon de la transformo.\n- Malpli grandan Ki-elfluon de la transformo.\n- Pli rapidan gxeneralan Ki-regeneradon.\nEn la baza formo, Ki-regenerado kaj maksimuma Ki pligrandigxas.",
				["KINGMOD_TUTORIAL_TRANSFORM_TRIGGER"] = "Kiam via majstreconivelo estas suficxe alta, aktivigu cxefan transformon per la transforma klavo (defauxlte C) kaj revenu al pli malalta formo per la klavo X. Kiam pliaj transformoj malfermigxas, denove premu la transforman klavon por atingi pli altan formon!",
				["KINGMOD_TUTORIAL_ULTIMATE_SKILL"] = "Dum transformiteco vi povas uzi finfinan kapablon. Aktivigu gxin per la klavo indikita sube.",
				["KINGMOD_TUTORIAL_KI_RESOURCE"] = "Ki estas rimedo uzata de viaj kapabloj. Reakiru gxin trafante malamikojn per via cxefa kapablo.",
				["KINGMOD_TUTORIAL_ZENKAI"] = "Akiru Zenkai mortante aux restado sub 20% da sano dum 30 sekundoj. Gxi donas konstantajn atributajn gratifikojn.",
				["KINGMOD_TUTORIAL_LIGHT_CHARGE"] = "Akiru lumsxargon trafante malamikojn per via glavo. Kiam gxi estas plena, aktivigu gxin tenante la transforman klavon. Dum aktivigo gxi donas plian damagxon kaj kritikan sxancon.",
				["KINGMOD_TUTORIAL_KAIOKEN"] = "Malfermu Kaioken-formojn altigante la nivelon de via baza formo.\nSagoj aperas super la Kaioken-mezurilo kiam Kaioken disponeblas.\nTenu la transforman klavon por aktivigi Kaioken.\nDum gxi aktivas, via korpo strecxigxas kaj la mezurilo plenigxas.\nSe la mezurilo plenigxas, estas granda sxanco ke vi miregigxos.\nAltigi la nivelon de via baza formo pliigas la strecxlimon.\nPli rapida strecxigxo plilongigas la miregigxon.\nCxefaj transformoj bezonas majstrecon por elteni Kaioken.",
				["KINGMOD_POPUP_ADDED_FORMAT"] = "{0} aldonita!",
				["KINGMOD_ULTIMATE_SKILL_TITLE"] = "FINFINA KAPABLO"
			},
			["la"] = new Dictionary<string, string>(StringComparer.Ordinal)
			{
				["KINGMOD_TUTORIAL_F1"] = "Doctrinam preme F1 ut accendas aut exstinguas",
				["KINGMOD_TUTORIAL_FORM_MASTERY"] = "Per peritiam formae experientiam tempore aut hostibus laedendis acquire. Forma ad gradum altiorem promota haec dat:\n- Maius incrementum attributorum transformationis.\n- Minorem consumptionem Ki transformationis.\n- Maiorem regenerationem Ki generalem.\nIn forma fundamentali regeneratio Ki et Ki maximum augentur.",
				["KINGMOD_TUTORIAL_TRANSFORM_TRIGGER"] = "Cum gradus peritiae satis altus sit, transformationem principalem tange clavi transformationis (ex praescripto C); ad formam inferiorem redi clavi X. Cum plures formae reserentur, clavem transformationis iterum preme ut altius ascendas!",
				["KINGMOD_TUTORIAL_ULTIMATE_SKILL"] = "Dum transformatus es, facultate ultima uti potes. Eam clavi infra indicata activa.",
				["KINGMOD_TUTORIAL_KI_RESOURCE"] = "Ki est vis quam facultates tuae consumunt. Aliquid recollige hostes facultate primaria feriendo.",
				["KINGMOD_TUTORIAL_ZENKAI"] = "Zenkai acquire moriendo aut per 30 secunda infra 20% salutis manendo. Incrementa perpetua attributorum dat.",
				["KINGMOD_TUTORIAL_LIGHT_CHARGE"] = "Lucis cumulum acquire hostes gladio feriendo. Cum plenus sit, eum activa clavem transformationis tenendo. Activus damnum et probabilitatem ictus critici auget.",
				["KINGMOD_TUTORIAL_KAIOKEN"] = "Formas Kaioken aperi gradum formae fundamentalis augendo.\nSagittae supra indicem Kaioken apparent cum Kaioken praesto est.\nGlobulum transformationis tene ut Kaioken excites.\nDum valet, corpus tuum fatigatur et index impletur.\nSi index plenus est, magna est probabilitas stuporis.\nGradu formae fundamentalis aucto, finis laboris corporis augetur.\nCelerior fatigatio tempus stuporis auget.\nTransformationes principales peritiam requirunt ut Kaioken sustineant.",
				["KINGMOD_POPUP_ADDED_FORMAT"] = "{0} additum!",
				["KINGMOD_ULTIMATE_SKILL_TITLE"] = "FACULTAS ULTIMA"
			}
		};

		internal static bool TryGet(string language, string key, out string value)
		{
			if (string.Equals(language, "uk", StringComparison.OrdinalIgnoreCase))
			{
				language = "UA";
			}
			if (language != null && Data.TryGetValue(language, out Dictionary<string, string> value2) && value2.TryGetValue(key, out value))
			{
				return true;
			}
			value = null;
			return false;
		}
	}
}