Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of SignScribe v1.0.0
SignScribe.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using SignScribe.Patches; using SignScribe.UI; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyCompany("Jubaroo")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © 2026 Jubaroo")] [assembly: AssemblyDescription("In-game rich text formatting studio and palette for Valheim signs using Jotunn")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SignScribe")] [assembly: AssemblyTitle("SignScribe")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [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 SignScribe { [BepInPlugin("com.jubaroo.signscribe", "SignScribe", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [BepInProcess("valheim.exe")] public sealed class SignScribePlugin : BaseUnityPlugin { public readonly struct EmojiItem { public readonly string Glyph; public readonly string Name; public readonly string[]? Tags; public EmojiItem(string glyph, string name, string[]? tags = null) { Glyph = glyph; Name = name; Tags = tags; } } public readonly struct EmojiGroup { public readonly string Header; public readonly EmojiItem[] Items; public EmojiGroup(string header, EmojiItem[] items) { Header = header; Items = items; } } internal static readonly string[] SavedColors = new string[5]; internal static readonly Color[] SavedColorValues = (Color[])(object)new Color[5]; internal static readonly string[][] ColorPalette = new string[16][] { new string[2] { "#FF3B30", "Red" }, new string[2] { "#FF9500", "Orange" }, new string[2] { "#FFCC00", "Yellow" }, new string[2] { "#34C759", "Lime" }, new string[2] { "#008F39", "Green" }, new string[2] { "#00C7BE", "Teal" }, new string[2] { "#32ADE6", "Cyan" }, new string[2] { "#007AFF", "Blue" }, new string[2] { "#5856D6", "Indigo" }, new string[2] { "#AF52DE", "Purple" }, new string[2] { "#FF2D55", "Magenta" }, new string[2] { "#FF69B4", "Pink" }, new string[2] { "#D4AF37", "Gold" }, new string[2] { "#8B5A2B", "Brown" }, new string[2] { "#FFFFFF", "White" }, new string[2] { "#8E8E93", "Gray" } }; internal static readonly EmojiGroup[] EmojiCatalog = new EmojiGroup[9] { new EmojiGroup("Combat & Tools", new EmojiItem[25] { new EmojiItem("⚔", "Swords", new string[5] { "combat", "pvp", "battle", "fight", "weapon" }), new EmojiItem("\ud83d\udde1", "Dagger", new string[3] { "knife", "weapon", "blade" }), new EmojiItem("\ud83c\udff9", "Bow", new string[4] { "arrow", "weapon", "ranged", "hunting" }), new EmojiItem("\ud83d\udee1", "Shield", new string[4] { "defense", "guard", "armor", "block" }), new EmojiItem("⛏", "Pickaxe", new string[5] { "mine", "mining", "stone", "ore", "tool" }), new EmojiItem("\ud83d\udd28", "Hammer", new string[4] { "build", "repair", "craft", "tool" }), new EmojiItem("\ud83e\ude93", "Axe", new string[5] { "chop", "wood", "tree", "tool", "weapon" }), new EmojiItem("\ud83d\udca3", "Bomb", new string[3] { "explosive", "blast", "danger" }), new EmojiItem("\ud83e\udde8", "Dynamite", new string[2] { "explosive", "firecracker" }), new EmojiItem("\ud83d\udd2a", "Knife", new string[3] { "blade", "kitchen", "cook" }), new EmojiItem("⚙", "Gear", new string[4] { "cog", "settings", "machine", "mechanism" }), new EmojiItem("\ud83d\udd27", "Wrench", new string[4] { "tool", "fix", "repair", "spanner" }), new EmojiItem("⛓", "Chains", new string[4] { "iron", "metal", "lock", "prison" }), new EmojiItem("\ud83e\ude9d", "Hook", new string[3] { "grapple", "fishing", "pirate" }), new EmojiItem("\ud83e\ude9a", "Saw", new string[3] { "carpentry", "woodwork", "tool" }), new EmojiItem("\ud83e\uddf2", "Magnet", new string[4] { "attract", "iron", "metal", "tool" }), new EmojiItem("\ud83e\ude84", "Wand", new string[4] { "magic", "wizard", "spell", "cast" }), new EmojiItem("\ud83d\udca5", "Explosion", new string[4] { "bang", "boom", "blast", "impact" }), new EmojiItem("\ud83e\ude78", "Blood", new string[3] { "damage", "wound", "bleed" }), new EmojiItem("\ud83c\udfaf", "Target", new string[4] { "bullseye", "aim", "archery", "goal" }), new EmojiItem("\ud83d\udea9", "Flag", new string[4] { "marker", "banner", "point", "claim" }), new EmojiItem("☠", "Skull Bones", new string[4] { "pirate", "death", "poison", "danger" }), new EmojiItem("\ud83d\udc80", "Skull", new string[4] { "death", "dead", "skeleton", "danger" }), new EmojiItem("⚰", "Coffin", new string[3] { "funeral", "grave", "death" }), new EmojiItem("\ud83e\udea6", "Headstone", new string[3] { "gravestone", "rip", "tomb" }) }), new EmojiGroup("Nature & Biomes", new EmojiItem[38] { new EmojiItem("\ud83c\udf32", "Pine Tree", new string[4] { "wood", "forest", "black forest", "timber" }), new EmojiItem("\ud83c\udf33", "Oak Tree", new string[4] { "wood", "meadows", "forest", "nature" }), new EmojiItem("\ud83c\udf34", "Palm Tree", new string[4] { "tree", "beach", "tropical", "island" }), new EmojiItem("\ud83e\udeb5", "Wood Log", new string[4] { "lumber", "timber", "fuel", "firewood" }), new EmojiItem("\ud83c\udf31", "Seedling", new string[4] { "plant", "grow", "sprout", "farming" }), new EmojiItem("\ud83c\udf3f", "Herb", new string[4] { "leaf", "alchemy", "ingredient", "plant" }), new EmojiItem("☘", "Shamrock", new string[3] { "clover", "plant", "green" }), new EmojiItem("\ud83c\udf40", "4-Leaf Clover", new string[4] { "lucky", "luck", "fortune", "plant" }), new EmojiItem("\ud83c\udf3e", "Grain / Barley", new string[4] { "wheat", "crop", "plains", "harvest" }), new EmojiItem("\ud83c\udf35", "Cactus", new string[3] { "desert", "plant", "spikes" }), new EmojiItem("\ud83c\udf37", "Tulip", new string[3] { "flower", "spring", "garden" }), new EmojiItem("\ud83c\udf38", "Cherry Blossom", new string[3] { "flower", "pink", "spring" }), new EmojiItem("\ud83c\udf39", "Rose", new string[4] { "flower", "red", "love", "garden" }), new EmojiItem("\ud83c\udf3b", "Sunflower", new string[3] { "flower", "yellow", "summer" }), new EmojiItem("\ud83c\udf3c", "Blossom", new string[3] { "flower", "bloom", "nature" }), new EmojiItem("\ud83c\udf44", "Mushroom", new string[4] { "food", "forage", "fungus", "shroom" }), new EmojiItem("\ud83c\udf42", "Fallen Leaf", new string[4] { "autumn", "fall", "orange", "leaf" }), new EmojiItem("\ud83c\udf41", "Maple Leaf", new string[3] { "autumn", "fall", "nature" }), new EmojiItem("\ud83d\udd25", "Fire", new string[5] { "campfire", "flame", "hot", "burn", "warmth" }), new EmojiItem("\ud83d\udca7", "Water Drop", new string[4] { "liquid", "water", "wet", "rain" }), new EmojiItem("\ud83c\udf0a", "Ocean Wave", new string[4] { "sea", "ocean", "water", "sailing" }), new EmojiItem("❄", "Snowflake", new string[5] { "snow", "frost", "cold", "mountain", "freeze" }), new EmojiItem("⚡", "Lightning", new string[4] { "thunder", "storm", "shock", "electric" }), new EmojiItem("⛅", "Sun Cloud", new string[3] { "weather", "cloudy", "sky" }), new EmojiItem("\ud83c\udf27", "Rain Cloud", new string[4] { "weather", "shower", "wet", "storm" }), new EmojiItem("\ud83c\udf29", "Thundercloud", new string[3] { "storm", "lightning", "weather" }), new EmojiItem("\ud83c\udf19", "Crescent Moon", new string[3] { "night", "dark", "evening" }), new EmojiItem("☀\ufe0f", "Sun", new string[4] { "day", "light", "sunny", "warm" }), new EmojiItem("⭐", "Star", new string[4] { "night", "sky", "space", "favorite" }), new EmojiItem("\ud83c\udf1f", "Glowing Star", new string[3] { "sparkle", "shine", "magic" }), new EmojiItem("\ud83c\udf0b", "Volcano", new string[4] { "ashlands", "lava", "fire", "magma" }), new EmojiItem("\ud83c\udfd4", "Snow Mountain", new string[4] { "mountains", "peak", "cold", "altitude" }), new EmojiItem("⛰", "Mountain", new string[3] { "rock", "hill", "highlands" }), new EmojiItem("\ud83c\udfd5", "Camping", new string[4] { "tent", "camp", "outdoors", "base" }), new EmojiItem("\ud83c\udfdc", "Desert", new string[3] { "sand", "dry", "sun" }), new EmojiItem("\ud83e\udea8", "Rock / Stone", new string[4] { "boulder", "mineral", "ore", "material" }), new EmojiItem("\ud83c\udf15", "Full Moon", new string[3] { "night", "lunar", "moonlight" }), new EmojiItem("☄", "Comet", new string[3] { "meteor", "space", "falling star" }) }), new EmojiGroup("Creatures & Wildlife", new EmojiItem[42] { new EmojiItem("\ud83d\udc17", "Boar", new string[5] { "pig", "animal", "tame", "meat", "leather" }), new EmojiItem("\ud83d\udc3a", "Wolf", new string[5] { "canine", "animal", "tame", "mountains", "pack" }), new EmojiItem("\ud83e\udd8c", "Deer", new string[5] { "animal", "hide", "antlers", "trophy", "hunt" }), new EmojiItem("\ud83d\udc3b", "Bear", new string[4] { "animal", "beast", "fur", "predator" }), new EmojiItem("\ud83e\udd87", "Bat", new string[4] { "cave", "flying", "night", "animal" }), new EmojiItem("\ud83e\udd85", "Eagle", new string[4] { "bird", "raptor", "feathers", "sky" }), new EmojiItem("\ud83e\udd89", "Owl", new string[4] { "bird", "night", "wise", "feathers" }), new EmojiItem("\ud83d\udc0d", "Snake", new string[4] { "serpent", "poison", "reptile", "sea serpent" }), new EmojiItem("\ud83d\udd77", "Spider", new string[4] { "arachnid", "mistlands", "web", "bug" }), new EmojiItem("\ud83e\udd82", "Scorpion", new string[3] { "poison", "stinger", "bug" }), new EmojiItem("\ud83d\udc1d", "Bee", new string[4] { "queen bee", "honey", "hive", "insect" }), new EmojiItem("\ud83d\udc1b", "Bug / Caterpillar", new string[3] { "insect", "larva", "creep" }), new EmojiItem("\ud83e\udd8b", "Butterfly", new string[3] { "insect", "wings", "pretty" }), new EmojiItem("\ud83d\udc0c", "Snail", new string[3] { "slow", "shell", "garden" }), new EmojiItem("\ud83d\udc1c", "Ant", new string[3] { "insect", "colony", "worker" }), new EmojiItem("\ud83e\udd9f", "Mosquito", new string[4] { "deathsquito", "plains", "sting", "needle" }), new EmojiItem("\ud83d\udc1f", "Fish", new string[4] { "angler", "fishing", "food", "ocean" }), new EmojiItem("\ud83e\udd88", "Shark", new string[4] { "predator", "ocean", "sea", "fish" }), new EmojiItem("\ud83d\udc19", "Octopus", new string[3] { "kraken", "tentacles", "sea" }), new EmojiItem("\ud83e\udd91", "Squid", new string[3] { "ocean", "calamari", "tentacles" }), new EmojiItem("\ud83e\udd80", "Crab", new string[3] { "ocean", "shellfish", "beach" }), new EmojiItem("\ud83e\udd9e", "Lobster", new string[3] { "seafood", "crustacean", "ocean" }), new EmojiItem("\ud83e\udd90", "Shrimp", new string[3] { "seafood", "ocean", "small" }), new EmojiItem("\ud83d\udc0e", "Horse", new string[4] { "steed", "mount", "animal", "ride" }), new EmojiItem("\ud83d\udc02", "Ox / Lox", new string[5] { "lox", "beast", "plains", "mount", "animal" }), new EmojiItem("\ud83d\udc04", "Cow", new string[3] { "farm", "milk", "cattle" }), new EmojiItem("\ud83d\udc16", "Pig", new string[3] { "farm", "pork", "swine" }), new EmojiItem("\ud83d\udc0f", "Ram", new string[3] { "sheep", "wool", "horns" }), new EmojiItem("\ud83d\udc11", "Sheep", new string[3] { "wool", "farm", "flock" }), new EmojiItem("\ud83d\udc10", "Goat", new string[3] { "animal", "horns", "farm" }), new EmojiItem("\ud83d\udc15", "Dog", new string[3] { "pet", "puppy", "canine" }), new EmojiItem("\ud83d\udc08", "Cat", new string[3] { "pet", "kitten", "feline" }), new EmojiItem("\ud83d\udc13", "Rooster", new string[4] { "chicken", "bird", "morning", "farm" }), new EmojiItem("\ud83e\udd83", "Turkey", new string[3] { "bird", "poultry", "farm" }), new EmojiItem("\ud83e\udd86", "Duck", new string[3] { "bird", "pond", "waterfowl" }), new EmojiItem("\ud83e\udda2", "Swan", new string[3] { "bird", "lake", "graceful" }), new EmojiItem("\ud83d\udc38", "Frog", new string[3] { "swamp", "amphibian", "hop" }), new EmojiItem("\ud83d\udc0a", "Crocodile", new string[4] { "reptile", "alligator", "swamp", "predator" }), new EmojiItem("\ud83d\udc22", "Turtle", new string[4] { "reptile", "shell", "slow", "chitin" }), new EmojiItem("\ud83d\udc09", "Dragon", new string[5] { "moder", "wyrm", "boss", "flying", "drake" }), new EmojiItem("\ud83e\udd95", "Sauropod", new string[3] { "dino", "dinosaur", "giant" }), new EmojiItem("\ud83e\udd96", "T-Rex", new string[4] { "dino", "dinosaur", "carnivore", "monster" }) }), new EmojiGroup("Food & Farming", new EmojiItem[46] { new EmojiItem("\ud83c\udf56", "Meat", new string[4] { "food", "cooked meat", "ribs", "eat" }), new EmojiItem("\ud83e\udd69", "Steak", new string[4] { "raw meat", "meat", "beef", "grill" }), new EmojiItem("\ud83c\udf57", "Poultry Leg", new string[4] { "chicken", "cooked", "food", "meat" }), new EmojiItem("\ud83e\udd53", "Bacon", new string[3] { "pork", "breakfast", "food" }), new EmojiItem("\ud83c\udf5e", "Bread", new string[5] { "baking", "oven", "barley", "food", "loaf" }), new EmojiItem("\ud83e\udd56", "Baguette", new string[3] { "bread", "bakery", "food" }), new EmojiItem("\ud83e\uddc0", "Cheese", new string[2] { "dairy", "food" }), new EmojiItem("\ud83c\udf73", "Fried Egg", new string[4] { "egg", "breakfast", "cooking", "food" }), new EmojiItem("\ud83e\udd5e", "Pancakes", new string[3] { "breakfast", "syrup", "food" }), new EmojiItem("\ud83c\udf6f", "Honey", new string[5] { "beehive", "mead", "sweet", "nectar", "food" }), new EmojiItem("\ud83c\udf4e", "Red Apple", new string[3] { "fruit", "food", "orchard" }), new EmojiItem("\ud83c\udf4f", "Green Apple", new string[3] { "fruit", "sour", "orchard" }), new EmojiItem("\ud83c\udf50", "Pear", new string[3] { "fruit", "orchard", "food" }), new EmojiItem("\ud83c\udf4a", "Orange", new string[3] { "fruit", "citrus", "food" }), new EmojiItem("\ud83c\udf4b", "Lemon", new string[3] { "fruit", "citrus", "sour" }), new EmojiItem("\ud83c\udf4c", "Banana", new string[3] { "fruit", "tropical", "food" }), new EmojiItem("\ud83c\udf49", "Watermelon", new string[3] { "fruit", "melon", "summer" }), new EmojiItem("\ud83c\udf47", "Grapes", new string[4] { "fruit", "wine", "vineyard", "berries" }), new EmojiItem("\ud83c\udf53", "Strawberry", new string[3] { "fruit", "berries", "sweet" }), new EmojiItem("\ud83e\uded0", "Blueberries", new string[4] { "berries", "forage", "black forest", "food" }), new EmojiItem("\ud83c\udf52", "Cherries", new string[3] { "fruit", "berries", "sweet" }), new EmojiItem("\ud83c\udf51", "Peach", new string[3] { "fruit", "orchard", "sweet" }), new EmojiItem("\ud83e\udd55", "Carrot", new string[5] { "vegetable", "farming", "crop", "seeds", "food" }), new EmojiItem("\ud83c\udf3d", "Corn", new string[3] { "vegetable", "crop", "harvest" }), new EmojiItem("\ud83e\udd54", "Potato", new string[4] { "turnip", "root", "vegetable", "farming" }), new EmojiItem("\ud83e\uddc5", "Onion", new string[4] { "vegetable", "farming", "cooking", "crop" }), new EmojiItem("\ud83e\uddc4", "Garlic", new string[3] { "herb", "flavor", "vegetable" }), new EmojiItem("\ud83e\udd66", "Broccoli", new string[3] { "vegetable", "healthy", "greens" }), new EmojiItem("\ud83e\udd6c", "Leafy Green", new string[3] { "lettuce", "salad", "vegetable" }), new EmojiItem("\ud83e\udd5c", "Peanuts", new string[3] { "nuts", "snack", "food" }), new EmojiItem("\ud83c\udf30", "Chestnut", new string[4] { "acorn", "nut", "seeds", "tree" }), new EmojiItem("\ud83c\udf7a", "Beer Mug", new string[5] { "mead", "ale", "drink", "tavern", "fermenter" }), new EmojiItem("\ud83c\udf7b", "Clinking Mugs", new string[4] { "toast", "cheers", "bar", "party" }), new EmojiItem("\ud83c\udf77", "Wine Glass", new string[3] { "drink", "alcohol", "vintage" }), new EmojiItem("\ud83e\udd42", "Champagne", new string[3] { "celebrate", "cheers", "toast" }), new EmojiItem("\ud83e\udd43", "Whiskey Glass", new string[3] { "liquor", "spirits", "drink" }), new EmojiItem("\ud83c\udf78", "Cocktail", new string[3] { "drink", "martini", "bar" }), new EmojiItem("\ud83c\udf76", "Sake Bottle", new string[3] { "flask", "potion", "bottle" }), new EmojiItem("☕", "Coffee Cup", new string[3] { "hot drink", "morning", "caffeine" }), new EmojiItem("\ud83c\udf75", "Tea Cup", new string[3] { "hot drink", "herbal", "potion" }), new EmojiItem("\ud83e\udd63", "Bowl of Stew", new string[4] { "soup", "stew", "cauldron", "serpent stew" }), new EmojiItem("\ud83c\udf72", "Pot of Food", new string[3] { "cauldron", "cooking", "hot pot" }), new EmojiItem("\ud83e\udd67", "Meat Pie", new string[4] { "pie", "baked", "food", "pastry" }), new EmojiItem("\ud83c\udf70", "Cake Slice", new string[3] { "dessert", "sweet", "party" }), new EmojiItem("\ud83c\udf6a", "Cookie", new string[3] { "snack", "biscuit", "sweet" }), new EmojiItem("\ud83e\uddc2", "Salt", new string[3] { "seasoning", "spice", "cooking" }) }), new EmojiGroup("Loot & Magic", new EmojiItem[37] { new EmojiItem("\ud83d\udc51", "Crown", new string[5] { "king", "jarl", "royalty", "leader", "loot" }), new EmojiItem("\ud83d\udcb0", "Money Bag", new string[5] { "gold", "coins", "coins bag", "treasure", "rich" }), new EmojiItem("\ud83e\ude99", "Gold Coin", new string[4] { "coin", "currency", "haldor", "trader" }), new EmojiItem("\ud83d\udc8e", "Gem", new string[6] { "ruby", "amber", "sapphire", "emerald", "crystal", "loot" }), new EmojiItem("\ud83d\udc8d", "Ring", new string[4] { "jewelry", "accessory", "magic ring", "treasure" }), new EmojiItem("\ud83c\udfc6", "Trophy", new string[4] { "award", "boss trophy", "hunt", "victory" }), new EmojiItem("\ud83e\udd47", "1st Gold Medal", new string[3] { "first", "champion", "winner" }), new EmojiItem("\ud83e\udd48", "2nd Silver Medal", new string[3] { "second", "silver", "runner-up" }), new EmojiItem("\ud83e\udd49", "3rd Bronze Medal", new string[3] { "third", "bronze", "medal" }), new EmojiItem("\ud83c\udf96", "Military Medal", new string[3] { "honor", "service", "decoration" }), new EmojiItem("\ud83d\udce6", "Storage Chest", new string[5] { "box", "crate", "package", "storage", "loot" }), new EmojiItem("\ud83c\udf81", "Gift Box", new string[3] { "present", "holiday", "reward" }), new EmojiItem("\ud83d\udcdc", "Scroll", new string[5] { "map", "rune", "recipe", "blueprint", "document" }), new EmojiItem("\ud83d\udddd", "Old Key", new string[4] { "swamp key", "crypt key", "dungeon", "lock" }), new EmojiItem("\ud83d\udd11", "Key", new string[4] { "lock", "open", "door", "chest" }), new EmojiItem("\ud83d\udd12", "Locked", new string[4] { "secure", "ward", "private", "no entry" }), new EmojiItem("\ud83d\udd13", "Unlocked", new string[3] { "open", "accessible", "free" }), new EmojiItem("\ud83d\udcef", "Postal Horn", new string[4] { "horn", "war horn", "call", "music" }), new EmojiItem("\ud83d\udd14", "Bell", new string[4] { "chime", "alarm", "church", "sound" }), new EmojiItem("\ud83c\udffa", "Amphora / Vase", new string[4] { "pottery", "relic", "urn", "ancient" }), new EmojiItem("\ud83d\udd6f", "Candle", new string[4] { "light", "wax", "flame", "lighting" }), new EmojiItem("\ud83d\udd2e", "Crystal Ball", new string[4] { "magic", "seer", "oracle", "future" }), new EmojiItem("\ud83e\uddff", "Nazar Amulet", new string[4] { "talisman", "ward", "protection", "charm" }), new EmojiItem("\ud83e\uddea", "Test Tube / Potion", new string[4] { "potion", "alchemy", "mead", "brew" }), new EmojiItem("\ud83e\uddec", "DNA", new string[3] { "essence", "life", "science" }), new EmojiItem("\ud83e\udded", "Compass", new string[4] { "direction", "navigation", "map", "way" }), new EmojiItem("⌛", "Hourglass Done", new string[3] { "time", "timer", "wait" }), new EmojiItem("⏳", "Hourglass Active", new string[4] { "time", "timing", "loading", "fermenting" }), new EmojiItem("\ud83d\udca1", "Lightbulb", new string[4] { "idea", "bright", "electricity", "invention" }), new EmojiItem("\ud83d\udd26", "Flashlight", new string[3] { "torch", "beam", "search" }), new EmojiItem("\ud83e\ude94", "Oil Lamp", new string[3] { "lantern", "light", "fuel" }), new EmojiItem("\ud83d\udcb5", "Dollar Banknote", new string[3] { "money", "cash", "bills" }), new EmojiItem("\ud83d\udcb3", "Card", new string[3] { "payment", "ticket", "pass" }), new EmojiItem("\ud83c\udff7", "Label / Tag", new string[4] { "portal tag", "tag", "name", "price" }), new EmojiItem("\ud83d\uddfa", "World Map", new string[3] { "cartography", "explore", "navigation" }), new EmojiItem("✉", "Envelope", new string[4] { "letter", "mail", "message", "note" }), new EmojiItem("✨", "Magic Sparkles", new string[5] { "stars", "enchant", "glowing", "clean", "magic" }) }), new EmojiGroup("Base & Travel", new EmojiItem[28] { new EmojiItem("\ud83c\udfe0", "House", new string[4] { "home", "base", "building", "shelter" }), new EmojiItem("\ud83c\udfe1", "Homestead", new string[3] { "farmhouse", "estate", "yard" }), new EmojiItem("\ud83c\udff0", "Castle", new string[4] { "fortress", "keep", "stronghold", "stone" }), new EmojiItem("\ud83d\uddfc", "Watchtower", new string[3] { "tower", "lookout", "spire" }), new EmojiItem("⛺", "Tent", new string[3] { "campsite", "temporary", "outdoors" }), new EmojiItem("\ud83d\uded6", "Hut", new string[3] { "cabin", "shack", "primitive" }), new EmojiItem("\ud83d\udeaa", "Door", new string[4] { "entrance", "portal", "exit", "entry" }), new EmojiItem("\ud83e\ude9f", "Window", new string[3] { "glass", "view", "wall" }), new EmojiItem("\ud83d\udecf", "Bed", new string[4] { "spawn point", "sleep", "rest", "comfort" }), new EmojiItem("\ud83d\udecb", "Couch", new string[3] { "comfort", "furniture", "living" }), new EmojiItem("\ud83e\ude91", "Chair", new string[3] { "throne", "furniture", "seat" }), new EmojiItem("⚓", "Anchor", new string[5] { "dock", "port", "harbor", "ship", "boat" }), new EmojiItem("⛵", "Sailboat", new string[4] { "karve", "raft", "boat", "sailing" }), new EmojiItem("\ud83d\udea4", "Speedboat", new string[2] { "fast boat", "watercraft" }), new EmojiItem("\ud83d\udea2", "Longship", new string[4] { "viking ship", "drakkar", "ship", "vessel" }), new EmojiItem("\ud83d\udef6", "Canoe", new string[3] { "kayak", "paddle", "boat" }), new EmojiItem("\ud83d\udea3", "Rowboat", new string[3] { "rowing", "boat", "water" }), new EmojiItem("\ud83d\uded2", "Cart", new string[4] { "wagon", "haul", "transport", "cargo" }), new EmojiItem("\ud83d\udee4", "Railway", new string[3] { "tracks", "path", "transport" }), new EmojiItem("\ud83d\udee3", "Road", new string[4] { "path", "trail", "highway", "travel" }), new EmojiItem("\ud83e\ude9c", "Ladder", new string[3] { "climb", "stairs", "reach" }), new EmojiItem("\ud83e\udea2", "Knot / Rope", new string[4] { "rope", "tie", "cord", "rigging" }), new EmojiItem("\ud83e\udea3", "Bucket", new string[3] { "water", "well", "pail" }), new EmojiItem("\ud83d\udec1", "Bathtub", new string[4] { "wash", "tub", "clean", "water" }), new EmojiItem("\ud83d\udebf", "Shower", new string[3] { "clean", "bathroom", "water" }), new EmojiItem("\ud83e\uddf9", "Broom", new string[3] { "sweep", "clean", "tidy" }), new EmojiItem("\ud83e\uddfa", "Basket", new string[3] { "storage", "container", "woven" }), new EmojiItem("\ud83e\ude9e", "Mirror", new string[3] { "reflection", "glass", "vanity" }) }), new EmojiGroup("Smileys & Faces", new EmojiItem[97] { new EmojiItem("☺", "Smile", new string[4] { "happy", "smile", "classic", "face" }), new EmojiItem("\ud83d\ude00", "Grinning", new string[3] { "happy", "smile", "joy" }), new EmojiItem("\ud83d\ude03", "Grinning Eyes", new string[3] { "happy", "smile", "open" }), new EmojiItem("\ud83d\ude04", "Smiling Eyes", new string[3] { "laugh", "happy", "cheerful" }), new EmojiItem("\ud83d\ude01", "Beaming", new string[3] { "grin", "teeth", "happy" }), new EmojiItem("\ud83d\ude06", "Laughing Squint", new string[3] { "haha", "lol", "funny" }), new EmojiItem("\ud83d\ude05", "Sweat Grin", new string[3] { "phew", "nervous", "relief" }), new EmojiItem("\ud83e\udd23", "ROFL", new string[3] { "rolling", "laughing", "hilarious" }), new EmojiItem("\ud83d\ude02", "Tears of Joy", new string[3] { "crying laughing", "lol", "funny" }), new EmojiItem("\ud83d\ude42", "Slight Smile", new string[3] { "calm", "pleasant", "ok" }), new EmojiItem("\ud83d\ude43", "Upside Down", new string[3] { "silly", "irony", "sarcasm" }), new EmojiItem("\ud83d\ude09", "Wink", new string[3] { "flirt", "joke", "secret" }), new EmojiItem("\ud83d\ude0a", "Warm Smile", new string[3] { "blush", "kind", "friendly" }), new EmojiItem("\ud83d\ude07", "Angel Halo", new string[3] { "innocent", "good", "holy" }), new EmojiItem("\ud83e\udd70", "Hearts Face", new string[3] { "love", "adorable", "sweet" }), new EmojiItem("\ud83d\ude0d", "Heart Eyes", new string[3] { "love", "crush", "gorgeous" }), new EmojiItem("\ud83e\udd29", "Star-Struck", new string[3] { "excited", "amazed", "wow" }), new EmojiItem("\ud83d\ude18", "Blowing Kiss", new string[3] { "love", "kiss", "affection" }), new EmojiItem("\ud83d\ude0b", "Yummy", new string[4] { "delicious", "tasty", "food", "tongue" }), new EmojiItem("\ud83d\ude1b", "Tongue Out", new string[3] { "silly", "playful", "joke" }), new EmojiItem("\ud83d\ude1c", "Winking Tongue", new string[3] { "crazy", "playful", "fun" }), new EmojiItem("\ud83e\udd2a", "Zany", new string[3] { "crazy", "wild", "goofy" }), new EmojiItem("\ud83d\ude1d", "Squinting Tongue", new string[3] { "mischief", "playful", "tease" }), new EmojiItem("\ud83e\udd11", "Money Face", new string[4] { "rich", "coins", "gold", "wealth" }), new EmojiItem("\ud83e\udd17", "Hugging", new string[3] { "hug", "welcome", "open hands" }), new EmojiItem("\ud83e\udd2d", "Hand on Mouth", new string[3] { "oops", "secret", "giggle" }), new EmojiItem("\ud83e\udd2b", "Shushing", new string[4] { "quiet", "silence", "hush", "secret" }), new EmojiItem("\ud83e\udd14", "Thinking", new string[4] { "hmm", "ponder", "wonder", "curious" }), new EmojiItem("\ud83e\udd10", "Zipper Mouth", new string[3] { "shut", "silent", "secret" }), new EmojiItem("\ud83e\udd28", "Raised Eyebrow", new string[3] { "skeptical", "suspicious", "doubt" }), new EmojiItem("\ud83d\ude10", "Neutral", new string[3] { "blank", "poker face", "indifferent" }), new EmojiItem("\ud83d\ude11", "Expressionless", new string[3] { "unimpressed", "flat", "done" }), new EmojiItem("\ud83d\ude36", "No Mouth", new string[3] { "speechless", "quiet", "mute" }), new EmojiItem("\ud83d\ude0f", "Smirking", new string[3] { "smug", "flirt", "clever" }), new EmojiItem("\ud83d\ude12", "Unamused", new string[3] { "annoyed", "grumpy", "bored" }), new EmojiItem("\ud83d\ude44", "Rolling Eyes", new string[3] { "whatever", "sarcasm", "annoyed" }), new EmojiItem("\ud83d\ude2c", "Grimacing", new string[3] { "awkward", "yikes", "nervous" }), new EmojiItem("\ud83e\udd25", "Lying Face", new string[3] { "pinocchio", "deceit", "fake" }), new EmojiItem("\ud83d\ude0c", "Relieved", new string[4] { "peace", "calm", "zen", "rest" }), new EmojiItem("\ud83d\ude14", "Pensive", new string[3] { "sad", "thoughtful", "down" }), new EmojiItem("\ud83d\ude2a", "Sleepy", new string[3] { "tired", "snooze", "rest" }), new EmojiItem("\ud83e\udd24", "Drooling", new string[3] { "hungry", "craving", "delicious" }), new EmojiItem("\ud83d\ude34", "Sleeping", new string[4] { "zzz", "bed", "rest", "night" }), new EmojiItem("\ud83d\ude37", "Mask", new string[3] { "sick", "doctor", "hygiene" }), new EmojiItem("\ud83e\udd12", "Thermometer", new string[3] { "fever", "sick", "ill" }), new EmojiItem("\ud83e\udd15", "Bandage Head", new string[3] { "hurt", "injured", "wound" }), new EmojiItem("\ud83e\udd22", "Nauseated", new string[3] { "sick", "gross", "disgust" }), new EmojiItem("\ud83e\udd2e", "Vomiting", new string[3] { "puke", "disgusted", "sick" }), new EmojiItem("\ud83e\udd27", "Sneezing", new string[3] { "cold", "allergies", "tissue" }), new EmojiItem("\ud83e\udd75", "Hot Face", new string[4] { "heat", "sweat", "fire", "spicy" }), new EmojiItem("\ud83e\udd76", "Cold Face", new string[4] { "freezing", "ice", "frost", "shivering" }), new EmojiItem("\ud83e\udd74", "Woozy", new string[4] { "drunk", "mead", "dizzy", "tipsy" }), new EmojiItem("\ud83d\ude35", "Dizzy", new string[3] { "stunned", "dead", "knocked out" }), new EmojiItem("\ud83e\udd2f", "Mind Blown", new string[3] { "exploding", "shocked", "amazing" }), new EmojiItem("\ud83e\udd20", "Cowboy", new string[3] { "hat", "western", "yeehaw" }), new EmojiItem("\ud83e\udd73", "Party Face", new string[3] { "celebration", "horn", "birthday" }), new EmojiItem("\ud83d\ude0e", "Sunglasses", new string[4] { "cool", "boss", "swag", "awesome" }), new EmojiItem("\ud83e\udd13", "Nerd", new string[3] { "glasses", "smart", "geek" }), new EmojiItem("\ud83e\uddd0", "Monocle", new string[3] { "detective", "inspect", "fancy" }), new EmojiItem("\ud83d\ude15", "Confused", new string[3] { "puzzled", "uncertain", "what" }), new EmojiItem("\ud83d\ude1f", "Worried", new string[3] { "anxious", "nervous", "concern" }), new EmojiItem("\ud83d\ude41", "Slight Frown", new string[2] { "disappointed", "sad" }), new EmojiItem("☹", "Frowning", new string[3] { "unhappy", "bummed", "sad" }), new EmojiItem("\ud83d\ude2e", "Open Mouth", new string[3] { "surprised", "gasp", "whoa" }), new EmojiItem("\ud83d\ude2f", "Hushed", new string[3] { "stunned", "quiet", "surprise" }), new EmojiItem("\ud83d\ude32", "Astonished", new string[3] { "shocked", "amazed", "unbelievable" }), new EmojiItem("\ud83d\ude33", "Flushed", new string[3] { "blushing", "embarrassed", "wide eyes" }), new EmojiItem("\ud83e\udd7a", "Pleading Eyes", new string[3] { "begging", "cute", "puppy eyes" }), new EmojiItem("\ud83d\ude26", "Frowning Open", new string[2] { "shock", "dismay" }), new EmojiItem("\ud83d\ude27", "Anguished", new string[3] { "pain", "distress", "worry" }), new EmojiItem("\ud83d\ude28", "Fearful", new string[3] { "scared", "frightened", "panic" }), new EmojiItem("\ud83d\ude30", "Anxious Sweat", new string[3] { "nervous", "stressed", "scared" }), new EmojiItem("\ud83d\ude25", "Sad Relieved", new string[2] { "close call", "disappointed" }), new EmojiItem("\ud83d\ude22", "Crying", new string[3] { "tear", "sad", "unhappy" }), new EmojiItem("\ud83d\ude2d", "Loudly Crying", new string[3] { "bawling", "sobbing", "tears" }), new EmojiItem("\ud83d\ude31", "Screaming", new string[4] { "horror", "terror", "scared", "munch" }), new EmojiItem("\ud83d\ude16", "Confounded", new string[2] { "frustrated", "struggling" }), new EmojiItem("\ud83d\ude23", "Persevering", new string[3] { "enduring", "struggling", "trying" }), new EmojiItem("\ud83d\ude1e", "Disappointed", new string[3] { "regret", "let down", "sad" }), new EmojiItem("\ud83d\ude13", "Downcast Sweat", new string[2] { "exhausted", "hard work" }), new EmojiItem("\ud83d\ude29", "Weary", new string[3] { "tired", "frustrated", "fed up" }), new EmojiItem("\ud83d\ude2b", "Tired", new string[3] { "exhausted", "whining", "done" }), new EmojiItem("\ud83e\udd71", "Yawning", new string[3] { "bored", "sleepy", "tired" }), new EmojiItem("\ud83d\ude24", "Steam Triumph", new string[3] { "proud", "determined", "puff" }), new EmojiItem("\ud83d\ude21", "Enraged", new string[4] { "mad", "furious", "angry", "red" }), new EmojiItem("\ud83d\ude20", "Angry", new string[3] { "mad", "cross", "annoyed" }), new EmojiItem("\ud83e\udd2c", "Cursing", new string[3] { "swearing", "profanity", "rage" }), new EmojiItem("\ud83d\ude08", "Smiling Devil", new string[3] { "mischief", "evil", "imp" }), new EmojiItem("\ud83d\udc7f", "Angry Devil", new string[3] { "demon", "furious", "fiend" }), new EmojiItem("\ud83d\udca9", "Poop", new string[3] { "crap", "dung", "funny" }), new EmojiItem("\ud83e\udd21", "Clown", new string[3] { "fool", "circus", "jester" }), new EmojiItem("\ud83d\udc79", "Ogre", new string[4] { "monster", "troll", "demon", "japanese" }), new EmojiItem("\ud83d\udc7a", "Goblin", new string[3] { "red face", "troll", "creature" }), new EmojiItem("\ud83d\udc7b", "Ghost", new string[4] { "spooky", "wraith", "phantom", "haunt" }), new EmojiItem("\ud83d\udc7d", "Alien", new string[3] { "ufo", "extraterrestrial", "space" }), new EmojiItem("\ud83d\udc7e", "Space Monster", new string[4] { "retro", "invader", "game", "pixel" }), new EmojiItem("\ud83e\udd16", "Robot", new string[4] { "droid", "mech", "ai", "bot" }) }), new EmojiGroup("Symbols & UI", new EmojiItem[61] { new EmojiItem("⚠", "Warning", new string[4] { "alert", "caution", "danger", "hazard" }), new EmojiItem("⛔", "No Entry", new string[3] { "stop", "forbidden", "restricted" }), new EmojiItem("\ud83d\udeab", "Prohibited", new string[3] { "banned", "no", "forbidden" }), new EmojiItem("❗", "Exclamation", new string[3] { "important", "notice", "alert" }), new EmojiItem("❓", "Question", new string[4] { "help", "info", "query", "unknown" }), new EmojiItem("❌", "Cross Mark", new string[4] { "no", "cancel", "wrong", "x" }), new EmojiItem("⭕", "Circle", new string[4] { "ok", "correct", "target", "round" }), new EmojiItem("\ud83d\uded1", "Stop Sign", new string[3] { "halt", "octagonal", "danger" }), new EmojiItem("\ud83d\udd34", "Red Circle", new string[3] { "marker", "dot", "danger" }), new EmojiItem("\ud83d\udfe0", "Orange Circle", new string[3] { "marker", "dot", "orange" }), new EmojiItem("\ud83d\udfe1", "Yellow Circle", new string[3] { "marker", "dot", "caution" }), new EmojiItem("\ud83d\udfe2", "Green Circle", new string[4] { "marker", "dot", "safe", "go" }), new EmojiItem("\ud83d\udd35", "Blue Circle", new string[4] { "marker", "dot", "water", "portal" }), new EmojiItem("\ud83d\udfe3", "Purple Circle", new string[3] { "marker", "dot", "magic" }), new EmojiItem("\ud83d\udfe4", "Brown Circle", new string[3] { "marker", "dot", "earth" }), new EmojiItem("⚫", "Black Circle", new string[3] { "marker", "dot", "dark" }), new EmojiItem("⚪", "White Circle", new string[3] { "marker", "dot", "light" }), new EmojiItem("\ud83d\udfe5", "Red Square", new string[3] { "marker", "box", "red" }), new EmojiItem("\ud83d\udfe9", "Green Square", new string[3] { "marker", "box", "green" }), new EmojiItem("\ud83d\udfe6", "Blue Square", new string[3] { "marker", "box", "blue" }), new EmojiItem("\ud83d\udfe8", "Yellow Square", new string[3] { "marker", "box", "yellow" }), new EmojiItem("⬛", "Black Square", new string[3] { "marker", "box", "black" }), new EmojiItem("⬜", "White Square", new string[3] { "marker", "box", "white" }), new EmojiItem("⬆", "Up Arrow", new string[3] { "north", "upward", "direction" }), new EmojiItem("⬇", "Down Arrow", new string[3] { "south", "downward", "direction" }), new EmojiItem("⬅", "Left Arrow", new string[3] { "west", "leftward", "direction" }), new EmojiItem("➡", "Right Arrow", new string[3] { "east", "rightward", "direction" }), new EmojiItem("↗", "Up-Right Arrow", new string[2] { "northeast", "direction" }), new EmojiItem("↘", "Down-Right Arrow", new string[2] { "southeast", "direction" }), new EmojiItem("↙", "Down-Left Arrow", new string[2] { "southwest", "direction" }), new EmojiItem("↖", "Up-Left Arrow", new string[2] { "northwest", "direction" }), new EmojiItem("↕", "Up-Down Arrow", new string[2] { "vertical", "direction" }), new EmojiItem("↔", "Left-Right Arrow", new string[2] { "horizontal", "direction" }), new EmojiItem("↩", "Return Arrow", new string[3] { "back", "undo", "left hook" }), new EmojiItem("↪", "Curve Arrow", new string[3] { "forward", "redo", "right hook" }), new EmojiItem("\ud83d\udd04", "Counter Clockwise", new string[3] { "refresh", "reload", "cycle" }), new EmojiItem("\ud83d\udd03", "Clockwise", new string[3] { "repeat", "loop", "sync" }), new EmojiItem("➕", "Plus", new string[3] { "add", "positive", "math" }), new EmojiItem("➖", "Minus", new string[3] { "subtract", "negative", "math" }), new EmojiItem("✖", "Multiply", new string[3] { "times", "x", "math" }), new EmojiItem("➗", "Divide", new string[2] { "division", "math" }), new EmojiItem("♾", "Infinity", new string[3] { "forever", "endless", "loop" }), new EmojiItem("\ud83d\udcb2", "Dollar", new string[3] { "price", "cost", "money" }), new EmojiItem("♻", "Recycle", new string[3] { "reuse", "green", "circle" }), new EmojiItem("⚜", "Fleur-de-lis", new string[3] { "heraldry", "lily", "french" }), new EmojiItem("\ud83d\udd31", "Trident", new string[3] { "poseidon", "fork", "spear" }), new EmojiItem("\ud83d\udd30", "Shield Symbol", new string[3] { "beginner", "leaf", "crest" }), new EmojiItem("❇", "Sparkle", new string[3] { "shine", "star", "clean" }), new EmojiItem("✳", "Eight-Spoke", new string[2] { "star", "asterisk" }), new EmojiItem("✴", "Eight-Point", new string[2] { "star", "burst" }), new EmojiItem("\ud83d\udca4", "Zzz", new string[3] { "sleep", "rest", "tired" }), new EmojiItem("\ud83d\udca2", "Anger Mark", new string[3] { "furious", "comic", "vein" }), new EmojiItem("\ud83d\udcac", "Speech Bubble", new string[3] { "talk", "chat", "message" }), new EmojiItem("\ud83d\udcad", "Thought Bubble", new string[3] { "think", "dream", "cloud" }), new EmojiItem("\ud83d\udcaf", "100 Points", new string[3] { "perfect", "score", "century" }), new EmojiItem("\ud83c\udfb2", "Game Die", new string[4] { "dice", "gamble", "random", "rpg" }), new EmojiItem("\ud83d\udd79", "Joystick", new string[3] { "gaming", "arcade", "controller" }), new EmojiItem("\ud83c\udfb5", "Musical Note", new string[3] { "song", "sound", "tune" }), new EmojiItem("\ud83c\udfb6", "Musical Notes", new string[3] { "music", "melody", "soundtrack" }), new EmojiItem("\ud83d\udce2", "Loudspeaker", new string[3] { "shout", "announce", "broadcast" }), new EmojiItem("\ud83d\udce3", "Megaphone", new string[3] { "cheer", "alert", "voice" }) }), new EmojiGroup("Hearts & Hands", new EmojiItem[59] { new EmojiItem("❤", "Red Heart", new string[4] { "love", "health", "life", "heart" }), new EmojiItem("\ud83e\udde1", "Orange Heart", new string[3] { "love", "orange", "warmth" }), new EmojiItem("\ud83d\udc9b", "Yellow Heart", new string[3] { "love", "friendship", "gold" }), new EmojiItem("\ud83d\udc9a", "Green Heart", new string[3] { "love", "nature", "green" }), new EmojiItem("\ud83d\udc99", "Blue Heart", new string[3] { "love", "loyalty", "ocean" }), new EmojiItem("\ud83d\udc9c", "Purple Heart", new string[3] { "love", "magic", "royalty" }), new EmojiItem("\ud83e\udd0e", "Brown Heart", new string[3] { "love", "earth", "wood" }), new EmojiItem("\ud83d\udda4", "Black Heart", new string[3] { "love", "dark", "sorrow" }), new EmojiItem("\ud83e\udd0d", "White Heart", new string[3] { "love", "pure", "peace" }), new EmojiItem("\ud83d\udc94", "Broken Heart", new string[3] { "heartbreak", "sad", "damage" }), new EmojiItem("❣", "Heart Exclamation", new string[3] { "emphasis", "love", "alert" }), new EmojiItem("\ud83d\udc95", "Two Hearts", new string[3] { "love", "sweet", "affection" }), new EmojiItem("\ud83d\udc9e", "Revolving Hearts", new string[3] { "love", "spinning", "motion" }), new EmojiItem("\ud83d\udc93", "Beating Heart", new string[3] { "pulse", "alive", "heartbeat" }), new EmojiItem("\ud83d\udc97", "Growing Heart", new string[3] { "expand", "love", "affection" }), new EmojiItem("\ud83d\udc96", "Sparkle Heart", new string[3] { "sparkling", "shine", "special" }), new EmojiItem("\ud83d\udc98", "Cupid Arrow", new string[3] { "love", "archer", "shot" }), new EmojiItem("\ud83d\udc9d", "Ribbon Heart", new string[3] { "gift", "present", "valentine" }), new EmojiItem("\ud83d\udc4d", "Thumbs Up", new string[5] { "yes", "good", "approve", "like", "agree" }), new EmojiItem("\ud83d\udc4e", "Thumbs Down", new string[4] { "no", "bad", "disapprove", "dislike" }), new EmojiItem("\ud83d\udc4c", "OK Hand", new string[3] { "perfect", "fine", "understood" }), new EmojiItem("✌", "Victory Hand", new string[3] { "peace", "two", "v sign" }), new EmojiItem("\ud83e\udd1e", "Crossed Fingers", new string[3] { "luck", "hope", "wish" }), new EmojiItem("\ud83e\udd1f", "Love-You Sign", new string[3] { "hand", "rock", "gesture" }), new EmojiItem("\ud83e\udd18", "Rock On", new string[3] { "horns", "metal", "heavy" }), new EmojiItem("\ud83e\udd19", "Call Me", new string[3] { "shaka", "hang loose", "hand" }), new EmojiItem("\ud83d\udc48", "Point Left", new string[3] { "hand", "direction", "west" }), new EmojiItem("\ud83d\udc49", "Point Right", new string[3] { "hand", "direction", "east" }), new EmojiItem("\ud83d\udc46", "Point Up", new string[3] { "hand", "direction", "north" }), new EmojiItem("\ud83d\udc47", "Point Down", new string[3] { "hand", "direction", "south" }), new EmojiItem("☝", "Index Point Up", new string[3] { "one", "first", "attention" }), new EmojiItem("✋", "Raised Hand", new string[3] { "stop", "high five", "palm" }), new EmojiItem("\ud83e\udd1a", "Back of Hand", new string[2] { "raised", "hand" }), new EmojiItem("\ud83d\udd90", "Splayed Hand", new string[3] { "five", "fingers", "palm" }), new EmojiItem("\ud83d\udd96", "Vulcan Salute", new string[3] { "spock", "prosper", "star trek" }), new EmojiItem("\ud83d\udc4b", "Waving Hand", new string[3] { "hello", "goodbye", "wave" }), new EmojiItem("\ud83d\udc4f", "Clapping", new string[3] { "applause", "bravo", "good job" }), new EmojiItem("\ud83d\ude4c", "Raising Hands", new string[3] { "celebrate", "praise", "cheer" }), new EmojiItem("\ud83d\udc50", "Open Hands", new string[3] { "hug", "receptive", "hands" }), new EmojiItem("\ud83e\udd32", "Palms Together", new string[3] { "prayer", "offering", "cupped" }), new EmojiItem("\ud83e\udd1d", "Handshake", new string[3] { "deal", "agreement", "partner" }), new EmojiItem("\ud83d\ude4f", "Folded Hands", new string[4] { "pray", "thank you", "please", "namaste" }), new EmojiItem("✍", "Writing Hand", new string[4] { "author", "pen", "sign", "scribe" }), new EmojiItem("\ud83d\udcaa", "Flexed Bicep", new string[4] { "strong", "power", "muscle", "workout" }), new EmojiItem("\ud83e\uddbe", "Mech Arm", new string[3] { "bionic", "robot", "prosthetic" }), new EmojiItem("\ud83e\uddbf", "Mech Leg", new string[3] { "bionic", "robot", "prosthetic" }), new EmojiItem("\ud83e\uddb5", "Leg", new string[3] { "limb", "kick", "foot" }), new EmojiItem("\ud83e\uddb6", "Foot", new string[3] { "step", "walk", "tracks" }), new EmojiItem("\ud83d\udc42", "Ear", new string[3] { "hear", "listen", "sound" }), new EmojiItem("\ud83d\udc43", "Nose", new string[3] { "smell", "scent", "sniff" }), new EmojiItem("\ud83e\udde0", "Brain", new string[3] { "smart", "intellect", "mind" }), new EmojiItem("\ud83e\udec0", "Anatomical Heart", new string[3] { "organ", "cardio", "pulse" }), new EmojiItem("\ud83e\udec1", "Lungs", new string[3] { "breath", "stamina", "air" }), new EmojiItem("\ud83e\uddb7", "Tooth", new string[3] { "dentist", "bite", "teeth" }), new EmojiItem("\ud83e\uddb4", "Bone", new string[3] { "remains", "skeleton", "crafting" }), new EmojiItem("\ud83d\udc40", "Eyes", new string[4] { "look", "see", "watch", "stare" }), new EmojiItem("\ud83d\udc41", "Single Eye", new string[4] { "odin", "vision", "gaze", "all-seeing" }), new EmojiItem("\ud83d\udc45", "Tongue", new string[3] { "taste", "lick", "mouth" }), new EmojiItem("\ud83d\udc44", "Lips", new string[3] { "mouth", "kiss", "speech" }) }) }; public const string PluginGuid = "com.jubaroo.signscribe"; public const string PluginName = "SignScribe"; public const string PluginVersion = "1.0.0"; internal const int SavedColorSlots = 5; internal const int UndoHistoryLimit = 50; internal static SignScribePlugin Instance = null; internal static ManualLogSource Log = null; private Harmony? _harmony; private ConfigEntry<KeyboardShortcut> _toggleKey; private ConfigEntry<int> _characterLimitConfig; private ConfigEntry<bool> _debugLoggingConfig; private ConfigEntry<float> _opacityConfig; private static ConfigEntry<string> _savedColorsConfig = null; private ConfigEntry<float> _windowPosXConfig; private ConfigEntry<float> _windowPosYConfig; private ConfigEntry<float> _scrollSensitivityConfig; private bool _isSignPrompt; private bool _wasOpen; private TMP_InputField? _activeField; private bool _showHud = true; internal static string DefaultHint = ""; internal static readonly List<string> UndoStack = new List<string>(); internal static readonly List<string> RedoStack = new List<string>(); internal const string ShorthandColorPattern = "<#[0-9a-fA-F]{3,8}>"; internal static readonly Regex ColorTagRegex = new Regex("</?color(=[^>]+)?>|<#[0-9a-fA-F]{3,8}>", RegexOptions.IgnoreCase | RegexOptions.Compiled); internal static readonly Regex AnyTagRegex = new Regex("<[^>]+>", RegexOptions.Compiled); internal static readonly Regex SpriteTagRegex = new Regex("<sprite[^>]*>", RegexOptions.Compiled); internal static readonly Regex SizeTagRegex = new Regex("</?size(=[^>]*)?>", RegexOptions.IgnoreCase | RegexOptions.Compiled); internal static readonly Regex ShorthandColorRegex = new Regex("<(#[0-9a-fA-F]{3,8})>", RegexOptions.Compiled); internal static readonly Regex SizeTagNumericRegex = new Regex("<size=([0-9]+)(px)?>", RegexOptions.IgnoreCase | RegexOptions.Compiled); internal static string[]? SignSpriteLabels; internal static string[]? SignSpriteTags; private static MethodInfo? _stringToCaretMethod; private static bool _stringToCaretResolved; internal static string StatusMessage = ""; internal static float StatusUntil = 0f; internal static int LastSelectionStart = -1; internal static int LastSelectionEnd = -1; private static readonly Dictionary<string, string> KnownHexSpriteNames = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { ["263a"] = "Smile", ["2639"] = "Frown", ["1f600"] = "Grinning", ["1f601"] = "Beaming", ["1f602"] = "Tears of Joy", ["1f603"] = "Grinning Eyes", ["1f604"] = "Smiling Eyes", ["1f605"] = "Sweat Grin", ["1f606"] = "Laughing Squint", ["1f607"] = "Angel Halo", ["1f609"] = "Wink", ["1f60a"] = "Warm Smile", ["1f60b"] = "Yummy", ["1f60c"] = "Relieved", ["1f60d"] = "Heart Eyes", ["1f60e"] = "Sunglasses", ["1f60f"] = "Smirking", ["1f618"] = "Blowing Kiss", ["1f642"] = "Slight Smile", ["1f643"] = "Upside Down", ["1f923"] = "ROFL" }; internal static int SignCharacterLimit { get { if (!((Object)(object)Instance != (Object)null)) { return 999; } return Instance._characterLimitConfig.Value; } } internal static bool IsDebugEnabled { get { if ((Object)(object)Instance != (Object)null && Instance._debugLoggingConfig != null) { return Instance._debugLoggingConfig.Value; } return false; } } internal ConfigEntry<float> OpacityConfig => _opacityConfig; internal ConfigEntry<float> PosXConfig => _windowPosXConfig; internal ConfigEntry<float> PosYConfig => _windowPosYConfig; internal ConfigEntry<float> ScrollSensitivityConfig => _scrollSensitivityConfig; internal static void LoadSavedColors() { string[] array = (_savedColorsConfig?.Value ?? "").Split(new char[1] { ',' }); Color val = default(Color); for (int i = 0; i < 5 && i < array.Length; i++) { string text = array[i].Trim(); if (text.Length > 0 && ColorUtility.TryParseHtmlString(text, ref val)) { SetSavedColor(i, text, saveConfig: false); } } } internal static void SetSavedColor(int slot, string hex, bool saveConfig = true) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (slot >= 0 && slot < 5) { Color val = default(Color); ColorUtility.TryParseHtmlString(hex, ref val); SavedColors[slot] = hex; SavedColorValues[slot] = val; if (saveConfig && (Object)(object)Instance != (Object)null) { Instance.SaveSettings(); } } } internal static void ClearSavedColors() { Array.Clear(SavedColors, 0, SavedColors.Length); Array.Clear(SavedColorValues, 0, SavedColorValues.Length); Instance?.SaveSettings(); } internal static void DebugLog(string message) { if (IsDebugEnabled) { ManualLogSource log = Log; if (log != null) { log.LogInfo((object)message); } } } private void Awake() { //IL_002c: 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_0076: Expected O, but got Unknown //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown //IL_01b3: 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_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; _toggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ToggleKey", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Key that shows/hides the SignScribe window while editing a sign."); _characterLimitConfig = ((BaseUnityPlugin)this).Config.Bind<int>("General", "SignCharacterLimit", 999, new ConfigDescription("Maximum character limit for signs. Vanilla Valheim default is 50. SignScribe expands this to 999 so rich text tags fit comfortably.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(50, 2000), Array.Empty<object>())); _debugLoggingConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DebugLogging", false, "Enable verbose diagnostic logging in the console and log file for troubleshooting sign formatting and UI operations."); _opacityConfig = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "WindowOpacity", 0.95f, new ConfigDescription("Opacity of the SignScribe window.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 1f), Array.Empty<object>())); _savedColorsConfig = ((BaseUnityPlugin)this).Config.Bind<string>("UI", "SavedColors", "", "Saved custom colors (comma-separated hex, managed by the in-game UI)."); _windowPosXConfig = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "WindowPositionX", 0f, "Saved horizontal position of the studio window (anchored top-center)."); _windowPosYConfig = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "WindowPositionY", -20f, "Saved vertical position of the studio window (anchored top-center)."); _scrollSensitivityConfig = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "ScrollSensitivity", 80f, new ConfigDescription("Scroll sensitivity for the icon palette in SignScribe Studio.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 300f), Array.Empty<object>())); _scrollSensitivityConfig.SettingChanged += delegate { StudioBuilder.UpdateScrollSensitivity(_scrollSensitivityConfig.Value); }; Vector2 sanitizedWindowPosition = GetSanitizedWindowPosition(_windowPosXConfig.Value, _windowPosYConfig.Value); if (!Mathf.Approximately(_windowPosXConfig.Value, sanitizedWindowPosition.x) || !Mathf.Approximately(_windowPosYConfig.Value, sanitizedWindowPosition.y)) { Log.LogInfo((object)$"Migrating studio window position from ({_windowPosXConfig.Value}, {_windowPosYConfig.Value}) to ({sanitizedWindowPosition.x}, {sanitizedWindowPosition.y})"); _windowPosXConfig.Value = sanitizedWindowPosition.x; _windowPosYConfig.Value = sanitizedWindowPosition.y; ((BaseUnityPlugin)this).Config.Save(); } DefaultHint = BuildDefaultHint(); _toggleKey.SettingChanged += delegate { DefaultHint = BuildDefaultHint(); }; LoadSavedColors(); _harmony = new Harmony("com.jubaroo.signscribe"); _harmony.PatchAll(typeof(RequestTextPatch).Assembly); List<MethodBase> list = _harmony.GetPatchedMethods().ToList(); Log.LogInfo((object)string.Format("{0} v{1} loaded! Hooked {2} methods. Jotunn native UI ready.", "SignScribe", "1.0.0", list.Count)); foreach (MethodBase item in list) { Log.LogDebug((object)(" Hooked: " + item.DeclaringType?.Name + "." + item.Name)); } } private void OnDestroy() { SaveSettings(); Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } private void Update() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = _toggleKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { _showHud = !_showHud; StudioBuilder.ToggleStudio(); } if ((Object)(object)_activeField != (Object)null && _activeField.isFocused) { int length = _activeField.text.Length; int num = Mathf.Clamp(_activeField.selectionStringAnchorPosition, 0, length); int num2 = Mathf.Clamp(_activeField.selectionStringFocusPosition, 0, length); LastSelectionStart = Mathf.Min(num, num2); LastSelectionEnd = Mathf.Max(num, num2); } bool flag = (Object)(object)TextInput.instance != (Object)null && (((Object)(object)TextInput.instance.m_panel != (Object)null && TextInput.instance.m_panel.activeInHierarchy) || TextInput.IsVisible()); bool flag2 = _isSignPrompt && flag; if (_wasOpen && !flag2) { OnPromptClosed(); } _wasOpen = flag2; if (flag2 && (Object)(object)_activeField != (Object)null) { bool flag3 = Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305); bool flag4 = Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303); if (flag3 && Input.GetKeyDown((KeyCode)122)) { if (flag4) { RedoNext(_activeField); } else { UndoLast(_activeField); } } else if (flag3 && Input.GetKeyDown((KeyCode)121)) { RedoNext(_activeField); } else if (flag3 && Input.GetKeyDown((KeyCode)98)) { WrapGenericTag(_activeField, "<b>", "</b>"); } else if (flag3 && Input.GetKeyDown((KeyCode)105)) { WrapGenericTag(_activeField, "<i>", "</i>"); } else if (flag3 && Input.GetKeyDown((KeyCode)117)) { WrapGenericTag(_activeField, "<u>", "</u>"); } } if (flag2 && StudioBuilder.IsVisible()) { StudioBuilder.UpdatePreview(); StudioBuilder.UpdateStatusText(); } } private string BuildDefaultHint() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) return $"{_toggleKey.Value} toggle · drag to move · Ctrl+Z/Y undo/redo · Ctrl+B/I/U tags"; } internal void OnPromptOpened(bool isSign) { _isSignPrompt = isSign; UndoStack.Clear(); RedoStack.Clear(); _activeField = null; if (!isSign || (Object)(object)TextInput.instance == (Object)null) { StudioBuilder.CloseStudio(); return; } _activeField = ((Component)TextInput.instance).gameObject.GetComponentInChildren<TMP_InputField>(true); if ((Object)(object)_activeField == (Object)null) { Log.LogWarning((object)"SignScribe: TMP_InputField could not be found under TextInput.instance."); return; } if (_activeField.characterLimit < SignCharacterLimit) { _activeField.characterLimit = SignCharacterLimit; } _activeField.onFocusSelectAll = false; int num = _activeField.text?.Length ?? 0; _activeField.selectionStringAnchorPosition = num; _activeField.selectionStringFocusPosition = num; _activeField.caretPosition = num; LastSelectionStart = num; LastSelectionEnd = num; if (_showHud && (Object)(object)_activeField != (Object)null) { StudioBuilder.OpenStudio(_activeField); _wasOpen = true; } } internal void OnPromptClosed() { _isSignPrompt = false; _activeField = null; LastSelectionStart = -1; LastSelectionEnd = -1; StudioBuilder.CloseStudio(); UndoStack.Clear(); SaveSettings(); } internal void SaveSettings() { if (_savedColorsConfig != null) { _savedColorsConfig.Value = string.Join(",", SavedColors); ((BaseUnityPlugin)this).Config.Save(); } } internal static Vector2 GetSanitizedWindowPosition(float x, float y) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (y > 0f || y < -2500f) { y = -20f; } if (Mathf.Abs(x) > 2500f) { x = 0f; } return new Vector2(x, y); } internal void SaveWindowPosition(float x, float y) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) Vector2 sanitizedWindowPosition = GetSanitizedWindowPosition(x, y); if (_windowPosXConfig != null && _windowPosYConfig != null) { _windowPosXConfig.Value = sanitizedWindowPosition.x; _windowPosYConfig.Value = sanitizedWindowPosition.y; ((BaseUnityPlugin)this).Config.Save(); } } internal static string GetPreview(string source) { if (string.IsNullOrEmpty(source)) { return ""; } string input = ShorthandColorRegex.Replace(source, "<color=$1>"); string text = SizeTagNumericRegex.Replace(input, delegate(Match match) { if (int.TryParse(match.Groups[1].Value, out var result)) { int num = Mathf.Clamp(Mathf.RoundToInt((float)result * 2.2f), 8, 30); return $"<size={num}>"; } return match.Value; }); if (source.IndexOf("<size", StringComparison.OrdinalIgnoreCase) >= 0 || source.IndexOf("<sprite", StringComparison.OrdinalIgnoreCase) >= 0) { DebugLog("[GetPreview] Source='" + source + "' -> Rendered Preview='" + text + "'"); } return text; } internal static void SetStatus(string message) { StatusMessage = message; StatusUntil = Time.realtimeSinceStartup + 2.5f; StudioBuilder.SetStatus(message); } internal static void GetSelection(TMP_InputField f, out int start, out int end) { int length = f.text.Length; if (LastSelectionStart >= 0 && LastSelectionEnd >= LastSelectionStart && LastSelectionStart != LastSelectionEnd) { start = Mathf.Clamp(LastSelectionStart, 0, length); end = Mathf.Clamp(LastSelectionEnd, 0, length); DebugLog($"[GetSelection] Using LastSelection: [{start}..{end}] of total length {length}"); return; } int num = Mathf.Clamp(f.selectionStringAnchorPosition, 0, length); int num2 = Mathf.Clamp(f.selectionStringFocusPosition, 0, length); start = Mathf.Min(num, num2); end = Mathf.Max(num, num2); DebugLog($"[GetSelection] Using selectionString: anchor={num}, focus={num2} -> [{start}..{end}] of total length {length} (LastSel: {LastSelectionStart}..{LastSelectionEnd})"); } internal static bool TryReplace(TMP_InputField f, int start, int end, string replacement, int caretOffset) { string text = f.text; DebugLog($"[TryReplace] Current text='{text}' (len={text.Length}), replace range [{start}..{end}], replacement='{replacement}', caretOffset={caretOffset}"); string text2 = text.Remove(start, end - start).Insert(start, replacement); if (text2 == text) { DebugLog("[TryReplace] Result identical to current ('" + text + "'). No-op returning true."); return true; } if (f.characterLimit > 0 && text2.Length > f.characterLimit) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)$"[TryReplace] Character limit reached! New length={text2.Length} exceeds limit={f.characterLimit}"); } SetStatus($"Sign limit reached ({f.characterLimit} chars)"); return false; } UndoStack.Add(text); if (UndoStack.Count > 50) { UndoStack.RemoveAt(0); } RedoStack.Clear(); f.text = text2; DebugLog($"[TryReplace] Assigned f.text='{f.text}' (actual length={f.text.Length})"); int num = start + caretOffset; LastSelectionStart = (LastSelectionEnd = num); FocusAndPlaceCaret(f, num); return true; } internal static void UndoLast(TMP_InputField f) { if (UndoStack.Count == 0) { SetStatus("Nothing to undo"); return; } RedoStack.Add(f.text ?? ""); string text = UndoStack[UndoStack.Count - 1]; UndoStack.RemoveAt(UndoStack.Count - 1); f.text = text; LastSelectionStart = (LastSelectionEnd = text.Length); FocusAndPlaceCaret(f, text.Length); SetStatus("Undid last action (Ctrl+Y to redo)"); } internal static void RedoNext(TMP_InputField f) { if (RedoStack.Count == 0) { SetStatus("Nothing to redo"); return; } UndoStack.Add(f.text ?? ""); string text = RedoStack[RedoStack.Count - 1]; RedoStack.RemoveAt(RedoStack.Count - 1); f.text = text; LastSelectionStart = (LastSelectionEnd = text.Length); FocusAndPlaceCaret(f, text.Length); SetStatus("Redid action (Ctrl+Z to undo)"); } internal static void InsertText(TMP_InputField f, string textToInsert) { GetSelection(f, out var start, out var end); if (start == 0 && end == f.text.Length && f.text.Length > 0) { start = end; } if (start == end) { Match match = Regex.Match(f.text.Substring(0, start), "(</(size|color|b|i|u|s|uppercase|lowercase|smallcaps|align|mark|sub|sup)>)+$", RegexOptions.IgnoreCase); if (match.Success) { start -= match.Length; end -= match.Length; } } TryReplace(f, start, end, textToInsert, textToInsert.Length); } internal static void WrapGenericTag(TMP_InputField f, string openTag, string closeTag) { GetSelection(f, out var start, out var end); if (start != end) { string text = openTag + f.text.Substring(start, end - start) + closeTag; TryReplace(f, start, end, text, text.Length); } else { TryReplace(f, start, end, openTag + closeTag, openTag.Length); } SetStatus("Applied " + openTag + " tag"); } internal static void ApplySize(TMP_InputField f, int size) { string text = $"<size={size}>"; string text2 = f.text ?? ""; DebugLog($"[ApplySize] Called with size={size}, openTag='{text}', current f.text='{text2}' (len={text2.Length})"); GetSelection(f, out var start, out var end); int num = start; bool flag = false; if (start == end) { if (text2.Length <= 0) { DebugLog("[ApplySize] Empty text, inserting empty tags: '" + text + "</size>'"); TryReplace(f, start, end, text + "</size>", text.Length); return; } start = 0; end = text2.Length; flag = true; DebugLog($"[ApplySize] No selection (start==end), defaulting to global apply: [0..{text2.Length}]"); } string text3 = text2.Substring(start, end - start); string text4 = SizeTagRegex.Replace(text3, ""); DebugLog($"[ApplySize] Selected range [{start}..{end}]: raw='{text3}', after SizeTagRegex strip='{text4}'"); int num2 = text2.Substring(0, start).LastIndexOf("<size=", StringComparison.OrdinalIgnoreCase); int num3 = text2.IndexOf("</size>", end, StringComparison.OrdinalIgnoreCase); DebugLog($"[ApplySize] Enclosing search: prevOpen={num2}, nextClose={num3}"); if (num2 != -1 && num3 != -1) { int num4 = text2.IndexOf('>', num2); if (num4 != -1 && num4 < start) { string text5 = text2.Substring(num4 + 1, start - (num4 + 1)); string text6 = text2.Substring(end, num3 - end); DebugLog($"[ApplySize] Found surrounding size tag: prevOpenEnd={num4}, lead='{text5}', trail='{text6}'"); if (string.IsNullOrWhiteSpace(text5) && string.IsNullOrWhiteSpace(text6)) { string text7 = text + text5 + text4 + text6 + "</size>"; int num5 = (flag ? (num + text.Length) : (num2 + text7.Length)); DebugLog(string.Format("[ApplySize] Modifying surrounding size tag block: [{0}..{1}], block='{2}'", num2, num3 + "</size>".Length, text7)); TryReplace(f, num2, num3 + "</size>".Length, text7, num5 - num2); return; } } } string text8 = text + text4 + "</size>"; int num6 = (flag ? (num + text.Length) : (start + text8.Length)); DebugLog($"[ApplySize] Standard replacement: range [{start}..{end}], newSegment='{text8}'"); TryReplace(f, start, end, text8, num6 - start); } internal static void ApplyColor(TMP_InputField f, string colorCode) { string text = "<color=" + colorCode + ">"; GetSelection(f, out var start, out var end); int num = start; bool flag = false; if (start == end) { if (f.text.Length <= 0) { TryReplace(f, start, end, text + "</color>", text.Length); return; } start = 0; end = f.text.Length; flag = true; } string text2 = f.text; string text3 = ColorTagRegex.Replace(text2.Substring(start, end - start), ""); int num2 = text2.Substring(0, start).LastIndexOf("<color=", StringComparison.OrdinalIgnoreCase); int num3 = text2.IndexOf("</color>", end, StringComparison.OrdinalIgnoreCase); if (num2 != -1 && num3 != -1) { int num4 = text2.IndexOf('>', num2); if (num4 != -1 && num4 < start) { string text4 = text2.Substring(num4 + 1, start - (num4 + 1)); string text5 = text2.Substring(end, num3 - end); if (string.IsNullOrWhiteSpace(text4) && string.IsNullOrWhiteSpace(text5)) { string text6 = text + text4 + text3 + text5 + "</color>"; int num5 = (flag ? (num + text.Length) : (num2 + text6.Length)); TryReplace(f, num2, num3 + "</color>".Length, text6, num5 - num2); return; } } } string text7 = text + text3 + "</color>"; int num6 = (flag ? (num + text.Length) : (start + text7.Length)); TryReplace(f, start, end, text7, num6 - start); } internal static void RegexClean(TMP_InputField f, Regex regex) { GetSelection(f, out var start, out var end); string text = f.text; if (start != end) { string text2 = regex.Replace(text.Substring(start, end - start), ""); TryReplace(f, start, end, text2, text2.Length); } else { string text3 = regex.Replace(text, ""); TryReplace(f, 0, text.Length, text3, Mathf.Min(start, text3.Length)); } SetStatus("Cleaned formatting tags (Ctrl+Z to undo)"); } internal static void ClearAll(TMP_InputField f) { if (!string.IsNullOrEmpty(f.text)) { TryReplace(f, 0, f.text.Length, "", 0); SetStatus("Cleared sign text (Ctrl+Z to undo)"); } } internal static void FocusAndPlaceCaret(TMP_InputField inputField, int caretPos) { inputField.onFocusSelectAll = false; inputField.ActivateInputField(); int num = Mathf.Clamp(caretPos, 0, inputField.text.Length); int num2 = StringToCaretIndex(inputField, num); inputField.selectionStringAnchorPosition = num; inputField.selectionStringFocusPosition = num; inputField.selectionAnchorPosition = num2; inputField.selectionFocusPosition = num2; inputField.caretPosition = num2; LastSelectionStart = num; LastSelectionEnd = num; } private static int StringToCaretIndex(TMP_InputField inputField, int stringIndex) { if (!_stringToCaretResolved) { _stringToCaretMethod = typeof(TMP_InputField).GetMethod("GetCaretPositionFromStringIndex", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); _stringToCaretResolved = true; } if (_stringToCaretMethod != null) { return (int)_stringToCaretMethod.Invoke(inputField, new object[1] { stringIndex }); } return stringIndex; } private static bool IsHexCode(string s) { if (string.IsNullOrEmpty(s) || s.Length < 4 || s.Length > 6) { return false; } if (!s.All((char c) => (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) { return false; } try { int num = Convert.ToInt32(s, 16); return (num >= 8192 && num <= 13311) || (num >= 126976 && num <= 131071) || (num >= 65024 && num <= 65039); } catch { return false; } } private static string? TryGetEmojiNameFromHex(string hex) { if (KnownHexSpriteNames.TryGetValue(hex, out string value)) { return value; } try { string text = char.ConvertFromUtf32(Convert.ToInt32(hex, 16)); EmojiGroup[] emojiCatalog = EmojiCatalog; for (int i = 0; i < emojiCatalog.Length; i++) { EmojiItem[] items = emojiCatalog[i].Items; for (int j = 0; j < items.Length; j++) { EmojiItem emojiItem = items[j]; if (emojiItem.Glyph.Equals(text, StringComparison.Ordinal) || emojiItem.Glyph.StartsWith(text, StringComparison.Ordinal) || text.StartsWith(emojiItem.Glyph, StringComparison.Ordinal)) { return emojiItem.Name; } } } } catch { } return null; } internal static void BuildSpriteCache(TMP_InputField inputField) { if (SignSpriteLabels != null) { return; } TMP_SpriteAsset val = (((Object)(object)inputField.textComponent != (Object)null) ? inputField.textComponent.spriteAsset : null); if ((Object)(object)val == (Object)null && (Object)(object)TMP_Settings.instance != (Object)null) { val = TMP_Settings.defaultSpriteAsset; } if ((Object)(object)val == (Object)null) { return; } List<string> labelsList = new List<string>(); List<string> tagsList = new List<string>(); if (val.spriteCharacterTable != null && val.spriteCharacterTable.Count > 0) { for (int i = 0; i < val.spriteCharacterTable.Count; i++) { ProcessSprite(val.spriteCharacterTable[i].name, i, isTable: true); } } else if (val.spriteInfoList != null && val.spriteInfoList.Count > 0) { for (int j = 0; j < val.spriteInfoList.Count; j++) { ProcessSprite(val.spriteInfoList[j].name, j, isTable: false); } } SignSpriteLabels = labelsList.ToArray(); SignSpriteTags = tagsList.ToArray(); void ProcessSprite(string name, int index, bool isTable) { string text = name; if (string.IsNullOrEmpty(name) || name == ".notdef") { text = $"Sprite {index}"; } else if (IsHexCode(name)) { text = TryGetEmojiNameFromHex(name) ?? ("U+" + name.ToUpper()); } else if (name.All(char.IsDigit)) { text = "Sprite " + name; } else { text = text.Replace("Keyboard_", "KB ").Replace("Gamepad_", "GP ").Replace("Mouse_", "Mouse ") .Replace("_", " "); if (text.Length > 1) { text = char.ToUpper(text[0]) + text.Substring(1); } } string item = (isTable ? ("<sprite name=\"" + name + "\">") : $"<sprite={index}>"); labelsList.Add(text); tagsList.Add(item); } } } } namespace SignScribe.UI { public class StudioEscapeHandler : MonoBehaviour { private void Update() { if (Input.GetKeyDown((KeyCode)27)) { StudioBuilder.CloseStudio(); } } } public static class StudioBuilder { private struct SpriteButtonItem { public GameObject ButtonObj; public string Tag; public string Label; public SpriteButtonItem(GameObject buttonObj, string tag, string label) { ButtonObj = buttonObj; Tag = tag; Label = label; } } [CompilerGenerated] private static class <>O { public static UnityAction <0>__CloseStudio; public static UnityAction<string> <1>__OnHexInputChanged; public static UnityAction <2>__ClearSavedColors; public static UnityAction<float> <3>__OnSizeSliderChanged; public static UnityAction<string> <4>__OnIconSearchChanged; public static UnityAction<string> <5>__OnSpriteSearchChanged; public static UnityAction<float> <6>__OnOpacityChanged; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__54_0; public static UnityAction<float> <>9__56_0; public static UnityAction<float> <>9__56_1; public static UnityAction<float> <>9__56_2; public static UnityAction <>9__56_3; public static UnityAction <>9__62_0; public static UnityAction <>9__62_1; public static UnityAction <>9__62_2; public static UnityAction <>9__62_3; public static UnityAction <>9__62_4; public static UnityAction <>9__62_5; public static UnityAction <>9__62_6; public static UnityAction <>9__62_7; public static UnityAction <>9__62_8; public static UnityAction <>9__62_9; public static UnityAction <>9__62_10; public static UnityAction <>9__62_11; public static UnityAction <>9__64_0; public static UnityAction <>9__64_1; public static UnityAction <>9__64_2; public static UnityAction <>9__68_0; public static UnityAction <>9__71_0; public static UnityAction <>9__71_1; public static UnityAction <>9__71_2; public static UnityAction <>9__71_3; public static UnityAction <>9__71_4; public static UnityAction <>9__71_5; public static UnityAction <>9__71_6; public static UnityAction <>9__71_7; public static UnityAction <>9__71_8; public static UnityAction <>9__71_9; public static UnityAction <>9__71_10; public static UnityAction <>9__71_11; public static UnityAction <>9__71_12; public static UnityAction <>9__71_13; public static UnityAction <>9__71_14; public static UnityAction <>9__71_15; public static UnityAction <>9__71_16; internal void <BuildStudio>b__54_0() { if ((Object)(object)_activeField != (Object)null) { SignScribePlugin.UndoLast(_activeField); } } internal void <BuildColorsTab>b__56_0(float _) { OnMixerSliderChanged(); } internal void <BuildColorsTab>b__56_1(float _) { OnMixerSliderChanged(); } internal void <BuildColorsTab>b__56_2(float _) { OnMixerSliderChanged(); } internal void <BuildColorsTab>b__56_3() { if ((Object)(object)_activeField != (Object)null) { SignScribePlugin.ApplyColor(_activeField, _currentMixedHex); } } internal void <BuildStylesTab>b__62_0() { if ((Object)(object)_activeField != (Object)null) { SignScribePlugin.WrapGenericTag(_activeField, "<b>", "</b>"); } } internal void <BuildStylesTab>b__62_1() { if ((Object)(object)_activeField != (Object)null) { SignScribePlugin.WrapGenericTag(_activeField, "<i>", "</i>"); } } internal void <BuildStylesTab>b__62_2() { if ((Object)(object)_activeField != (Object)null) { SignScribePlugin.WrapGenericTag(_activeField, "<u>", "</u>"); } } internal void <BuildStylesTab>b__62_3() { if ((Object)(object)_activeField != (Object)null) { SignScribePlugin.WrapGenericTag(_activeField, "<s>", "</s>"); } } internal void <BuildStylesTab>b__62_4() { if ((Object)(object)_activeField != (Object)null) { SignScribePlugin.WrapGenericTag(_activeField, "<uppercase>", "</uppercase>"); } } internal void <BuildStylesTab>b__62_5() { if ((Object)(object)_activeField != (Object)null) { SignScribePlugin.WrapGenericTag(_activeField, "<lowercase>", "</lowercase>"); } } internal void <BuildStylesTab>b__62_6() { if ((Object)(object)_activeField != (Object)null) { SignScribePlugin.WrapGenericTag(_activeField, "<smallcaps>", "</smallcaps>"); } } internal void <BuildStylesTab>b__62_7() { if ((Object)(object)_activeField != (Object)null) { SignScribePlugin.WrapGenericTag(_activeField, "<align=\"left\">", "</align>"); } } internal void <BuildStylesTab>b__62_8() { if ((Object)(object)_activeField != (Object)null) { SignScribePlugin.WrapGenericTag(_activeField, "<align=\"center\">", "</align>"); } } internal void <BuildStylesTab>b__62_9() { if ((Object)(object)_activeField != (Object)null) { SignScribePlugin.WrapGenericTag(_activeField, "<align=\"right\">", "</align>"); } } internal void <BuildStylesTab>b__62_10() { object[] array = new object[5]; Slider? sliderSize = _sliderSize; array[0] = ((sliderSize != null) ? new float?(sliderSize.value) : ((float?)null)); array[1] = (((Object)(object)_activeField != (Object)null) ? "Valid" : "NULL"); TMP_InputField? activeField = _activeField; array[2] = ((activeField != null) ? activeField.text : null); array[3] = SignScribePlugin.LastSelectionStart; array[4] = SignScribePlugin.LastSelectionEnd; SignScribePlugin.DebugLog(string.Format("[StudioBuilder ApplySize Click] Slider={0}, ActiveField={1}, ActiveFieldText='{2}', SelStart={3}, SelEnd={4}", array)); if ((Object)(object)_activeField != (Object)null && (Object)(object)_sliderSize != (Object)null) { int num = Mathf.RoundToInt(_sliderSize.value); SignScribePlugin.DebugLog($"[StudioBuilder ApplySize Click] Applying absolute size {num}"); SignScribePlugin.ApplySize(_activeField, num); SignScribePlugin.DebugLog("[StudioBuilder ApplySize Click] After ApplySize: ActiveFieldText='" + _activeField.text + "'"); } else { ManualLogSource log = SignScribePlugin.Log; if (log != null) { log.LogWarning((object)("[StudioBuilder ApplySize Click] FAILED: _activeField=" + (((Object)(object)_activeField != (Object)null) ? "Valid" : "NULL") + ", _sliderSize=" + (((Object)(object)_sliderSize != (Object)null) ? "Valid" : "NULL"))); } } } internal void <BuildStylesTab>b__62_11() { string[] obj = new string[5] { "[StudioBuilder DefaultSize Click] ActiveField=", ((Object)(object)_activeField != (Object)null) ? "Valid" : "NULL", ", ActiveFieldText='", null, null }; TMP_InputField? activeField = _activeField; obj[3] = ((activeField != null) ? activeField.text : null); obj[4] = "'"; SignScribePlugin.DebugLog(string.Concat(obj)); if ((Object)(object)_sliderSize != (Object)null) { _sliderSize.value = 6f; } if ((Object)(object)_activeField != (Object)null) { SignScribePlugin.ApplySize(_activeField, 6); SignScribePlugin.DebugLog("[StudioBuilder DefaultSize Click] After ApplySize: ActiveFieldText='" + _activeField.text + "'"); } } internal void <BuildIconsTab>b__64_0() { if ((Object)(object)_activeField != (Object)null && (Object)(object)_customEmojiInput != (Object)null && !string.IsNullOrEmpty(_customEmojiInput.text)) { SignScribePlugin.InsertText(_activeField, _customEmojiInput.text); } } internal void <BuildIconsTab>b__64_1() { Application.OpenURL("https://emojipedia.org/"); } internal void <BuildIconsTab>b__64_2() { } internal void <BuildSpritesTab>b__68_0() { } internal void <BuildToolsTab>b__71_0() { if ((Object)(object)_activeField != (Object)null) { SignScribePlugin.WrapGenericTag(_activeField, "<sub>", "</sub>"); } } internal void <BuildToolsTab>b__71_1() { if ((Object)(object)_activeField != (Object)null) { SignScribePlugin.WrapGenericTag(_activeField, "<sup>", "</sup>"); } } internal void <BuildToolsTab>b__71_2() { if ((Object)(object)_activeField != (Object)null) { SignScribePlugin.WrapGenericTag(_activeField, "<mark=#FFFF0088>", "</mark>"); } } internal void <BuildToolsTab>b__71_3() { if ((Object)(object)_activeField != (Object)null) { SignScribePlugin.WrapGenericTag(_activeField, "<mark=#000000AA>", "</mark>"); } } internal void <BuildToolsTab>b__71_4() { if ((Object)(object)_activeField != (Object)null) { SignScribePlugin.InsertText(_activeField, "<br>"); } } internal void <BuildToolsTab>b__71_5() { if ((Object)(object)_activeField != (Object)null) { SignScribePlugin.WrapGenericTag(_activeField, "<noparse>", "</noparse>"); } } internal void <BuildToolsTab>b__71_6() { if ((Object)(object)_activeField != (Object)null) { SignScribePlugin.RegexClean(_activeField, SignScribePlugin.ColorTagRegex); } } internal void <BuildToolsTab>b__71_7() { if ((Object)(object)_activeField != (Object)null) { SignScribePlugin.RegexClean(_activeField, SignScribePlugin.AnyTagRegex); } } internal void <BuildToolsTab>b__71_8() { if ((Object)(object)_activeField != (Object)null) { SignScribePlugin.ClearAll(_activeField); } } internal void <BuildToolsTab>b__71_9() { InsertPreset("<color=#FF6B6B><b>⚔\ufe0f Weapons</b></color>"); } internal void <BuildToolsTab>b__71_10() { InsertPreset("<color=#4D96FF><b>\ud83d\udee1\ufe0f Armor</b></color>"); } internal void <BuildToolsTab>b__71_11() { InsertPreset("<color=#D4A373><b>\ud83c\udf32 Materials</b></color>"); } internal void <BuildToolsTab>b__71_12() { InsertPreset("<color=#FFD93D><b>\ud83e\udd69 Food</b></color>"); } internal void <BuildToolsTab>b__71_13() { InsertPreset("<color=#B983FF><b>\ud83e\uddea Potions</b></color>"); } internal void <BuildToolsTab>b__71_14() { InsertPreset("<color=#FFD700><b>\ud83e\ude99 Valuables</b></color>"); } internal void <BuildToolsTab>b__71_15() { InsertPreset("<color=#6BCB77><b>⚡ Portal: </b></color>"); } internal void <BuildToolsTab>b__71_16() { InsertPreset("<color=#FF3333><b>⚠\ufe0f Warning!</b></color>"); } } private static GameObject? _studioPanel; private static RectTransform? _studioRect; private static CanvasGroup? _canvasGroup; private static TMP_InputField? _activeField; private static readonly string[] TabNames = new string[5] { "Icons", "Sprites", "Colors", "Styles", "Tools" }; private static readonly GameObject?[] TabObjects = (GameObject?[])(object)new GameObject[5]; private static readonly Text?[] TabButtonTexts = (Text?[])(object)new Text[5]; private static int _currentTabIndex = 0; private static Slider? _sliderR; private static Slider? _sliderG; private static Slider? _sliderB; private static Text? _textR; private static Text? _textG; private static Text? _textB; private static Image? _colorSwatchImage; private static InputField? _hexInputField; private static bool _updatingHexInput; private static Text? _applyCustomBtnText; private static string _currentMixedHex = "#FFCC33"; private static readonly Text?[] SavedColorTexts = (Text?[])(object)new Text[5]; private static readonly Image?[] SavedColorImages = (Image?[])(object)new Image[5]; private static Slider? _sliderSize; private static Text? _textSizeValue; private static Text? _applySizeBtnText; private static InputField? _customEmojiInput; private static InputField? _iconSearchInput; private static GameObject? _categoryContainer; private static GameObject? _searchContainer; private static GameObject? _loadingIndicator; private static GameObject? _iconButtonTemplate; private static readonly List<GameObject> _searchButtonPool = new List<GameObject>(); private static readonly List<SignScribePlugin.EmojiItem> _allEmojis = new List<SignScribePlugin.EmojiItem>(); private static bool _iconsPopulated = false; private static Coroutine? _populateCoroutine; private static InputField? _spriteSearchInput; private static GameObject? _spriteGrid; private static GameObject? _spriteButtonTemplate; private static readonly List<SpriteButtonItem> _spriteButtons = new List<SpriteButtonItem>(); private static bool _spritesPopulated = false; private static Slider? _sliderOpacity; private static Text? _textOpacityValue; private static Text? _statusText; private static TextMeshProUGUI? _previewText; private static string _lastPreviewSource = ""; public static bool IsVisible() { if ((Object)(object)_studioPanel != (Object)null) { return _studioPanel.activeSelf; } return false; } public static bool IsMouseOverStudio() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) try { if (!IsVisible() || (Object)(object)_studioRect == (Object)null) { return false; } Canvas componentInParent = ((Component)_studioRect).GetComponentInParent<Canvas>(); Camera val = (((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) ? componentInParent.worldCamera : null); return RectTransformUtility.RectangleContainsScreenPoint(_studioRect, Vector2.op_Implicit(Input.mousePosition), val); } catch { return false; } } public static void UpdateScrollSensitivity(float sensitivity) { if ((Object)(object)_studioPanel != (Object)null) { ScrollRect[] componentsInChildren = _studioPanel.GetComponentsInChildren<ScrollRect>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].scrollSensitivity = sensitivity; } } } public static void OpenStudio(TMP_InputField inputField) { //IL_0263: Unknown result type (might be due to invalid IL or missing references) try { _activeField = inputField; if ((Object)(object)_studioPanel == (Object)null) { BuildStudio(); } if (!((Object)(object)_studioPanel != (Object)null)) { return; } _studioPanel.SetActive(true); if ((Object)(object)_previewText != (Object)null && (Object)(object)_activeField != (Object)null && (Object)(object)_activeField.textComponent != (Object)null) { ((TMP_Text)_previewText).font = _activeField.textComponent.font; ((TMP_Text)_previewText).fontSharedMaterial = _activeField.textComponent.fontSharedMaterial; TMP_SpriteAsset val = _activeField.textComponent.spriteAsset ?? TMP_Settings.defaultSpriteAsset; if ((Object)(object)val != (Object)null) { ((TMP_Text)_previewText).spriteAsset = val; } } if ((Object)(object)_iconButtonTemplate != (Object)null && (Object)(object)_activeField != (Object)null && (Object)(object)_activeField.textComponent != (Object)null) { TextMeshProUGUI componentInChildren = _iconButtonTemplate.GetComponentInChildren<TextMeshProUGUI>(); if ((Object)(object)componentInChildren != (Object)null) { ((TMP_Text)componentInChildren).font = _activeField.textComponent.font; ((TMP_Text)componentInChildren).fontSharedMaterial = _activeField.textComponent.fontSharedMaterial; if ((Object)(object)_activeField.textComponent.spriteAsset != (Object)null) { ((TMP_Text)componentInChildren).spriteAsset = _activeField.textComponent.spriteAsset; } } } if ((Object)(object)_spriteButtonTemplate != (Object)null && (Object)(object)_activeField != (Object)null && (Object)(object)_activeField.textComponent != (Object)null) { TextMeshProUGUI componentInChildren2 = _spriteButtonTemplate.GetComponentInChildren<TextMeshProUGUI>(); if ((Object)(object)componentInChildren2 != (Object)null) { ((TMP_Text)componentInChildren2).font = _activeField.textComponent.font; ((TMP_Text)componentInChildren2).fontSharedMaterial = _activeField.textComponent.fontSharedMaterial; if ((Object)(object)_activeField.textComponent.spriteAsset != (Object)null) { ((TMP_Text)componentInChildren2).spriteAsset = _activeField.textComponent.spriteAsset; } } } if (_currentTabIndex == 0) { EnsureIconsPopulated(); } else if (_currentTabIndex == 1) { EnsureSpritesPopulated(); } _lastPreviewSource = ""; OnMixerSliderChanged(); RefreshSavedColorButtons(); UpdatePreview(); ManualLogSource log = SignScribePlugin.Log; if (log != null) { Transform parent = _studioPanel.transform.parent; string arg = ((parent != null) ? ((Object)parent).name : null); RectTransform? studioRect = _studioRect; log.LogInfo((object)$"SignScribe studio opened! Parent: {arg}, Position: {((studioRect != null) ? new Vector2?(studioRect.anchoredPosition) : ((Vector2?)null))}, Active: {_studioPanel.activeSelf}"); } } catch (Exception arg2) { ManualLogSource log2 = SignScribePlugin.Log; if (log2 != null) { log2.LogError((object)$"Error in OpenStudio: {arg2}"); } } } public static void CloseStudio() { //IL_0040: 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 ((Object)(object)_studioPanel != (Object)null && _studioPanel.activeSelf) { RectTransform component = _studioPanel.GetComponent<RectTransform>(); if ((Object)(object)component != (Object)null && (Object)(object)SignScribePlugin.Instance != (Object)null) { SignScribePlugin.Instance.SaveWindowPosition(component.anchoredPosition.x, component.anchoredPosition.y); } _studioPanel.SetActive(false); ManualLogSource log = SignScribePlugin.Log; if (log != null) { log.LogInfo((object)"SignScribe studio closed."); } } } public static void ToggleStudio() { if (IsVisible()) { CloseStudio(); } else if ((Object)(object)_activeField != (Object)null && (Object)(object)TextInput.instance != (Object)null && (((Object)(object)TextInput.instance.m_panel != (Object)null && TextInput.instance.m_panel.activeInHierarchy) || TextInput.IsVisible())) { OpenStudio(_activeField); } } public static void SetStatus(string message) { if ((Object)(object)_statusText != (Object)null) { _statusText.text = message; } } public static void UpdateStatusText() { if (!((Object)(object)_statusText == (Object)null)) { if (Time.realtimeSinceStartup < SignScribePlugin.StatusUntil) { _statusText.text = SignScribePlugin.StatusMessage; } else { _statusText.text = SignScribePlugin.DefaultHint; } } } public static void UpdatePreview() { if (!((Object)(object)_activeField == (Object)null) && !((Object)(object)_previewText == (Object)null)) { string text = _activeField.text ?? ""; if (text != _lastPreviewSource) { _lastPreviewSource = text; string preview = SignScribePlugin.GetPreview(text); ((TMP_Text)_previewText).text = preview; SignScribePlugin.DebugLog("[StudioBuilder.UpdatePreview] Source='" + text + "' -> Rendered Preview='" + preview + "'"); } } } public static void BuildStudio() { //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0119: 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_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Expected O, but got Unknown //IL_021d: 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_0233: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Expected O, but got Unknown //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_0377: Expected O, but got Unknown //IL_03c2: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_03e0: Unknown result type (might be due to invalid IL or missing references) //IL_03f7: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Expected O, but got Unknown //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_0447: Expected O, but got Unknown //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_0481: Unknown result type (might be due to invalid IL or missing references) //IL_0496: Unknown result type (might be due to invalid IL or missing references) //IL_04ab: Unknown result type (might be due to invalid IL or missing references) //IL_04bf: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)_studioPanel != (Object)null) { Object.Destroy((Object)(object)_studioPanel); _studioPanel = null; } if (_populateCoroutine != null && (Object)(object)SignScribePlugin.Instance != (Object)null) { ((MonoBehaviour)SignScribePlugin.Instance).StopCoroutine(_populateCoroutine); _populateCoroutine = null; } _iconsPopulated = false; _spritesPopulated = false; _searchButtonPool.Clear(); _spriteButtons.Clear(); Transform val = (((Object)(object)GUIManager.CustomGUIFront != (Object)null) ? GUIManager.CustomGUIFront.transform : (((Object)(object)TextInput.instance != (Object)null) ? ((Component)TextInput.instance).transform : null)); if ((Object)(object)val == (Object)null) { ManualLogSource log = SignScribePlugin.Log; if (log != null) { log.LogWarning((object)"No suitable GUI parent found for SignScribe studio panel."); } return; } Vector2 sanitizedWindowPosition = SignScribePlugin.GetSanitizedWindowPosition(((Object)(object)SignScribePlugin.Instance != (Object)null) ? SignScribePlugin.Instance.PosXConfig.Value : 0f, ((Object)(object)SignScribePlugin.Instance != (Object)null) ? SignScribePlugin.Instance.PosYConfig.Value : (-20f)); _studioPanel = GUIManager.Instance.CreateWoodpanel(val, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), sanitizedWindowPosition, 520f, 660f, true); ((Object)_studioPanel).name = "SignScribe_StudioPanel"; _studioRect = _studioPanel.GetComponent<RectTransform>(); _studioRect.pivot = new Vector2(0.5f, 1f); _studioRect.anchoredPosition = sanitizedWindowPosition; _studioPanel.transform.localScale = Vector3.one; _canvasGroup = _studioPanel.AddComponent<CanvasGroup>(); float alpha = (((Object)(object)SignScribePlugin.Instance != (Object)null) ? SignScribePlugin.Instance.OpacityConfig.Value : 0.95f); _canvasGroup.alpha = alpha; _studioPanel.AddComponent<StudioEscapeHandler>(); GameObject val2 = new GameObject("StudioContent", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(_studioPanel.transform, false); RectTransform component = val2.GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.sizeDelta = Vector2.zero; component.anchoredPosition = Vector2.zero; GUIManager.Instance.CreateText("<color=#E08A2E>SignScribe</color> Studio", val2.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(-75f, -28f), GUIManager.Instance.AveriaSerifBold, 22, GUIManager.Instance.ValheimOrange, true, Color.black, 260f, 34f, false); Transform transform = val2.transform; Vector2 anchorMin = new Vector2(0.5f, 1f); Vector2 anchorMax = new Vector2(0.5f, 1f); Vector2 pos = new Vector2(145f, -28f); object obj = <>c.<>9__54_0; if (obj == null) { UnityAction val3 = delegate { if ((Object)(object)_activeField != (Object)null) { SignScribePlugin.UndoLast(_activeField); } }; <>c.<>9__54_0 = val3; obj = (object)val3; } CreateButton("Undo", transform, anchorMin, anchorMax, pos, 65f, 30f, (UnityAction)obj, 13); Transform transform2 = val2.transform; Vector2 anchorMin2 = new Vector2(0.5f, 1f); Vector2 anchorMax2 = new Vector2(0.5f, 1f); Vector2 pos2 = new Vector2(215f, -28f); object obj2 = <>O.<0>__CloseStudio; if (obj2 == null) { UnityAction val4 = CloseStudio; <>O.<0>__CloseStudio = val4; obj2 = (object)val4; } CreateButton("✕", transform2, anchorMin2, anchorMax2, pos2, 35f, 30f, (UnityAction)obj2); float[] array = new float[5] { -192f, -96f,