Decompiled source of SignEditor v1.1.0

plugins\SignEditor\SignEditor.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using BepInEx;
using HarmonyLib;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("SignEditor")]
[assembly: AssemblyDescription("Enhanced Valheim sign editor with colors, sizes, emojis, and rich-text editing.")]
[assembly: AssemblyCompany("LEGIOmods")]
[assembly: AssemblyProduct("SignEditor")]
[assembly: AssemblyCopyright("Copyright © 2026 LEGIOmods")]
[assembly: ComVisible(false)]
[assembly: Guid("4fcb2435-77bf-4d04-af4c-5f34fb7ef7dc")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyMetadata("AI_Assisted_Creation", "This assembly was partially created with the assistance of Generative AI for code changes, localization, documentation, and package preparation.")]
[assembly: AssemblyMetadata("AI_Model_Vendor", "OpenAI")]
[assembly: AssemblyMetadata("AI_Agent", "OpenAI Codex")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SignEditor
{
	[BepInPlugin("legiomods.signeditor", "SignEditor", "1.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class SignEditorPlugin : BaseUnityPlugin
	{
		private readonly struct ColorChoice
		{
			internal readonly string EnglishName;

			internal readonly string GermanName;

			internal readonly string HexTag;

			private readonly string[] legacyHexTags;

			internal ColorChoice(string englishName, string germanName, string hex, params string[] legacyHexes)
			{
				EnglishName = englishName;
				GermanName = germanName;
				HexTag = "<" + hex + ">";
				legacyHexTags = new string[legacyHexes.Length];
				for (int i = 0; i < legacyHexes.Length; i++)
				{
					legacyHexTags[i] = "<" + legacyHexes[i] + ">";
				}
			}

			internal bool TryStripTag(ref string value)
			{
				if (value.StartsWith(HexTag, StringComparison.OrdinalIgnoreCase))
				{
					value = value.Substring(HexTag.Length);
					return true;
				}
				for (int i = 0; i < legacyHexTags.Length; i++)
				{
					if (value.StartsWith(legacyHexTags[i], StringComparison.OrdinalIgnoreCase))
					{
						value = value.Substring(legacyHexTags[i].Length);
						return true;
					}
				}
				return false;
			}
		}

		private readonly struct EmojiChoice
		{
			internal readonly string Value;

			internal readonly string EnglishLabel;

			internal readonly string GermanLabel;

			internal EmojiChoice(string value, string englishLabel, string germanLabel)
			{
				Value = value;
				EnglishLabel = englishLabel;
				GermanLabel = germanLabel;
			}
		}

		private static class TextInputAccessor
		{
			private static FieldInfo inputFieldInfo;

			private static FieldInfo panelInfo;

			private static MethodInfo isVisibleMethod;

			private static MethodInfo setTextMethod;

			private static MethodInfo onEnterMethod;

			private static PropertyInfo textProperty;

			private static PropertyInfo caretProperty;

			private static PropertyInfo selectionFocusProperty;

			private static PropertyInfo selectionAnchorProperty;

			private static MethodInfo activateMethod;

			private static CanvasGroup blockedPanelGroup;

			private static bool panelGroupWasAdded;

			private static bool previousInteractable;

			private static bool previousBlocksRaycasts;

			internal static bool IsTextInputOpen()
			{
				TextInput instance = TextInput.instance;
				if (!Object.op_Implicit((Object)(object)instance))
				{
					return false;
				}
				isVisibleMethod = isVisibleMethod ?? typeof(TextInput).GetMethod("IsVisible", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (isVisibleMethod != null)
				{
					object obj = isVisibleMethod.Invoke(instance, null);
					if (obj is bool)
					{
						return (bool)obj;
					}
				}
				GameObject panel = GetPanel();
				if (Object.op_Implicit((Object)(object)panel))
				{
					return panel.activeInHierarchy;
				}
				return false;
			}

			internal static void BlockUnderlyingPanel()
			{
				if (Object.op_Implicit((Object)(object)blockedPanelGroup))
				{
					return;
				}
				GameObject panel = GetPanel();
				if (Object.op_Implicit((Object)(object)panel))
				{
					blockedPanelGroup = panel.GetComponent<CanvasGroup>();
					panelGroupWasAdded = !Object.op_Implicit((Object)(object)blockedPanelGroup);
					if (panelGroupWasAdded)
					{
						blockedPanelGroup = panel.AddComponent<CanvasGroup>();
					}
					previousInteractable = blockedPanelGroup.interactable;
					previousBlocksRaycasts = blockedPanelGroup.blocksRaycasts;
					blockedPanelGroup.interactable = false;
					blockedPanelGroup.blocksRaycasts = true;
				}
			}

			internal static void UnblockUnderlyingPanel()
			{
				if (Object.op_Implicit((Object)(object)blockedPanelGroup))
				{
					if (panelGroupWasAdded)
					{
						Object.Destroy((Object)(object)blockedPanelGroup);
					}
					else
					{
						blockedPanelGroup.interactable = previousInteractable;
						blockedPanelGroup.blocksRaycasts = previousBlocksRaycasts;
					}
					blockedPanelGroup = null;
					panelGroupWasAdded = false;
				}
			}

			internal static string GetText()
			{
				object inputField = GetInputField();
				if (inputField == null)
				{
					return null;
				}
				return (textProperty?.GetValue(inputField, null) as string) ?? string.Empty;
			}

			internal static void ReplaceText(string value)
			{
				object inputField = GetInputField();
				if (inputField != null)
				{
					string text = value ?? string.Empty;
					textProperty?.SetValue(inputField, text, null);
					setTextMethod = setTextMethod ?? typeof(TextInput).GetMethod("setText", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					setTextMethod?.Invoke(TextInput.instance, new object[1] { text });
					SetCaret(inputField, text.Length);
					activateMethod?.Invoke(inputField, null);
				}
			}

			internal static void Confirm()
			{
				TextInput instance = TextInput.instance;
				if (Object.op_Implicit((Object)(object)instance))
				{
					onEnterMethod = onEnterMethod ?? typeof(TextInput).GetMethod("OnEnter", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					onEnterMethod?.Invoke(instance, null);
				}
			}

			private static object GetInputField()
			{
				TextInput instance = TextInput.instance;
				if (!Object.op_Implicit((Object)(object)instance))
				{
					return null;
				}
				inputFieldInfo = inputFieldInfo ?? typeof(TextInput).GetField("m_inputField", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				object obj = inputFieldInfo?.GetValue(instance);
				if (obj == null)
				{
					return null;
				}
				Type type = obj.GetType();
				textProperty = textProperty ?? type.GetProperty("text", BindingFlags.Instance | BindingFlags.Public);
				caretProperty = caretProperty ?? type.GetProperty("caretPosition", BindingFlags.Instance | BindingFlags.Public);
				selectionFocusProperty = selectionFocusProperty ?? type.GetProperty("selectionFocusPosition", BindingFlags.Instance | BindingFlags.Public);
				selectionAnchorProperty = selectionAnchorProperty ?? type.GetProperty("selectionAnchorPosition", BindingFlags.Instance | BindingFlags.Public);
				activateMethod = activateMethod ?? type.GetMethod("ActivateInputField", BindingFlags.Instance | BindingFlags.Public);
				return obj;
			}

			private static GameObject GetPanel()
			{
				TextInput instance = TextInput.instance;
				if (!Object.op_Implicit((Object)(object)instance))
				{
					return null;
				}
				panelInfo = panelInfo ?? typeof(TextInput).GetField("m_panel", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				object? obj = panelInfo?.GetValue(instance);
				return (GameObject)((obj is GameObject) ? obj : null);
			}

			private static int GetCaret(object inputField, int fallback)
			{
				object obj = selectionFocusProperty?.GetValue(inputField, null) ?? caretProperty?.GetValue(inputField, null);
				if (obj is int)
				{
					return (int)obj;
				}
				return fallback;
			}

			private static void SetCaret(object inputField, int position)
			{
				caretProperty?.SetValue(inputField, position, null);
				selectionAnchorProperty?.SetValue(inputField, position, null);
				selectionFocusProperty?.SetValue(inputField, position, null);
			}
		}

		public const string PluginGuid = "legiomods.signeditor";

		public const string PluginName = "SignEditor";

		public const string PluginVersion = "1.1.0";

		private static Harmony harmony;

		private static Sign lastEditedSign;

		private static float lastSignInteractTime;

		private readonly EmojiChoice[][] emojiRows = new EmojiChoice[5][]
		{
			new EmojiChoice[11]
			{
				E("↑", "Up", "Hoch"),
				E("↓", "Down", "Runter"),
				E("←", "Left", "Links"),
				E("→", "Right", "Rechts"),
				E("❤\ufe0f", "Heart", "Herz"),
				E("\ud83e\udd55", "Carrot", "Karotte"),
				E("\ud83e\uddc5", "Onion", "Zwiebel"),
				E("\ud83d\udce6", "Box", "Kiste"),
				E("\ud83e\udeb5", "Wood", "Holz"),
				E("\ud83e\udea8", "Stone", "Stein"),
				E("\ud83e\ude99", "Coin", "Muenze")
			},
			new EmojiChoice[11]
			{
				E("⚡", "Lightning", "Blitz"),
				E("⚒\ufe0f", "Hammer and pick", "Hammer und Pickel"),
				E("⚙\ufe0f", "Gear", "Zahnrad"),
				E("⛓\ufe0f", "Chain", "Kette"),
				E("\ud83d\udee1\ufe0f", "Shield", "Schild"),
				E("\ud83c\udff9", "Bow", "Bogen"),
				E("\ud83d\udde1\ufe0f", "Dagger", "Dolch"),
				E("⛏\ufe0f", "Pickaxe", "Spitzhacke"),
				E("\ud83e\ude93", "Axe", "Axt"),
				E("\ud83d\udd28", "Hammer", "Hammer"),
				E("\ud83c\udfe0", "House", "Haus")
			},
			new EmojiChoice[11]
			{
				E("⚔\ufe0f", "Swords", "Schwerter"),
				E("\ud83e\ude9a", "Saw", "Saege"),
				E("\ud83d\udca3", "Bomb", "Bombe"),
				E("\ud83e\uddd9", "Mage", "Magier"),
				E("\ud83c\udf44", "Mushroom", "Pilz"),
				E("\ud83c\udf53", "Berry", "Beere"),
				E("\ud83c\udf47", "Grapes", "Trauben"),
				E("\ud83d\udeaa", "Door", "Tuer"),
				E("\ud83d\udecf\ufe0f", "Bed", "Bett"),
				E("\ud83d\udd25", "Fire", "Feuer"),
				E("⚓\ufe0f", "Anchor", "Anker")
			},
			new EmojiChoice[11]
			{
				E("\ud83e\uded8", "Beans", "Bohnen"),
				E("\ud83c\udf31", "Sprout", "Keim"),
				E("\ud83e\ude84", "Magic", "Zauber"),
				E("\ud83c\udf3e", "Grain", "Korn"),
				E("\ud83d\udc80", "Skull", "Totenkopf"),
				E("⛵\ufe0f", "Sailboat", "Segelboot"),
				E("\ud83c\udf00", "Portal", "Portal"),
				E("\ud83c\udf56", "Meat", "Fleisch"),
				E("\ud83c\udf5e", "Bread", "Brot"),
				E("\ud83d\udc1f", "Fish", "Fisch"),
				E("\ud83c\udf6f", "Honey", "Honig")
			},
			new EmojiChoice[10]
			{
				E("\ud83d\udc17", "Boar", "Wildschwein"),
				E("\ud83d\udc3a", "Wolf", "Wolf"),
				E("\ud83e\udd8c", "Deer", "Hirsch"),
				E("❗", "Warning", "Warnung"),
				E("❌", "No", "Nein"),
				E("✅", "Yes", "Ja"),
				E("☠\ufe0f", "Danger", "Gefahr"),
				E("\ud83e\uddea", "Potion", "Trank"),
				E("\ud83c\udf7a", "Beer", "Bier"),
				E("\ud83d\udd2e", "Crystal ball", "Kristallkugel")
			}
		};

		private readonly ColorChoice[] colors = new ColorChoice[7]
		{
			new ColorChoice("White", "Weiß", "#FFF", "#FFFFFF"),
			new ColorChoice("Red", "Rot", "#F44", "#FF4D4D", "#FF0000"),
			new ColorChoice("Yellow", "Gelb", "#EF0", "#E5FF00"),
			new ColorChoice("Blue", "Blau", "#69E", "#6495ED"),
			new ColorChoice("Orange", "Orange", "#FB1", "#FFB90F"),
			new ColorChoice("Green", "Grün", "#0F0", "#00FF00"),
			new ColorChoice("Black", "Schwarz", "#000", "#000000")
		};

		private int selectedColor;

		private int fontSize = 10;

		private string editText = string.Empty;

		private string markupText = string.Empty;

		private int savedMarkupAnchor = -1;

		private int savedMarkupFocus = -1;

		private int restoreMarkupFocusFrames;

		private bool syncingMarkupInput;

		private bool editorInitialized;

		private Vector2 editorScroll;

		private Rect editorRect;

		private GUIStyle overlayStyle;

		private GUIStyle panelStyle;

		private GUIStyle titleStyle;

		private GUIStyle buttonStyle;

		private GUIStyle emojiClickStyle;

		private GUIStyle selectedStyle;

		private GUIStyle labelStyle;

		private Texture2D overlayTexture;

		private Texture2D selectedTexture;

		private Texture2D transparentTexture;

		private GameObject visualOverlayRoot;

		private TMP_FontAsset visualFont;

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

		private TMP_InputField markupInput;

		private TextMeshProUGUI markupInputText;

		private Image markupCaretVisual;

		private Image overlayPanelVisual;

		private GameObject woodPanelVisual;

		private int emojiVisualCount;

		private void Awake()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			editorRect = new Rect(0f, 0f, 1380f, 900f);
			harmony = new Harmony("legiomods.signeditor");
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"SignEditor 1.1.0 loaded.");
		}

		private void OnDestroy()
		{
			TextInputAccessor.UnblockUnderlyingPanel();
			DestroyVisualOverlay();
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}

		private void LateUpdate()
		{
			if (editorInitialized && Object.op_Implicit((Object)(object)markupInput) && ((Component)markupInput).gameObject.activeInHierarchy)
			{
				if (restoreMarkupFocusFrames > 0)
				{
					int num = Mathf.Clamp(savedMarkupFocus, 0, (markupText ?? string.Empty).Length);
					markupInput.ActivateInputField();
					((Selectable)markupInput).Select();
					markupInput.stringPosition = num;
					markupInput.selectionStringAnchorPosition = num;
					markupInput.selectionStringFocusPosition = num;
					markupInput.ForceLabelUpdate();
					restoreMarkupFocusFrames--;
				}
				UpdateMarkupCaretVisual();
			}
		}

		private void OnGUI()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			if (ShouldShowEditor())
			{
				if (!editorInitialized)
				{
					LoadExistingText();
				}
				EnsureStyles();
				GUI.depth = -2000;
				GUI.ModalWindow(493812, new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), new WindowFunction(DrawOverlay), string.Empty, overlayStyle);
			}
		}

		internal static void RememberSign(Sign sign)
		{
			lastEditedSign = sign;
			lastSignInteractTime = Time.time;
		}

		private bool ShouldShowEditor()
		{
			if (!Object.op_Implicit((Object)(object)lastEditedSign) || Time.time - lastSignInteractTime > 600f || !TextInputAccessor.IsTextInputOpen())
			{
				bool num = editorInitialized;
				lastEditedSign = null;
				editorInitialized = false;
				if (num)
				{
					TextInputAccessor.UnblockUnderlyingPanel();
					HideVisualOverlay();
					RestoreGameCursor();
				}
				return false;
			}
			Cursor.visible = true;
			Cursor.lockState = (CursorLockMode)0;
			return true;
		}

		private void DrawOverlay(int id)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Min(1460f, (float)Screen.width - 16f);
			float num2 = Mathf.Min(980f, (float)Screen.height - 16f);
			editorRect = new Rect(((float)Screen.width - num) * 0.5f, ((float)Screen.height - num2) * 0.5f, num, num2);
			GUILayout.BeginArea(editorRect, panelStyle);
			DrawEditor();
			GUILayout.EndArea();
		}

		private void DrawEditor()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			BeginVisualOverlay();
			RememberMarkupSelection();
			GUILayout.Label(Text("Sign Editor", "Schild-Editor"), titleStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Space(8f);
			float num = Mathf.Max(180f, ((Rect)(ref editorRect)).height - 340f);
			editorScroll = GUILayout.BeginScrollView(editorScroll, false, false, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(num) });
			GUILayout.Label(Text("Color", "Farbe"), labelStyle, Array.Empty<GUILayoutOption>());
			for (int i = 0; i < colors.Length; i += 7)
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				for (int j = i; j < Mathf.Min(i + 7, colors.Length); j++)
				{
					DrawColorButton(j);
				}
				GUILayout.FlexibleSpace();
				GUILayout.EndHorizontal();
			}
			GUILayout.Space(10f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(Text("Size", "Größe"), labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) });
			if (GUILayout.Button("-10", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(76f),
				GUILayout.Height(44f)
			}))
			{
				fontSize = Mathf.Max(1, fontSize - 10);
				RebuildMarkup();
			}
			if (GUILayout.Button("-", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(64f),
				GUILayout.Height(44f)
			}))
			{
				fontSize = Mathf.Max(1, fontSize - 1);
				RebuildMarkup();
			}
			GUILayout.Label(fontSize.ToString(), labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(56f) });
			if (GUILayout.Button("+", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(64f),
				GUILayout.Height(44f)
			}))
			{
				fontSize = Mathf.Min(9000, fontSize + 1);
				RebuildMarkup();
			}
			if (GUILayout.Button("+10", buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(76f),
				GUILayout.Height(44f)
			}))
			{
				fontSize = Mathf.Min(9000, fontSize + 10);
				RebuildMarkup();
			}
			GUILayout.EndHorizontal();
			DrawFormattingControls();
			GUILayout.Space(14f);
			GUILayout.Label(Text("Insert emoji", "Emoji einfügen"), labelStyle, Array.Empty<GUILayoutOption>());
			float num2 = Mathf.Clamp((((Rect)(ref editorRect)).width - 80f) / 11f, 70f, 120f);
			for (int k = 0; k < emojiRows.Length; k++)
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				for (int l = 0; l < emojiRows[k].Length; l++)
				{
					EmojiChoice emojiChoice = emojiRows[k][l];
					if (GUILayout.Button(GUIContent.none, emojiClickStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.Width(num2),
						GUILayout.Height(46f)
					}))
					{
						InsertEmojiAtCaret(emojiChoice.Value);
					}
					UpdateEmojiVisual(emojiChoice.Value, GUILayoutUtility.GetLastRect());
				}
				GUILayout.FlexibleSpace();
				GUILayout.EndHorizontal();
			}
			GUILayout.EndScrollView();
			GUILayout.Space(10f);
			GUILayout.Label(Text("Sign text (edit directly)", "Schild-Text (direkt bearbeiten)"), labelStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Box(GUIContent.none, GUIStyle.none, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.ExpandWidth(true),
				GUILayout.Height(130f)
			});
			UpdateMarkupInput(GUILayoutUtility.GetLastRect());
			GUILayout.Space(10f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button(Text("Apply & OK", "Übernehmen & OK"), selectedStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(60f) }))
			{
				TextInputAccessor.ReplaceText(markupText);
				TextInputAccessor.Confirm();
				CloseEditor();
			}
			if (GUILayout.Button(Text("Clear", "Leeren"), buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(60f) }))
			{
				selectedColor = 0;
				fontSize = 10;
				editText = string.Empty;
				RebuildMarkup();
			}
			GUILayout.EndHorizontal();
			EndVisualOverlay();
		}

		private void CloseEditor()
		{
			lastEditedSign = null;
			editorInitialized = false;
			TextInputAccessor.UnblockUnderlyingPanel();
			HideVisualOverlay();
			RestoreGameCursor();
		}

		private void InsertEmojiAtCaret(string emoji)
		{
			ReplaceSelectionAtCaret(emoji ?? string.Empty);
		}

		private void ReplaceSelectionAtCaret(string replacement)
		{
			string text = markupText ?? string.Empty;
			GetMarkupSelection(text.Length, out var anchor, out var focus);
			int num = Mathf.Min(anchor, focus);
			int count = Mathf.Abs(anchor - focus);
			markupText = text.Remove(num, count).Insert(num, replacement ?? string.Empty);
			int position = num + (replacement?.Length ?? 0);
			LoadMarkup(markupText);
			RequestMarkupFocus(position);
			SyncMarkupInputText();
		}

		private void WrapSelectionAtCaret(string openingTag, string closingTag)
		{
			string text = markupText ?? string.Empty;
			GetMarkupSelection(text.Length, out var anchor, out var focus);
			int num = Mathf.Min(anchor, focus);
			int num2 = Mathf.Abs(anchor - focus);
			string text2 = text.Substring(num, num2);
			string text3 = openingTag + text2 + closingTag;
			int position = ((num2 > 0) ? (num + text3.Length) : (num + openingTag.Length));
			markupText = text.Remove(num, num2).Insert(num, text3);
			LoadMarkup(markupText);
			RequestMarkupFocus(position);
			SyncMarkupInputText();
		}

		private void GetMarkupSelection(int textLength, out int anchor, out int focus)
		{
			if (Object.op_Implicit((Object)(object)markupInput) && markupInput.isFocused)
			{
				anchor = Mathf.Clamp(markupInput.selectionStringAnchorPosition, 0, textLength);
				focus = Mathf.Clamp(markupInput.selectionStringFocusPosition, 0, textLength);
			}
			else
			{
				anchor = ((savedMarkupAnchor >= 0) ? Mathf.Clamp(savedMarkupAnchor, 0, textLength) : textLength);
				focus = ((savedMarkupFocus >= 0) ? Mathf.Clamp(savedMarkupFocus, 0, textLength) : anchor);
			}
		}

		private void RequestMarkupFocus(int position)
		{
			savedMarkupFocus = (savedMarkupAnchor = Mathf.Clamp(position, 0, (markupText ?? string.Empty).Length));
			restoreMarkupFocusFrames = 2;
		}

		private void RememberMarkupSelection()
		{
			if (Object.op_Implicit((Object)(object)markupInput) && markupInput.isFocused)
			{
				int length = (markupText ?? string.Empty).Length;
				savedMarkupAnchor = Mathf.Clamp(markupInput.selectionStringAnchorPosition, 0, length);
				savedMarkupFocus = Mathf.Clamp(markupInput.selectionStringFocusPosition, 0, length);
			}
		}

		private static void RestoreGameCursor()
		{
			Cursor.visible = false;
			Cursor.lockState = (CursorLockMode)1;
		}

		private void DrawColorButton(int index)
		{
			bool flag = selectedColor == index;
			string text = (flag ? "[x] " : "[ ] ") + Text(colors[index].EnglishName, colors[index].GermanName);
			float num = Mathf.Clamp((((Rect)(ref editorRect)).width - 135f) / 7f, 90f, 175f);
			if (GUILayout.Button(text, flag ? selectedStyle : buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(num),
				GUILayout.Height(44f)
			}))
			{
				selectedColor = index;
				RebuildMarkup();
			}
		}

		private void DrawFormattingControls()
		{
			GUILayout.Space(14f);
			GUILayout.Label(Text("Formatting", "Formatierung"), labelStyle, Array.Empty<GUILayoutOption>());
			float width = Mathf.Clamp((((Rect)(ref editorRect)).width - 90f) / 6f, 120f, 210f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			DrawFormatButton(Text("Italic", "Kursiv"), "<i>", "</i>", width);
			DrawFormatButton(Text("Underline", "Unterstrichen"), "<u>", "</u>", width);
			DrawFormatButton(Text("Strike", "Durchgestrichen"), "<s>", "</s>", width);
			DrawFormatButton(Text("Highlight", "Markieren"), "<mark>", "</mark>", width);
			DrawFormatButton(Text("Subscript", "Tiefgestellt"), "<sub>", "</sub>", width);
			DrawFormatButton(Text("Superscript", "Hochgestellt"), "<sup>", "</sup>", width);
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			DrawFormatButton(Text("Align left", "Linksbündig"), "<align=left>", "</align>", width);
			DrawFormatButton(Text("Align center", "Zentriert"), "<align=center>", "</align>", width);
			DrawFormatButton(Text("Align right", "Rechtsbündig"), "<align=right>", "</align>", width);
			DrawFormatButton(Text("Rotate 90°", "90° drehen"), "<rotate=90>", "</rotate>", width);
			GUILayout.FlexibleSpace();
			GUILayout.EndHorizontal();
		}

		private void DrawFormatButton(string label, string openingTag, string closingTag, float width)
		{
			if (GUILayout.Button(label, buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(width),
				GUILayout.Height(42f)
			}))
			{
				WrapSelectionAtCaret(openingTag, closingTag);
			}
		}

		private void LoadExistingText()
		{
			//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)
			selectedColor = 0;
			fontSize = 10;
			savedMarkupAnchor = -1;
			savedMarkupFocus = -1;
			editorScroll = Vector2.zero;
			string text = TextInputAccessor.GetText();
			if (text == null && Object.op_Implicit((Object)(object)lastEditedSign))
			{
				text = lastEditedSign.GetText();
			}
			if (string.IsNullOrEmpty(text))
			{
				selectedColor = 0;
				fontSize = 10;
				editText = string.Empty;
				RebuildMarkup();
			}
			else
			{
				LoadMarkup(text);
			}
			TextInputAccessor.BlockUnderlyingPanel();
			editorInitialized = true;
		}

		private void LoadMarkup(string value)
		{
			markupText = value ?? string.Empty;
			string value2 = markupText;
			for (int i = 0; i < colors.Length; i++)
			{
				if (colors[i].TryStripTag(ref value2))
				{
					selectedColor = i;
					break;
				}
			}
			if (value2.StartsWith("<color=", StringComparison.OrdinalIgnoreCase))
			{
				int num = value2.IndexOf('>');
				if (num > 7)
				{
					SelectNamedColor(value2.Substring(7, num - 7));
					value2 = value2.Substring(num + 1);
				}
			}
			if (value2.StartsWith("<size=", StringComparison.OrdinalIgnoreCase))
			{
				int num2 = value2.IndexOf('>');
				if (num2 > 6 && int.TryParse(value2.Substring(6, num2 - 6), out var result))
				{
					fontSize = Mathf.Clamp(result, 1, 9000);
					value2 = value2.Substring(num2 + 1);
				}
			}
			editText = value2;
		}

		private void SelectNamedColor(string value)
		{
			string text = (value ?? string.Empty).Trim().ToLowerInvariant();
			string text2;
			switch (text)
			{
			case "weiss":
			case "white":
				text2 = "#FFF";
				break;
			case "red":
			case "rot":
				text2 = "#F44";
				break;
			case "yellow":
			case "gelb":
				text2 = "#EF0";
				break;
			case "blau":
			case "blue":
				text2 = "#69E";
				break;
			case "orange":
				text2 = "#FB1";
				break;
			case "green":
			case "gruen":
				text2 = "#0F0";
				break;
			case "black":
			case "schwarz":
				text2 = "#000";
				break;
			default:
				text2 = text;
				break;
			}
			for (int i = 0; i < colors.Length; i++)
			{
				if (string.Equals(colors[i].HexTag, "<" + text2 + ">", StringComparison.OrdinalIgnoreCase))
				{
					selectedColor = i;
					break;
				}
			}
		}

		private void RebuildMarkup()
		{
			string text = (editText = StripEditorStyleTags(editText ?? string.Empty));
			markupText = colors[selectedColor].HexTag + "<size=" + fontSize + ">" + text;
			SyncMarkupInputText();
			RequestMarkupFocus((savedMarkupFocus >= 0) ? savedMarkupFocus : markupText.Length);
		}

		private static string StripEditorStyleTags(string value)
		{
			return Regex.Replace(Regex.Replace(value ?? string.Empty, "<#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})>|<color\\s*=\\s*[^>]+>", string.Empty, RegexOptions.IgnoreCase), "<size\\s*=\\s*\\d+>", string.Empty, RegexOptions.IgnoreCase);
		}

		private static EmojiChoice E(string value, string englishLabel, string germanLabel)
		{
			return new EmojiChoice(value, englishLabel, germanLabel);
		}

		private static string Text(string english, string german)
		{
			if (Localization.instance == null)
			{
				return english;
			}
			string text = Localization.instance.GetSelectedLanguage() ?? string.Empty;
			if (!text.Equals("German", StringComparison.OrdinalIgnoreCase) && !text.Equals("Deutsch", StringComparison.OrdinalIgnoreCase) && !text.StartsWith("de", StringComparison.OrdinalIgnoreCase))
			{
				return english;
			}
			return german;
		}

		private void BeginVisualOverlay()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			EnsureVisualOverlay();
			if (Object.op_Implicit((Object)(object)visualOverlayRoot))
			{
				visualOverlayRoot.SetActive(true);
				if (Object.op_Implicit((Object)(object)woodPanelVisual))
				{
					ConfigurePanelRect(woodPanelVisual.GetComponent<RectTransform>(), editorRect);
				}
				else
				{
					ConfigureBackground(overlayPanelVisual, editorRect, new Color(0.2f, 0.095f, 0.035f, 0.98f));
				}
				emojiVisualCount = 0;
			}
		}

		private void EndVisualOverlay()
		{
			for (int i = emojiVisualCount; i < emojiVisuals.Count; i++)
			{
				((Component)emojiVisuals[i]).gameObject.SetActive(false);
			}
		}

		private void EnsureVisualOverlay()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)visualOverlayRoot))
			{
				visualOverlayRoot = new GameObject("SignEditorVisualOverlay");
				((Object)visualOverlayRoot).hideFlags = (HideFlags)61;
				Canvas obj = visualOverlayRoot.AddComponent<Canvas>();
				obj.renderMode = (RenderMode)0;
				obj.sortingOrder = 32767;
				visualOverlayRoot.AddComponent<GraphicRaycaster>();
				try
				{
					woodPanelVisual = GUIManager.Instance.CreateWoodpanel(visualOverlayRoot.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, ((Rect)(ref editorRect)).width, ((Rect)(ref editorRect)).height, false);
					((Object)woodPanelVisual).name = "SignEditorWoodPanel";
					woodPanelVisual.transform.SetAsFirstSibling();
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not create Jotunn wood panel; using fallback background: " + ex.Message));
					overlayPanelVisual = CreateBackground("Panel");
				}
				CreateMarkupInput();
			}
		}

		private void UpdateEmojiVisual(string emoji, Rect rect)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI emojiVisual = GetEmojiVisual(emojiVisualCount++);
			if (Object.op_Implicit((Object)(object)emojiVisual))
			{
				ConfigureVisual(emojiVisual, emoji, ToScreenRect(rect, insideScrollView: true), 34f, (TextAlignmentOptions)514, wrap: false);
				((Graphic)emojiVisual).color = new Color(1f, 0.86f, 0.6f, 1f);
			}
		}

		private void CreateMarkupInput()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Expected O, but got Unknown
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Expected O, but got Unknown
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)visualOverlayRoot) && !Object.op_Implicit((Object)(object)markupInput))
			{
				GameObject val = new GameObject("SignEditorMarkupInput");
				((Object)val).hideFlags = (HideFlags)61;
				val.transform.SetParent(visualOverlayRoot.transform, false);
				Image obj = val.AddComponent<Image>();
				((Graphic)obj).color = new Color(0.075f, 0.035f, 0.015f, 0.97f);
				((Graphic)obj).raycastTarget = true;
				markupInput = val.AddComponent<TMP_InputField>();
				GameObject val2 = new GameObject("Text Area");
				((Object)val2).hideFlags = (HideFlags)61;
				val2.transform.SetParent(val.transform, false);
				RectTransform val3 = val2.AddComponent<RectTransform>();
				val3.anchorMin = Vector2.zero;
				val3.anchorMax = Vector2.one;
				val3.offsetMin = new Vector2(10f, 8f);
				val3.offsetMax = new Vector2(-10f, -8f);
				val2.AddComponent<RectMask2D>();
				GameObject val4 = new GameObject("Text");
				((Object)val4).hideFlags = (HideFlags)61;
				val4.transform.SetParent(val2.transform, false);
				RectTransform obj2 = val4.AddComponent<RectTransform>();
				obj2.anchorMin = Vector2.zero;
				obj2.anchorMax = Vector2.one;
				obj2.offsetMin = Vector2.zero;
				obj2.offsetMax = Vector2.zero;
				markupInputText = val4.AddComponent<TextMeshProUGUI>();
				((Graphic)markupInputText).raycastTarget = false;
				((TMP_Text)markupInputText).richText = false;
				((Graphic)markupInputText).color = new Color(1f, 0.91f, 0.68f, 1f);
				((TMP_Text)markupInputText).fontSize = 24f;
				((TMP_Text)markupInputText).alignment = (TextAlignmentOptions)514;
				((TMP_Text)markupInputText).enableWordWrapping = true;
				((TMP_Text)markupInputText).font = GetVisualFont();
				GameObject val5 = new GameObject("Visible Caret");
				((Object)val5).hideFlags = (HideFlags)61;
				val5.transform.SetParent(val4.transform, false);
				RectTransform obj3 = val5.AddComponent<RectTransform>();
				obj3.anchorMin = new Vector2(0.5f, 0.5f);
				obj3.anchorMax = new Vector2(0.5f, 0.5f);
				obj3.pivot = new Vector2(0.5f, 0.5f);
				markupCaretVisual = val5.AddComponent<Image>();
				((Graphic)markupCaretVisual).color = Color.white;
				((Graphic)markupCaretVisual).raycastTarget = false;
				markupInput.textViewport = val3;
				markupInput.textComponent = (TMP_Text)(object)markupInputText;
				markupInput.lineType = (LineType)1;
				markupInput.contentType = (ContentType)0;
				markupInput.onFocusSelectAll = false;
				markupInput.keepTextSelectionVisible = true;
				markupInput.customCaretColor = true;
				markupInput.caretColor = Color.white;
				markupInput.caretWidth = 3;
				markupInput.caretBlinkRate = 0.8f;
				markupInput.selectionColor = new Color(0.5f, 0.35f, 0.12f, 0.75f);
				((UnityEvent<string>)(object)markupInput.onValueChanged).AddListener((UnityAction<string>)OnMarkupInputChanged);
				((UnityEvent<string>)(object)markupInput.onSubmit).AddListener((UnityAction<string>)OnMarkupInputSubmitted);
				SyncMarkupInputText();
				markupInput.ForceLabelUpdate();
			}
		}

		private void UpdateMarkupCaretVisual()
		{
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)markupCaretVisual) || !Object.op_Implicit((Object)(object)markupInputText))
			{
				return;
			}
			TMP_TextInfo textInfo = ((TMP_Text)markupInputText).textInfo;
			int num = textInfo?.characterCount ?? 0;
			int num2 = Mathf.Clamp(markupInput.isFocused ? markupInput.selectionStringFocusPosition : savedMarkupFocus, 0, (markupText ?? string.Empty).Length);
			float num3 = 0f;
			float num4 = ((TMP_Text)markupInputText).fontSize * 0.55f;
			float num5 = (0f - ((TMP_Text)markupInputText).fontSize) * 0.55f;
			int num6 = 0;
			if (num > 0)
			{
				int i;
				for (i = 0; i < num && textInfo.characterInfo[i].index < num2; i++)
				{
				}
				if (i < num && textInfo.characterInfo[i].index == num2)
				{
					TMP_CharacterInfo val = textInfo.characterInfo[i];
					num3 = val.origin;
					num6 = val.lineNumber;
				}
				else
				{
					TMP_CharacterInfo val2 = textInfo.characterInfo[Mathf.Max(0, i - 1)];
					num3 = val2.xAdvance;
					num6 = val2.lineNumber;
					if (val2.character == '\n' && num6 + 1 < textInfo.lineCount)
					{
						num3 = 0f;
						num6++;
					}
				}
				if (num6 >= 0 && num6 < textInfo.lineCount)
				{
					num4 = textInfo.lineInfo[num6].ascender;
					num5 = textInfo.lineInfo[num6].descender;
				}
			}
			float num7 = Mathf.Max(24f, num4 - num5);
			RectTransform rectTransform = ((Graphic)markupCaretVisual).rectTransform;
			rectTransform.anchoredPosition = new Vector2(num3, (num4 + num5) * 0.5f);
			rectTransform.sizeDelta = new Vector2(3f, num7);
			((Transform)rectTransform).SetAsLastSibling();
			((Component)markupCaretVisual).gameObject.SetActive(true);
		}

		private void UpdateMarkupInput(Rect rect)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: 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)
			EnsureVisualOverlay();
			if (Object.op_Implicit((Object)(object)markupInput))
			{
				TMP_FontAsset val = GetVisualFont();
				if (Object.op_Implicit((Object)(object)val) && (Object)(object)((TMP_Text)markupInputText).font != (Object)(object)val)
				{
					((TMP_Text)markupInputText).font = val;
					markupInput.ForceLabelUpdate();
				}
				SyncMarkupInputText();
				Rect val2 = ToScreenRect(rect, insideScrollView: false);
				RectTransform component = ((Component)markupInput).GetComponent<RectTransform>();
				component.anchorMin = new Vector2(0f, 1f);
				component.anchorMax = new Vector2(0f, 1f);
				component.pivot = new Vector2(0f, 1f);
				component.anchoredPosition = new Vector2(((Rect)(ref val2)).x, 0f - ((Rect)(ref val2)).y);
				component.sizeDelta = new Vector2(((Rect)(ref val2)).width, ((Rect)(ref val2)).height);
				((Component)markupInput).gameObject.SetActive(true);
			}
		}

		private void OnMarkupInputChanged(string value)
		{
			if (!syncingMarkupInput)
			{
				LoadMarkup(value ?? string.Empty);
				markupInput.ForceLabelUpdate();
			}
		}

		private void OnMarkupInputSubmitted(string value)
		{
			ReplaceSelectionAtCaret("\\n");
		}

		private void SyncMarkupInputText()
		{
			if (!Object.op_Implicit((Object)(object)markupInput) || string.Equals(markupInput.text, markupText ?? string.Empty, StringComparison.Ordinal))
			{
				return;
			}
			int length = (markupText ?? string.Empty).Length;
			int num;
			int num2;
			if (savedMarkupAnchor >= 0)
			{
				num = ((savedMarkupFocus >= 0) ? 1 : 0);
				if (num != 0)
				{
					num2 = Mathf.Clamp(savedMarkupAnchor, 0, length);
					goto IL_0070;
				}
			}
			else
			{
				num = 0;
			}
			num2 = length;
			goto IL_0070;
			IL_0070:
			int selectionStringAnchorPosition = num2;
			int selectionStringFocusPosition = ((num != 0) ? Mathf.Clamp(savedMarkupFocus, 0, length) : length);
			syncingMarkupInput = true;
			markupInput.SetTextWithoutNotify(markupText ?? string.Empty);
			syncingMarkupInput = false;
			markupInput.selectionStringAnchorPosition = selectionStringAnchorPosition;
			markupInput.selectionStringFocusPosition = selectionStringFocusPosition;
			savedMarkupAnchor = selectionStringAnchorPosition;
			savedMarkupFocus = selectionStringFocusPosition;
			markupInput.ForceLabelUpdate();
		}

		private TextMeshProUGUI GetEmojiVisual(int index)
		{
			while (emojiVisuals.Count <= index)
			{
				emojiVisuals.Add(CreateVisual("Emoji" + emojiVisuals.Count));
			}
			return emojiVisuals[index];
		}

		private TextMeshProUGUI CreateVisual(string name)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)visualOverlayRoot))
			{
				return null;
			}
			GameObject val = new GameObject("SignEditor" + name)
			{
				hideFlags = (HideFlags)61
			};
			val.transform.SetParent(visualOverlayRoot.transform, false);
			TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>();
			((Graphic)obj).raycastTarget = false;
			((TMP_Text)obj).richText = false;
			((Graphic)obj).color = Color.white;
			return obj;
		}

		private Image CreateBackground(string name)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)visualOverlayRoot))
			{
				return null;
			}
			GameObject val = new GameObject("SignEditor" + name + "Background")
			{
				hideFlags = (HideFlags)61
			};
			val.transform.SetParent(visualOverlayRoot.transform, false);
			Image obj = val.AddComponent<Image>();
			((Graphic)obj).raycastTarget = false;
			return obj;
		}

		private static void ConfigureBackground(Image background, Rect rect, Color color)
		{
			//IL_000a: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)background))
			{
				((Graphic)background).color = color;
				((Component)background).gameObject.SetActive(true);
				RectTransform rectTransform = ((Graphic)background).rectTransform;
				rectTransform.anchorMin = new Vector2(0f, 1f);
				rectTransform.anchorMax = new Vector2(0f, 1f);
				rectTransform.pivot = new Vector2(0f, 1f);
				rectTransform.anchoredPosition = new Vector2(((Rect)(ref rect)).x, 0f - ((Rect)(ref rect)).y);
				rectTransform.sizeDelta = new Vector2(((Rect)(ref rect)).width, ((Rect)(ref rect)).height);
			}
		}

		private static void ConfigurePanelRect(RectTransform transform, Rect rect)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)transform))
			{
				transform.anchorMin = new Vector2(0f, 1f);
				transform.anchorMax = new Vector2(0f, 1f);
				transform.pivot = new Vector2(0f, 1f);
				transform.anchoredPosition = new Vector2(((Rect)(ref rect)).x, 0f - ((Rect)(ref rect)).y);
				transform.sizeDelta = new Vector2(((Rect)(ref rect)).width, ((Rect)(ref rect)).height);
			}
		}

		private void ConfigureVisual(TextMeshProUGUI visual, string value, Rect rect, float size, TextAlignmentOptions alignment, bool wrap)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			TMP_FontAsset val = GetVisualFont();
			if (Object.op_Implicit((Object)(object)val))
			{
				((TMP_Text)visual).font = val;
			}
			((TMP_Text)visual).text = value ?? string.Empty;
			((TMP_Text)visual).fontSize = size;
			((TMP_Text)visual).alignment = alignment;
			((TMP_Text)visual).enableWordWrapping = wrap;
			((Component)visual).gameObject.SetActive(true);
			RectTransform rectTransform = ((TMP_Text)visual).rectTransform;
			rectTransform.anchorMin = new Vector2(0f, 1f);
			rectTransform.anchorMax = new Vector2(0f, 1f);
			rectTransform.pivot = new Vector2(0f, 1f);
			rectTransform.anchoredPosition = new Vector2(((Rect)(ref rect)).x, 0f - ((Rect)(ref rect)).y);
			rectTransform.sizeDelta = new Vector2(((Rect)(ref rect)).width, ((Rect)(ref rect)).height);
		}

		private static Rect ToScreenRect(Rect rect, bool insideScrollView)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = GUIUtility.GUIToScreenPoint(new Vector2(((Rect)(ref rect)).x, ((Rect)(ref rect)).y));
			return new Rect(val.x, val.y, ((Rect)(ref rect)).width, ((Rect)(ref rect)).height);
		}

		private TMP_FontAsset GetVisualFont()
		{
			if (Object.op_Implicit((Object)(object)lastEditedSign))
			{
				TMP_Text componentInChildren = ((Component)lastEditedSign).GetComponentInChildren<TMP_Text>(true);
				if (Object.op_Implicit((Object)(object)componentInChildren) && Object.op_Implicit((Object)(object)componentInChildren.font))
				{
					visualFont = componentInChildren.font;
				}
			}
			return visualFont ?? TMP_Settings.defaultFontAsset;
		}

		private void HideVisualOverlay()
		{
			if (Object.op_Implicit((Object)(object)visualOverlayRoot))
			{
				visualOverlayRoot.SetActive(false);
			}
		}

		private void DestroyVisualOverlay()
		{
			if (Object.op_Implicit((Object)(object)visualOverlayRoot))
			{
				Object.Destroy((Object)(object)visualOverlayRoot);
				visualOverlayRoot = null;
			}
		}

		private void EnsureStyles()
		{
			//IL_001e: 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)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			//IL_00a6: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Expected O, but got Unknown
			//IL_00ef: Expected O, but got Unknown
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Expected O, but got Unknown
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Expected O, but got Unknown
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Expected O, but got Unknown
			//IL_0202: 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)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Expected O, but got Unknown
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Expected O, but got Unknown
			if (panelStyle == null)
			{
				overlayTexture = MakeTexture(new Color(0f, 0f, 0f, 0.58f));
				selectedTexture = MakeTexture(new Color(0.48f, 0.255f, 0.065f, 1f));
				transparentTexture = MakeTexture(Color.clear);
				GUIStyle val = new GUIStyle(GUI.skin.box);
				val.normal.background = overlayTexture;
				val.normal.textColor = Color.white;
				val.padding = new RectOffset(0, 0, 0, 0);
				overlayStyle = val;
				GUIStyle val2 = new GUIStyle(GUI.skin.box);
				val2.normal.background = transparentTexture;
				val2.normal.textColor = Color.white;
				val2.padding = new RectOffset(28, 28, 24, 24);
				panelStyle = val2;
				GUIStyle val3 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 36,
					fontStyle = (FontStyle)1
				};
				val3.normal.textColor = new Color(1f, 0.66f, 0.1f, 1f);
				titleStyle = val3;
				GUIStyle val4 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 24
				};
				val4.normal.textColor = new Color(1f, 0.86f, 0.6f, 1f);
				labelStyle = val4;
				GUIStyle val5 = new GUIStyle(GUI.skin.button)
				{
					fontSize = 22,
					fontStyle = (FontStyle)1,
					wordWrap = true
				};
				val5.normal.textColor = new Color(1f, 0.86f, 0.62f, 1f);
				val5.hover.textColor = Color.white;
				val5.active.textColor = new Color(1f, 0.67f, 0.12f, 1f);
				buttonStyle = val5;
				GUIStyle val6 = new GUIStyle(buttonStyle);
				val6.normal.background = transparentTexture;
				val6.normal.textColor = Color.clear;
				val6.hover.background = transparentTexture;
				val6.hover.textColor = Color.clear;
				val6.active.background = transparentTexture;
				val6.active.textColor = Color.clear;
				emojiClickStyle = val6;
				GUIStyle val7 = new GUIStyle(buttonStyle);
				val7.normal.background = selectedTexture;
				val7.normal.textColor = Color.white;
				selectedStyle = val7;
			}
		}

		private static Texture2D MakeTexture(Color color)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false);
			val.SetPixel(0, 0, color);
			val.Apply();
			return val;
		}
	}
	[HarmonyPatch(typeof(Sign), "Interact")]
	internal static class SignInteractPatch
	{
		private static void Postfix(Sign __instance, bool __result)
		{
			if (__result)
			{
				SignEditorPlugin.RememberSign(__instance);
			}
		}
	}
}