Decompiled source of Mantle v0.1.29

plugins/Mantle/Mantle.Core.dll

Decompiled 5 hours ago
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ExtraPotions")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright 2026 ExtraPotions")]
[assembly: AssemblyFileVersion("0.1.29.0")]
[assembly: AssemblyInformationalVersion("0.1.29+fatal: not a git repository (or any of the parent directories): .git")]
[assembly: AssemblyProduct("Mantle.Core")]
[assembly: AssemblyTitle("Mantle.Core")]
[assembly: AssemblyVersion("0.1.29.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Mantle.Trinkets
{
	public static class KillGain
	{
		public static float Calculate(float fraction, float effectiveMaximum, float targetMultiplier)
		{
			if (!Finite(fraction) || fraction <= 0f || fraction > 0.1f || !Finite(effectiveMaximum) || effectiveMaximum <= 0f || !Finite(targetMultiplier) || targetMultiplier <= 0f)
			{
				return 0f;
			}
			double num = (double)fraction * (double)effectiveMaximum * (double)targetMultiplier;
			if (!(num <= 3.4028234663852886E+38))
			{
				return 0f;
			}
			return (float)num;
		}

		internal static bool Finite(float value)
		{
			if (!float.IsNaN(value))
			{
				return !float.IsInfinity(value);
			}
			return false;
		}
	}
	public static class KillEligibility
	{
		public static bool IsEligible(bool serverValidated, bool unambiguousAttribution, bool hasNativeTrinket, bool isPlayer, bool isTamed, bool isHostile, float targetMultiplier, long creditedKiller, long recipient)
		{
			if (serverValidated && unambiguousAttribution && hasNativeTrinket && !isPlayer && !isTamed && isHostile && KillGain.Finite(targetMultiplier) && targetMultiplier > 0f && creditedKiller != 0L)
			{
				return creditedKiller == recipient;
			}
			return false;
		}
	}
	public sealed class DeathCreditLedger
	{
		private readonly HashSet<string> deaths = new HashSet<string>(StringComparer.Ordinal);

		private readonly int capacity;

		private readonly object gate = new object();

		public int Count
		{
			get
			{
				lock (gate)
				{
					return deaths.Count;
				}
			}
		}

		public DeathCreditLedger(int capacity = 1000000)
		{
			if (capacity <= 0)
			{
				throw new ArgumentOutOfRangeException("capacity");
			}
			this.capacity = capacity;
		}

		public bool TryClaim(string deathId, long killer)
		{
			if (string.IsNullOrWhiteSpace(deathId) || deathId.Length > 256 || killer == 0L)
			{
				return false;
			}
			lock (gate)
			{
				return deaths.Count < capacity && deaths.Add(deathId);
			}
		}

		public void Clear()
		{
			lock (gate)
			{
				deaths.Clear();
			}
		}
	}
	public enum TrinketPreset
	{
		Native,
		Conservative,
		Custom
	}
	public sealed class TrinketRow
	{
		public string PrefabId { get; }

		public float Threshold { get; }

		public float Duration { get; }

		public float KillFraction { get; }

		public IReadOnlyDictionary<string, float> Effects { get; }

		public TrinketRow(string prefabId, float threshold, float duration, float killFraction, IReadOnlyDictionary<string, float> effects)
		{
			PrefabId = prefabId;
			Threshold = threshold;
			Duration = duration;
			KillFraction = killFraction;
			Dictionary<string, float> dictionary = new Dictionary<string, float>(StringComparer.Ordinal);
			if (effects != null)
			{
				foreach (KeyValuePair<string, float> effect in effects)
				{
					dictionary.Add(effect.Key, effect.Value);
				}
			}
			Effects = new ReadOnlyDictionary<string, float>(dictionary);
		}

		public TrinketRow WithKillFraction(float fraction)
		{
			return new TrinketRow(PrefabId, Threshold, Duration, fraction, Effects);
		}
	}
	public sealed class TrinketTable
	{
		private static readonly HashSet<string> nativeIds = new HashSet<string>(NativeIds, StringComparer.Ordinal);

		public static IReadOnlyList<string> NativeIds { get; } = Array.AsReadOnly(new string[15]
		{
			"TrinketBronzeHealth", "TrinketBronzeStamina", "TrinketChitinSwim", "TrinketIronHealth", "TrinketIronStamina", "TrinketSilverDamage", "TrinketSilverResist", "TrinketBlackDamageHealth", "TrinketBlackStamina", "TrinketCarapaceEitr",
			"TrinketScaleStaminaDamage", "TrinketFlametalEitr", "TrinketFlametalStaminaHealth", "TrinketBloodGoldHealth", "TrinketBloodGoldStamina"
		});

		public IReadOnlyDictionary<string, TrinketRow> Rows { get; }

		private TrinketTable(Dictionary<string, TrinketRow> rows)
		{
			Rows = new ReadOnlyDictionary<string, TrinketRow>(rows);
		}

		public bool TryGet(string prefabId, out TrinketRow row)
		{
			row = null;
			if (prefabId != null)
			{
				return Rows.TryGetValue(prefabId, out row);
			}
			return false;
		}

		public static bool TryCreateNative(IEnumerable<TrinketRow> rows, out TrinketTable table, out string error)
		{
			return TryCreate(rows, null, out table, out error);
		}

		public static bool TryCreateCustom(IEnumerable<TrinketRow> rows, TrinketTable native, out TrinketTable table, out string error)
		{
			if (native == null)
			{
				table = null;
				error = "Native trinket data is unavailable.";
				return false;
			}
			return TryCreate(rows, native, out table, out error);
		}

		public static TrinketTable ForPreset(TrinketPreset preset, TrinketTable native, TrinketTable custom = null)
		{
			if (native == null)
			{
				return null;
			}
			switch (preset)
			{
			case TrinketPreset.Custom:
				return custom ?? native;
			default:
				return native;
			case TrinketPreset.Conservative:
			{
				Dictionary<string, TrinketRow> dictionary = new Dictionary<string, TrinketRow>(StringComparer.Ordinal);
				foreach (KeyValuePair<string, TrinketRow> row in native.Rows)
				{
					dictionary.Add(row.Key, row.Value.WithKillFraction(0.05f));
				}
				return new TrinketTable(dictionary);
			}
			}
		}

		private static bool TryCreate(IEnumerable<TrinketRow> source, TrinketTable native, out TrinketTable table, out string error)
		{
			table = null;
			error = null;
			if (source == null)
			{
				error = "A complete trinket table is required.";
				return false;
			}
			Dictionary<string, TrinketRow> dictionary = new Dictionary<string, TrinketRow>(StringComparer.Ordinal);
			foreach (TrinketRow item in source)
			{
				if (item == null || item.PrefabId == null || !nativeIds.Contains(item.PrefabId))
				{
					error = "Unknown native trinket prefab.";
					return false;
				}
				if (dictionary.ContainsKey(item.PrefabId))
				{
					error = "Duplicate trinket prefab: " + item.PrefabId;
					return false;
				}
				if (!InRange(item.Threshold, 1f, 200f) || !InRange(item.Duration, 0.1f, 300f) || !InRange(item.KillFraction, 0f, 0.1f) || (native == null && item.KillFraction != 0f))
				{
					error = "Invalid threshold, duration or kill fraction: " + item.PrefabId;
					return false;
				}
				if (item.Effects.Count == 0 || item.Effects.Count > 24)
				{
					error = "Native effect fields are required: " + item.PrefabId;
					return false;
				}
				TrinketRow row = null;
				if (native != null && (!native.TryGet(item.PrefabId, out row) || row.Effects.Count != item.Effects.Count))
				{
					error = "Effect fields must match the native trinket: " + item.PrefabId;
					return false;
				}
				foreach (KeyValuePair<string, float> effect in item.Effects)
				{
					if (!ValidEffect(effect.Key, effect.Value) || (row != null && !row.Effects.ContainsKey(effect.Key)))
					{
						error = "Invalid or unknown effect field: " + item.PrefabId + "/" + effect.Key;
						return false;
					}
				}
				dictionary.Add(item.PrefabId, item);
			}
			if (dictionary.Count != NativeIds.Count)
			{
				error = "A trinket table must contain all 15 native prefabs.";
				return false;
			}
			table = new TrinketTable(dictionary);
			return true;
		}

		private static bool InRange(float value, float minimum, float maximum)
		{
			if (KillGain.Finite(value) && value >= minimum)
			{
				return value <= maximum;
			}
			return false;
		}

		private static bool ValidEffect(string field, float value)
		{
			switch (field)
			{
			case "m_healthUpFront":
			case "m_staminaUpFront":
			case "m_eitrUpFront":
				return InRange(value, 0f, 200f);
			case "m_skillLevelModifier2":
			case "m_skillLevelModifier":
				return InRange(value, 0f, 30f);
			case "m_addArmor":
				return InRange(value, 0f, 40f);
			case "m_eitrRegenMultiplier":
			case "m_staminaRegenMultiplier":
			case "m_healthRegenMultiplier":
				return InRange(value, 1f, 2f);
			case "m_timedBlockBonus":
				return InRange(value, 0f, 1f);
			case "m_swimStaminaUseModifier":
			case "m_blockStaminaUseModifier":
			case "m_runStaminaDrainModifier":
			case "m_attackStaminaUseModifier":
				return InRange(value, -1f, 0f);
			case "m_speedModifier":
			case "m_swimSpeedModifier":
				return InRange(value, 0f, 0.5f);
			case "m_percentigeDamageModifiers.m_blunt":
			case "m_percentigeDamageModifiers.m_slash":
			case "m_percentigeDamageModifiers.m_pierce":
				return InRange(value, 0f, 1f);
			case "resistance.Blunt":
			case "resistance.Slash":
			case "resistance.Pierce":
				return ValidResistance(value);
			default:
				return false;
			}
		}

		private static bool ValidResistance(float value)
		{
			if (InRange(value, 0f, 8f))
			{
				return value == (float)(int)value;
			}
			return false;
		}
	}
}
namespace Mantle.Tackle
{
	public static class BaitRule
	{
		public static bool Matches(bool equipableAmmo, bool nonEquipableAmmo, string ammoType, string rodAmmoType)
		{
			if (!equipableAmmo && !nonEquipableAmmo)
			{
				return false;
			}
			if (string.IsNullOrEmpty(rodAmmoType))
			{
				return nonEquipableAmmo;
			}
			return ammoType == rodAmmoType;
		}
	}
}
namespace Mantle.Compatibility
{
	public static class SlowJoinWait
	{
		public readonly struct Step
		{
			public float Deadline { get; }

			public bool Holding { get; }

			public bool GiveUp { get; }

			public bool LogSlow { get; }

			public Step(float deadline, bool holding, bool giveUp, bool logSlow)
			{
				Deadline = deadline;
				Holding = holding;
				GiveUp = giveUp;
				LogSlow = logSlow;
			}
		}

		public const float QuietSeconds = 60f;

		public const float CeilingSeconds = 300f;

		public const float FormerTimeoutSeconds = 20f;

		public const int BacklogBytes = 65536;

		public static Step Advance(float greeted, float deadline, float now, int queuedBytes, bool slowLogged)
		{
			return Advance(greeted, deadline, now, queuedBytes, slowLogged, -1);
		}

		public static Step Advance(float greeted, float deadline, float now, int queuedBytes, bool slowLogged, int previousQueuedBytes)
		{
			float num = greeted + 300f;
			bool flag = !(now >= deadline) && !(now >= num) && previousQueuedBytes > 65536 && queuedBytes >= 0 && queuedBytes < previousQueuedBytes;
			float num2 = (flag ? Math.Min(num, Math.Max(deadline, now + 60f)) : deadline);
			bool flag2 = now >= num2 || now >= num;
			bool holding = !flag2 && queuedBytes > 65536;
			return new Step(num2, holding, flag2, flag && !slowLogged && now - greeted > 20f);
		}

		public static string[] NoAnswerLines(float seconds)
		{
			string text = seconds.ToString("0", CultureInfo.InvariantCulture);
			return new string[7]
			{
				"Your game did not answer this server's mod check in " + text + " seconds (mods missing, or a very slow connection).",
				"Tu juego no respondió a la comprobación de mods de este servidor en " + text + " segundos (faltan mods, o la conexión es muy lenta).",
				"Votre jeu n'a pas répondu à la vérification des mods de ce serveur en " + text + " secondes (mods manquants, ou connexion très lente).",
				"Dein Spiel hat die Mod-Prüfung dieses Servers innerhalb von " + text + " Sekunden nicht beantwortet (Mods fehlen, oder die Verbindung ist sehr langsam).",
				"Твоя игра не ответила на проверку модов этого сервера за " + text + " с (моды отсутствуют или соединение очень медленное).",
				"你的游戏未在 " + text + " 秒内回应此服务器的模组检查(缺少模组,或连接非常慢)。",
				"게임이 " + text + "초 안에 이 서버의 모드 확인에 응답하지 않았습니다(모드가 없거나 연결이 매우 느립니다)."
			};
		}

		public static string ServerRuns(string title, string version)
		{
			string text = title + " " + version;
			return "This server runs " + text + ". / Este servidor ejecuta " + text + ". / Ce serveur utilise " + text + ". / Dieser Server verwendet " + text + ". / Этот сервер использует " + text + ". / 此服务器运行 " + text + "。 / 이 서버는 " + text + "을(를) 실행합니다.";
		}
	}
	public static class StatusRowRoom
	{
		public const float Margin = 8f;

		public static int PerRow(int nativePerRow, float firstCenter, float cell, float rowTop, float rowBottom, float left, float right, float top, float bottom)
		{
			int num = Math.Max(1, nativePerRow);
			if (cell <= 0f || bottom <= rowTop || top >= rowBottom || left >= firstCenter + cell * 0.5f)
			{
				return num;
			}
			float num2 = firstCenter - cell * 0.5f - (right + 8f);
			if (num2 < 0f)
			{
				return 1;
			}
			return Math.Max(1, Math.Min(num, 1 + (int)Math.Floor(num2 / cell)));
		}

		public static bool Overlaps(float left, float right, float bottom, float top, float otherLeft, float otherRight, float otherBottom, float otherTop)
		{
			if (left <= otherRight && otherLeft <= right && bottom <= otherTop)
			{
				return otherBottom <= top;
			}
			return false;
		}
	}
	public sealed class StatusRowHold
	{
		public const int ReleaseFrames = 2;

		private bool holding;

		private int lastOpenFrame;

		public bool Holding(bool windowOpen, int frame)
		{
			if (windowOpen)
			{
				holding = true;
				lastOpenFrame = frame;
				return true;
			}
			if (holding && frame - lastOpenFrame <= 2 && frame >= lastOpenFrame)
			{
				return true;
			}
			holding = false;
			return false;
		}

		public void Reset()
		{
			holding = false;
		}
	}
	public static class VersionFloor
	{
		public static string OldestAccepted(string version)
		{
			Version version2 = new Version(version);
			return version2.Major + "." + version2.Minor + ".0";
		}
	}
}
namespace Mantle.Accessories
{
	public static class AccessoryCatalog
	{
		private const string Workbench = "piece_workbench";

		private const string Forge = "forge";

		private const string GaldrTable = "piece_magetable";

		public static IReadOnlyList<AccessoryEntry> All { get; } = new List<AccessoryEntry>
		{
			Mantles("Mantle_BoneBand", AccessorySlot.Ring, "Bone Band", "A band of polished bone, bound with a strip of leather.", 0.2f, "piece_workbench", 1, "BoneFragments:6, LeatherScraps:2", new AccessoryStats(0f, 5f)),
			Mantles("Mantle_CopperRing", AccessorySlot.Ring, "Copper Ring", "A plain copper ring set with a chip of amber.", 0.2f, "forge", 1, "Copper:3, Amber:1", new AccessoryStats(10f)),
			Mantles("Mantle_IronRing", AccessorySlot.Ring, "Iron Ring", "A heavy iron ring, its inside smeared with blood.", 0.3f, "forge", 2, "Iron:3, Bloodbag:2", new AccessoryStats(0f, 0f, 0f, 10f)),
			Mantles("Mantle_SilverRing", AccessorySlot.Ring, "Silver Ring", "A silver ring as cold as the glands it was cooled in.", 0.2f, "forge", 3, "Silver:3, FreezeGland:2", new AccessoryStats(0f, 0f, 0f, 0f, 5f)),
			Mantles("Mantle_BlackMetalRing", AccessorySlot.Ring, "Black Metal Ring", "A black metal ring stitched through with needle wire.", 0.3f, "forge", 4, "BlackMetal:3, Needle:3", new AccessoryStats(0f, 0f, 0f, 0f, 0f, -10f)),
			Mantles("Mantle_EitrRing", AccessorySlot.Ring, "Eitr Ring", "A silver ring that hums with refined eitr.", 0.2f, "piece_magetable", 1, "Eitr:3, Silver:2", new AccessoryStats(0f, 0f, 15f)),
			Mantles("Mantle_LeatherBelt", AccessorySlot.Belt, "Leather Belt", "A sturdy belt of deer hide and leather scraps.", 1f, "piece_workbench", 1, "DeerHide:4, LeatherScraps:4", new AccessoryStats(0f, 0f, 0f, 0f, 0f, 0f, 25f)),
			Mantles("Mantle_TrollHideBelt", AccessorySlot.Belt, "Troll Hide Belt", "A thick troll hide belt with a bronze buckle.", 1.5f, "piece_workbench", 2, "TrollHide:3, Bronze:1", new AccessoryStats(0f, 0f, 0f, 0f, 0f, 0f, 40f)),
			Mantles("Mantle_LoxBelt", AccessorySlot.Belt, "Lox Belt", "A broad belt of lox pelt, reinforced with black metal.", 2f, "piece_workbench", 3, "LoxPelt:3, BlackMetal:2", new AccessoryStats(0f, 5f, 0f, 0f, 0f, 0f, 60f)),
			new AccessoryEntry("BeltStrength", AccessorySlot.Belt, new AccessoryStats(0f, 0f, 0f, 0f, 0f, 0f, 150f))
		};

		private static AccessoryEntry Mantles(string id, AccessorySlot slot, string name, string look, float weight, string station, int level, string cost, AccessoryStats stats)
		{
			return new AccessoryEntry(id, slot, stats, new AccessoryRecipe(station, level, cost), name, look, weight, enabled: true, builtIn: true);
		}
	}
	public sealed class StatLine
	{
		public string Key { get; }

		public string Number { get; }

		public StatLine(string key, string number)
		{
			Key = key;
			Number = number;
		}
	}
	public static class AccessoryDescription
	{
		public static IReadOnlyList<StatLine> Lines(AccessoryStats stats)
		{
			List<StatLine> list = new List<StatLine>();
			Add(list, "stat_max_health", stats.MaxHealth);
			Add(list, "stat_max_stamina", stats.MaxStamina);
			Add(list, "stat_max_eitr", stats.MaxEitr);
			Add(list, "stat_carry", stats.Carry);
			Add(list, "stat_stamina_regen", stats.StaminaRegenPercent);
			Add(list, "stat_move_speed", stats.MoveSpeedPercent);
			Add(list, (stats.AttackStaminaPercent < 0f) ? "stat_attack_stamina_less" : "stat_attack_stamina_more", stats.AttackStaminaPercent);
			return list;
		}

		private static void Add(List<StatLine> lines, string key, float value)
		{
			if (value != 0f)
			{
				lines.Add(new StatLine(key, Math.Abs(value).ToString("0.##", CultureInfo.InvariantCulture)));
			}
		}
	}
	public enum AccessorySlot
	{
		Ring,
		Belt
	}
	public sealed class AccessoryRecipe
	{
		public string Station { get; }

		public int Level { get; }

		public string Cost { get; }

		public AccessoryRecipe(string station, int level, string cost)
		{
			Station = station;
			Level = level;
			Cost = cost;
		}
	}
	public sealed class AccessoryEntry
	{
		public string Id { get; }

		public AccessorySlot Slot { get; }

		public AccessoryStats Stats { get; }

		public AccessoryRecipe Recipe { get; }

		public string Name { get; }

		public string Look { get; }

		public float Weight { get; }

		public bool Enabled { get; }

		public bool BuiltIn { get; }

		public AccessoryEntry(string id, AccessorySlot slot, AccessoryStats stats, AccessoryRecipe recipe = null, string name = null, string look = null, float weight = 0f, bool enabled = true, bool builtIn = false)
		{
			Id = id;
			Slot = slot;
			Stats = stats ?? AccessoryStats.None;
			Recipe = recipe;
			Name = name;
			Look = look;
			Weight = weight;
			Enabled = enabled;
			BuiltIn = builtIn;
		}

		public AccessoryEntry With(AccessoryOverride change)
		{
			AccessoryRecipe recipe = Recipe;
			if (BuiltIn && (change.Station != null || change.Level.HasValue || change.Cost != null))
			{
				recipe = new AccessoryRecipe(change.Station ?? Recipe.Station, change.Level ?? Recipe.Level, change.Cost ?? Recipe.Cost);
			}
			return new AccessoryEntry(Id, BuiltIn ? Slot : (change.Slot ?? Slot), change.ApplyTo(Stats), recipe, Name, Look, Weight, change.Enabled ?? Enabled, BuiltIn);
		}
	}
	public sealed class AccessoryOverride
	{
		public string Id { get; set; }

		public AccessorySlot? Slot { get; set; }

		public bool? Enabled { get; set; }

		public string Station { get; set; }

		public int? Level { get; set; }

		public string Cost { get; set; }

		public float? MaxHealth { get; set; }

		public float? MaxStamina { get; set; }

		public float? MaxEitr { get; set; }

		public float? StaminaRegenPercent { get; set; }

		public float? MoveSpeedPercent { get; set; }

		public float? AttackStaminaPercent { get; set; }

		public float? Carry { get; set; }

		public AccessoryStats ApplyTo(AccessoryStats stats)
		{
			return new AccessoryStats(MaxHealth ?? stats.MaxHealth, MaxStamina ?? stats.MaxStamina, MaxEitr ?? stats.MaxEitr, StaminaRegenPercent ?? stats.StaminaRegenPercent, MoveSpeedPercent ?? stats.MoveSpeedPercent, AttackStaminaPercent ?? stats.AttackStaminaPercent, Carry ?? stats.Carry);
		}
	}
	public sealed class AccessoryRegistry
	{
		private readonly Dictionary<string, AccessoryEntry> entries = new Dictionary<string, AccessoryEntry>(StringComparer.OrdinalIgnoreCase);

		public static AccessoryRegistry Current { get; private set; } = new AccessoryRegistry();

		public IReadOnlyCollection<AccessoryEntry> All => entries.Values;

		public static AccessoryRegistry Build(IEnumerable<AccessoryEntry> builtIn, IEnumerable<AccessoryOverride> overrides, ICollection<string> warnings = null)
		{
			AccessoryRegistry accessoryRegistry = new AccessoryRegistry();
			foreach (AccessoryEntry item in builtIn)
			{
				accessoryRegistry.entries[item.Id] = item;
			}
			foreach (AccessoryOverride item2 in overrides ?? Array.Empty<AccessoryOverride>())
			{
				if (!string.IsNullOrWhiteSpace(item2.Id))
				{
					string text = item2.Id.Trim();
					if (accessoryRegistry.entries.TryGetValue(text, out AccessoryEntry value))
					{
						accessoryRegistry.entries[value.Id] = value.With(item2);
					}
					else if (item2.Slot.HasValue)
					{
						accessoryRegistry.entries[text] = new AccessoryEntry(text, item2.Slot.Value, item2.ApplyTo(AccessoryStats.None), null, null, null, 0f, item2.Enabled ?? true);
					}
					else
					{
						warnings?.Add(text + ": not one of Mantle's items; add slot: ring or slot: belt to tag it");
					}
				}
			}
			return accessoryRegistry;
		}

		public static void Load(AccessoryRegistry registry)
		{
			Current = registry ?? new AccessoryRegistry();
		}

		public AccessoryEntry Find(string prefab)
		{
			if (prefab == null || !entries.TryGetValue(prefab, out AccessoryEntry value))
			{
				return null;
			}
			return value;
		}

		public AccessorySlot? SlotOf(string prefab)
		{
			AccessoryEntry accessoryEntry = Find(prefab);
			if (accessoryEntry == null || !accessoryEntry.Enabled)
			{
				return null;
			}
			return accessoryEntry.Slot;
		}

		public AccessoryStats Total(IEnumerable<KeyValuePair<AccessorySlot, string>> inCells)
		{
			AccessoryStats accessoryStats = AccessoryStats.None;
			foreach (KeyValuePair<AccessorySlot, string> inCell in inCells)
			{
				accessoryStats = Add(accessoryStats, inCell.Key, inCell.Value);
			}
			return accessoryStats;
		}

		public AccessoryStats Add(AccessoryStats total, AccessorySlot cell, string prefab)
		{
			AccessoryEntry accessoryEntry = Find(prefab);
			if (accessoryEntry == null || !accessoryEntry.Enabled || accessoryEntry.Slot != cell)
			{
				return total;
			}
			return total.Plus(accessoryEntry.Stats);
		}
	}
	public sealed class AccessoryStats
	{
		public static readonly AccessoryStats None = new AccessoryStats();

		public float MaxHealth { get; }

		public float MaxStamina { get; }

		public float MaxEitr { get; }

		public float StaminaRegenPercent { get; }

		public float MoveSpeedPercent { get; }

		public float AttackStaminaPercent { get; }

		public float Carry { get; }

		public bool IsNone
		{
			get
			{
				if (MaxHealth == 0f && MaxStamina == 0f && MaxEitr == 0f && StaminaRegenPercent == 0f && MoveSpeedPercent == 0f && AttackStaminaPercent == 0f)
				{
					return Carry == 0f;
				}
				return false;
			}
		}

		public float StaminaRegenAdd => StaminaRegenPercent / 100f;

		public AccessoryStats(float maxHealth = 0f, float maxStamina = 0f, float maxEitr = 0f, float staminaRegenPercent = 0f, float moveSpeedPercent = 0f, float attackStaminaPercent = 0f, float carry = 0f)
		{
			MaxHealth = maxHealth;
			MaxStamina = maxStamina;
			MaxEitr = maxEitr;
			StaminaRegenPercent = staminaRegenPercent;
			MoveSpeedPercent = moveSpeedPercent;
			AttackStaminaPercent = attackStaminaPercent;
			Carry = carry;
		}

		public float SpeedAdd(float baseSpeed)
		{
			return baseSpeed * MoveSpeedPercent / 100f;
		}

		public float AttackStaminaAdd(float baseUse)
		{
			return baseUse * AttackStaminaPercent / 100f;
		}

		public float AttackStaminaApplied(float baseUse, float current, bool minZero)
		{
			float num = current + AttackStaminaAdd(baseUse);
			if (!minZero || !(num < 0f))
			{
				return num;
			}
			return 0f;
		}

		public AccessoryStats Plus(AccessoryStats other)
		{
			return new AccessoryStats(MaxHealth + other.MaxHealth, MaxStamina + other.MaxStamina, MaxEitr + other.MaxEitr, StaminaRegenPercent + other.StaminaRegenPercent, MoveSpeedPercent + other.MoveSpeedPercent, AttackStaminaPercent + other.AttackStaminaPercent, Carry + other.Carry);
		}

		public override bool Equals(object obj)
		{
			if (obj is AccessoryStats accessoryStats && MaxHealth == accessoryStats.MaxHealth && MaxStamina == accessoryStats.MaxStamina && MaxEitr == accessoryStats.MaxEitr && StaminaRegenPercent == accessoryStats.StaminaRegenPercent && MoveSpeedPercent == accessoryStats.MoveSpeedPercent && AttackStaminaPercent == accessoryStats.AttackStaminaPercent)
			{
				return Carry == accessoryStats.Carry;
			}
			return false;
		}

		public override int GetHashCode()
		{
			return MaxHealth.GetHashCode() ^ (MaxStamina.GetHashCode() * 31) ^ (Carry.GetHashCode() * 17) ^ (MaxEitr.GetHashCode() * 13);
		}

		public override string ToString()
		{
			return $"hp {MaxHealth}, stamina {MaxStamina}, eitr {MaxEitr}, regen {StaminaRegenPercent}%, speed {MoveSpeedPercent}%, attack {AttackStaminaPercent}%, carry {Carry}";
		}
	}
}

plugins/Mantle/Mantle.dll

Decompiled 5 hours ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExtraPotions.Mantle.Embedded.BundlePrefabs;
using ExtraPotions.Mantle.Embedded.Charter;
using ExtraPotions.Mantle.Embedded.ConfigReload;
using ExtraPotions.Mantle.Embedded.EliteCraftingLink;
using ExtraPotions.Mantle.Embedded.Hotkeys;
using ExtraPotions.Mantle.Embedded.ItemCopies;
using ExtraPotions.Mantle.Embedded.PatchGuard;
using ExtraPotions.Mantle.Embedded.PlateColumn;
using ExtraPotions.Mantle.Embedded.SyncedConfig;
using ExtraPotions.Mantle.Embedded.YamlConfig;
using ExtraPotions.Meadworks.Contracts;
using ExtraPotions.Meadworks.Crucible;
using ExtraPotions.Meadworks.Crucible.UI;
using ExtraPotions.Meadworks.OriginalArt;
using HarmonyLib;
using Jotunn.Utils;
using MagicaCloth2;
using Mantle.Accessories;
using Mantle.Backpacks;
using Mantle.Compatibility;
using Mantle.Consume;
using Mantle.Core;
using Mantle.Crafting;
using Mantle.Elite;
using Mantle.Interop;
using Mantle.Layout;
using Mantle.Look;
using Mantle.Panels;
using Mantle.Presentation;
using Mantle.Protection;
using Mantle.Ring;
using Mantle.Settings;
using Mantle.Slots;
using Mantle.Tackle;
using Mantle.Trinkets;
using Mantle.Worn;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;
using YamlDotNet.Core;
using YamlDotNet.RepresentationModel;
using YamlDotNet.Serialization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ExtraPotions")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright 2026 ExtraPotions")]
[assembly: AssemblyFileVersion("0.1.29.0")]
[assembly: AssemblyInformationalVersion("0.1.29+fatal: not a git repository (or any of the parent directories): .git")]
[assembly: AssemblyProduct("Mantle")]
[assembly: AssemblyTitle("Mantle")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.29.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ExtraPotions.Meadworks.OriginalArt
{
	internal static class OriginalItemArt
	{
		[Serializable]
		private sealed class Catalog
		{
			public Entry[] assets;

			public Surface[] materials;
		}

		[Serializable]
		private sealed class Entry
		{
			public string id;

			public string[] prefabs;
		}

		[Serializable]
		private sealed class Surface
		{
			public string id;

			public string nativePrefab;
		}

		private static AssetBundle bundle;

		private static Dictionary<string, string> ids;

		private static Dictionary<string, string> nativeMaterials;

		private static readonly List<Material> ownedMaterials = new List<Material>();

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

		private static void Load()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Invalid comparison between Unknown and I4
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Invalid comparison between Unknown and I4
			if ((Object)(object)bundle != (Object)null)
			{
				return;
			}
			Assembly assembly = typeof(OriginalItemArt).Assembly;
			string platform = (((int)Application.platform == 13 || (int)Application.platform == 43) ? "linux" : "windows");
			string text = assembly.GetManifestResourceNames().Single((string n) => n.EndsWith(".original-items." + platform, StringComparison.Ordinal));
			using (Stream stream = assembly.GetManifestResourceStream(text))
			{
				using MemoryStream memoryStream = new MemoryStream();
				stream.CopyTo(memoryStream);
				bundle = AssetBundle.LoadFromMemory(memoryStream.ToArray());
			}
			if ((Object)(object)bundle == (Object)null)
			{
				throw new InvalidOperationException("Original item art bundle did not load: " + text);
			}
			using Stream stream2 = assembly.GetManifestResourceStream("MeadWorks.OriginalItems.catalog.json");
			using StreamReader streamReader = new StreamReader(stream2);
			ids = new Dictionary<string, string>(StringComparer.Ordinal);
			Catalog catalog = JsonConvert.DeserializeObject<Catalog>(streamReader.ReadToEnd());
			if (catalog == null || catalog.assets == null || catalog.assets.Length == 0)
			{
				throw new InvalidDataException("Original item catalog contains no assets");
			}
			nativeMaterials = new Dictionary<string, string>(StringComparer.Ordinal);
			Surface[] array = catalog.materials ?? Array.Empty<Surface>();
			foreach (Surface surface in array)
			{
				if (!string.IsNullOrEmpty(surface.nativePrefab))
				{
					nativeMaterials.Add(surface.id, surface.nativePrefab);
				}
			}
			Entry[] assets = catalog.assets;
			foreach (Entry entry in assets)
			{
				ids.Add(entry.id, entry.id);
				string[] array2 = entry.prefabs ?? Array.Empty<string>();
				foreach (string text2 in array2)
				{
					if (text2 != entry.id)
					{
						ids.Add(text2, entry.id);
					}
				}
			}
		}

		internal static Sprite Icon(string prefab)
		{
			if (MeadworksHeadless.IsHeadless)
			{
				return null;
			}
			Load();
			if (!ids.TryGetValue(prefab, out string value))
			{
				throw new KeyNotFoundException("Original icon missing: " + prefab);
			}
			return bundle.LoadAsset<Sprite>(value + "_icon") ?? throw new InvalidDataException("Original icon sprite missing: " + value);
		}

		internal static GameObject Model(ZNetScene scene, string prefab)
		{
			if (MeadworksHeadless.IsHeadless)
			{
				return null;
			}
			GameObject val = (((Object)(object)scene != (Object)null) ? (scene.GetPrefab("SerpentScale") ?? scene.GetPrefab("TrollHide")) : null);
			if ((Object)(object)val == (Object)null && (Object)(object)ObjectDB.instance != (Object)null)
			{
				val = ObjectDB.instance.GetItemPrefab("SerpentScale") ?? ObjectDB.instance.GetItemPrefab("TrollHide");
			}
			return ModelCore(val, prefab, scene);
		}

		internal static GameObject Model(GameObject native, string prefab)
		{
			if (MeadworksHeadless.IsHeadless)
			{
				return null;
			}
			return ModelCore(native, prefab, ZNetScene.instance);
		}

		private static bool ActiveBelowRoot(Renderer renderer, Transform root)
		{
			Transform val = ((Component)renderer).transform;
			while ((Object)(object)val != (Object)(object)root)
			{
				if (!((Component)val).gameObject.activeSelf)
				{
					return false;
				}
				val = val.parent;
			}
			return true;
		}

		internal static Material NativeBaseMaterial(GameObject source)
		{
			Material? obj = (((Object)(object)source != (Object)null) ? (from renderer in source.GetComponentsInChildren<Renderer>(true)
				where (renderer is MeshRenderer || renderer is SkinnedMeshRenderer) && renderer.enabled && ActiveBelowRoot(renderer, source.transform)
				select renderer).SelectMany((Renderer renderer) => renderer.sharedMaterials).FirstOrDefault((Func<Material, bool>)((Material candidate) => (Object)(object)candidate != (Object)null && (Object)(object)candidate.shader != (Object)null && ((Object)candidate.shader).name.IndexOf("Snow", StringComparison.OrdinalIgnoreCase) < 0 && candidate.renderQueue <= 2500 && candidate.HasProperty("_MainTex") && (Object)(object)candidate.GetTexture("_MainTex") != (Object)null)) : null);
			if ((Object)(object)obj == (Object)null)
			{
				throw new InvalidOperationException("Native opaque base material with albedo unavailable: " + (((Object)(object)source != (Object)null) ? ((Object)source).name : "<null>"));
			}
			return obj;
		}

		private static GameObject ModelCore(GameObject native, string prefab, ZNetScene scene)
		{
			Load();
			if (!ids.TryGetValue(prefab, out string value))
			{
				throw new KeyNotFoundException("Original model missing: " + prefab);
			}
			if (models.TryGetValue(value, out GameObject value2) && (Object)(object)value2 != (Object)null)
			{
				return value2;
			}
			GameObject obj = bundle.LoadAsset<GameObject>(value) ?? throw new InvalidDataException("Original model prefab missing: " + value);
			Material nativeMaterial = NativeBaseMaterial(native);
			GameObject val = Object.Instantiate<GameObject>(obj);
			((Object)val).name = value;
			val.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)val);
			Dictionary<Material, Material> dress = new Dictionary<Material, Material>();
			Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer obj2 in componentsInChildren)
			{
				obj2.sharedMaterials = ((IEnumerable<Material>)obj2.sharedMaterials).Select((Func<Material, Material>)delegate(Material original)
				{
					//IL_0088: Unknown result type (might be due to invalid IL or missing references)
					//IL_008d: Unknown result type (might be due to invalid IL or missing references)
					//IL_00a4: Expected O, but got Unknown
					//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
					//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
					//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
					//IL_0242: Unknown result type (might be due to invalid IL or missing references)
					//IL_0218: Unknown result type (might be due to invalid IL or missing references)
					if (dress.TryGetValue(original, out Material value3))
					{
						return value3;
					}
					Material val2 = nativeMaterial;
					if (nativeMaterials.TryGetValue(((Object)original).name.Replace(" (Instance)", ""), out string value4))
					{
						GameObject val3 = (((Object)(object)scene != (Object)null) ? scene.GetPrefab(value4) : null);
						if ((Object)(object)val3 == (Object)null && (Object)(object)ObjectDB.instance != (Object)null)
						{
							val3 = ObjectDB.instance.GetItemPrefab(value4);
						}
						val2 = NativeBaseMaterial(val3);
					}
					Material val4 = new Material(val2)
					{
						name = "MW_" + ((Object)original).name
					};
					if (val4.HasProperty("_MainTex"))
					{
						val4.SetTexture("_MainTex", original.mainTexture);
					}
					if (val4.HasProperty("_Color"))
					{
						val4.SetColor("_Color", original.color);
					}
					val4.mainTextureScale = Vector2.one;
					val4.mainTextureOffset = Vector2.zero;
					if (val4.HasProperty("_BumpMap"))
					{
						val4.SetTexture("_BumpMap", (Texture)null);
					}
					string[] array = new string[3] { "_MetallicGlossMap", "_EmissionMap", "_StyleTex" };
					foreach (string text in array)
					{
						if (val4.HasProperty(text))
						{
							val4.SetTexture(text, (Texture)null);
						}
					}
					if (val4.HasProperty("_UseStyles"))
					{
						val4.SetFloat("_UseStyles", 0f);
					}
					val4.DisableKeyword("_USESTYLES_ON");
					if (val4.HasProperty("_Glossiness"))
					{
						val4.SetFloat("_Glossiness", original.GetFloat("_Glossiness"));
					}
					if (val4.HasProperty("_Metallic"))
					{
						val4.SetFloat("_Metallic", original.GetFloat("_Metallic"));
					}
					if (val4.HasProperty("_MetalGloss"))
					{
						val4.SetFloat("_MetalGloss", 0f);
					}
					if (val4.HasProperty("_EmissionColor") && original.IsKeywordEnabled("_EMISSION"))
					{
						val4.EnableKeyword("_EMISSION");
						val4.SetColor("_EmissionColor", original.GetColor("_EmissionColor"));
					}
					else if (val4.HasProperty("_EmissionColor"))
					{
						val4.DisableKeyword("_EMISSION");
						val4.SetColor("_EmissionColor", Color.black);
					}
					ownedMaterials.Add(val4);
					dress.Add(original, val4);
					return val4;
				}).ToArray();
			}
			models[value] = val;
			return val;
		}

		internal static GameObject Instantiate(ZNetScene scene, string prefab, Transform parent)
		{
			GameObject val = Model(scene, prefab);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			GameObject obj = Object.Instantiate<GameObject>(val, parent, false);
			((Object)obj).name = "meadworks_original_model";
			obj.SetActive(true);
			return obj;
		}

		internal static GameObject Instantiate(GameObject nativeMaterialItem, string prefab, Transform parent)
		{
			GameObject val = Model(nativeMaterialItem, prefab);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			GameObject obj = Object.Instantiate<GameObject>(val, parent, false);
			((Object)obj).name = "meadworks_original_model";
			obj.SetActive(true);
			return obj;
		}

		internal static void Shutdown()
		{
			foreach (GameObject value in models.Values)
			{
				if ((Object)(object)value != (Object)null)
				{
					Object.Destroy((Object)(object)value);
				}
			}
			models.Clear();
			foreach (Material ownedMaterial in ownedMaterials)
			{
				if ((Object)(object)ownedMaterial != (Object)null)
				{
					Object.Destroy((Object)(object)ownedMaterial);
				}
			}
			ownedMaterials.Clear();
			if ((Object)(object)bundle != (Object)null)
			{
				bundle.Unload(false);
			}
			bundle = null;
			ids = null;
			nativeMaterials = null;
		}
	}
}
namespace ExtraPotions.Mantle.Embedded.YamlConfig
{
	public sealed class YamlFileHub
	{
		private readonly string modName;

		private readonly ManualLogSource log;

		private readonly ExtraPotions.Mantle.Embedded.Charter.Charter? charter;

		private readonly List<YamlFileSet> sets = new List<YamlFileSet>();

		private readonly YamlFileStore store;

		private readonly YamlFileWatcher watcher;

		private bool loaded;

		public IReadOnlyList<YamlFileSet> Sets => sets;

		public bool IsAuthor => charter?.IsAuthor ?? true;

		public bool IsLocked
		{
			get
			{
				if (charter != null && charter.IsBound)
				{
					return !charter.MayAmend;
				}
				return false;
			}
		}

		public bool SuppressWriteBack { get; set; }

		public Func<bool> CanApply { get; set; } = () => true;

		public event Action<YamlFileSet>? Applied;

		public YamlFileHub(string modName, ManualLogSource log, IEnumerable<string> searchFolders, ExtraPotions.Mantle.Embedded.Charter.Charter? charter)
		{
			this.modName = modName;
			this.log = log;
			this.charter = charter;
			store = new YamlFileStore(modName, log, searchFolders);
			watcher = new YamlFileWatcher(store, sets, ReloadFromDisk, log, modName);
		}

		public YamlFileSet Register(YamlFileSet set)
		{
			if (sets.Any((YamlFileSet s) => string.Equals(s.SyncKey, set.SyncKey, StringComparison.OrdinalIgnoreCase)))
			{
				throw new ArgumentException(modName + ": a YAML file set with sync key '" + set.SyncKey + "' is already registered");
			}
			sets.Add(set);
			if (charter != null)
			{
				Article<List<string>> channel = new Article<List<string>>(charter, set.SyncKey, new List<string>());
				set.Channel = channel;
				channel.Changed += delegate
				{
					Receive(set, YamlFileList.Unflatten(channel.Value));
				};
			}
			return set;
		}

		public void LoadAll()
		{
			loaded = true;
			foreach (YamlFileSet set in sets)
			{
				LoadSet(set);
			}
			watcher.Start();
		}

		public void ApplyAll()
		{
			if (!CanApply())
			{
				log.LogDebug((object)(modName + ": YAML apply skipped, the game is not ready"));
				return;
			}
			foreach (YamlFileSet set in sets)
			{
				Apply(set);
			}
		}

		public bool TryBuild(YamlFileSet set, IReadOnlyDictionary<string, string> files, out YamlModel model, string context)
		{
			model = set.CreateModel();
			model.LoadAll(files);
			foreach (string warning in model.Warnings)
			{
				log.LogWarning((object)(modName + ": " + warning));
			}
			if (model.Errors.Count == 0)
			{
				return true;
			}
			log.LogError((object)$"{modName}: {set.MainFileName} ({context}) has {model.Errors.Count} error(s), the previous configuration stays:");
			foreach (string error in model.Errors)
			{
				log.LogError((object)(modName + ": " + error));
			}
			return false;
		}

		public void Replace(YamlFileSet set, IReadOnlyDictionary<string, string> files, bool saveToDisk)
		{
			if (TryBuild(set, files, out YamlModel _, "editor"))
			{
				Publish(set, files, saveToDisk);
			}
		}

		public void HookGame(Harmony harmony, int applyPriority)
		{
			YamlGameHooks.Install(this, harmony, applyPriority);
		}

		internal void LoadFromHook()
		{
			if (loaded)
			{
				return;
			}
			try
			{
				LoadAll();
			}
			catch (Exception arg)
			{
				log.LogError((object)$"{modName}: loading YAML files failed: {arg}");
			}
		}

		internal void ApplyFromHook()
		{
			try
			{
				ApplyAll();
			}
			catch (Exception arg)
			{
				log.LogError((object)$"{modName}: applying YAML files failed: {arg}");
			}
		}

		private void LoadSet(YamlFileSet set)
		{
			Dictionary<string, string> dictionary = store.ReadOrCreate(set);
			watcher.TakeSnapshot(set);
			YamlModel model;
			if (dictionary.Count == 0)
			{
				if (set.Enabled())
				{
					log.LogWarning((object)(modName + ": no " + set.FilePattern + " found in " + string.Join(" or ", store.SearchFolders)));
				}
			}
			else if (TryBuild(set, dictionary, out model, "startup"))
			{
				Publish(set, dictionary, writeBack: false);
			}
		}

		private void ReloadFromDisk(YamlFileSet set)
		{
			Dictionary<string, string> dictionary = store.Read(store.Discover(set));
			watcher.TakeSnapshot(set);
			YamlModel model;
			if (dictionary.Count == 0)
			{
				log.LogWarning((object)(modName + ": every " + set.FilePattern + " file is gone, keeping the loaded configuration"));
			}
			else if (TryBuild(set, dictionary, out model, "reload"))
			{
				Publish(set, dictionary, writeBack: false);
				log.LogInfo((object)(modName + ": " + set.MainFileName + " reloaded" + (IsAuthor ? "" : ", not applied, remote configuration active")));
			}
		}

		private void Publish(YamlFileSet set, IReadOnlyDictionary<string, string> files, bool writeBack)
		{
			bool suppressWriteBack = SuppressWriteBack;
			SuppressWriteBack = suppressWriteBack || !writeBack;
			try
			{
				if (set.Channel == null)
				{
					Receive(set, files);
				}
				else
				{
					set.Channel.Assign(YamlFileList.Flatten(files));
				}
			}
			finally
			{
				SuppressWriteBack = suppressWriteBack;
			}
		}

		private void Receive(YamlFileSet set, IReadOnlyDictionary<string, string> files)
		{
			if (!TryBuild(set, files, out YamlModel model, "received"))
			{
				foreach (KeyValuePair<string, string> file in files)
				{
					log.LogWarning((object)(modName + ": content of " + file.Key + ":\n" + file.Value));
				}
				return;
			}
			set.Files = files;
			set.Current = model;
			if (CanApply())
			{
				Apply(set);
			}
			if (IsAuthor && !SuppressWriteBack)
			{
				store.WriteAll(files);
				watcher.TakeSnapshot(set);
			}
		}

		private void Apply(YamlFileSet set)
		{
			if (set.Current == null || !set.Enabled())
			{
				return;
			}
			try
			{
				set.Apply(set.Current);
				this.Applied?.Invoke(set);
			}
			catch (Exception arg)
			{
				log.LogError((object)$"{modName}: applying {set.MainFileName} failed: {arg}");
			}
		}
	}
	internal static class YamlFileList
	{
		public static List<string> Flatten(IReadOnlyDictionary<string, string> files)
		{
			List<string> list = new List<string>(files.Count * 2);
			foreach (KeyValuePair<string, string> file in files)
			{
				list.Add(file.Key);
				list.Add(file.Value);
			}
			return list;
		}

		public static Dictionary<string, string> Unflatten(List<string>? list)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			int num = 0;
			while (list != null && num + 1 < list.Count)
			{
				dictionary[list[num]] = list[num + 1];
				num += 2;
			}
			return dictionary;
		}
	}
	public sealed class YamlFileSet
	{
		internal int ReloadPending;

		public string FilePattern { get; }

		public string MainFileName { get; }

		public string SyncKey { get; }

		public Func<YamlModel> CreateModel { get; }

		public Action<YamlModel> Apply { get; }

		public Func<bool> Enabled { get; set; } = () => true;

		public Func<byte[]?>? DefaultContent { get; set; }

		public Func<string> EditorLabel { get; set; }

		public IReadOnlyDictionary<string, string> Files { get; internal set; } = new Dictionary<string, string>();

		public YamlModel? Current { get; internal set; }

		internal Article<List<string>>? Channel { get; set; }

		internal Dictionary<string, DateTime> Snapshot { get; } = new Dictionary<string, DateTime>(StringComparer.OrdinalIgnoreCase);

		public YamlFileSet(string filePattern, string syncKey, Func<YamlModel> createModel, Action<YamlModel> apply)
		{
			FilePattern = filePattern;
			MainFileName = filePattern.Replace("*", "");
			SyncKey = syncKey;
			CreateModel = createModel;
			Apply = apply;
			EditorLabel = () => "Edit " + MainFileName;
		}
	}
	internal sealed class YamlFileStore
	{
		private readonly string modName;

		private readonly ManualLogSource log;

		private readonly List<string> searchFolders;

		public IReadOnlyList<string> SearchFolders => searchFolders;

		public YamlFileStore(string modName, ManualLogSource log, IEnumerable<string> searchFolders)
		{
			this.modName = modName;
			this.log = log;
			this.searchFolders = searchFolders.ToList();
		}

		public List<string> Discover(YamlFileSet set)
		{
			Regex nameFilter = new Regex("^" + Regex.Escape(set.FilePattern).Replace("\\*", ".*") + "$", RegexOptions.IgnoreCase);
			List<string> list = new List<string>();
			foreach (string item in searchFolders.Where(Directory.Exists))
			{
				list.AddRange(from p in Directory.GetFiles(item, set.FilePattern)
					where nameFilter.IsMatch(Path.GetFileName(p))
					select p);
			}
			return list.OrderBy((string p) => (!string.Equals(Path.GetFileName(p), set.MainFileName, StringComparison.OrdinalIgnoreCase)) ? 1 : 0).ThenBy<string, string>(Path.GetFileName, StringComparer.OrdinalIgnoreCase).ToList();
		}

		public Dictionary<string, string> Read(IEnumerable<string> paths)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			foreach (string path in paths)
			{
				try
				{
					dictionary[path] = File.ReadAllText(path);
				}
				catch (Exception ex)
				{
					log.LogError((object)(modName + ": reading " + path + " failed: " + ex.Message));
				}
			}
			return dictionary;
		}

		public Dictionary<string, string> ReadOrCreate(YamlFileSet set)
		{
			Dictionary<string, string> dictionary = Read(Discover(set));
			if (dictionary.Count <= 0)
			{
				return WriteDefault(set);
			}
			return dictionary;
		}

		public Dictionary<string, DateTime> WriteTimes(YamlFileSet set)
		{
			Dictionary<string, DateTime> dictionary = new Dictionary<string, DateTime>(StringComparer.OrdinalIgnoreCase);
			foreach (string item in Discover(set))
			{
				dictionary[item] = File.GetLastWriteTimeUtc(item);
			}
			return dictionary;
		}

		public void WriteAll(IReadOnlyDictionary<string, string> files)
		{
			foreach (KeyValuePair<string, string> file in files)
			{
				WriteAtomic(file.Key, file.Value);
			}
		}

		private Dictionary<string, string> WriteDefault(YamlFileSet set)
		{
			byte[] array = set.DefaultContent?.Invoke();
			if (array == null || searchFolders.Count == 0)
			{
				return new Dictionary<string, string>();
			}
			string text = Path.Combine(searchFolders[0], set.MainFileName);
			try
			{
				Directory.CreateDirectory(searchFolders[0]);
				File.WriteAllBytes(text, array);
				log.LogInfo((object)(modName + ": wrote default " + text));
			}
			catch (Exception ex)
			{
				log.LogError((object)(modName + ": writing default " + text + " failed: " + ex.Message));
				return new Dictionary<string, string>();
			}
			return Read(new string[1] { text });
		}

		private void WriteAtomic(string path, string content)
		{
			try
			{
				if (!File.Exists(path) || !(File.ReadAllText(path) == content))
				{
					ReplaceThroughTempFile(path, content);
					log.LogInfo((object)(modName + ": wrote " + path));
				}
			}
			catch (Exception ex)
			{
				log.LogError((object)(modName + ": writing " + path + " failed: " + ex.Message));
			}
		}

		private static void ReplaceThroughTempFile(string path, string content)
		{
			string text = path + ".tmp";
			File.WriteAllText(text, content, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
			if (File.Exists(path))
			{
				File.Replace(text, path, null);
			}
			else
			{
				File.Move(text, path);
			}
		}
	}
	internal sealed class YamlFileWatcher
	{
		private const int PollMilliseconds = 5000;

		private readonly YamlFileStore store;

		private readonly IReadOnlyList<YamlFileSet> sets;

		private readonly Action<YamlFileSet> reload;

		private readonly ManualLogSource log;

		private readonly string modName;

		private Timer? timer;

		public YamlFileWatcher(YamlFileStore store, IReadOnlyList<YamlFileSet> sets, Action<YamlFileSet> reload, ManualLogSource log, string modName)
		{
			this.store = store;
			this.sets = sets;
			this.reload = reload;
			this.log = log;
			this.modName = modName;
		}

		public void Start()
		{
			if (timer == null)
			{
				timer = new Timer(delegate
				{
					Poll();
				}, null, 5000, 5000);
			}
		}

		public void TakeSnapshot(YamlFileSet set)
		{
			Dictionary<string, DateTime> dictionary = store.WriteTimes(set);
			lock (set.Snapshot)
			{
				set.Snapshot.Clear();
				foreach (KeyValuePair<string, DateTime> item in dictionary)
				{
					set.Snapshot[item.Key] = item.Value;
				}
			}
		}

		private void Poll()
		{
			try
			{
				foreach (YamlFileSet set in sets.Where(HasChanged))
				{
					if (Interlocked.CompareExchange(ref set.ReloadPending, 1, 0) == 0)
					{
						ThreadingHelper.SynchronizingObject.BeginInvoke((Action)delegate
						{
							Reload(set);
						}, null);
					}
				}
			}
			catch (Exception ex)
			{
				log.LogError((object)(modName + ": watching YAML files failed: " + ex.Message));
			}
		}

		private bool HasChanged(YamlFileSet set)
		{
			Dictionary<string, DateTime> dictionary = store.WriteTimes(set);
			lock (set.Snapshot)
			{
				DateTime value;
				return dictionary.Count != set.Snapshot.Count || dictionary.Any((KeyValuePair<string, DateTime> pair) => !set.Snapshot.TryGetValue(pair.Key, out value) || value != pair.Value);
			}
		}

		private void Reload(YamlFileSet set)
		{
			try
			{
				reload(set);
			}
			catch (Exception arg)
			{
				log.LogError((object)$"{modName}: reloading {set.MainFileName} failed: {arg}");
			}
			finally
			{
				Interlocked.Exchange(ref set.ReloadPending, 0);
			}
		}
	}
	internal static class YamlGameHooks
	{
		private static class Patches
		{
			public static void AfterMenuStart()
			{
				LoadHooked();
			}

			public static void AfterNetworkStart(ZNet __instance)
			{
				if (__instance.IsServer() && __instance.IsDedicated())
				{
					LoadHooked();
				}
			}

			public static void AfterRespawnRequest(Game __instance)
			{
				object obj = firstSpawnField?.GetValue(__instance);
				if (obj is bool && (bool)obj)
				{
					ApplyHooked();
				}
			}
		}

		private static readonly List<YamlFileHub> hooked = new List<YamlFileHub>();

		private static readonly FieldInfo? firstSpawnField = AccessTools.Field(typeof(Game), "m_firstSpawn");

		private static bool patched;

		public static void Install(YamlFileHub hub, Harmony harmony, int applyPriority)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			if (!hooked.Contains(hub))
			{
				hooked.Add(hub);
			}
			if (!patched)
			{
				patched = true;
				harmony.Patch((MethodBase)AccessTools.Method(typeof(FejdStartup), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "AfterMenuStart", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				harmony.Patch((MethodBase)AccessTools.Method(typeof(ZNet), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "AfterNetworkStart", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				HarmonyMethod val = new HarmonyMethod(typeof(Patches), "AfterRespawnRequest", (Type[])null)
				{
					priority = applyPriority
				};
				harmony.Patch((MethodBase)AccessTools.Method(typeof(Game), "RequestRespawn", (Type[])null, (Type[])null), (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		private static void LoadHooked()
		{
			foreach (YamlFileHub item in hooked)
			{
				item.LoadFromHook();
			}
		}

		private static void ApplyHooked()
		{
			foreach (YamlFileHub item in hooked)
			{
				item.ApplyFromHook();
			}
		}
	}
	public sealed class YamlGroupTable
	{
		private readonly Dictionary<string, List<string>> members = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);

		private readonly Dictionary<string, List<string>> parents = new Dictionary<string, List<string>>(StringComparer.OrdinalIgnoreCase);

		public IReadOnlyCollection<string> Names => members.Keys;

		public bool IsGroup(string name)
		{
			return members.ContainsKey(name);
		}

		public void Add(string group, IEnumerable<string> names)
		{
			if (!members.TryGetValue(group, out List<string> value))
			{
				value = new List<string>();
				members.Add(group, value);
			}
			foreach (string name in names)
			{
				value.Add(name);
				if (!parents.TryGetValue(name, out List<string> value2))
				{
					value2 = new List<string>();
					parents.Add(name, value2);
				}
				value2.Add(group);
			}
		}

		public IReadOnlyList<string> Resolve(string name)
		{
			List<string> list = new List<string>();
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			Queue<string> queue = new Queue<string>();
			queue.Enqueue(name);
			while (queue.Count > 0)
			{
				if (!parents.TryGetValue(queue.Dequeue(), out List<string> value))
				{
					continue;
				}
				foreach (string item in value)
				{
					if (hashSet.Add(item))
					{
						list.Add(item);
						queue.Enqueue(item);
					}
				}
			}
			return list;
		}

		public IReadOnlyList<string> Expand(string group)
		{
			List<string> result = new List<string>();
			HashSet<string> seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			Expand(group, seen, result);
			return result;
		}

		private void Expand(string name, HashSet<string> seen, List<string> result)
		{
			if (!seen.Add(name))
			{
				return;
			}
			if (!members.TryGetValue(name, out List<string> value))
			{
				result.Add(name);
				return;
			}
			foreach (string item in value)
			{
				Expand(item, seen, result);
			}
		}
	}
	public abstract class YamlModel
	{
		private static readonly IDeserializer Parser = new DeserializerBuilder().Build();

		private string? currentFile;

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

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

		protected YamlGroupTable Groups { get; } = new YamlGroupTable();

		public void Load(string yamlText)
		{
			ReadText(yamlText);
			Verify();
		}

		public void LoadAll(IEnumerable<KeyValuePair<string, string>> files)
		{
			foreach (KeyValuePair<string, string> file in files)
			{
				currentFile = Path.GetFileName(file.Key);
				ReadText(file.Value);
			}
			currentFile = null;
			Verify();
		}

		public IReadOnlyList<string> ResolveGroups(string name)
		{
			return Groups.Resolve(name);
		}

		protected abstract void Read(YamlNode root);

		protected virtual void Verify()
		{
		}

		protected void ReadGroups(YamlNode root, string key = "groups")
		{
			foreach (KeyValuePair<string, YamlNode> entry in root.Get(key).Entries)
			{
				if (entry.Value.TryStringList(out List<string> items))
				{
					Groups.Add(entry.Key, items);
				}
			}
		}

		internal void AddError(string message)
		{
			Errors.Add(WithFile(message));
		}

		internal void AddWarning(string message)
		{
			Warnings.Add(WithFile(message));
		}

		private string WithFile(string message)
		{
			if (currentFile != null)
			{
				return currentFile + ": " + message;
			}
			return message;
		}

		private void ReadText(string yamlText)
		{
			if (TryParse(yamlText, out object graph) && graph != null)
			{
				if (!(graph is IDictionary<object, object>))
				{
					AddError("the file must be a map of keys at the top level, not " + ((graph is IList<object>) ? "a list" : "a single value"));
					return;
				}
				YamlNode yamlNode = new YamlNode(this, graph, "");
				Read(yamlNode);
				yamlNode.WarnUnknownKeys();
			}
		}

		private bool TryParse(string yamlText, out object? graph)
		{
			try
			{
				graph = Parser.Deserialize<object>(yamlText.TrimStart('\ufeff'));
				return true;
			}
			catch (Exception ex)
			{
				AddError("invalid YAML: " + ex.Message + ((ex.InnerException == null) ? "" : (" (" + ex.InnerException.Message + ")")));
				graph = null;
				return false;
			}
		}
	}
	public enum YamlNodeKind
	{
		Scalar,
		List,
		Map,
		Null,
		Missing
	}
	public sealed class YamlNode
	{
		private readonly YamlModel model;

		private readonly object? value;

		private List<KeyValuePair<string, YamlNode>>? mapEntries;

		private Dictionary<string, YamlNode>? mapLookup;

		private List<YamlNode>? listItems;

		private HashSet<string>? askedKeys;

		private bool visited;

		private bool shapeReported;

		public string Path { get; }

		public YamlNodeKind Kind { get; }

		public string? Text
		{
			get
			{
				if (Kind != YamlNodeKind.Scalar)
				{
					return null;
				}
				return Convert.ToString(value, CultureInfo.InvariantCulture);
			}
		}

		public int Count => Kind switch
		{
			YamlNodeKind.Map => MapEntries.Count, 
			YamlNodeKind.List => ListItems.Count, 
			_ => 0, 
		};

		public IReadOnlyList<KeyValuePair<string, YamlNode>> Entries
		{
			get
			{
				if (!ExpectShape(YamlNodeKind.Map, "a map"))
				{
					return Array.Empty<KeyValuePair<string, YamlNode>>();
				}
				visited = true;
				AskedKeys.UnionWith(MapEntries.Select<KeyValuePair<string, YamlNode>, string>((KeyValuePair<string, YamlNode> e) => e.Key));
				return MapEntries;
			}
		}

		public IReadOnlyList<YamlNode> Items
		{
			get
			{
				if (!ExpectShape(YamlNodeKind.List, "a list"))
				{
					return Array.Empty<YamlNode>();
				}
				return ListItems;
			}
		}

		private HashSet<string> AskedKeys => askedKeys ?? (askedKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase));

		private List<KeyValuePair<string, YamlNode>> MapEntries
		{
			get
			{
				if (mapEntries == null)
				{
					BuildMap();
				}
				return mapEntries;
			}
		}

		private Dictionary<string, YamlNode> MapLookup
		{
			get
			{
				if (mapLookup == null)
				{
					BuildMap();
				}
				return mapLookup;
			}
		}

		private List<YamlNode> ListItems
		{
			get
			{
				if (listItems == null)
				{
					IList<object> source = (IList<object>)value;
					listItems = source.Select((object item, int i) => new YamlNode(model, item, $"{Path}[{i}]")).ToList();
				}
				return listItems;
			}
		}

		internal YamlNode(YamlModel model, object? value, string path, YamlNodeKind kind)
		{
			this.model = model;
			this.value = value;
			Path = path;
			Kind = kind;
		}

		internal YamlNode(YamlModel model, object? value, string path)
			: this(model, value, path, KindOf(value))
		{
		}

		public YamlNode Get(string key)
		{
			string path = (string.IsNullOrEmpty(Path) ? key : (Path + "." + key));
			if (!ExpectShape(YamlNodeKind.Map, "a map"))
			{
				return new YamlNode(model, null, path, YamlNodeKind.Missing);
			}
			visited = true;
			AskedKeys.Add(key);
			if (!MapLookup.TryGetValue(key, out YamlNode result))
			{
				return new YamlNode(model, null, path, YamlNodeKind.Missing);
			}
			return result;
		}

		public bool Is(string keyword)
		{
			if (Kind == YamlNodeKind.Scalar)
			{
				return string.Equals(Text.Trim(), keyword, StringComparison.OrdinalIgnoreCase);
			}
			return false;
		}

		public void Error(string message)
		{
			model.AddError(Prefixed(message));
		}

		public void Warn(string message)
		{
			model.AddWarning(Prefixed(message));
		}

		public void WarnUnknownKeys()
		{
			if (Kind == YamlNodeKind.Map && visited)
			{
				List<string> list = (from e in MapEntries
					select e.Key into k
					where !AskedKeys.Contains(k)
					select k).ToList();
				if (list.Count > 0)
				{
					Warn("unknown keys " + string.Join(", ", list));
				}
				{
					foreach (KeyValuePair<string, YamlNode> mapEntry in MapEntries)
					{
						mapEntry.Value.WarnUnknownKeys();
					}
					return;
				}
			}
			if (Kind == YamlNodeKind.List && listItems != null)
			{
				listItems.ForEach(delegate(YamlNode item)
				{
					item.WarnUnknownKeys();
				});
			}
		}

		private string Prefixed(string message)
		{
			if (!string.IsNullOrEmpty(Path))
			{
				return Path + ": " + message;
			}
			return message;
		}

		private void BuildMap()
		{
			mapEntries = new List<KeyValuePair<string, YamlNode>>();
			mapLookup = new Dictionary<string, YamlNode>(StringComparer.OrdinalIgnoreCase);
			foreach (KeyValuePair<object, object> item in (IDictionary<object, object>)value)
			{
				string text = Convert.ToString(item.Key, CultureInfo.InvariantCulture) ?? "";
				string path = (string.IsNullOrEmpty(Path) ? text : (Path + "." + text));
				YamlNode yamlNode = new YamlNode(model, item.Value, path);
				if (mapLookup.ContainsKey(text))
				{
					yamlNode.Warn("duplicate key (differs only in case), ignored");
					continue;
				}
				mapLookup.Add(text, yamlNode);
				mapEntries.Add(new KeyValuePair<string, YamlNode>(text, yamlNode));
			}
		}

		private bool ExpectShape(YamlNodeKind wanted, string description)
		{
			if (Kind == wanted)
			{
				return true;
			}
			if (Kind != YamlNodeKind.Missing && !shapeReported)
			{
				shapeReported = true;
				Error((Kind == YamlNodeKind.Null) ? ("expected " + description + " but the key has no value") : ("expected " + description + ", found " + Describe(Kind)));
			}
			return false;
		}

		private static string Describe(YamlNodeKind kind)
		{
			return kind switch
			{
				YamlNodeKind.Scalar => "a single value", 
				YamlNodeKind.List => "a list", 
				YamlNodeKind.Map => "a map", 
				_ => "nothing", 
			};
		}

		private static YamlNodeKind KindOf(object? value)
		{
			if (value != null)
			{
				if (!(value is IDictionary<object, object>))
				{
					if (value is IList<object>)
					{
						return YamlNodeKind.List;
					}
					return YamlNodeKind.Scalar;
				}
				return YamlNodeKind.Map;
			}
			return YamlNodeKind.Null;
		}

		public bool TryInt(out int result)
		{
			return TryScalar<int>(out result);
		}

		public bool TryFloat(out float result)
		{
			return TryScalar<float>(out result);
		}

		public bool TryBool(out bool result)
		{
			return TryScalar<bool>(out result);
		}

		public bool TryString(out string result)
		{
			return TryScalar<string>(out result);
		}

		public bool TryEnum<T>(out T result) where T : struct, Enum
		{
			return TryScalar<T>(out result);
		}

		public bool TryList<T>(out List<T> items)
		{
			items = new List<T>();
			if (!ExpectShape(YamlNodeKind.List, "a list of " + YamlScalarParser.Plural<T>()))
			{
				return false;
			}
			bool result = true;
			foreach (YamlNode listItem in ListItems)
			{
				if (listItem.TryScalar<T>(out var result2))
				{
					items.Add(result2);
				}
				else
				{
					result = false;
				}
			}
			return result;
		}

		public bool TryStringList(out List<string> items)
		{
			if (Kind == YamlNodeKind.Scalar)
			{
				items = new List<string> { Text };
				return true;
			}
			return TryList(out items);
		}

		private bool TryScalar<T>(out T result)
		{
			result = default(T);
			if (!ExpectShape(YamlNodeKind.Scalar, YamlScalarParser.Describe(typeof(T))))
			{
				return false;
			}
			if (YamlScalarParser.TryParse(Text, typeof(T), out object result2))
			{
				result = (T)result2;
				return true;
			}
			Error("'" + Text + "' is not " + YamlScalarParser.Describe(typeof(T)));
			return false;
		}
	}
	internal static class YamlScalarParser
	{
		private static readonly string[] TrueWords = new string[4] { "true", "yes", "on", "1" };

		private static readonly string[] FalseWords = new string[4] { "false", "no", "off", "0" };

		public static bool TryParse(string text, Type type, out object? result)
		{
			string text2 = text.Trim();
			result = null;
			if (type == typeof(string))
			{
				result = text;
				return true;
			}
			if (type == typeof(int))
			{
				int result3;
				bool result2 = int.TryParse(text2, NumberStyles.Integer, CultureInfo.InvariantCulture, out result3);
				result = result3;
				return result2;
			}
			if (type == typeof(float))
			{
				float result5;
				bool result4 = float.TryParse(text2, NumberStyles.Float, CultureInfo.InvariantCulture, out result5);
				result = result5;
				return result4;
			}
			if (!(type == typeof(bool)))
			{
				return TryParseEnum(text2, type, out result);
			}
			return TryParseBool(text2, out result);
		}

		public static string Describe(Type type)
		{
			if (type == typeof(int))
			{
				return "an integer";
			}
			if (type == typeof(float))
			{
				return "a number";
			}
			if (type == typeof(bool))
			{
				return "true or false";
			}
			if (!type.IsEnum)
			{
				return "text";
			}
			return "one of " + string.Join(", ", Enum.GetNames(type));
		}

		public static string Plural<T>()
		{
			if (!(typeof(T) == typeof(int)))
			{
				if (!(typeof(T) == typeof(float)))
				{
					if (!(typeof(T) == typeof(bool)))
					{
						if (!typeof(T).IsEnum)
						{
							return "text values";
						}
						return "names (" + string.Join(", ", Enum.GetNames(typeof(T))) + ")";
					}
					return "true/false values";
				}
				return "numbers";
			}
			return "integers";
		}

		private static bool TryParseBool(string text, out object? result)
		{
			if (TrueWords.Contains<string>(text, StringComparer.OrdinalIgnoreCase))
			{
				result = true;
				return true;
			}
			result = false;
			return FalseWords.Contains<string>(text, StringComparer.OrdinalIgnoreCase);
		}

		private static bool TryParseEnum(string text, Type type, out object? result)
		{
			if (!type.IsEnum)
			{
				throw new NotSupportedException("YamlNode cannot read values of type " + type.Name);
			}
			string text2 = Enum.GetNames(type).FirstOrDefault((string n) => string.Equals(n, text, StringComparison.OrdinalIgnoreCase));
			result = ((text2 == null) ? null : Enum.Parse(type, text2));
			return text2 != null;
		}
	}
}
namespace ExtraPotions.Mantle.Embedded.WindowInput
{
	public static class GameWindow
	{
		private sealed class Entry
		{
			public Func<bool> IsOpen;

			public Action Close;
		}

		private static readonly List<Entry> windows = new List<Entry>();

		public static bool AnyOpen
		{
			get
			{
				foreach (Entry window in windows)
				{
					if (Open(window))
					{
						return true;
					}
				}
				return false;
			}
		}

		public static void Install(Harmony harmony)
		{
			WindowPatches.Install(harmony);
		}

		public static void Add(Func<bool> isOpen, Action close)
		{
			windows.Add(new Entry
			{
				IsOpen = isOpen,
				Close = close
			});
		}

		public static bool CloseOpen()
		{
			bool result = false;
			foreach (Entry window in windows)
			{
				if (Open(window))
				{
					window.Close();
					result = true;
				}
			}
			return result;
		}

		private static bool Open(Entry window)
		{
			try
			{
				return window.IsOpen();
			}
			catch (Exception)
			{
				return false;
			}
		}
	}
	internal static class WindowPatches
	{
		private static bool patched;

		public static void Install(Harmony harmony)
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			if (!patched)
			{
				patched = true;
				Postfix(harmony, AccessTools.Method(typeof(Player), "TakeInput", (Type[])null, (Type[])null), "NoPlayerInput");
				Postfix(harmony, AccessTools.Method(typeof(PlayerController), "InInventoryEtc", (Type[])null, (Type[])null), "InWindow");
				Postfix(harmony, AccessTools.Method(typeof(GameCamera), "UpdateMouseCapture", (Type[])null, (Type[])null), "FreeCursor");
				Postfix(harmony, AccessTools.Method(typeof(ZInput), "GetMouseScrollWheel", (Type[])null, (Type[])null), "NoZoom");
				harmony.Patch((MethodBase)AccessTools.Method(typeof(Menu), "Update", (Type[])null, (Type[])null), new HarmonyMethod(typeof(WindowPatches), "Escape", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		private static void Postfix(Harmony harmony, MethodInfo target, string patch)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			harmony.Patch((MethodBase)target, (HarmonyMethod)null, new HarmonyMethod(typeof(WindowPatches), patch, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static void NoPlayerInput(ref bool __result)
		{
			if (__result && GameWindow.AnyOpen)
			{
				__result = false;
			}
		}

		private static void InWindow(ref bool __result)
		{
			if (!__result && GameWindow.AnyOpen)
			{
				__result = true;
			}
		}

		private static void FreeCursor()
		{
			if (GameWindow.AnyOpen && !Menu.IsVisible())
			{
				ZCursor.LockState = (CursorLockMode)0;
				ZCursor.Show();
			}
		}

		private static void NoZoom(ref float __result)
		{
			if (__result != 0f && GameWindow.AnyOpen)
			{
				__result = 0f;
			}
		}

		private static bool Escape(Menu __instance)
		{
			if ((Object)(object)__instance.m_root == (Object)null || ((Component)__instance.m_root).gameObject.activeSelf || !ZInput.GetKeyDown((KeyCode)27, true))
			{
				return true;
			}
			return !GameWindow.CloseOpen();
		}
	}
}
namespace ExtraPotions.Mantle.Embedded.SyncedConfig
{
	public sealed class SyncedConfiguration
	{
		public ExtraPotions.Mantle.Embedded.Charter.Charter Sync { get; }

		public ConfigFile Config { get; }

		public ManualLogSource Log { get; }

		public YamlFileHub Yaml { get; }

		public IReadOnlyList<string> SearchPaths { get; }

		public IDisposable? ConfigWatcher { get; private set; }

		public bool IsLocked
		{
			get
			{
				if (Sync.IsBound)
				{
					return !Sync.MayAmend;
				}
				return false;
			}
		}

		public bool IsAdmin => Sync.IsSteward;

		public bool IsAuthor => Sync.IsAuthor;

		public SyncedConfiguration(BaseUnityPlugin plugin, ManualLogSource log, string title, string version, string? oldestAccepted = null, bool mandatory = true)
		{
			Config = plugin.Config;
			Log = log;
			string gUID = plugin.Info.Metadata.GUID;
			Sync = new ExtraPotions.Mantle.Embedded.Charter.Charter(gUID, title, version, oldestAccepted, mandatory);
			SearchPaths = new string[2]
			{
				Path.GetDirectoryName(Config.ConfigFilePath) ?? Paths.ConfigPath,
				Path.GetDirectoryName(((object)plugin).GetType().Assembly.Location) ?? Paths.PluginPath
			};
			Yaml = new YamlFileHub(title, Log, SearchPaths, Sync);
		}

		public ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, string description, bool synced = true, AcceptableValueBase? acceptableValues = null, params object[] tags)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			return Bind(section, key, defaultValue, new ConfigDescription(description, acceptableValues, tags), synced);
		}

		public ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, ConfigDescription description, bool synced = true)
		{
			ConfigEntry<T> val = Config.Bind<T>(section, key, defaultValue, description);
			Sync.Clause<T>(val, !synced);
			return val;
		}

		public Clause<T> Add<T>(ConfigEntry<T> entry, bool synced = true)
		{
			return Sync.Clause<T>(entry, !synced);
		}

		public ConfigEntry<bool> BindLocking(string section, string key, bool defaultValue, string description)
		{
			ConfigEntry<bool> val = Config.Bind<bool>(section, key, defaultValue, description);
			Sync.Binding(val);
			return val;
		}

		public YamlFileSet AddYaml(YamlFileSet set)
		{
			return Yaml.Register(set);
		}

		public void Finish(Harmony harmony, int yamlApplyPriority = 400)
		{
			ExtraPotions.Mantle.Embedded.Charter.Charter.Install(harmony);
			ConfigWatcher = ConfigReloader.Setup(Config, Log, saveNow: true, Sync.HoldsServerValue, Sync.ReloadKeepingServerValues);
			if (Yaml.Sets.Count > 0)
			{
				Yaml.HookGame(harmony, yamlApplyPriority);
			}
		}

		public static Func<byte[]?> EmbeddedResource(Assembly assembly, string resourceName)
		{
			return delegate
			{
				using Stream stream = assembly.GetManifestResourceStream(resourceName);
				if (stream != null)
				{
					using MemoryStream memoryStream = new MemoryStream();
					stream.CopyTo(memoryStream);
					return memoryStream.ToArray();
				}
				return (byte[]?)null;
			};
		}
	}
}
namespace ExtraPotions.Mantle.Embedded.PlateColumn
{
	internal static class BoxContainer
	{
		public const string Name = "PlateColumn_boxes";

		private const string PanelBackground = "Bkg";

		public static bool Is(Transform? t, Transform panel)
		{
			if ((Object)(object)t != (Object)null && (Object)(object)t.parent == (Object)(object)panel)
			{
				return ((Object)t).name == "PlateColumn_boxes";
			}
			return false;
		}

		public static RectTransform Get(RectTransform panel)
		{
			Transform obj = ((Transform)panel).Find("PlateColumn_boxes");
			RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null);
			if ((Object)(object)val == (Object)null)
			{
				val = Make(panel);
			}
			PlaceAfterBackground((Transform)(object)panel, (Transform)(object)val);
			if (!PlateParts.Carries(((Component)val).gameObject, typeof(SeatWatch)))
			{
				((Component)val).gameObject.AddComponent<SeatWatch>();
			}
			return val;
		}

		private static RectTransform Make(RectTransform panel)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			GameObject val = new GameObject("PlateColumn_boxes", new Type[1] { typeof(RectTransform) });
			val.layer = ((Component)panel).gameObject.layer;
			RectTransform val2 = (RectTransform)val.transform;
			((Transform)val2).SetParent((Transform)(object)panel, false);
			val2.anchorMin = Vector2.one;
			val2.anchorMax = Vector2.one;
			val2.pivot = new Vector2(0f, 1f);
			val2.anchoredPosition = new Vector2(8f, -6f);
			val2.sizeDelta = new Vector2(64f, 64f);
			Stack(val);
			return val2;
		}

		private static void Stack(GameObject go)
		{
			VerticalLayoutGroup obj = go.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 6f;
			((LayoutGroup)obj).childAlignment = (TextAnchor)1;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			go.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
		}

		private static void PlaceAfterBackground(Transform panel, Transform boxes)
		{
			Transform val = panel.Find("Bkg");
			if (!((Object)(object)val == (Object)null))
			{
				int siblingIndex = val.GetSiblingIndex();
				int siblingIndex2 = boxes.GetSiblingIndex();
				if (siblingIndex2 != siblingIndex + 1)
				{
					boxes.SetSiblingIndex((siblingIndex2 < siblingIndex) ? siblingIndex : (siblingIndex + 1));
				}
			}
		}
	}
	internal sealed class BoxStack
	{
		private readonly RectTransform panel;

		public RectTransform Boxes { get; }

		public GamePlates Game { get; }

		private BoxStack(RectTransform panel, RectTransform boxes, GamePlates game)
		{
			this.panel = panel;
			Boxes = boxes;
			Game = game;
		}

		public static BoxStack? Ready(InventoryGui gui)
		{
			GamePlates gamePlates = (MantleOwner.LaysOutInventory ? GamePlates.Find(gui) : null);
			if (gamePlates == null)
			{
				return null;
			}
			BoxStack boxStack = new BoxStack(gui.m_player, BoxContainer.Get(gui.m_player), gamePlates);
			boxStack.Adopt();
			BoxStyle.Apply(gamePlates.Armor);
			BoxStyle.Apply(gamePlates.Weight);
			Seats.Seat(boxStack.panel, boxStack.Boxes, gamePlates.Armor, 100);
			Seats.Seat(boxStack.panel, boxStack.Boxes, gamePlates.Weight, 300);
			Seats.SeatGuests(boxStack.panel, boxStack.Boxes);
			gamePlates.Tip(gui);
			boxStack.Order();
			return boxStack;
		}

		public void Order()
		{
			Seats.Arrange(panel, Boxes);
		}

		private void Adopt()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			List<Transform> list = new List<Transform>();
			foreach (Transform item in (Transform)panel)
			{
				Transform val = item;
				if (ColumnLayout.IsMember(val))
				{
					list.Add(val);
				}
			}
			foreach (Transform item2 in list)
			{
				item2.SetParent((Transform)(object)Boxes, false);
			}
		}
	}
	internal static class BoxStyle
	{
		private const float IconSize = 30f;

		private const float IconAloneSize = 40f;

		private const float IconTop = 6f;

		private const float TextHeight = 22f;

		private const float TextSide = 4f;

		private const float TextBottom = 4f;

		private const float FontMin = 10f;

		private const float FontMax = 16f;

		public static void Apply(RectTransform box)
		{
			Image val = PlateParts.BackgroundOf((Transform)(object)box);
			if ((Object)(object)val == (Object)null || Skin.IsBox(val.sprite))
			{
				return;
			}
			TMP_Text componentInChildren = ((Component)box).GetComponentInChildren<TMP_Text>(true);
			Transform val2 = PlateParts.ChildHolding((Transform)(object)box, ((Object)(object)componentInChildren != (Object)null) ? componentInChildren.transform : null);
			Image val3 = PlateParts.IconOf((Transform)(object)box, val2);
			Frame(box);
			Background(val);
			if ((Object)(object)val3 != (Object)null)
			{
				Icon(val3);
			}
			if ((Object)(object)componentInChildren != (Object)null)
			{
				RectTransform val4 = (RectTransform)(object)((val2 is RectTransform) ? val2 : null);
				if (val4 != null)
				{
					Caption(componentInChildren, val4);
				}
			}
		}

		public static void IconAlone(Image icon)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			RectTransform rectTransform = ((Graphic)icon).rectTransform;
			rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
			rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			rectTransform.sizeDelta = new Vector2(40f, 40f);
			rectTransform.anchoredPosition = Vector2.zero;
		}

		private static void Frame(RectTransform box)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			box.anchorMin = new Vector2(0f, 1f);
			box.anchorMax = new Vector2(0f, 1f);
			box.pivot = new Vector2(0.5f, 0.5f);
			box.sizeDelta = new Vector2(64f, 64f);
			((Transform)box).localScale = Vector3.one;
		}

		private static void Background(Image image)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			Stretch(((Graphic)image).rectTransform);
			image.sprite = Skin.Box;
			image.type = (Type)1;
			image.fillCenter = true;
			image.pixelsPerUnitMultiplier = 1f;
			image.preserveAspect = false;
			((Graphic)image).color = Color.white;
			((Graphic)image).material = null;
			((Graphic)image).raycastTarget = true;
			((Transform)((Graphic)image).rectTransform).SetSiblingIndex(0);
		}

		private static void Icon(Image icon)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			RectTransform rectTransform = ((Graphic)icon).rectTransform;
			rectTransform.anchorMin = new Vector2(0.5f, 1f);
			rectTransform.anchorMax = new Vector2(0.5f, 1f);
			rectTransform.pivot = new Vector2(0.5f, 1f);
			rectTransform.sizeDelta = new Vector2(30f, 30f);
			rectTransform.anchoredPosition = new Vector2(0f, -6f);
			icon.type = (Type)0;
			icon.preserveAspect = true;
			((Transform)rectTransform).SetSiblingIndex(1);
		}

		private static void Caption(TMP_Text text, RectTransform line)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			line.anchorMin = new Vector2(0f, 0f);
			line.anchorMax = new Vector2(1f, 0f);
			line.pivot = new Vector2(0.5f, 0f);
			line.sizeDelta = new Vector2(-8f, 22f);
			line.anchoredPosition = new Vector2(0f, 4f);
			if ((Object)(object)text.rectTransform != (Object)(object)line)
			{
				Stretch(text.rectTransform);
			}
			text.alignment = (TextAlignmentOptions)514;
			text.enableAutoSizing = true;
			text.fontSizeMin = 10f;
			text.fontSizeMax = 16f;
			text.textWrappingMode = (TextWrappingModes)0;
			text.margin = Vector4.zero;
		}

		private static void Stretch(RectTransform rect)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			rect.anchorMin = Vector2.zero;
			rect.anchorMax = Vector2.one;
			rect.pivot = new Vector2(0.5f, 0.5f);
			rect.offsetMin = Vector2.zero;
			rect.offsetMax = Vector2.zero;
		}
	}
	public static class Column
	{
		public const int ArmorRank = 100;

		public const int WeightRank = 300;

		public const float Left = 8f;

		public const float BoxSize = 64f;

		public const float Spacing = 6f;

		public const float Top = 6f;

		public static bool Active => MantleOwner.LaysOutInventory;

		public static bool Arrange(InventoryGui gui)
		{
			return BoxStack.Ready(gui) != null;
		}

		public static RectTransform? Boxes(InventoryGui gui)
		{
			return BoxStack.Ready(gui)?.Boxes;
		}

		public static Plate? Add(InventoryGui gui, PlateSpec spec)
		{
			BoxStack boxStack = BoxStack.Ready(gui);
			if (boxStack == null)
			{
				return null;
			}
			string text = ColumnLayout.NameOf(spec);
			Transform obj = ((Transform)boxStack.Boxes).Find(text);
			RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null);
			Plate plate = ((val != null) ? PlateCopy.Wrap(val) : PlateCopy.Make(boxStack.Game.Armor, spec, text, (Transform?)(object)boxStack.Boxes));
			if (plate != null)
			{
				PlateTips.Set(gui, plate.Rect, spec.Topic, spec.Tip);
				boxStack.Order();
			}
			return plate;
		}

		public static void BoxesIn(RectTransform boxes, List<RectTransform> into)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			into.Clear();
			Transform parent = ((Transform)boxes).parent;
			RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
			foreach (Transform item in (Transform)boxes)
			{
				Transform val2 = item;
				object obj;
				if ((Object)(object)val != (Object)null)
				{
					RectTransform val3 = (RectTransform)(object)((val2 is RectTransform) ? val2 : null);
					if (val3 != null)
					{
						obj = Seats.BoxOf(val, val3);
						goto IL_004c;
					}
				}
				obj = ((val2 is RectTransform) ? val2 : null);
				goto IL_004c;
				IL_004c:
				RectTransform val4 = (RectTransform)obj;
				if ((Object)(object)val4 != (Object)null)
				{
					into.Add(val4);
				}
			}
		}

		public static bool DressTooltip(InventoryGui gui, UITooltip tooltip)
		{
			GameObject val = TipTemplate.For(gui);
			if ((Object)(object)val == (Object)null || (Object)(object)tooltip == (Object)null)
			{
				return false;
			}
			tooltip.m_tooltipPrefab = val;
			return true;
		}
	}
	internal static class ColumnLayout
	{
		private const string PlatePrefix = "PlateColumn_plate_";

		private const string SeatMark = "_seat_";

		private const int RankDigits = 4;

		private const string LegacyTrash = "OpenKeep_trash";

		private const int LegacyTrashRank = 200;

		public static string NameOf(PlateSpec spec)
		{
			return string.Format("{0}{1:D4}_{2}", "PlateColumn_plate_", spec.Rank, spec.Id);
		}

		public static string SeatName(int rank, string occupant)
		{
			return string.Format("{0}{1:D4}{2}{3}", "PlateColumn_plate_", Mathf.Clamp(rank, 0, 9999), "_seat_", occupant);
		}

		public static bool IsMember(Transform t)
		{
			return RankOf(((Object)t).name).HasValue;
		}

		public static string? OccupantOf(string name)
		{
			int num = "PlateColumn_plate_".Length + 4;
			if (name.Length <= num + "_seat_".Length || !name.StartsWith("PlateColumn_plate_", StringComparison.Ordinal))
			{
				return null;
			}
			if (string.CompareOrdinal(name, num, "_seat_", 0, "_seat_".Length) != 0)
			{
				return null;
			}
			return name.Substring(num + "_seat_".Length);
		}

		public static List<RectTransform> Sorted(Transform parent)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			List<KeyValuePair<string, RectTransform>> list = new List<KeyValuePair<string, RectTransform>>();
			foreach (Transform item in parent)
			{
				Transform val = item;
				RectTransform val2 = (RectTransform)(object)((val is RectTransform) ? val : null);
				if (val2 != null)
				{
					string text = KeyOf(val);
					if (text != null)
					{
						list.Add(new KeyValuePair<string, RectTransform>(text, val2));
					}
				}
			}
			list.Sort((KeyValuePair<string, RectTransform> a, KeyValuePair<string, RectTransform> b) => string.CompareOrdinal(a.Key, b.Key));
			return list.ConvertAll((KeyValuePair<string, RectTransform> pair) => pair.Value);
		}

		private static string? KeyOf(Transform t)
		{
			string name = ((Object)t).name;
			int? num = RankOf(name);
			if (num.HasValue)
			{
				int valueOrDefault = num.GetValueOrDefault();
				return $"{valueOrDefault:D4}{name}";
			}
			return null;
		}

		private static int? RankOf(string name)
		{
			if (name == "OpenKeep_trash")
			{
				return 200;
			}
			if (!name.StartsWith("PlateColumn_plate_", StringComparison.Ordinal) || name.Length < "PlateColumn_plate_".Length + 4)
			{
				return null;
			}
			if (!int.TryParse(name.Substring("PlateColumn_plate_".Length, 4), out var result))
			{
				return null;
			}
			return result;
		}
	}
	internal sealed class ColumnWatch : MonoBehaviour
	{
		private int seen = int.MinValue;

		private void LateUpdate()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			int num = Shape(((Component)this).transform);
			if (num != seen)
			{
				seen = num;
				LayoutRebuilder.MarkLayoutForRebuild((RectTransform)((Component)this).transform);
			}
		}

		public static int Shape(Transform boxes)
		{
			int num = boxes.childCount;
			for (int i = 0; i < boxes.childCount; i++)
			{
				num = num * 31 + (((Component)boxes.GetChild(i)).gameObject.activeSelf ? 1 : 0);
			}
			return num;
		}
	}
	public static class EmbeddedSprite
	{
		public static Sprite? Load(Assembly assembly, string resource, string spriteName)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = Read(assembly, resource);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true)
			{
				filterMode = (FilterMode)2,
				wrapMode = (TextureWrapMode)1
			};
			if (array == null || !Decode(val, array))
			{
				Object.Destroy((Object)(object)val);
				return null;
			}
			Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
			((Object)obj).name = spriteName;
			return obj;
		}

		private static bool Decode(Texture2D texture, byte[] png)
		{
			MethodInfo methodInfo = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule")?.GetMethod("LoadImage", new Type[3]
			{
				typeof(Texture2D),
				typeof(byte[]),
				typeof(bool)
			});
			if (methodInfo != null)
			{
				return (bool)methodInfo.Invoke(null, new object[3] { texture, png, true });
			}
			return false;
		}

		private static byte[]? Read(Assembly assembly, string resource)
		{
			using Stream stream = assembly.GetManifestResourceStream(resource);
			if (stream == null)
			{
				return null;
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}
	}
	internal sealed class GamePlates
	{
		private const string ArmorTopic = "Armor";

		private const string ArmorTip = "The armor of everything you wear. It reduces the damage of every hit you take.";

		private const string WeightTopic = "Carry weight";

		private const string WeightTip = "What you carry, out of the most you can carry. Over it you are encumbered and cannot run.";

		public RectTransform Armor { get; }

		public RectTransform Weight { get; }

		private GamePlates(RectTransform armor, RectTransform weight)
		{
			Armor = armor;
			Weight = weight;
		}

		public static GamePlates? Find(InventoryGui gui)
		{
			if ((Object)(object)gui == (Object)null || (Object)(object)gui.m_player == (Object)null || (Object)(object)gui.m_armor == (Object)null || (Object)(object)gui.m_weight == (Object)null)
			{
				return null;
			}
			RectTransform val = PlateOf(gui.m_player, gui.m_armor.transform);
			RectTransform val2 = PlateOf(gui.m_player, gui.m_weight.transform);
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val == (Object)(object)val2)
			{
				return null;
			}
			return new GamePlates(val, val2);
		}

		public void Tip(InventoryGui gui)
		{
			PlateTips.SetIfMissing(gui, Armor, "Armor", "The armor of everything you wear. It reduces the damage of every hit you take.");
			PlateTips.SetIfMissing(gui, Weight, "Carry weight", "What you carry, out of the most you can carry. Over it you are encumbered and cannot run.");
		}

		private static RectTransform? PlateOf(RectTransform panel, Transform text)
		{
			Transform val = text;
			while ((Object)(object)val != (Object)null && (Object)(object)val.parent != (Object)(object)panel && !BoxContainer.Is(val.parent, (Transform)(object)panel))
			{
				val = val.parent;
			}
			return (RectTransform?)(object)((val is RectTransform) ? val : null);
		}
	}
	internal sealed class Guests
	{
		private const string BoxPart = "armor_icon";

		private static readonly List<Canvas> Canvases = new List<Canvas>();

		public static readonly Guests[] Known = new Guests[3]
		{
			new Guests("Jewelcrafting Synergy", 110),
			new Guests("Trash", 125),
			new Guests("CoinPocketUI", 200)
		};

		public string Name { get; }

		public int Rank { get; }

		public string Seat { get; }

		private Guests(string name, int rank)
		{
			Name = name;
			Rank = rank;
			Seat = ColumnLayout.SeatName(rank, name);
		}

		public static bool LooksLikeBox(Transform box)
		{
			return (Object)(object)box.Find("armor_icon") != (Object)null;
		}

		public static void Lift(RectTransform box, Canvas root)
		{
			((Component)box).GetComponentsInChildren<Canvas>(true, Canvases);
			foreach (Canvas canvase in Canvases)
			{
				if (canvase.overrideSorting && canvase.sortingOrder <= root.sortingOrder)
				{
					canvase.sortingOrder = root.sortingOrder + 1;
				}
			}
			Canvases.Clear();
		}

		public static void Dress(RectTransform box)
		{
			MonoBehaviour[] components = ((Component)box).GetComponents<MonoBehaviour>();
			foreach (MonoBehaviour val in components)
			{
				if ((Object)(object)val != (Object)null && ((object)val).GetType().FullName == typeof(PlateTip).FullName)
				{
					Object.Destroy((Object)(object)val);
				}
			}
		}
	}
	internal static class HudContainer
	{
		public const string Name = "PlateColumn_hudboxes";

		public static RectTransform? Get()
		{
			GameObject val = (((Object)(object)Minimap.instance != (Object)null) ? Minimap.instance.m_smallRoot : null);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Transform obj = val.transform.Find("PlateColumn_hudboxes");
			RectTransform val2 = (RectTransform)(object)((obj is RectTransform) ? obj : null);
			if (val2 == null)
			{
				return Make(val.transform);
			}
			HorizontalLayoutGroup component = ((Component)val2).GetComponent<HorizontalLayoutGroup>();
			if (component != null)
			{
				Object.DestroyImmediate((Object)(object)component);
				Shape(val2);
			}
			return val2;
		}

		private static RectTransform Make(Transform small)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("PlateColumn_hudboxes", new Type[1] { typeof(RectTransform) });
			RectTransform val2 = (RectTransform)val.transform;
			((Transform)val2).SetParent(small, false);
			Shape(val2);
			ContentSizeFitter obj = val.AddComponent<ContentSizeFitter>();
			FitMode horizontalFit = (FitMode)2;
			obj.verticalFit = (FitMode)2;
			obj.horizontalFit = horizontalFit;
			val.AddComponent<ColumnWatch>();
			return val2;
		}

		private static void Shape(RectTransform column)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(1f, 1f);
			column.anchorMax = val;
			column.anchorMin = val;
			column.pivot = new Vector2(0f, 1f);
			column.anchoredPosition = new Vector2(6f, 0f);
			((Transform)column).localScale = Vector3.one * 0.7f;
			VerticalLayoutGroup obj = ((Component)column).gameObject.AddComponent<VerticalLayoutGroup>();
			((LayoutGroup)obj).childAlignment = (TextAnchor)0;
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 6f;
			bool childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = false);
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = childControlWidth;
			childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false);
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = childControlWidth;
		}
	}
	public static class HudRow
	{
		public const float Scale = 0.7f;

		public const float Gap = 6f;

		public static Plate? Add(InventoryGui gui, PlateSpec spec)
		{
			if (!Column.Active)
			{
				return null;
			}
			RectTransform val = HudContainer.Get();
			BoxStack boxStack = (((Object)(object)val != (Object)null) ? BoxStack.Ready(gui) : null);
			if ((Object)(object)val == (Object)null || boxStack == null)
			{
				return null;
			}
			string text = ColumnLayout.NameOf(spec);
			Transform obj = ((Transform)val).Find(text);
			RectTransform val2 = (RectTransform)(object)((obj is RectTransform) ? obj : null);
			Plate? obj2 = ((val2 != null) ? PlateCopy.Wrap(val2) : Make(boxStack, spec, text, val));
			if (obj2 != null)
			{
				Order(val);
			}
			return obj2;
		}

		public static RectTransform? Container()
		{
			if (!Column.Active)
			{
				return null;
			}
			return HudContainer.Get();
		}

		public static Sprite? WeightIcon(InventoryGui gui)
		{
			GamePlates gamePlates = GamePlates.Find(gui);
			Plate plate = ((gamePlates != null) ? PlateCopy.Wrap(gamePlates.Weight) : null);
			if (plate == null)
			{
				return null;
			}
			return plate.Icon.sprite;
		}

		private static Plate? Make(BoxStack stack, PlateSpec spec, string name, RectTransform row)
		{
			Plate plate = PlateCopy.Make(stack.Game.Armor, spec, name, (Transform?)(object)row);
			if (plate != null)
			{
				Graphic[] componentsInChildren = ((Component)plate.Rect).GetComponentsInChildren<Graphic>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].raycastTarget = false;
				}
			}
			return plate;
		}

		private static void Order(RectTransform row)
		{
			List<RectTransform> list = ColumnLayout.Sorted((Transform)(object)row);
			for (int i = 0; i < list.Count; i++)
			{
				if (((Transform)list[i]).GetSiblingIndex() != i)
				{
					((Transform)list[i]).SetSiblingIndex(i);
				}
			}
			LayoutRebuilder.ForceRebuildLayoutImmediate(row);
		}
	}
	internal static class LinkBounds
	{
		public static Vector3[]? Of(TMP_Text text, string id)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			TMP_TextInfo textInfo = text.textInfo;
			for (int i = 0; i < textInfo.linkCount; i++)
			{
				TMP_LinkInfo link = textInfo.linkInfo[i];
				if (((TMP_LinkInfo)(ref link)).GetLinkID() == id)
				{
					return Corners(text, link);
				}
			}
			return null;
		}

		private static Vector3[]? Corners(TMP_Text text, TMP_LinkInfo link)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			TMP_TextInfo textInfo = text.textInfo;
			int linkTextfirstCharacterIndex = link.linkTextfirstCharacterIndex;
			if (link.linkTextLength <= 0 || linkTextfirstCharacterIndex < 0 || linkTextfirstCharacterIndex >= textInfo.characterCount)
			{
				return null;
			}
			TMP_CharacterInfo val = textInfo.characterInfo[linkTextfirstCharacterIndex];
			Vector3 val2 = val.bottomLeft;
			Vector3 val3 = val.topRight;
			int num = Mathf.Min(linkTextfirstCharacterIndex + link.linkTextLength, textInfo.characterCount);
			for (int i = linkTextfirstCharacterIndex + 1; i < num && textInfo.characterInfo[i].lineNumber == val.lineNumber; i++)
			{
				val2 = Vector3.Min(val2, textInfo.characterInfo[i].bottomLeft);
				val3 = Vector3.Max(val3, textInfo.characterInfo[i].topRight);
			}
			Transform transform = text.transform;
			return (Vector3[]?)(object)new Vector3[4]
			{
				transform.TransformPoint(new Vector3(val2.x, val2.y)),
				transform.TransformPoint(new Vector3(val2.x, val3.y)),
				transform.TransformPoint(new Vector3(val3.x, val3.y)),
				transform.TransformPoint(new Vector3(val3.x, val2.y))
			};
		}
	}
	public sealed class LinkTips : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerMoveHandler, IPointerExitHandler
	{
		private const float ShowDelay = 0.3f;

		private readonly Dictionary<string, KeyValuePair<string, string>> tips = new Dictionary<string, KeyValuePair<string, string>>();

		private GameObject? prefab;

		private TMP_Text? text;

		private Camera? eventCamera;

		private Vector2 pointer;

		private bool inside;

		private string hovered = "";

		private float showAt = -1f;

		private GameObject? box;

		public static LinkTips? On(InventoryGui gui, TMP_Text text)
		{
			GameObject val = TipTemplate.For(gui);
			if ((Object)(object)val == (Object)null || (Object)(object)text == (Object)null)
			{
				return null;
			}
			LinkTips linkTips = ((Component)text).GetComponent<LinkTips>();
			if ((Object)(object)linkTips == (Object)null)
			{
				linkTips = ((Component)text).gameObject.AddComponent<LinkTips>();
			}
			linkTips.prefab = val;
			linkTips.text = text;
			((Graphic)text).raycastTarget = true;
			return linkTips;
		}

		public void Set(string id, string topic, string words)
		{
			tips[id] = new KeyValuePair<string, string>(topic, words);
		}

		public void Clear()
		{
			tips.Clear();
			Hide();
		}

		public void OnPointerEnter(PointerEventData eventData)
		{
			inside = true;
			Track(eventData);
		}

		public void OnPointerMove(PointerEventData eventData)
		{
			Track(eventData);
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			inside = false;
			Hide();
		}

		private void Track(PointerEventData eventData)
		{
			//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)
			pointer = eventData.position;
			eventCamera = eventData.enterEventCamera;
		}

		private void Update()
		{
			string text = (inside ? LinkAt() : "");
			if (text != hovered)
			{
				Hide();
				hovered = text;
				showAt = ((text.Length > 0) ? (Time.unscaledTime + 0.3f) : (-1f));
			}
			if (showAt >= 0f && Time.unscaledTime >= showAt)
			{
				showAt = -1f;
				Show();
			}
		}

		private string LinkAt()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)text == (Object)null)
			{
				return "";
			}
			int num = TMP_TextUtilities.FindIntersectingLink(text, Vector2.op_Implicit(pointer), eventCamera);
			if (num < 0 || num >= text.textInfo.linkCount)
			{
				return "";
			}
			string linkID = ((TMP_LinkInfo)(ref text.textInfo.linkInfo[num])).GetLinkID();
			if (!tips.ContainsKey(linkID))
			{
				return "";
			}
			return linkID;
		}

		private void Show()
		{
			if (!((Object)(object)text == (Object)null) && tips.TryGetValue(hovered, out KeyValuePair<string, string> value))
			{
				Vector3[] array = LinkBounds.Of(text, hovered);
				if (array != null)
				{
					UITooltip.HideTooltip();
					box = TipBox.Show(prefab, ((Graphic)text).canvas, array, value.Key, value.Value);
				}
			}
		}

		private void OnDisable()
		{
			inside = false;
			Hide();
		}

		private void Hide()
		{
			hovered = "";
			showAt = -1f;
			if ((Object)(object)box != (Object)null)
			{
				Object.Destroy((Object)(object)box);
				box = null;
			}
		}
	}
	internal static class MantleOwner
	{
		private const string Guid = "com.meadworks.mantle";

		private static bool looked;

		private static ConfigEntry<bool>? enabled;

		public static bool LaysOutInventory
		{
			get
			{
				if (!looked)
				{
					looked = true;
					enabled = Find();
				}
				if (enabled != null)
				{
					return enabled.Value;
				}
				return false;
			}
		}

		private static ConfigEntry<bool>? Find()
		{
			if (!Chainloader.PluginInfos.TryGetValue("com.meadworks.mantle", out var value) || (Object)(object)value.Instance == (Object)null)
			{
				return null;
			}
			ConfigEntry<bool> result = default(ConfigEntry<bool>);
			if (!value.Instance.Config.TryGetEntry<bool>("1. Inventory", "Enabled", ref result))
			{
				return null;
			}
			return result;
		}
	}
	public sealed class Plate
	{
		public RectTransform Rect { get; }

		public Image Icon { get; }

		public TMP_Text? Text { get; }

		public Plate(RectTransform rect, Image icon, TMP_Text? text)
		{
			Rect = rect;
			Icon = icon;
			Text = text;
		}
	}
	internal static class PlateCopy
	{
		public static Plate? Make(RectTransform source, PlateSpec spec, string name, Transform? parent = null)
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			GameObject val = Object.Instantiate<GameObject>(((Component)source).gameObject, (Transform)(((Object)(object)parent != (Object)null) ? ((object)parent) : ((object)((Transform)source).parent)), false);
			((Object)val).name = name;
			Transform transform = val.transform;
			TMP_Text componentInChildren = val.GetComponentInChildren<TMP_Text>(true);
			Transform val2 = PlateParts.ChildHolding(transform, ((Object)(object)componentInChildren != (Object)null) ? componentInChildren.transform : null);
			Image background = PlateParts.BackgroundOf(transform);
			Image val3 = PlateParts.IconOf(transform, val2);
			if ((Object)(object)val3 == (Object)null)
			{
				Object.DestroyImmediate((Object)(object)val);
				return null;
			}
			Strip(val, background, val3, spec.WithText ? val2 : null);
			TMP_Text text = (spec.WithText ? componentInChildren : null);
			Dress(val3, text, spec);
			val.SetActive(true);
			return new Plate((RectTransform)transform, val3, text);
		}

		public static Plate? Wrap(RectTransform box)
		{
			TMP_Text componentInChildren = ((Component)box).GetComponentInChildren<TMP_Text>(true);
			Image val = PlateParts.IconOf((Transform)(object)box, PlateParts.ChildHolding((Transform)(object)box, ((Object)(object)componentInChildren != (Object)null) ? componentInChildren.transform : null));
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return new Plate(box, val, componentInChildren);
		}

		private static void Dress(Image icon, TMP_Text? text, PlateSpec spec)
		{
			if ((Object)(object)spec.Icon != (Object)null)
			{
				icon.sprite = spec.Icon;
			}
			if ((Object)(object)text != (Object)null)
			{
				text.text = "";
			}
			else
			{
				BoxStyle.IconAlone(icon);
			}
		}

		private static void Strip(GameObject go, Image? background, Image icon, Transform? keptText)
		{
			Transform transform = go.transform;
			for (int num = transform.childCount - 1; num >= 0; num--)
			{
				Transform child = transform.GetChild(num);
				if ((!((Object)(object)background != (Object)null) || !((Object)(object)child == (Object)(object)((Component)background).transform)) && !((Object)(object)child == (Object)(object)((Component)icon).transform) && !((Object)(object)child == (Object)(object)keptText))
				{
					Object.DestroyImmediate((Object)(object)((Component)child).gameObject);
				}
			}
			Behaviour[] components = go.GetComponents<Behaviour>();
			for (int i = 0; i < components.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)components[i]);
			}
		}
	}
	internal static class PlateParts
	{
		public static Transform? ChildHolding(Transform parent, Transform? part)
		{
			Transform val = part;
			while ((Object)(object)val != (Object)null && (Object)(object)val.parent != (Object)(object)parent)
			{
				val = val.parent;
			}
			return val;
		}

		public static Image? BackgroundOf(Transform box)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			Image result = null;
			float num = 0f;
			foreach (Transform item in box)
			{
				Image component = ((Component)item).GetComponent<Image>();
				RectTransform val2 = (RectTransform)((item is RectTransform) ? item : null);
				Rect val3 = (Rect)((val2 != null) ? val2.rect : default(Rect));
				if ((Object)(object)component != (Object)null && ((Rect)(ref val3)).width * ((Rect)(ref val3)).height > num)
				{
					result = component;
					num = ((Rect)(ref val3)).width * ((Rect)(ref val3)).height;
				}
			}
			return result;
		}

		public static Image? IconOf(Transform box, Transform? textChild)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			Image val = BackgroundOf(box);
			foreach (Transform item in box)
			{
				Transform val2 = item;
				Image component = ((Component)val2).GetComponent<Image>();
				if ((Object)(object)component != (Object)null && (Object)(object)component != (Object)(object)val && (Object)(object)val2 != (Object)(object)textChild)
				{
					return component;
				}
			}
			return null;
		}

		public static bool Carries(GameObject go, Type type)
		{
			MonoBehaviour[] components = go.GetComponents<MonoBehaviour>();
			foreach (MonoBehaviour val in components)
			{
				if ((Object)(object)val != (Object)null && ((object)val).GetType().FullName == type.FullName)
				{
					return true;
				}
			}
			return false;
		}
	}
	public sealed class PlateSpec
	{
		public string Id { get; }

		public int Rank { get; }

		public Sprite? Icon { get; }

		public bool WithText { get; }

		public string Topic { get; }

		public string Tip { get; }

		public PlateSpec(string id, int rank, Sprite? icon, bool withText, string topic, string tip)
		{
			Id = id;
			Rank = Mathf.Clamp(rank, 0, 9999);
			Icon = icon;
			WithText = withText;
			Topic = topic;
			Tip = tip;
		}
	}
	internal sealed class PlateTip : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		private const float ShowDelay = 0.5f;

		public GameObject? Prefab;

		public string Topic = "";

		public string Text = "";

		private float showAt = -1f;

		private GameObject? box;

		public void OnPointerEnter(PointerEventData eventData)
		{
			UITooltip[] components = ((Component)this).GetComponents<UITooltip>();
			for (int i = 0; i < components.Length; i++)
			{
				Object.Destroy((Object)(object)components[i]);
			}
			UITooltip.HideTooltip();
			showAt = Time.unscaledTime + 0.5f;
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			Hide();
		}

		private void Update()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			if (showAt >= 0f && Time.unscaledTime >= showAt)
			{
				showAt = -1f;
				box = TipBox.Show(Prefab, (RectTransform)((Component)this).transform, Topic, Text);
			}
		}

		private void OnDisable()
		{
			Hide();
		}

		private void Hide()
		{
			showAt = -1f;
			if ((Object)(object)box != (Object)null)
			{
				Object.Destroy((Object)(object)box);
				box = null;
			}
		}
	}
	internal static class PlateTips
	{
		public static void Set(InventoryGui gui, RectTransform box, string topic, string text)
		{
			PlateTip plateTip = ((Component)box).GetComponent<PlateTip>();
			if ((Object)(object)plateTip == (Object)null)
			{
				GameObject val = TipTemplate.For(gui);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				plateTip = ((Component)box).gameObject.AddComponent<PlateTip>();
				plateTip.Prefab = val;
			}
			plateTip.Topic = topic;
			plateTip.Text = text;
		}

		public static void SetIfMissing(InventoryGui gui, RectTransform box, string topic, string text)
		{
			if (!PlateParts.Carries(((Component)box).gameObject, typeof(PlateTip)))
			{
				Set(gui, box, topic, text);
			}
		}
	}
	internal static class Seats
	{
		public static bool Seat(RectTransform panel, RectTransform boxes, RectTransform box, int rank)
		{
			bool result = MoveOut(panel, boxes, box);
			if ((Object)(object)((Transform)box).parent != (Object)(object)panel)
			{
				return result;
			}
			string text = ColumnLayout.SeatName(rank, ((Object)box).name);
			if ((Object)(object)((Transform)boxes).Find(text) != (Object)null)
			{
				return result;
			}
			Make(boxes, text, box);
			return true;
		}

		public static bool SeatGuests(RectTransform panel, RectTransform boxes)
		{
			bool flag = false;
			Guests[] known = Guests.Known;
			foreach (Guests guests in known)
			{
				if ((Object)(object)((Transform)boxes).Find(guests.Seat) == (Object)null)
				{
					Transform obj = ((Transform)panel).Find(guests.Name);
					RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null);
					if (val != null && Guests.LooksLikeBox((Transform)(object)val))
					{
						Guests.Dress(val);
						flag |= Seat(panel, boxes, val, guests.Rank);
					}
				}
			}
			return flag;
		}

		public static void Arrange(RectTransform panel, RectTransform boxes)
		{
			List<RectTransform> list = ColumnLayout.Sorted((Transform)(object)boxes);
			for (int i = 0; i < list.Count; i++)
			{
				if (ColumnLayout.OccupantOf(((Object)list[i]).name) == null)
				{
					BoxStyle.Apply(list[i]);
				}
				if (((Transform)list[i]).GetSiblingIndex() != i)
				{
					((Transform)list[i]).SetSiblingIndex(i);
				}
			}
			List<KeyValuePair<RectTransform, string>> list2 = new List<KeyValuePair<RectTransform, string>>();
			Collect(boxes, list2);
			Follow(panel, list2);
			LayoutRebuilder.ForceRebuildLayoutImmediate(boxes);
			Pin(panel, boxes, list2);
		}

		public static void Collect(RectTransform boxes, List<KeyValuePair<RectTransform, string>> into)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			into.Clear();
			foreach (Transform item in (Transform)boxes)
			{
				Transform val = item;
				RectTransform val2 = (RectTransform)(object)((val is RectTransform) ? val : null);
				if (val2 != null)
				{
					string text = ColumnLayout.OccupantOf(((Object)val).name);
					if (text != null)
					{
						into.Add(new KeyValuePair<RectTransform, string>(val2, text));
					}
				}
			}
		}

		public static RectTransform? BoxOf(RectTransform panel, RectTransform member)
		{
			string text = ColumnLayout.OccupantOf(((Object)member).name);
			if (text != null)
			{
				Transform obj = ((Transform)panel).Find(text);
				return (RectTransform?)(object)((obj is RectTransform) ? obj : null);
			}
			return member;
		}

		public static bool Follow(RectTransform panel, List<KeyValuePair<RectTransform, string>> seats)
		{
			bool flag = false;
			foreach (KeyValuePair<RectTransform, string> seat in seats)
			{
				if ((Object)(object)seat.Key != (Object)null)
				{
					bool num = flag;
					RectTransform key = seat.Key;
					Transform obj = ((Transform)panel).Find(seat.Value);
					flag = num | Follow(key, (RectTransform?)(object)((obj is RectTransform) ? obj : null));
				}
			}
			return flag;
		}

		public static void Pin(RectTransform panel, RectTransform boxes, List<KeyValuePair<RectTransform, string>> seats)
		{
			foreach (KeyValuePair<RectTransform, string> seat in seats)
			{
				if ((Object)(object)seat.Key != (Object)null && ((Component)seat.Key).gameObject.activeSelf)
				{
					Transform obj = ((Transform)panel).Find(seat.Value);
					RectTransform val = (RectTransform)(object)((obj is RectTransform) ? obj : null);
					if (val != null)
					{
						Pin(panel, boxes, seat.Key, val);
					}
				}
			}
		}

		private static bool Follow(RectTransform seat, RectTransform? box)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			bool flag = (Object)(object)box != (Object)null && ((Component)box).gameObject.activeSelf;
			bool flag2 = ((Component)seat).gameObject.activeSelf != flag;
			if (flag2)
			{
				((Component)seat).gameObject.SetActive(flag);
			}
			if ((Object)(object)box == (Object)null)
			{
				return flag2;
			}
			Rect rect = box.rect;
			Vector2 val = Vector2.Scale(((Rect)(ref rect)).size, Vector2.op_Implicit(((Transform)box).localScale));
			Vector2 val2 = seat.sizeDelta - val;
			if (((Vector2)(ref val2)).sqrMagnitude > 0.01f)
			{
				seat.sizeDelta = val;
				flag2 = true;
			}
			return flag2;
		}

		private static void Pin(RectTransform panel, RectTransform boxes, RectTransform seat, RectTransform box)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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)
			//IL_0049: Unknown result type (might be due to invalid IL or missing

plugins/Mantle/YamlDotNet.dll

Decompiled 5 hours ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using Microsoft.CodeAnalysis;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.BufferedDeserialization;
using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators;
using YamlDotNet.Serialization.Callbacks;
using YamlDotNet.Serialization.Converters;
using YamlDotNet.Serialization.EventEmitters;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.NodeDeserializers;
using YamlDotNet.Serialization.NodeTypeResolvers;
using YamlDotNet.Serialization.ObjectFactories;
using YamlDotNet.Serialization.ObjectGraphTraversalStrategies;
using YamlDotNet.Serialization.ObjectGraphVisitors;
using YamlDotNet.Serialization.Schemas;
using YamlDotNet.Serialization.TypeInspectors;
using YamlDotNet.Serialization.TypeResolvers;
using YamlDotNet.Serialization.Utilities;
using YamlDotNet.Serialization.ValueDeserializers;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: ComVisible(false)]
[assembly: AssemblyFileVersion("13.7.1.0")]
[assembly: AssemblyInformationalVersion("13.7.1")]
[assembly: AssemblyTitle("YamlDotNet")]
[assembly: AssemblyDescription("The YamlDotNet library.")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("YamlDotNet")]
[assembly: AssemblyCopyright("Copyright (c) Antoine Aubry and contributors 2008 - 2019")]
[assembly: AssemblyTrademark("")]
[assembly: CLSCompliant(true)]
[assembly: InternalsVisibleTo("YamlDotNet.Test, PublicKey=002400000480000094000000060200000024000052534131000400000100010065e52a453dde5c5b4be5bbe2205755727fce80244b79b894faf8793d80f7db9a96d360b51c220782db32aacee4cb5b8a91bee33aeec700e1f21895c4baadef501eeeac609220d1651603b378173811ee5bb6a002df973d38821bd2fef820c00c174a69faec326a1983b570f07ec66147026b9c8753465de3a8d0c44b613b02af")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("13.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace YamlDotNet
{
	internal sealed class CultureInfoAdapter : CultureInfo
	{
		private readonly IFormatProvider provider;

		public CultureInfoAdapter(CultureInfo baseCulture, IFormatProvider provider)
			: base(baseCulture.Name)
		{
			this.provider = provider;
		}

		public override object GetFormat(Type formatType)
		{
			return provider.GetFormat(formatType);
		}
	}
	internal static class ReflectionExtensions
	{
		private static readonly Func<PropertyInfo, bool> IsInstance = (PropertyInfo property) => !(property.GetMethod ?? property.SetMethod).IsStatic;

		private static readonly Func<PropertyInfo, bool> IsInstancePublic = (PropertyInfo property) => IsInstance(property) && (property.GetMethod ?? property.SetMethod).IsPublic;

		public static Type? BaseType(this Type type)
		{
			return type.GetTypeInfo().BaseType;
		}

		public static bool IsValueType(this Type type)
		{
			return type.GetTypeInfo().IsValueType;
		}

		public static bool IsGenericType(this Type type)
		{
			return type.GetTypeInfo().IsGenericType;
		}

		public static bool IsGenericTypeDefinition(this Type type)
		{
			return type.GetTypeInfo().IsGenericTypeDefinition;
		}

		public static bool IsInterface(this Type type)
		{
			return type.GetTypeInfo().IsInterface;
		}

		public static bool IsEnum(this Type type)
		{
			return type.GetTypeInfo().IsEnum;
		}

		public static bool HasDefaultConstructor(this Type type, bool allowPrivateConstructors)
		{
			TypeInfo typeInfo = type.GetTypeInfo();
			if (!typeInfo.IsValueType)
			{
				return typeInfo.DeclaredConstructors.Any((ConstructorInfo c) => (c.IsPublic || (allowPrivateConstructors && c.IsPrivate)) && !c.IsStatic && c.GetParameters().Length == 0);
			}
			return true;
		}

		public static bool IsAssignableFrom(this Type type, Type source)
		{
			return type.IsAssignableFrom(source.GetTypeInfo());
		}

		public static bool IsAssignableFrom(this Type type, TypeInfo source)
		{
			return type.GetTypeInfo().IsAssignableFrom(source);
		}

		public static TypeCode GetTypeCode(this Type type)
		{
			if (type.IsEnum())
			{
				type = Enum.GetUnderlyingType(type);
			}
			if (type == typeof(bool))
			{
				return TypeCode.Boolean;
			}
			if (type == typeof(char))
			{
				return TypeCode.Char;
			}
			if (type == typeof(sbyte))
			{
				return TypeCode.SByte;
			}
			if (type == typeof(byte))
			{
				return TypeCode.Byte;
			}
			if (type == typeof(short))
			{
				return TypeCode.Int16;
			}
			if (type == typeof(ushort))
			{
				return TypeCode.UInt16;
			}
			if (type == typeof(int))
			{
				return TypeCode.Int32;
			}
			if (type == typeof(uint))
			{
				return TypeCode.UInt32;
			}
			if (type == typeof(long))
			{
				return TypeCode.Int64;
			}
			if (type == typeof(ulong))
			{
				return TypeCode.UInt64;
			}
			if (type == typeof(float))
			{
				return TypeCode.Single;
			}
			if (type == typeof(double))
			{
				return TypeCode.Double;
			}
			if (type == typeof(decimal))
			{
				return TypeCode.Decimal;
			}
			if (type == typeof(DateTime))
			{
				return TypeCode.DateTime;
			}
			if (type == typeof(string))
			{
				return TypeCode.String;
			}
			return TypeCode.Object;
		}

		public static bool IsDbNull(this object value)
		{
			return value?.GetType()?.FullName == "System.DBNull";
		}

		public static Type[] GetGenericArguments(this Type type)
		{
			return type.GetTypeInfo().GenericTypeArguments;
		}

		public static PropertyInfo? GetPublicProperty(this Type type, string name)
		{
			return type.GetRuntimeProperty(name);
		}

		public static FieldInfo? GetPublicStaticField(this Type type, string name)
		{
			return type.GetRuntimeField(name);
		}

		public static IEnumerable<PropertyInfo> GetProperties(this Type type, bool includeNonPublic)
		{
			Func<PropertyInfo, bool> predicate = (includeNonPublic ? IsInstance : IsInstancePublic);
			if (!type.IsInterface())
			{
				return type.GetRuntimeProperties().Where(predicate);
			}
			return new Type[1] { type }.Concat(type.GetInterfaces()).SelectMany((Type i) => i.GetRuntimeProperties().Where(predicate));
		}

		public static IEnumerable<PropertyInfo> GetPublicProperties(this Type type)
		{
			return type.GetProperties(includeNonPublic: false);
		}

		public static IEnumerable<FieldInfo> GetPublicFields(this Type type)
		{
			return from f in type.GetRuntimeFields()
				where !f.IsStatic && f.IsPublic
				select f;
		}

		public static IEnumerable<MethodInfo> GetPublicStaticMethods(this Type type)
		{
			return from m in type.GetRuntimeMethods()
				where m.IsPublic && m.IsStatic
				select m;
		}

		public static MethodInfo GetPrivateStaticMethod(this Type type, string name)
		{
			return type.GetRuntimeMethods().FirstOrDefault((MethodInfo m) => !m.IsPublic && m.IsStatic && m.Name.Equals(name)) ?? throw new MissingMethodException("Expected to find a method named '" + name + "' in '" + type.FullName + "'.");
		}

		public static MethodInfo? GetPublicStaticMethod(this Type type, string name, params Type[] parameterTypes)
		{
			return type.GetRuntimeMethods().FirstOrDefault(delegate(MethodInfo m)
			{
				if (m.IsPublic && m.IsStatic && m.Name.Equals(name))
				{
					ParameterInfo[] parameters = m.GetParameters();
					if (parameters.Length == parameterTypes.Length)
					{
						return parameters.Zip(parameterTypes, (ParameterInfo pi, Type pt) => pi.ParameterType == pt).All((bool r) => r);
					}
					return false;
				}
				return false;
			});
		}

		public static MethodInfo? GetPublicInstanceMethod(this Type type, string name)
		{
			return type.GetRuntimeMethods().FirstOrDefault((MethodInfo m) => m.IsPublic && !m.IsStatic && m.Name.Equals(name));
		}

		public static MethodInfo? GetGetMethod(this PropertyInfo property, bool nonPublic)
		{
			MethodInfo methodInfo = property.GetMethod;
			if (!nonPublic && !methodInfo.IsPublic)
			{
				methodInfo = null;
			}
			return methodInfo;
		}

		public static MethodInfo GetSetMethod(this PropertyInfo property)
		{
			return property.SetMethod;
		}

		public static IEnumerable<Type> GetInterfaces(this Type type)
		{
			return type.GetTypeInfo().ImplementedInterfaces;
		}

		public static Exception Unwrap(this TargetInvocationException ex)
		{
			return ex.InnerException;
		}

		public static bool IsInstanceOf(this Type type, object o)
		{
			if (!(o.GetType() == type))
			{
				return o.GetType().GetTypeInfo().IsSubclassOf(type);
			}
			return true;
		}

		public static Attribute[] GetAllCustomAttributes<TAttribute>(this PropertyInfo member)
		{
			List<Attribute> list = new List<Attribute>();
			Type type = member.DeclaringType;
			while (type != null)
			{
				type.GetPublicProperty(member.Name);
				list.AddRange(member.GetCustomAttributes(typeof(TAttribute)));
				type = type.BaseType();
			}
			return list.ToArray();
		}
	}
	internal static class PropertyInfoExtensions
	{
		public static object? ReadValue(this PropertyInfo property, object target)
		{
			return property.GetValue(target, null);
		}
	}
	internal static class StandardRegexOptions
	{
		public const RegexOptions Compiled = RegexOptions.Compiled;
	}
}
namespace YamlDotNet.Serialization
{
	public abstract class BuilderSkeleton<TBuilder> where TBuilder : BuilderSkeleton<TBuilder>
	{
		internal INamingConvention namingConvention = NullNamingConvention.Instance;

		internal ITypeResolver typeResolver;

		internal readonly YamlAttributeOverrides overrides;

		internal readonly LazyComponentRegistrationList<Nothing, IYamlTypeConverter> typeConverterFactories;

		internal readonly LazyComponentRegistrationList<ITypeInspector, ITypeInspector> typeInspectorFactories;

		internal bool ignoreFields;

		internal bool includeNonPublicProperties;

		internal Settings settings;

		internal YamlFormatter yamlFormatter = YamlFormatter.Default;

		protected abstract TBuilder Self { get; }

		internal BuilderSkeleton(ITypeResolver typeResolver)
		{
			overrides = new YamlAttributeOverrides();
			typeConverterFactories = new LazyComponentRegistrationList<Nothing, IYamlTypeConverter>
			{
				{
					typeof(YamlDotNet.Serialization.Converters.GuidConverter),
					(Nothing _) => new YamlDotNet.Serialization.Converters.GuidConverter(jsonCompatible: false)
				},
				{
					typeof(SystemTypeConverter),
					(Nothing _) => new SystemTypeConverter()
				}
			};
			typeInspectorFactories = new LazyComponentRegistrationList<ITypeInspector, ITypeInspector>();
			this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver");
			settings = new Settings();
		}

		public TBuilder IgnoreFields()
		{
			ignoreFields = true;
			return Self;
		}

		public TBuilder IncludeNonPublicProperties()
		{
			includeNonPublicProperties = true;
			return Self;
		}

		public TBuilder EnablePrivateConstructors()
		{
			settings.AllowPrivateConstructors = true;
			return Self;
		}

		public TBuilder WithNamingConvention(INamingConvention namingConvention)
		{
			this.namingConvention = namingConvention ?? throw new ArgumentNullException("namingConvention");
			return Self;
		}

		public TBuilder WithTypeResolver(ITypeResolver typeResolver)
		{
			this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver");
			return Self;
		}

		public abstract TBuilder WithTagMapping(TagName tag, Type type);

		public TBuilder WithAttributeOverride<TClass>(Expression<Func<TClass, object>> propertyAccessor, Attribute attribute)
		{
			overrides.Add(propertyAccessor, attribute);
			return Self;
		}

		public TBuilder WithAttributeOverride(Type type, string member, Attribute attribute)
		{
			overrides.Add(type, member, attribute);
			return Self;
		}

		public TBuilder WithTypeConverter(IYamlTypeConverter typeConverter)
		{
			return WithTypeConverter(typeConverter, delegate(IRegistrationLocationSelectionSyntax<IYamlTypeConverter> w)
			{
				w.OnTop();
			});
		}

		public TBuilder WithTypeConverter(IYamlTypeConverter typeConverter, Action<IRegistrationLocationSelectionSyntax<IYamlTypeConverter>> where)
		{
			if (typeConverter == null)
			{
				throw new ArgumentNullException("typeConverter");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeConverterFactories.CreateRegistrationLocationSelector(typeConverter.GetType(), (Nothing _) => typeConverter));
			return Self;
		}

		public TBuilder WithTypeConverter<TYamlTypeConverter>(WrapperFactory<IYamlTypeConverter, IYamlTypeConverter> typeConverterFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IYamlTypeConverter>> where) where TYamlTypeConverter : IYamlTypeConverter
		{
			if (typeConverterFactory == null)
			{
				throw new ArgumentNullException("typeConverterFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeConverterFactories.CreateTrackingRegistrationLocationSelector(typeof(TYamlTypeConverter), (IYamlTypeConverter wrapped, Nothing _) => typeConverterFactory(wrapped)));
			return Self;
		}

		public TBuilder WithoutTypeConverter<TYamlTypeConverter>() where TYamlTypeConverter : IYamlTypeConverter
		{
			return WithoutTypeConverter(typeof(TYamlTypeConverter));
		}

		public TBuilder WithoutTypeConverter(Type converterType)
		{
			if (converterType == null)
			{
				throw new ArgumentNullException("converterType");
			}
			typeConverterFactories.Remove(converterType);
			return Self;
		}

		public TBuilder WithTypeInspector<TTypeInspector>(Func<ITypeInspector, TTypeInspector> typeInspectorFactory) where TTypeInspector : ITypeInspector
		{
			return WithTypeInspector(typeInspectorFactory, delegate(IRegistrationLocationSelectionSyntax<ITypeInspector> w)
			{
				w.OnTop();
			});
		}

		public TBuilder WithTypeInspector<TTypeInspector>(Func<ITypeInspector, TTypeInspector> typeInspectorFactory, Action<IRegistrationLocationSelectionSyntax<ITypeInspector>> where) where TTypeInspector : ITypeInspector
		{
			if (typeInspectorFactory == null)
			{
				throw new ArgumentNullException("typeInspectorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeInspectorFactories.CreateRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector inner) => typeInspectorFactory(inner)));
			return Self;
		}

		public TBuilder WithTypeInspector<TTypeInspector>(WrapperFactory<ITypeInspector, ITypeInspector, TTypeInspector> typeInspectorFactory, Action<ITrackingRegistrationLocationSelectionSyntax<ITypeInspector>> where) where TTypeInspector : ITypeInspector
		{
			if (typeInspectorFactory == null)
			{
				throw new ArgumentNullException("typeInspectorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeInspectorFactories.CreateTrackingRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector wrapped, ITypeInspector inner) => typeInspectorFactory(wrapped, inner)));
			return Self;
		}

		public TBuilder WithoutTypeInspector<TTypeInspector>() where TTypeInspector : ITypeInspector
		{
			return WithoutTypeInspector(typeof(TTypeInspector));
		}

		public TBuilder WithoutTypeInspector(Type inspectorType)
		{
			if (inspectorType == null)
			{
				throw new ArgumentNullException("inspectorType");
			}
			typeInspectorFactories.Remove(inspectorType);
			return Self;
		}

		public TBuilder WithYamlFormatter(YamlFormatter formatter)
		{
			yamlFormatter = formatter ?? throw new ArgumentNullException("formatter");
			return Self;
		}

		protected IEnumerable<IYamlTypeConverter> BuildTypeConverters()
		{
			return typeConverterFactories.BuildComponentList();
		}
	}
	public delegate TComponent WrapperFactory<TComponentBase, TComponent>(TComponentBase wrapped) where TComponent : TComponentBase;
	public delegate TComponent WrapperFactory<TArgument, TComponentBase, TComponent>(TComponentBase wrapped, TArgument argument) where TComponent : TComponentBase;
	[Flags]
	public enum DefaultValuesHandling
	{
		Preserve = 0,
		OmitNull = 1,
		OmitDefaults = 2,
		OmitEmptyCollections = 4
	}
	public sealed class Deserializer : IDeserializer
	{
		private readonly IValueDeserializer valueDeserializer;

		public Deserializer()
			: this(new DeserializerBuilder().BuildValueDeserializer())
		{
		}

		private Deserializer(IValueDeserializer valueDeserializer)
		{
			this.valueDeserializer = valueDeserializer ?? throw new ArgumentNullException("valueDeserializer");
		}

		public static Deserializer FromValueDeserializer(IValueDeserializer valueDeserializer)
		{
			return new Deserializer(valueDeserializer);
		}

		public T Deserialize<T>(string input)
		{
			using StringReader input2 = new StringReader(input);
			return Deserialize<T>(input2);
		}

		public T Deserialize<T>(TextReader input)
		{
			return Deserialize<T>(new Parser(input));
		}

		public T Deserialize<T>(IParser parser)
		{
			return (T)Deserialize(parser, typeof(T));
		}

		public object? Deserialize(string input)
		{
			return Deserialize(input, typeof(object));
		}

		public object? Deserialize(TextReader input)
		{
			return Deserialize(input, typeof(object));
		}

		public object? Deserialize(IParser parser)
		{
			return Deserialize(parser, typeof(object));
		}

		public object? Deserialize(string input, Type type)
		{
			using StringReader input2 = new StringReader(input);
			return Deserialize(input2, type);
		}

		public object? Deserialize(TextReader input, Type type)
		{
			return Deserialize(new Parser(input), type);
		}

		public object? Deserialize(IParser parser, Type type)
		{
			if (parser == null)
			{
				throw new ArgumentNullException("parser");
			}
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			YamlDotNet.Core.Events.StreamStart @event;
			bool flag = parser.TryConsume<YamlDotNet.Core.Events.StreamStart>(out @event);
			YamlDotNet.Core.Events.DocumentStart event2;
			bool flag2 = parser.TryConsume<YamlDotNet.Core.Events.DocumentStart>(out event2);
			object result = null;
			if (!parser.Accept<YamlDotNet.Core.Events.DocumentEnd>(out var _) && !parser.Accept<YamlDotNet.Core.Events.StreamEnd>(out var _))
			{
				using SerializerState serializerState = new SerializerState();
				result = valueDeserializer.DeserializeValue(parser, type, serializerState, valueDeserializer);
				serializerState.OnDeserialization();
			}
			if (flag2)
			{
				parser.Consume<YamlDotNet.Core.Events.DocumentEnd>();
			}
			if (flag)
			{
				parser.Consume<YamlDotNet.Core.Events.StreamEnd>();
			}
			return result;
		}
	}
	public sealed class DeserializerBuilder : BuilderSkeleton<DeserializerBuilder>
	{
		private Lazy<IObjectFactory> objectFactory;

		private readonly LazyComponentRegistrationList<Nothing, INodeDeserializer> nodeDeserializerFactories;

		private readonly LazyComponentRegistrationList<Nothing, INodeTypeResolver> nodeTypeResolverFactories;

		private readonly Dictionary<TagName, Type> tagMappings;

		private readonly Dictionary<Type, Type> typeMappings;

		private readonly ITypeConverter typeConverter;

		private bool ignoreUnmatched;

		private bool duplicateKeyChecking;

		private bool attemptUnknownTypeDeserialization;

		protected override DeserializerBuilder Self => this;

		public DeserializerBuilder()
			: base((ITypeResolver)new StaticTypeResolver())
		{
			typeMappings = new Dictionary<Type, Type>();
			objectFactory = new Lazy<IObjectFactory>(() => new DefaultObjectFactory(typeMappings, settings), isThreadSafe: true);
			tagMappings = new Dictionary<TagName, Type>
			{
				{
					FailsafeSchema.Tags.Map,
					typeof(Dictionary<object, object>)
				},
				{
					FailsafeSchema.Tags.Str,
					typeof(string)
				},
				{
					JsonSchema.Tags.Bool,
					typeof(bool)
				},
				{
					JsonSchema.Tags.Float,
					typeof(double)
				},
				{
					JsonSchema.Tags.Int,
					typeof(int)
				},
				{
					DefaultSchema.Tags.Timestamp,
					typeof(DateTime)
				}
			};
			typeInspectorFactories.Add(typeof(CachedTypeInspector), (ITypeInspector inner) => new CachedTypeInspector(inner));
			typeInspectorFactories.Add(typeof(NamingConventionTypeInspector), (ITypeInspector inner) => (!(namingConvention is NullNamingConvention)) ? new NamingConventionTypeInspector(inner, namingConvention) : inner);
			typeInspectorFactories.Add(typeof(YamlAttributesTypeInspector), (ITypeInspector inner) => new YamlAttributesTypeInspector(inner));
			typeInspectorFactories.Add(typeof(YamlAttributeOverridesInspector), (ITypeInspector inner) => (overrides == null) ? inner : new YamlAttributeOverridesInspector(inner, overrides.Clone()));
			typeInspectorFactories.Add(typeof(ReadableAndWritablePropertiesTypeInspector), (ITypeInspector inner) => new ReadableAndWritablePropertiesTypeInspector(inner));
			nodeDeserializerFactories = new LazyComponentRegistrationList<Nothing, INodeDeserializer>
			{
				{
					typeof(YamlConvertibleNodeDeserializer),
					(Nothing _) => new YamlConvertibleNodeDeserializer(objectFactory.Value)
				},
				{
					typeof(YamlSerializableNodeDeserializer),
					(Nothing _) => new YamlSerializableNodeDeserializer(objectFactory.Value)
				},
				{
					typeof(TypeConverterNodeDeserializer),
					(Nothing _) => new TypeConverterNodeDeserializer(BuildTypeConverters())
				},
				{
					typeof(NullNodeDeserializer),
					(Nothing _) => new NullNodeDeserializer()
				},
				{
					typeof(ScalarNodeDeserializer),
					(Nothing _) => new ScalarNodeDeserializer(attemptUnknownTypeDeserialization, typeConverter, yamlFormatter)
				},
				{
					typeof(ArrayNodeDeserializer),
					(Nothing _) => new ArrayNodeDeserializer()
				},
				{
					typeof(DictionaryNodeDeserializer),
					(Nothing _) => new DictionaryNodeDeserializer(objectFactory.Value, duplicateKeyChecking)
				},
				{
					typeof(CollectionNodeDeserializer),
					(Nothing _) => new CollectionNodeDeserializer(objectFactory.Value)
				},
				{
					typeof(EnumerableNodeDeserializer),
					(Nothing _) => new EnumerableNodeDeserializer()
				},
				{
					typeof(ObjectNodeDeserializer),
					(Nothing _) => new ObjectNodeDeserializer(objectFactory.Value, BuildTypeInspector(), ignoreUnmatched, duplicateKeyChecking, typeConverter)
				}
			};
			nodeTypeResolverFactories = new LazyComponentRegistrationList<Nothing, INodeTypeResolver>
			{
				{
					typeof(MappingNodeTypeResolver),
					(Nothing _) => new MappingNodeTypeResolver(typeMappings)
				},
				{
					typeof(YamlConvertibleTypeResolver),
					(Nothing _) => new YamlConvertibleTypeResolver()
				},
				{
					typeof(YamlSerializableTypeResolver),
					(Nothing _) => new YamlSerializableTypeResolver()
				},
				{
					typeof(TagNodeTypeResolver),
					(Nothing _) => new TagNodeTypeResolver(tagMappings)
				},
				{
					typeof(PreventUnknownTagsNodeTypeResolver),
					(Nothing _) => new PreventUnknownTagsNodeTypeResolver()
				},
				{
					typeof(DefaultContainersNodeTypeResolver),
					(Nothing _) => new DefaultContainersNodeTypeResolver()
				}
			};
			typeConverter = new ReflectionTypeConverter();
		}

		internal ITypeInspector BuildTypeInspector()
		{
			ITypeInspector typeInspector = new WritablePropertiesTypeInspector(typeResolver, includeNonPublicProperties);
			if (!ignoreFields)
			{
				typeInspector = new CompositeTypeInspector(new ReadableFieldsTypeInspector(typeResolver), typeInspector);
			}
			return typeInspectorFactories.BuildComponentChain(typeInspector);
		}

		public DeserializerBuilder WithAttemptingUnquotedStringTypeDeserialization()
		{
			attemptUnknownTypeDeserialization = true;
			return this;
		}

		public DeserializerBuilder WithObjectFactory(IObjectFactory objectFactory)
		{
			if (objectFactory == null)
			{
				throw new ArgumentNullException("objectFactory");
			}
			this.objectFactory = new Lazy<IObjectFactory>(() => objectFactory, isThreadSafe: true);
			return this;
		}

		public DeserializerBuilder WithObjectFactory(Func<Type, object> objectFactory)
		{
			if (objectFactory == null)
			{
				throw new ArgumentNullException("objectFactory");
			}
			return WithObjectFactory(new LambdaObjectFactory(objectFactory));
		}

		public DeserializerBuilder WithNodeDeserializer(INodeDeserializer nodeDeserializer)
		{
			return WithNodeDeserializer(nodeDeserializer, delegate(IRegistrationLocationSelectionSyntax<INodeDeserializer> w)
			{
				w.OnTop();
			});
		}

		public DeserializerBuilder WithNodeDeserializer(INodeDeserializer nodeDeserializer, Action<IRegistrationLocationSelectionSyntax<INodeDeserializer>> where)
		{
			if (nodeDeserializer == null)
			{
				throw new ArgumentNullException("nodeDeserializer");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeDeserializerFactories.CreateRegistrationLocationSelector(nodeDeserializer.GetType(), (Nothing _) => nodeDeserializer));
			return this;
		}

		public DeserializerBuilder WithNodeDeserializer<TNodeDeserializer>(WrapperFactory<INodeDeserializer, TNodeDeserializer> nodeDeserializerFactory, Action<ITrackingRegistrationLocationSelectionSyntax<INodeDeserializer>> where) where TNodeDeserializer : INodeDeserializer
		{
			if (nodeDeserializerFactory == null)
			{
				throw new ArgumentNullException("nodeDeserializerFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeDeserializerFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeDeserializer), (INodeDeserializer wrapped, Nothing _) => nodeDeserializerFactory(wrapped)));
			return this;
		}

		public DeserializerBuilder WithoutNodeDeserializer<TNodeDeserializer>() where TNodeDeserializer : INodeDeserializer
		{
			return WithoutNodeDeserializer(typeof(TNodeDeserializer));
		}

		public DeserializerBuilder WithoutNodeDeserializer(Type nodeDeserializerType)
		{
			if (nodeDeserializerType == null)
			{
				throw new ArgumentNullException("nodeDeserializerType");
			}
			nodeDeserializerFactories.Remove(nodeDeserializerType);
			return this;
		}

		public DeserializerBuilder WithTypeDiscriminatingNodeDeserializer(Action<ITypeDiscriminatingNodeDeserializerOptions> configureTypeDiscriminatingNodeDeserializerOptions, int maxDepth = -1, int maxLength = -1)
		{
			TypeDiscriminatingNodeDeserializerOptions typeDiscriminatingNodeDeserializerOptions = new TypeDiscriminatingNodeDeserializerOptions();
			configureTypeDiscriminatingNodeDeserializerOptions(typeDiscriminatingNodeDeserializerOptions);
			TypeDiscriminatingNodeDeserializer nodeDeserializer = new TypeDiscriminatingNodeDeserializer(nodeDeserializerFactories.BuildComponentList(), typeDiscriminatingNodeDeserializerOptions.discriminators, maxDepth, maxLength);
			return WithNodeDeserializer(nodeDeserializer, delegate(IRegistrationLocationSelectionSyntax<INodeDeserializer> s)
			{
				s.Before<DictionaryNodeDeserializer>();
			});
		}

		public DeserializerBuilder WithNodeTypeResolver(INodeTypeResolver nodeTypeResolver)
		{
			return WithNodeTypeResolver(nodeTypeResolver, delegate(IRegistrationLocationSelectionSyntax<INodeTypeResolver> w)
			{
				w.OnTop();
			});
		}

		public DeserializerBuilder WithNodeTypeResolver(INodeTypeResolver nodeTypeResolver, Action<IRegistrationLocationSelectionSyntax<INodeTypeResolver>> where)
		{
			if (nodeTypeResolver == null)
			{
				throw new ArgumentNullException("nodeTypeResolver");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeTypeResolverFactories.CreateRegistrationLocationSelector(nodeTypeResolver.GetType(), (Nothing _) => nodeTypeResolver));
			return this;
		}

		public DeserializerBuilder WithNodeTypeResolver<TNodeTypeResolver>(WrapperFactory<INodeTypeResolver, TNodeTypeResolver> nodeTypeResolverFactory, Action<ITrackingRegistrationLocationSelectionSyntax<INodeTypeResolver>> where) where TNodeTypeResolver : INodeTypeResolver
		{
			if (nodeTypeResolverFactory == null)
			{
				throw new ArgumentNullException("nodeTypeResolverFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeTypeResolverFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeTypeResolver), (INodeTypeResolver wrapped, Nothing _) => nodeTypeResolverFactory(wrapped)));
			return this;
		}

		public DeserializerBuilder WithoutNodeTypeResolver<TNodeTypeResolver>() where TNodeTypeResolver : INodeTypeResolver
		{
			return WithoutNodeTypeResolver(typeof(TNodeTypeResolver));
		}

		public DeserializerBuilder WithoutNodeTypeResolver(Type nodeTypeResolverType)
		{
			if (nodeTypeResolverType == null)
			{
				throw new ArgumentNullException("nodeTypeResolverType");
			}
			nodeTypeResolverFactories.Remove(nodeTypeResolverType);
			return this;
		}

		public override DeserializerBuilder WithTagMapping(TagName tag, Type type)
		{
			if (tag.IsEmpty)
			{
				throw new ArgumentException("Non-specific tags cannot be maped");
			}
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (tagMappings.TryGetValue(tag, out Type value))
			{
				throw new ArgumentException($"Type already has a registered type '{value.FullName}' for tag '{tag}'", "tag");
			}
			tagMappings.Add(tag, type);
			return this;
		}

		public DeserializerBuilder WithTypeMapping<TInterface, TConcrete>() where TConcrete : TInterface
		{
			Type typeFromHandle = typeof(TInterface);
			Type typeFromHandle2 = typeof(TConcrete);
			if (!typeFromHandle.IsAssignableFrom(typeFromHandle2))
			{
				throw new InvalidOperationException("The type '" + typeFromHandle2.Name + "' does not implement interface '" + typeFromHandle.Name + "'.");
			}
			if (typeMappings.ContainsKey(typeFromHandle))
			{
				typeMappings[typeFromHandle] = typeFromHandle2;
			}
			else
			{
				typeMappings.Add(typeFromHandle, typeFromHandle2);
			}
			return this;
		}

		public DeserializerBuilder WithoutTagMapping(TagName tag)
		{
			if (tag.IsEmpty)
			{
				throw new ArgumentException("Non-specific tags cannot be maped");
			}
			if (!tagMappings.Remove(tag))
			{
				throw new KeyNotFoundException($"Tag '{tag}' is not registered");
			}
			return this;
		}

		public DeserializerBuilder IgnoreUnmatchedProperties()
		{
			ignoreUnmatched = true;
			return this;
		}

		public DeserializerBuilder WithDuplicateKeyChecking()
		{
			duplicateKeyChecking = true;
			return this;
		}

		public IDeserializer Build()
		{
			return Deserializer.FromValueDeserializer(BuildValueDeserializer());
		}

		public IValueDeserializer BuildValueDeserializer()
		{
			return new AliasValueDeserializer(new NodeValueDeserializer(nodeDeserializerFactories.BuildComponentList(), nodeTypeResolverFactories.BuildComponentList(), typeConverter));
		}
	}
	public sealed class EmissionPhaseObjectGraphVisitorArgs
	{
		private readonly IEnumerable<IObjectGraphVisitor<Nothing>> preProcessingPhaseVisitors;

		public IObjectGraphVisitor<IEmitter> InnerVisitor { get; private set; }

		public IEventEmitter EventEmitter { get; private set; }

		public ObjectSerializer NestedObjectSerializer { get; private set; }

		public IEnumerable<IYamlTypeConverter> TypeConverters { get; private set; }

		public EmissionPhaseObjectGraphVisitorArgs(IObjectGraphVisitor<IEmitter> innerVisitor, IEventEmitter eventEmitter, IEnumerable<IObjectGraphVisitor<Nothing>> preProcessingPhaseVisitors, IEnumerable<IYamlTypeConverter> typeConverters, ObjectSerializer nestedObjectSerializer)
		{
			InnerVisitor = innerVisitor ?? throw new ArgumentNullException("innerVisitor");
			EventEmitter = eventEmitter ?? throw new ArgumentNullException("eventEmitter");
			this.preProcessingPhaseVisitors = preProcessingPhaseVisitors ?? throw new ArgumentNullException("preProcessingPhaseVisitors");
			TypeConverters = typeConverters ?? throw new ArgumentNullException("typeConverters");
			NestedObjectSerializer = nestedObjectSerializer ?? throw new ArgumentNullException("nestedObjectSerializer");
		}

		public T GetPreProcessingPhaseObjectGraphVisitor<T>() where T : IObjectGraphVisitor<Nothing>
		{
			return preProcessingPhaseVisitors.OfType<T>().Single();
		}
	}
	public abstract class EventInfo
	{
		public IObjectDescriptor Source { get; }

		protected EventInfo(IObjectDescriptor source)
		{
			Source = source ?? throw new ArgumentNullException("source");
		}
	}
	public class AliasEventInfo : EventInfo
	{
		public AnchorName Alias { get; }

		public bool NeedsExpansion { get; set; }

		public AliasEventInfo(IObjectDescriptor source, AnchorName alias)
			: base(source)
		{
			if (alias.IsEmpty)
			{
				throw new ArgumentNullException("alias");
			}
			Alias = alias;
		}
	}
	public class ObjectEventInfo : EventInfo
	{
		public AnchorName Anchor { get; set; }

		public TagName Tag { get; set; }

		protected ObjectEventInfo(IObjectDescriptor source)
			: base(source)
		{
		}
	}
	public sealed class ScalarEventInfo : ObjectEventInfo
	{
		public string RenderedValue { get; set; }

		public ScalarStyle Style { get; set; }

		public bool IsPlainImplicit { get; set; }

		public bool IsQuotedImplicit { get; set; }

		public ScalarEventInfo(IObjectDescriptor source)
			: base(source)
		{
			Style = source.ScalarStyle;
			RenderedValue = string.Empty;
		}
	}
	public sealed class MappingStartEventInfo : ObjectEventInfo
	{
		public bool IsImplicit { get; set; }

		public MappingStyle Style { get; set; }

		public MappingStartEventInfo(IObjectDescriptor source)
			: base(source)
		{
		}
	}
	public sealed class MappingEndEventInfo : EventInfo
	{
		public MappingEndEventInfo(IObjectDescriptor source)
			: base(source)
		{
		}
	}
	public sealed class SequenceStartEventInfo : ObjectEventInfo
	{
		public bool IsImplicit { get; set; }

		public SequenceStyle Style { get; set; }

		public SequenceStartEventInfo(IObjectDescriptor source)
			: base(source)
		{
		}
	}
	public sealed class SequenceEndEventInfo : EventInfo
	{
		public SequenceEndEventInfo(IObjectDescriptor source)
			: base(source)
		{
		}
	}
	public interface IAliasProvider
	{
		AnchorName GetAlias(object target);
	}
	public interface IDeserializer
	{
		T Deserialize<T>(string input);

		T Deserialize<T>(TextReader input);

		T Deserialize<T>(IParser parser);

		object? Deserialize(string input);

		object? Deserialize(TextReader input);

		object? Deserialize(IParser parser);

		object? Deserialize(string input, Type type);

		object? Deserialize(TextReader input, Type type);

		object? Deserialize(IParser parser, Type type);
	}
	public interface IEventEmitter
	{
		void Emit(AliasEventInfo eventInfo, IEmitter emitter);

		void Emit(ScalarEventInfo eventInfo, IEmitter emitter);

		void Emit(MappingStartEventInfo eventInfo, IEmitter emitter);

		void Emit(MappingEndEventInfo eventInfo, IEmitter emitter);

		void Emit(SequenceStartEventInfo eventInfo, IEmitter emitter);

		void Emit(SequenceEndEventInfo eventInfo, IEmitter emitter);
	}
	public interface INamingConvention
	{
		string Apply(string value);
	}
	public interface INodeDeserializer
	{
		bool Deserialize(IParser reader, Type expectedType, Func<IParser, Type, object?> nestedObjectDeserializer, out object? value);
	}
	public interface INodeTypeResolver
	{
		bool Resolve(NodeEvent? nodeEvent, ref Type currentType);
	}
	public interface IObjectAccessor
	{
		void Set(string name, object target, object value);

		object? Read(string name, object target);
	}
	public interface IObjectDescriptor
	{
		object? Value { get; }

		Type Type { get; }

		Type StaticType { get; }

		ScalarStyle ScalarStyle { get; }
	}
	public static class ObjectDescriptorExtensions
	{
		public static object NonNullValue(this IObjectDescriptor objectDescriptor)
		{
			return objectDescriptor.Value ?? throw new InvalidOperationException("Attempted to use a IObjectDescriptor of type '" + objectDescriptor.Type.FullName + "' whose Value is null at a point whete it is invalid to do so. This may indicate a bug in YamlDotNet.");
		}
	}
	public interface IObjectFactory
	{
		object Create(Type type);

		object? CreatePrimitive(Type type);

		bool GetDictionary(IObjectDescriptor descriptor, out IDictionary? dictionary, out Type[]? genericArguments);

		Type GetValueType(Type type);

		void ExecuteOnDeserializing(object value);

		void ExecuteOnDeserialized(object value);

		void ExecuteOnSerializing(object value);

		void ExecuteOnSerialized(object value);
	}
	public interface IObjectGraphTraversalStrategy
	{
		void Traverse<TContext>(IObjectDescriptor graph, IObjectGraphVisitor<TContext> visitor, TContext context);
	}
	public interface IObjectGraphVisitor<TContext>
	{
		bool Enter(IObjectDescriptor value, TContext context);

		bool EnterMapping(IObjectDescriptor key, IObjectDescriptor value, TContext context);

		bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value, TContext context);

		void VisitScalar(IObjectDescriptor scalar, TContext context);

		void VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType, TContext context);

		void VisitMappingEnd(IObjectDescriptor mapping, TContext context);

		void VisitSequenceStart(IObjectDescriptor sequence, Type elementType, TContext context);

		void VisitSequenceEnd(IObjectDescriptor sequence, TContext context);
	}
	public interface IPropertyDescriptor
	{
		string Name { get; }

		bool CanWrite { get; }

		Type Type { get; }

		Type? TypeOverride { get; set; }

		int Order { get; set; }

		ScalarStyle ScalarStyle { get; set; }

		T? GetCustomAttribute<T>() where T : Attribute;

		IObjectDescriptor Read(object target);

		void Write(object target, object? value);
	}
	public interface IRegistrationLocationSelectionSyntax<TBaseRegistrationType>
	{
		void InsteadOf<TRegistrationType>() where TRegistrationType : TBaseRegistrationType;

		void Before<TRegistrationType>() where TRegistrationType : TBaseRegistrationType;

		void After<TRegistrationType>() where TRegistrationType : TBaseRegistrationType;

		void OnTop();

		void OnBottom();
	}
	public interface ITrackingRegistrationLocationSelectionSyntax<TBaseRegistrationType>
	{
		void InsteadOf<TRegistrationType>() where TRegistrationType : TBaseRegistrationType;
	}
	public interface ISerializer
	{
		string Serialize(object? graph);

		string Serialize(object? graph, Type type);

		void Serialize(TextWriter writer, object? graph);

		void Serialize(TextWriter writer, object? graph, Type type);

		void Serialize(IEmitter emitter, object? graph);

		void Serialize(IEmitter emitter, object? graph, Type type);
	}
	public interface ITypeInspector
	{
		IEnumerable<IPropertyDescriptor> GetProperties(Type type, object? container);

		IPropertyDescriptor GetProperty(Type type, object? container, string name, [MaybeNullWhen(true)] bool ignoreUnmatched);
	}
	public interface ITypeResolver
	{
		Type Resolve(Type staticType, object? actualValue);
	}
	public interface IValueDeserializer
	{
		object? DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer);
	}
	public interface IValuePromise
	{
		event Action<object?> ValueAvailable;
	}
	public interface IValueSerializer
	{
		void SerializeValue(IEmitter emitter, object? value, Type? type);
	}
	public interface IYamlConvertible
	{
		void Read(IParser parser, Type expectedType, ObjectDeserializer nestedObjectDeserializer);

		void Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer);
	}
	public delegate object? ObjectDeserializer(Type type);
	public delegate void ObjectSerializer(object? value, Type? type = null);
	[Obsolete("Please use IYamlConvertible instead")]
	public interface IYamlSerializable
	{
		void ReadYaml(IParser parser);

		void WriteYaml(IEmitter emitter);
	}
	public interface IYamlTypeConverter
	{
		bool Accepts(Type type);

		object? ReadYaml(IParser parser, Type type);

		void WriteYaml(IEmitter emitter, object? value, Type type);
	}
	internal sealed class LazyComponentRegistrationList<TArgument, TComponent> : IEnumerable<Func<TArgument, TComponent>>, IEnumerable
	{
		public sealed class LazyComponentRegistration
		{
			public readonly Type ComponentType;

			public readonly Func<TArgument, TComponent> Factory;

			public LazyComponentRegistration(Type componentType, Func<TArgument, TComponent> factory)
			{
				ComponentType = componentType;
				Factory = factory;
			}
		}

		public sealed class TrackingLazyComponentRegistration
		{
			public readonly Type ComponentType;

			public readonly Func<TComponent, TArgument, TComponent> Factory;

			public TrackingLazyComponentRegistration(Type componentType, Func<TComponent, TArgument, TComponent> factory)
			{
				ComponentType = componentType;
				Factory = factory;
			}
		}

		private class RegistrationLocationSelector : IRegistrationLocationSelectionSyntax<TComponent>
		{
			private readonly LazyComponentRegistrationList<TArgument, TComponent> registrations;

			private readonly LazyComponentRegistration newRegistration;

			public RegistrationLocationSelector(LazyComponentRegistrationList<TArgument, TComponent> registrations, LazyComponentRegistration newRegistration)
			{
				this.registrations = registrations;
				this.newRegistration = newRegistration;
			}

			void IRegistrationLocationSelectionSyntax<TComponent>.InsteadOf<TRegistrationType>()
			{
				if (newRegistration.ComponentType != typeof(TRegistrationType))
				{
					registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType);
				}
				int index = registrations.EnsureRegistrationExists<TRegistrationType>();
				registrations.entries[index] = newRegistration;
			}

			void IRegistrationLocationSelectionSyntax<TComponent>.After<TRegistrationType>()
			{
				registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType);
				int num = registrations.EnsureRegistrationExists<TRegistrationType>();
				registrations.entries.Insert(num + 1, newRegistration);
			}

			void IRegistrationLocationSelectionSyntax<TComponent>.Before<TRegistrationType>()
			{
				registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType);
				int index = registrations.EnsureRegistrationExists<TRegistrationType>();
				registrations.entries.Insert(index, newRegistration);
			}

			void IRegistrationLocationSelectionSyntax<TComponent>.OnBottom()
			{
				registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType);
				registrations.entries.Add(newRegistration);
			}

			void IRegistrationLocationSelectionSyntax<TComponent>.OnTop()
			{
				registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType);
				registrations.entries.Insert(0, newRegistration);
			}
		}

		private class TrackingRegistrationLocationSelector : ITrackingRegistrationLocationSelectionSyntax<TComponent>
		{
			private readonly LazyComponentRegistrationList<TArgument, TComponent> registrations;

			private readonly TrackingLazyComponentRegistration newRegistration;

			public TrackingRegistrationLocationSelector(LazyComponentRegistrationList<TArgument, TComponent> registrations, TrackingLazyComponentRegistration newRegistration)
			{
				this.registrations = registrations;
				this.newRegistration = newRegistration;
			}

			void ITrackingRegistrationLocationSelectionSyntax<TComponent>.InsteadOf<TRegistrationType>()
			{
				if (newRegistration.ComponentType != typeof(TRegistrationType))
				{
					registrations.EnsureNoDuplicateRegistrationType(newRegistration.ComponentType);
				}
				int index = registrations.EnsureRegistrationExists<TRegistrationType>();
				Func<TArgument, TComponent> innerComponentFactory = registrations.entries[index].Factory;
				registrations.entries[index] = new LazyComponentRegistration(newRegistration.ComponentType, (TArgument arg) => newRegistration.Factory(innerComponentFactory(arg), arg));
			}
		}

		private readonly List<LazyComponentRegistration> entries = new List<LazyComponentRegistration>();

		public int Count => entries.Count;

		public IEnumerable<Func<TArgument, TComponent>> InReverseOrder
		{
			get
			{
				int i = entries.Count - 1;
				while (i >= 0)
				{
					yield return entries[i].Factory;
					int num = i - 1;
					i = num;
				}
			}
		}

		public LazyComponentRegistrationList<TArgument, TComponent> Clone()
		{
			LazyComponentRegistrationList<TArgument, TComponent> lazyComponentRegistrationList = new LazyComponentRegistrationList<TArgument, TComponent>();
			foreach (LazyComponentRegistration entry in entries)
			{
				lazyComponentRegistrationList.entries.Add(entry);
			}
			return lazyComponentRegistrationList;
		}

		public void Clear()
		{
			entries.Clear();
		}

		public void Add(Type componentType, Func<TArgument, TComponent> factory)
		{
			entries.Add(new LazyComponentRegistration(componentType, factory));
		}

		public void Remove(Type componentType)
		{
			for (int i = 0; i < entries.Count; i++)
			{
				if (entries[i].ComponentType == componentType)
				{
					entries.RemoveAt(i);
					return;
				}
			}
			throw new KeyNotFoundException("A component registration of type '" + componentType.FullName + "' was not found.");
		}

		public IRegistrationLocationSelectionSyntax<TComponent> CreateRegistrationLocationSelector(Type componentType, Func<TArgument, TComponent> factory)
		{
			return new RegistrationLocationSelector(this, new LazyComponentRegistration(componentType, factory));
		}

		public ITrackingRegistrationLocationSelectionSyntax<TComponent> CreateTrackingRegistrationLocationSelector(Type componentType, Func<TComponent, TArgument, TComponent> factory)
		{
			return new TrackingRegistrationLocationSelector(this, new TrackingLazyComponentRegistration(componentType, factory));
		}

		public IEnumerator<Func<TArgument, TComponent>> GetEnumerator()
		{
			return entries.Select((LazyComponentRegistration e) => e.Factory).GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}

		private int IndexOfRegistration(Type registrationType)
		{
			for (int i = 0; i < entries.Count; i++)
			{
				if (registrationType == entries[i].ComponentType)
				{
					return i;
				}
			}
			return -1;
		}

		private void EnsureNoDuplicateRegistrationType(Type componentType)
		{
			if (IndexOfRegistration(componentType) != -1)
			{
				throw new InvalidOperationException("A component of type '" + componentType.FullName + "' has already been registered.");
			}
		}

		private int EnsureRegistrationExists<TRegistrationType>()
		{
			int num = IndexOfRegistration(typeof(TRegistrationType));
			if (num == -1)
			{
				throw new InvalidOperationException("A component of type '" + typeof(TRegistrationType).FullName + "' has not been registered.");
			}
			return num;
		}
	}
	internal static class LazyComponentRegistrationListExtensions
	{
		public static TComponent BuildComponentChain<TComponent>(this LazyComponentRegistrationList<TComponent, TComponent> registrations, TComponent innerComponent)
		{
			return registrations.InReverseOrder.Aggregate(innerComponent, (TComponent inner, Func<TComponent, TComponent> factory) => factory(inner));
		}

		public static TComponent BuildComponentChain<TArgument, TComponent>(this LazyComponentRegistrationList<TArgument, TComponent> registrations, TComponent innerComponent, Func<TComponent, TArgument> argumentBuilder)
		{
			return registrations.InReverseOrder.Aggregate(innerComponent, (TComponent inner, Func<TArgument, TComponent> factory) => factory(argumentBuilder(inner)));
		}

		public static List<TComponent> BuildComponentList<TComponent>(this LazyComponentRegistrationList<Nothing, TComponent> registrations)
		{
			return registrations.Select((Func<Nothing, TComponent> factory) => factory(default(Nothing))).ToList();
		}

		public static List<TComponent> BuildComponentList<TArgument, TComponent>(this LazyComponentRegistrationList<TArgument, TComponent> registrations, TArgument argument)
		{
			return registrations.Select((Func<TArgument, TComponent> factory) => factory(argument)).ToList();
		}
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	public struct Nothing
	{
	}
	public sealed class ObjectDescriptor : IObjectDescriptor
	{
		public object? Value { get; private set; }

		public Type Type { get; private set; }

		public Type StaticType { get; private set; }

		public ScalarStyle ScalarStyle { get; private set; }

		public ObjectDescriptor(object? value, Type type, Type staticType)
			: this(value, type, staticType, ScalarStyle.Any)
		{
		}

		public ObjectDescriptor(object? value, Type type, Type staticType, ScalarStyle scalarStyle)
		{
			Value = value;
			Type = type ?? throw new ArgumentNullException("type");
			StaticType = staticType ?? throw new ArgumentNullException("staticType");
			ScalarStyle = scalarStyle;
		}
	}
	public delegate IObjectGraphTraversalStrategy ObjectGraphTraversalStrategyFactory(ITypeInspector typeInspector, ITypeResolver typeResolver, IEnumerable<IYamlTypeConverter> typeConverters, int maximumRecursion);
	public sealed class PropertyDescriptor : IPropertyDescriptor
	{
		private readonly IPropertyDescriptor baseDescriptor;

		public string Name { get; set; }

		public Type Type => baseDescriptor.Type;

		public Type? TypeOverride
		{
			get
			{
				return baseDescriptor.TypeOverride;
			}
			set
			{
				baseDescriptor.TypeOverride = value;
			}
		}

		public int Order { get; set; }

		public ScalarStyle ScalarStyle
		{
			get
			{
				return baseDescriptor.ScalarStyle;
			}
			set
			{
				baseDescriptor.ScalarStyle = value;
			}
		}

		public bool CanWrite => baseDescriptor.CanWrite;

		public PropertyDescriptor(IPropertyDescriptor baseDescriptor)
		{
			this.baseDescriptor = baseDescriptor;
			Name = baseDescriptor.Name;
		}

		public void Write(object target, object? value)
		{
			baseDescriptor.Write(target, value);
		}

		public T? GetCustomAttribute<T>() where T : Attribute
		{
			return baseDescriptor.GetCustomAttribute<T>();
		}

		public IObjectDescriptor Read(object target)
		{
			return baseDescriptor.Read(target);
		}
	}
	public sealed class Serializer : ISerializer
	{
		private readonly IValueSerializer valueSerializer;

		private readonly EmitterSettings emitterSettings;

		public Serializer()
			: this(new SerializerBuilder().BuildValueSerializer(), EmitterSettings.Default)
		{
		}

		private Serializer(IValueSerializer valueSerializer, EmitterSettings emitterSettings)
		{
			this.valueSerializer = valueSerializer ?? throw new ArgumentNullException("valueSerializer");
			this.emitterSettings = emitterSettings ?? throw new ArgumentNullException("emitterSettings");
		}

		public static Serializer FromValueSerializer(IValueSerializer valueSerializer, EmitterSettings emitterSettings)
		{
			return new Serializer(valueSerializer, emitterSettings);
		}

		public string Serialize(object? graph)
		{
			using StringWriter stringWriter = new StringWriter();
			Serialize(stringWriter, graph);
			return stringWriter.ToString();
		}

		public string Serialize(object? graph, Type type)
		{
			using StringWriter stringWriter = new StringWriter();
			Serialize(stringWriter, graph, type);
			return stringWriter.ToString();
		}

		public void Serialize(TextWriter writer, object? graph)
		{
			Serialize(new Emitter(writer, emitterSettings), graph);
		}

		public void Serialize(TextWriter writer, object? graph, Type type)
		{
			Serialize(new Emitter(writer, emitterSettings), graph, type);
		}

		public void Serialize(IEmitter emitter, object? graph)
		{
			if (emitter == null)
			{
				throw new ArgumentNullException("emitter");
			}
			EmitDocument(emitter, graph, null);
		}

		public void Serialize(IEmitter emitter, object? graph, Type type)
		{
			if (emitter == null)
			{
				throw new ArgumentNullException("emitter");
			}
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			EmitDocument(emitter, graph, type);
		}

		private void EmitDocument(IEmitter emitter, object? graph, Type? type)
		{
			emitter.Emit(new YamlDotNet.Core.Events.StreamStart());
			emitter.Emit(new YamlDotNet.Core.Events.DocumentStart());
			valueSerializer.SerializeValue(emitter, graph, type);
			emitter.Emit(new YamlDotNet.Core.Events.DocumentEnd(isImplicit: true));
			emitter.Emit(new YamlDotNet.Core.Events.StreamEnd());
		}
	}
	public sealed class SerializerBuilder : BuilderSkeleton<SerializerBuilder>
	{
		private class ValueSerializer : IValueSerializer
		{
			private readonly IObjectGraphTraversalStrategy traversalStrategy;

			private readonly IEventEmitter eventEmitter;

			private readonly IEnumerable<IYamlTypeConverter> typeConverters;

			private readonly LazyComponentRegistrationList<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitorFactories;

			private readonly LazyComponentRegistrationList<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>> emissionPhaseObjectGraphVisitorFactories;

			public ValueSerializer(IObjectGraphTraversalStrategy traversalStrategy, IEventEmitter eventEmitter, IEnumerable<IYamlTypeConverter> typeConverters, LazyComponentRegistrationList<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitorFactories, LazyComponentRegistrationList<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>> emissionPhaseObjectGraphVisitorFactories)
			{
				this.traversalStrategy = traversalStrategy;
				this.eventEmitter = eventEmitter;
				this.typeConverters = typeConverters;
				this.preProcessingPhaseObjectGraphVisitorFactories = preProcessingPhaseObjectGraphVisitorFactories;
				this.emissionPhaseObjectGraphVisitorFactories = emissionPhaseObjectGraphVisitorFactories;
			}

			public void SerializeValue(IEmitter emitter, object? value, Type? type)
			{
				Type type2 = type ?? ((value != null) ? value.GetType() : typeof(object));
				Type staticType = type ?? typeof(object);
				ObjectDescriptor graph = new ObjectDescriptor(value, type2, staticType);
				List<IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitors = preProcessingPhaseObjectGraphVisitorFactories.BuildComponentList(typeConverters);
				foreach (IObjectGraphVisitor<Nothing> item in preProcessingPhaseObjectGraphVisitors)
				{
					traversalStrategy.Traverse(graph, item, default(Nothing));
				}
				IObjectGraphVisitor<IEmitter> visitor = emissionPhaseObjectGraphVisitorFactories.BuildComponentChain<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>>(new EmittingObjectGraphVisitor(eventEmitter), (IObjectGraphVisitor<IEmitter> inner) => new EmissionPhaseObjectGraphVisitorArgs(inner, eventEmitter, preProcessingPhaseObjectGraphVisitors, typeConverters, NestedObjectSerializer));
				traversalStrategy.Traverse(graph, visitor, emitter);
				void NestedObjectSerializer(object? v, Type? t)
				{
					SerializeValue(emitter, v, t);
				}
			}
		}

		private ObjectGraphTraversalStrategyFactory objectGraphTraversalStrategyFactory;

		private readonly LazyComponentRegistrationList<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitorFactories;

		private readonly LazyComponentRegistrationList<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>> emissionPhaseObjectGraphVisitorFactories;

		private readonly LazyComponentRegistrationList<IEventEmitter, IEventEmitter> eventEmitterFactories;

		private readonly IDictionary<Type, TagName> tagMappings = new Dictionary<Type, TagName>();

		private readonly IObjectFactory objectFactory;

		private int maximumRecursion = 50;

		private EmitterSettings emitterSettings = EmitterSettings.Default;

		private DefaultValuesHandling defaultValuesHandlingConfiguration;

		private ScalarStyle defaultScalarStyle;

		private bool quoteNecessaryStrings;

		private bool quoteYaml1_1Strings;

		protected override SerializerBuilder Self => this;

		public SerializerBuilder()
			: base((ITypeResolver)new DynamicTypeResolver())
		{
			typeInspectorFactories.Add(typeof(CachedTypeInspector), (ITypeInspector inner) => new CachedTypeInspector(inner));
			typeInspectorFactories.Add(typeof(NamingConventionTypeInspector), (ITypeInspector inner) => (!(namingConvention is NullNamingConvention)) ? new NamingConventionTypeInspector(inner, namingConvention) : inner);
			typeInspectorFactories.Add(typeof(YamlAttributesTypeInspector), (ITypeInspector inner) => new YamlAttributesTypeInspector(inner));
			typeInspectorFactories.Add(typeof(YamlAttributeOverridesInspector), (ITypeInspector inner) => (overrides == null) ? inner : new YamlAttributeOverridesInspector(inner, overrides.Clone()));
			preProcessingPhaseObjectGraphVisitorFactories = new LazyComponentRegistrationList<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>> { 
			{
				typeof(AnchorAssigner),
				(IEnumerable<IYamlTypeConverter> typeConverters) => new AnchorAssigner(typeConverters)
			} };
			emissionPhaseObjectGraphVisitorFactories = new LazyComponentRegistrationList<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>>
			{
				{
					typeof(CustomSerializationObjectGraphVisitor),
					(EmissionPhaseObjectGraphVisitorArgs args) => new CustomSerializationObjectGraphVisitor(args.InnerVisitor, args.TypeConverters, args.NestedObjectSerializer)
				},
				{
					typeof(AnchorAssigningObjectGraphVisitor),
					(EmissionPhaseObjectGraphVisitorArgs args) => new AnchorAssigningObjectGraphVisitor(args.InnerVisitor, args.EventEmitter, args.GetPreProcessingPhaseObjectGraphVisitor<AnchorAssigner>())
				},
				{
					typeof(DefaultValuesObjectGraphVisitor),
					(EmissionPhaseObjectGraphVisitorArgs args) => new DefaultValuesObjectGraphVisitor(defaultValuesHandlingConfiguration, args.InnerVisitor, new DefaultObjectFactory())
				},
				{
					typeof(CommentsObjectGraphVisitor),
					(EmissionPhaseObjectGraphVisitorArgs args) => new CommentsObjectGraphVisitor(args.InnerVisitor)
				}
			};
			eventEmitterFactories = new LazyComponentRegistrationList<IEventEmitter, IEventEmitter> { 
			{
				typeof(TypeAssigningEventEmitter),
				(IEventEmitter inner) => new TypeAssigningEventEmitter(inner, requireTagWhenStaticAndActualTypesAreDifferent: false, tagMappings, quoteNecessaryStrings, quoteYaml1_1Strings, defaultScalarStyle, yamlFormatter)
			} };
			objectFactory = new DefaultObjectFactory();
			objectGraphTraversalStrategyFactory = (ITypeInspector typeInspector, ITypeResolver typeResolver, IEnumerable<IYamlTypeConverter> typeConverters, int maximumRecursion) => new FullObjectGraphTraversalStrategy(typeInspector, typeResolver, maximumRecursion, namingConvention, objectFactory);
		}

		public SerializerBuilder WithQuotingNecessaryStrings(bool quoteYaml1_1Strings = false)
		{
			quoteNecessaryStrings = true;
			this.quoteYaml1_1Strings = quoteYaml1_1Strings;
			return this;
		}

		public SerializerBuilder WithDefaultScalarStyle(ScalarStyle style)
		{
			defaultScalarStyle = style;
			return this;
		}

		public SerializerBuilder WithMaximumRecursion(int maximumRecursion)
		{
			if (maximumRecursion <= 0)
			{
				throw new ArgumentOutOfRangeException("maximumRecursion", $"The maximum recursion specified ({maximumRecursion}) is invalid. It should be a positive integer.");
			}
			this.maximumRecursion = maximumRecursion;
			return this;
		}

		public SerializerBuilder WithEventEmitter<TEventEmitter>(Func<IEventEmitter, TEventEmitter> eventEmitterFactory) where TEventEmitter : IEventEmitter
		{
			return WithEventEmitter(eventEmitterFactory, delegate(IRegistrationLocationSelectionSyntax<IEventEmitter> w)
			{
				w.OnTop();
			});
		}

		public SerializerBuilder WithEventEmitter<TEventEmitter>(Func<IEventEmitter, TEventEmitter> eventEmitterFactory, Action<IRegistrationLocationSelectionSyntax<IEventEmitter>> where) where TEventEmitter : IEventEmitter
		{
			if (eventEmitterFactory == null)
			{
				throw new ArgumentNullException("eventEmitterFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(eventEmitterFactories.CreateRegistrationLocationSelector(typeof(TEventEmitter), (IEventEmitter inner) => eventEmitterFactory(inner)));
			return Self;
		}

		public SerializerBuilder WithEventEmitter<TEventEmitter>(WrapperFactory<IEventEmitter, IEventEmitter, TEventEmitter> eventEmitterFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IEventEmitter>> where) where TEventEmitter : IEventEmitter
		{
			if (eventEmitterFactory == null)
			{
				throw new ArgumentNullException("eventEmitterFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(eventEmitterFactories.CreateTrackingRegistrationLocationSelector(typeof(TEventEmitter), (IEventEmitter wrapped, IEventEmitter inner) => eventEmitterFactory(wrapped, inner)));
			return Self;
		}

		public SerializerBuilder WithoutEventEmitter<TEventEmitter>() where TEventEmitter : IEventEmitter
		{
			return WithoutEventEmitter(typeof(TEventEmitter));
		}

		public SerializerBuilder WithoutEventEmitter(Type eventEmitterType)
		{
			if (eventEmitterType == null)
			{
				throw new ArgumentNullException("eventEmitterType");
			}
			eventEmitterFactories.Remove(eventEmitterType);
			return this;
		}

		public override SerializerBuilder WithTagMapping(TagName tag, Type type)
		{
			if (tag.IsEmpty)
			{
				throw new ArgumentException("Non-specific tags cannot be maped");
			}
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (tagMappings.TryGetValue(type, out var value))
			{
				throw new ArgumentException($"Type already has a registered tag '{value}' for type '{type.FullName}'", "type");
			}
			tagMappings.Add(type, tag);
			return this;
		}

		public SerializerBuilder WithoutTagMapping(Type type)
		{
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (!tagMappings.Remove(type))
			{
				throw new KeyNotFoundException("Tag for type '" + type.FullName + "' is not registered");
			}
			return this;
		}

		public SerializerBuilder EnsureRoundtrip()
		{
			objectGraphTraversalStrategyFactory = (ITypeInspector typeInspector, ITypeResolver typeResolver, IEnumerable<IYamlTypeConverter> typeConverters, int maximumRecursion) => new RoundtripObjectGraphTraversalStrategy(typeConverters, typeInspector, typeResolver, maximumRecursion, namingConvention, settings, objectFactory);
			WithEventEmitter((IEventEmitter inner) => new TypeAssigningEventEmitter(inner, requireTagWhenStaticAndActualTypesAreDifferent: true, tagMappings, quoteNecessaryStrings, quoteYaml1_1Strings, defaultScalarStyle, yamlFormatter), delegate(IRegistrationLocationSelectionSyntax<IEventEmitter> loc)
			{
				loc.InsteadOf<TypeAssigningEventEmitter>();
			});
			return WithTypeInspector((ITypeInspector inner) => new ReadableAndWritablePropertiesTypeInspector(inner), delegate(IRegistrationLocationSelectionSyntax<ITypeInspector> loc)
			{
				loc.OnBottom();
			});
		}

		public SerializerBuilder DisableAliases()
		{
			preProcessingPhaseObjectGraphVisitorFactories.Remove(typeof(AnchorAssigner));
			emissionPhaseObjectGraphVisitorFactories.Remove(typeof(AnchorAssigningObjectGraphVisitor));
			return this;
		}

		[Obsolete("The default behavior is now to always emit default values, thefore calling this method has no effect. This behavior is now controlled by ConfigureDefaultValuesHandling.", true)]
		public SerializerBuilder EmitDefaults()
		{
			return ConfigureDefaultValuesHandling(DefaultValuesHandling.Preserve);
		}

		public SerializerBuilder ConfigureDefaultValuesHandling(DefaultValuesHandling configuration)
		{
			defaultValuesHandlingConfiguration = configuration;
			return this;
		}

		public SerializerBuilder JsonCompatible()
		{
			emitterSettings = emitterSettings.WithMaxSimpleKeyLength(int.MaxValue).WithoutAnchorName();
			return WithTypeConverter(new YamlDotNet.Serialization.Converters.GuidConverter(jsonCompatible: true), delegate(IRegistrationLocationSelectionSyntax<IYamlTypeConverter> w)
			{
				w.InsteadOf<YamlDotNet.Serialization.Converters.GuidConverter>();
			}).WithTypeConverter(new YamlDotNet.Serialization.Converters.DateTimeConverter(DateTimeKind.Utc, null, true)).WithEventEmitter((IEventEmitter inner) => new JsonEventEmitter(inner, yamlFormatter), delegate(IRegistrationLocationSelectionSyntax<IEventEmitter> loc)
			{
				loc.InsteadOf<TypeAssigningEventEmitter>();
			});
		}

		public SerializerBuilder WithNewLine(string newLine)
		{
			emitterSettings = emitterSettings.WithNewLine(newLine);
			return this;
		}

		public SerializerBuilder WithPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>(TObjectGraphVisitor objectGraphVisitor) where TObjectGraphVisitor : IObjectGraphVisitor<Nothing>
		{
			return WithPreProcessingPhaseObjectGraphVisitor(objectGraphVisitor, delegate(IRegistrationLocationSelectionSyntax<IObjectGraphVisitor<Nothing>> w)
			{
				w.OnTop();
			});
		}

		public SerializerBuilder WithPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>(TObjectGraphVisitor objectGraphVisitor, Action<IRegistrationLocationSelectionSyntax<IObjectGraphVisitor<Nothing>>> where) where TObjectGraphVisitor : IObjectGraphVisitor<Nothing>
		{
			if (objectGraphVisitor == null)
			{
				throw new ArgumentNullException("objectGraphVisitor");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(preProcessingPhaseObjectGraphVisitorFactories.CreateRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IEnumerable<IYamlTypeConverter> _) => objectGraphVisitor));
			return this;
		}

		public SerializerBuilder WithPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>(WrapperFactory<IObjectGraphVisitor<Nothing>, TObjectGraphVisitor> objectGraphVisitorFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IObjectGraphVisitor<Nothing>>> where) where TObjectGraphVisitor : IObjectGraphVisitor<Nothing>
		{
			if (objectGraphVisitorFactory == null)
			{
				throw new ArgumentNullException("objectGraphVisitorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(preProcessingPhaseObjectGraphVisitorFactories.CreateTrackingRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IObjectGraphVisitor<Nothing> wrapped, IEnumerable<IYamlTypeConverter> _) => objectGraphVisitorFactory(wrapped)));
			return this;
		}

		public SerializerBuilder WithoutPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>() where TObjectGraphVisitor : IObjectGraphVisitor<Nothing>
		{
			return WithoutPreProcessingPhaseObjectGraphVisitor(typeof(TObjectGraphVisitor));
		}

		public SerializerBuilder WithoutPreProcessingPhaseObjectGraphVisitor(Type objectGraphVisitorType)
		{
			if (objectGraphVisitorType == null)
			{
				throw new ArgumentNullException("objectGraphVisitorType");
			}
			preProcessingPhaseObjectGraphVisitorFactories.Remove(objectGraphVisitorType);
			return this;
		}

		public SerializerBuilder WithObjectGraphTraversalStrategyFactory(ObjectGraphTraversalStrategyFactory objectGraphTraversalStrategyFactory)
		{
			this.objectGraphTraversalStrategyFactory = objectGraphTraversalStrategyFactory;
			return this;
		}

		public SerializerBuilder WithEmissionPhaseObjectGraphVisitor<TObjectGraphVisitor>(Func<EmissionPhaseObjectGraphVisitorArgs, TObjectGraphVisitor> objectGraphVisitorFactory) where TObjectGraphVisitor : IObjectGraphVisitor<IEmitter>
		{
			return WithEmissionPhaseObjectGraphVisitor(objectGraphVisitorFactory, delegate(IRegistrationLocationSelectionSyntax<IObjectGraphVisitor<IEmitter>> w)
			{
				w.OnTop();
			});
		}

		public SerializerBuilder WithEmissionPhaseObjectGraphVisitor<TObjectGraphVisitor>(Func<EmissionPhaseObjectGraphVisitorArgs, TObjectGraphVisitor> objectGraphVisitorFactory, Action<IRegistrationLocationSelectionSyntax<IObjectGraphVisitor<IEmitter>>> where) where TObjectGraphVisitor : IObjectGraphVisitor<IEmitter>
		{
			if (objectGraphVisitorFactory == null)
			{
				throw new ArgumentNullException("objectGraphVisitorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(emissionPhaseObjectGraphVisitorFactories.CreateRegistrationLocationSelector(typeof(TObjectGraphVisitor), (EmissionPhaseObjectGraphVisitorArgs args) => objectGraphVisitorFactory(args)));
			return this;
		}

		public SerializerBuilder WithEmissionPhaseObjectGraphVisitor<TObjectGraphVisitor>(WrapperFactory<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>, TObjectGraphVisitor> objectGraphVisitorFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IObjectGraphVisitor<IEmitter>>> where) where TObjectGraphVisitor : IObjectGraphVisitor<IEmitter>
		{
			if (objectGraphVisitorFactory == null)
			{
				throw new ArgumentNullException("objectGraphVisitorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(emissionPhaseObjectGraphVisitorFactories.CreateTrackingRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IObjectGraphVisitor<IEmitter> wrapped, EmissionPhaseObjectGraphVisitorArgs args) => objectGraphVisitorFactory(wrapped, args)));
			return this;
		}

		public SerializerBuilder WithoutEmissionPhaseObjectGraphVisitor<TObjectGraphVisitor>() where TObjectGraphVisitor : IObjectGraphVisitor<IEmitter>
		{
			return WithoutEmissionPhaseObjectGraphVisitor(typeof(TObjectGraphVisitor));
		}

		public SerializerBuilder WithoutEmissionPhaseObjectGraphVisitor(Type objectGraphVisitorType)
		{
			if (objectGraphVisitorType == null)
			{
				throw new ArgumentNullException("objectGraphVisitorType");
			}
			emissionPhaseObjectGraphVisitorFactories.Remove(objectGraphVisitorType);
			return this;
		}

		public SerializerBuilder WithIndentedSequences()
		{
			emitterSettings = emitterSettings.WithIndentedSequences();
			return this;
		}

		public ISerializer Build()
		{
			return Serializer.FromValueSerializer(BuildValueSerializer(), emitterSettings);
		}

		public IValueSerializer BuildValueSerializer()
		{
			IEnumerable<IYamlTypeConverter> typeConverters = BuildTypeConverters();
			ITypeInspector typeInspector = BuildTypeInspector();
			IObjectGraphTraversalStrategy traversalStrategy = objectGraphTraversalStrategyFactory(typeInspector, typeResolver, typeConverters, maximumRecursion);
			IEventEmitter eventEmitter = eventEmitterFactories.BuildComponentChain(new WriterEventEmitter());
			return new ValueSerializer(traversalStrategy, eventEmitter, typeConverters, preProcessingPhaseObjectGraphVisitorFactories.Clone(), emissionPhaseObjectGraphVisitorFactories.Clone());
		}

		internal ITypeInspector BuildTypeInspector()
		{
			ITypeInspector typeInspector = new ReadablePropertiesTypeInspector(typeResolver, includeNonPublicProperties);
			if (!ignoreFields)
			{
				typeInspector = new CompositeTypeInspector(new ReadableFieldsTypeInspector(typeResolver), typeInspector);
			}
			return typeInspectorFactories.BuildComponentChain(typeInspector);
		}
	}
	public class Settings
	{
		public bool AllowPrivateConstructors { get; set; }
	}
	public abstract class StaticBuilderSkeleton<TBuilder> where TBuilder : StaticBuilderSkeleton<TBuilder>
	{
		internal INamingConvention namingConvention = NullNamingConvention.Instance;

		internal ITypeResolver typeResolver;

		internal readonly LazyComponentRegistrationList<Nothing, IYamlTypeConverter> typeConverterFactories;

		internal readonly LazyComponentRegistrationList<ITypeInspector, ITypeInspector> typeInspectorFactories;

		internal bool includeNonPublicProperties;

		internal Settings settings;

		internal YamlFormatter yamlFormatter = YamlFormatter.Default;

		protected abstract TBuilder Self { get; }

		internal StaticBuilderSkeleton(ITypeResolver typeResolver)
		{
			typeConverterFactories = new LazyComponentRegistrationList<Nothing, IYamlTypeConverter> { 
			{
				typeof(YamlDotNet.Serialization.Converters.GuidConverter),
				(Nothing _) => new YamlDotNet.Serialization.Converters.GuidConverter(jsonCompatible: false)
			} };
			typeInspectorFactories = new LazyComponentRegistrationList<ITypeInspector, ITypeInspector>();
			this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver");
			settings = new Settings();
		}

		public TBuilder WithNamingConvention(INamingConvention namingConvention)
		{
			this.namingConvention = namingConvention ?? throw new ArgumentNullException("namingConvention");
			return Self;
		}

		public TBuilder WithTypeResolver(ITypeResolver typeResolver)
		{
			this.typeResolver = typeResolver ?? throw new ArgumentNullException("typeResolver");
			return Self;
		}

		public abstract TBuilder WithTagMapping(TagName tag, Type type);

		public TBuilder WithTypeConverter(IYamlTypeConverter typeConverter)
		{
			return WithTypeConverter(typeConverter, delegate(IRegistrationLocationSelectionSyntax<IYamlTypeConverter> w)
			{
				w.OnTop();
			});
		}

		public TBuilder WithTypeConverter(IYamlTypeConverter typeConverter, Action<IRegistrationLocationSelectionSyntax<IYamlTypeConverter>> where)
		{
			if (typeConverter == null)
			{
				throw new ArgumentNullException("typeConverter");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeConverterFactories.CreateRegistrationLocationSelector(typeConverter.GetType(), (Nothing _) => typeConverter));
			return Self;
		}

		public TBuilder WithTypeConverter<TYamlTypeConverter>(WrapperFactory<IYamlTypeConverter, IYamlTypeConverter> typeConverterFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IYamlTypeConverter>> where) where TYamlTypeConverter : IYamlTypeConverter
		{
			if (typeConverterFactory == null)
			{
				throw new ArgumentNullException("typeConverterFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeConverterFactories.CreateTrackingRegistrationLocationSelector(typeof(TYamlTypeConverter), (IYamlTypeConverter wrapped, Nothing _) => typeConverterFactory(wrapped)));
			return Self;
		}

		public TBuilder WithoutTypeConverter<TYamlTypeConverter>() where TYamlTypeConverter : IYamlTypeConverter
		{
			return WithoutTypeConverter(typeof(TYamlTypeConverter));
		}

		public TBuilder WithoutTypeConverter(Type converterType)
		{
			if (converterType == null)
			{
				throw new ArgumentNullException("converterType");
			}
			typeConverterFactories.Remove(converterType);
			return Self;
		}

		public TBuilder WithTypeInspector<TTypeInspector>(Func<ITypeInspector, TTypeInspector> typeInspectorFactory) where TTypeInspector : ITypeInspector
		{
			return WithTypeInspector(typeInspectorFactory, delegate(IRegistrationLocationSelectionSyntax<ITypeInspector> w)
			{
				w.OnTop();
			});
		}

		public TBuilder WithTypeInspector<TTypeInspector>(Func<ITypeInspector, TTypeInspector> typeInspectorFactory, Action<IRegistrationLocationSelectionSyntax<ITypeInspector>> where) where TTypeInspector : ITypeInspector
		{
			if (typeInspectorFactory == null)
			{
				throw new ArgumentNullException("typeInspectorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeInspectorFactories.CreateRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector inner) => typeInspectorFactory(inner)));
			return Self;
		}

		public TBuilder WithTypeInspector<TTypeInspector>(WrapperFactory<ITypeInspector, ITypeInspector, TTypeInspector> typeInspectorFactory, Action<ITrackingRegistrationLocationSelectionSyntax<ITypeInspector>> where) where TTypeInspector : ITypeInspector
		{
			if (typeInspectorFactory == null)
			{
				throw new ArgumentNullException("typeInspectorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeInspectorFactories.CreateTrackingRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector wrapped, ITypeInspector inner) => typeInspectorFactory(wrapped, inner)));
			return Self;
		}

		public TBuilder WithoutTypeInspector<TTypeInspector>() where TTypeInspector : ITypeInspector
		{
			return WithoutTypeInspector(typeof(TTypeInspector));
		}

		public TBuilder WithoutTypeInspector(Type inspectorType)
		{
			if (inspectorType == null)
			{
				throw new ArgumentNullException("inspectorType");
			}
			typeInspectorFactories.Remove(inspectorType);
			return Self;
		}

		public TBuilder WithYamlFormatter(YamlFormatter formatter)
		{
			yamlFormatter = formatter ?? throw new ArgumentNullException("formatter");
			return Self;
		}

		protected IEnumerable<IYamlTypeConverter> BuildTypeConverters()
		{
			return typeConverterFactories.BuildComponentList();
		}
	}
	public abstract class StaticContext
	{
		public virtual bool IsKnownType(Type type)
		{
			throw new NotImplementedException();
		}

		public virtual ITypeResolver GetTypeResolver()
		{
			throw new NotImplementedException();
		}

		public virtual StaticObjectFactory GetFactory()
		{
			throw new NotImplementedException();
		}

		public virtual ITypeInspector GetTypeInspector()
		{
			throw new NotImplementedException();
		}
	}
	public sealed class StaticDeserializerBuilder : StaticBuilderSkeleton<StaticDeserializerBuilder>
	{
		private readonly StaticContext context;

		private readonly StaticObjectFactory factory;

		private readonly LazyComponentRegistrationList<Nothing, INodeDeserializer> nodeDeserializerFactories;

		private readonly LazyComponentRegistrationList<Nothing, INodeTypeResolver> nodeTypeResolverFactories;

		private readonly Dictionary<TagName, Type> tagMappings;

		private readonly ITypeConverter typeConverter;

		private readonly Dictionary<Type, Type> typeMappings;

		private bool ignoreUnmatched;

		private bool duplicateKeyChecking;

		private bool attemptUnknownTypeDeserialization;

		protected override StaticDeserializerBuilder Self => this;

		public StaticDeserializerBuilder(StaticContext context)
			: base(context.GetTypeResolver())
		{
			this.context = context;
			factory = context.GetFactory();
			typeMappings = new Dictionary<Type, Type>();
			tagMappings = new Dictionary<TagName, Type>
			{
				{
					FailsafeSchema.Tags.Map,
					typeof(Dictionary<object, object>)
				},
				{
					FailsafeSchema.Tags.Str,
					typeof(string)
				},
				{
					JsonSchema.Tags.Bool,
					typeof(bool)
				},
				{
					JsonSchema.Tags.Float,
					typeof(double)
				},
				{
					JsonSchema.Tags.Int,
					typeof(int)
				},
				{
					DefaultSchema.Tags.Timestamp,
					typeof(DateTime)
				}
			};
			typeInspectorFactories.Add(typeof(CachedTypeInspector), (ITypeInspector inner) => new CachedTypeInspector(inner));
			typeInspectorFactories.Add(typeof(NamingConventionTypeInspector), (ITypeInspector inner) => (!(namingConvention is NullNamingConvention)) ? new NamingConventionTypeInspector(inner, namingConvention) : inner);
			typeInspectorFactories.Add(typeof(YamlAttributesTypeInspector), (ITypeInspector inner) => new YamlAttributesTypeInspector(inner));
			nodeDeserializerFactories = new LazyComponentRegistrationList<Nothing, INodeDeserializer>
			{
				{
					typeof(YamlConvertibleNodeDeserializer),
					(Nothing _) => new YamlConvertibleNodeDeserializer(factory)
				},
				{
					typeof(YamlSerializableNodeDeserializer),
					(Nothing _) => new YamlSerializableNodeDeserializer(factory)
				},
				{
					typeof(TypeConverterNodeDeserializer),
					(Nothing _) => new TypeConverterNodeDeserializer(BuildTypeConverters())
				},
				{
					typeof(NullNodeDeserializer),
					(Nothing _) => new NullNodeDeserializer()
				},
				{
					typeof(ScalarNodeDeserializer),
					(Nothing _) => new ScalarNodeDeserializer(attemptUnknownTypeDeserialization, typeConverter, yamlFormatter)
				},
				{
					typeof(StaticArrayNodeDeserializer),
					(Nothing _) => new StaticArrayNodeDeserializer(factory)
				},
				{
					typeof(StaticDictionaryNodeDeserializer),
					(Nothing _) => new StaticDictionaryNodeDeserializer(factory, duplicateKeyChecking)
				},
				{
					typeof(StaticCollectionNodeDeserializer),
					(Nothing _) => new StaticCollectionNodeDeserializer(factory)
				},
				{
					typeof(ObjectNodeDeserializer),
					(Nothing _) => new ObjectNodeDeserializer(factory, BuildTypeInspector(), ignoreUnmatched, duplicateKeyChecking, typeConverter)
				}
			};
			nodeTypeResolverFactories = new LazyComponentRegistrationList<Nothing, INodeTypeResolver>
			{
				{
					typeof(MappingNodeTypeResolver),
					(Nothing _) => new MappingNodeTypeResolver(typeMappings)
				},
				{
					typeof(YamlConvertibleTypeResolver),
					(Nothing _) => new YamlConvertibleTypeResolver()
				},
				{
					typeof(YamlSerializableTypeResolver),
					(Nothing _) => new YamlSerializableTypeResolver()
				},
				{
					typeof(TagNodeTypeResolver),
					(Nothing _) => new TagNodeTypeResolver(tagMappings)
				},
				{
					typeof(PreventUnknownTagsNodeTypeResolver),
					(Nothing _) => new PreventUnknownTagsNodeTypeResolver()
				},
				{
					typeof(DefaultContainersNodeTypeResolver),
					(Nothing _) => new DefaultContainersNodeTypeResolver()
				}
			};
			typeConverter = new NullTypeConverter();
		}

		internal ITypeInspector BuildTypeInspector()
		{
			ITypeInspector typeInspector = context.GetTypeInspector();
			return typeInspectorFactories.BuildComponentChain(typeInspector);
		}

		public StaticDeserializerBuilder WithAttemptingUnquotedStringTypeDeserialization()
		{
			attemptUnknownTypeDeserialization = true;
			return this;
		}

		public StaticDeserializerBuilder WithNodeDeserializer(INodeDeserializer nodeDeserializer)
		{
			return WithNodeDeserializer(nodeDeserializer, delegate(IRegistrationLocationSelectionSyntax<INodeDeserializer> w)
			{
				w.OnTop();
			});
		}

		public StaticDeserializerBuilder WithNodeDeserializer(INodeDeserializer nodeDeserializer, Action<IRegistrationLocationSelectionSyntax<INodeDeserializer>> where)
		{
			if (nodeDeserializer == null)
			{
				throw new ArgumentNullException("nodeDeserializer");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeDeserializerFactories.CreateRegistrationLocationSelector(nodeDeserializer.GetType(), (Nothing _) => nodeDeserializer));
			return this;
		}

		public StaticDeserializerBuilder WithNodeDeserializer<TNodeDeserializer>(WrapperFactory<INodeDeserializer, TNodeDeserializer> nodeDeserializerFactory, Action<ITrackingRegistrationLocationSelectionSyntax<INodeDeserializer>> where) where TNodeDeserializer : INodeDeserializer
		{
			if (nodeDeserializerFactory == null)
			{
				throw new ArgumentNullException("nodeDeserializerFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeDeserializerFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeDeserializer), (INodeDeserializer wrapped, Nothing _) => nodeDeserializerFactory(wrapped)));
			return this;
		}

		public StaticDeserializerBuilder WithoutNodeDeserializer<TNodeDeserializer>() where TNodeDeserializer : INodeDeserializer
		{
			return WithoutNodeDeserializer(typeof(TNodeDeserializer));
		}

		public StaticDeserializerBuilder WithoutNodeDeserializer(Type nodeDeserializerType)
		{
			if (nodeDeserializerType == null)
			{
				throw new ArgumentNullException("nodeDeserializerType");
			}
			nodeDeserializerFactories.Remove(nodeDeserializerType);
			return this;
		}

		public StaticDeserializerBuilder WithTypeDiscriminatingNodeDeserializer(Action<ITypeDiscriminatingNodeDeserializerOptions> configureTypeDiscriminatingNodeDeserializerOptions, int maxDepth = -1, int maxLength = -1)
		{
			TypeDiscriminatingNodeDeserializerOptions typeDiscriminatingNodeDeserializerOptions = new TypeDiscriminatingNodeDeserializerOptions();
			configureTypeDiscriminatingNodeDeserializerOptions(typeDiscriminatingNodeDeserializerOptions);
			TypeDiscriminatingNodeDeserializer nodeDeserializer = new TypeDiscriminatingNodeDeserializer(nodeDeserializerFactories.BuildComponentList(), typeDiscriminatingNodeDeserializerOptions.discriminators, maxDepth, maxLength);
			return WithNodeDeserializer(nodeDeserializer, delegate(IRegistrationLocationSelectionSyntax<INodeDeserializer> s)
			{
				s.Before<DictionaryNodeDeserializer>();
			});
		}

		public StaticDeserializerBuilder WithNodeTypeResolver(INodeTypeResolver nodeTypeResolver)
		{
			return WithNodeTypeResolver(nodeTypeResolver, delegate(IRegistrationLocationSelectionSyntax<INodeTypeResolver> w)
			{
				w.OnTop();
			});
		}

		public StaticDeserializerBuilder WithNodeTypeResolver(INodeTypeResolver nodeTypeResolver, Action<IRegistrationLocationSelectionSyntax<INodeTypeResolver>> where)
		{
			if (nodeTypeResolver == null)
			{
				throw new ArgumentNullException("nodeTypeResolver");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeTypeResolverFactories.CreateRegistrationLocationSelector(nodeTypeResolver.GetType(), (Nothing _) => nodeTypeResolver));
			return this;
		}

		public StaticDeserializerBuilder WithNodeTypeResolver<TNodeTypeResolver>(WrapperFactory<INodeTypeResolver, TNodeTypeResolver> nodeTypeResolverFactory, Action<ITrackingRegistrationLocationSelectionSyntax<INodeTypeResolver>> where) where TNodeTypeResolver : INodeTypeResolver
		{
			if (nodeTypeResolverFactory == null)
			{
				throw new ArgumentNullException("nodeTypeResolverFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeTypeResolverFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeTypeResolver), (INodeTypeResolver wrapped, Nothing _) => nodeTypeResolverFactory(wrapped)));
			return this;
		}

		public StaticDeserializerBuilder WithoutNodeTypeResolver<TNodeTypeResolver>() where TNodeTypeResolver : INodeTypeResolver
		{
			return WithoutNodeTypeResolver(typeof(TNodeTypeResolver));
		}

		public StaticDeserializerBuilder WithoutNodeTypeResolver(Type nodeTypeResolverType)
		{
			if (nodeTypeResolverType == null)
			{
				throw new ArgumentNullException("nodeTypeResolverType");
			}
			nodeTypeResolverFactories.Remove(nodeTypeResolverType);
			return this;
		}

		public override StaticDeserializerBuilder WithTagMapping(TagName tag, Type type)
		{
			if (tag.IsEmpty)
			{
				throw new ArgumentException("Non-specific tags cannot be maped");
			}
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (tagMappings.TryGetValue(tag, out Type value))
			{
				throw new ArgumentException($"Type already has a registered type '{value.FullName}' for tag '{tag}'", "tag");
			}
			tagMappings.Add(tag, type);
			return this;
		}

		public StaticDeserializerBuilder WithTypeMapping<TInterface, TConcrete>() where TConcrete : TInterface
		{
			Type typeFromHandle = typeof(TInterface);
			Type typeFromHandle2 = typeof(TConcrete);
			if (!typeFromHandle.IsAssignableFrom(typeFromHandle2))
			{
				throw new InvalidOperationException("The type '" + typeFromHandle2.Name + "' does not implement interface '" + typeFromHandle.Name + "'.");
			}
			if (typeMappings.ContainsKey(typeFromHandle))
			{
				typeMappings[typeFromHandle] = typeFromHandle2;
			}
			else
			{
				typeMappings.Add(typeFromHandle, typeFromHandle2);
			}
			return this;
		}

		public StaticDeserializerBuilder WithoutTagMapping(TagName tag)
		{
			if (tag.IsEmpty)
			{
				throw new ArgumentException("Non-specific tags cannot be maped");
			}
			if (!tagMappings.Remove(tag))
			{
				throw new KeyNotFoundException($"Tag '{tag}' is not registered");
			}
			return this;
		}

		public StaticDeserializerBuilder IgnoreUnmatchedProperties()
		{
			ignoreUnmatched = true;
			return this;
		}

		public StaticDeserializerBuilder WithDuplicateKeyChecking()
		{
			duplicateKeyChecking = true;
			return this;
		}

		public IDeserializer Build()
		{
			return Deserializer.FromValueDeserializer(BuildValueDeserializer());
		}

		public IValueDeserializer BuildValueDeserializer()
		{
			return new AliasValueDeserializer(new NodeValueDeserializer(nodeDeserializerFactories.BuildComponentList(), nodeTypeResolverFactories.BuildComponentList(), typeConverter));
		}
	}
	public sealed class StaticSerializerBuilder : StaticBuilderSkeleton<StaticSerializerBuilder>
	{
		private class ValueSerializer : IValueSerializer
		{
			private readonly IObjectGraphTraversalStrategy traversalStrategy;

			private readonly IEventEmitter eventEmitter;

			private readonly IEnumerable<IYamlTypeConverter> typeConverters;

			private readonly LazyComponentRegistrationList<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitorFactories;

			private readonly LazyComponentRegistrationList<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>> emissionPhaseObjectGraphVisitorFactories;

			public ValueSerializer(IObjectGraphTraversalStrategy traversalStrategy, IEventEmitter eventEmitter, IEnumerable<IYamlTypeConverter> typeConverters, LazyComponentRegistrationList<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitorFactories, LazyComponentRegistrationList<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>> emissionPhaseObjectGraphVisitorFactories)
			{
				this.traversalStrategy = traversalStrategy;
				this.eventEmitter = eventEmitter;
				this.typeConverters = typeConverters;
				this.preProcessingPhaseObjectGraphVisitorFactories = preProcessingPhaseObjectGraphVisitorFactories;
				this.emissionPhaseObjectGraphVisitorFactories = emissionPhaseObjectGraphVisitorFactories;
			}

			public void SerializeValue(IEmitter emitter, object? value, Type? type)
			{
				Type type2 = type ?? ((value != null) ? value.GetType() : typeof(object));
				Type staticType = type ?? typeof(object);
				ObjectDescriptor graph = new ObjectDescriptor(value, type2, staticType);
				List<IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitors = preProcessingPhaseObjectGraphVisitorFactories.BuildComponentList(typeConverters);
				foreach (IObjectGraphVisitor<Nothing> item in preProcessingPhaseObjectGraphVisitors)
				{
					traversalStrategy.Traverse(graph, item, default(Nothing));
				}
				IObjectGraphVisitor<IEmitter> visitor = emissionPhaseObjectGraphVisitorFactories.BuildComponentChain<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>>(new EmittingObjectGraphVisitor(eventEmitter), (IObjectGraphVisitor<IEmitter> inner) => new EmissionPhaseObjectGraphVisitorArgs(inner, eventEmitter, preProcessingPhaseObjectGraphVisitors, typeConverters, NestedObjectSerializer));
				traversalStrategy.Traverse(graph, visitor, emitter);
				void NestedObjectSerializer(object? v, Type? t)
				{
					SerializeValue(emitter, v, t);
				}
			}
		}

		private readonly StaticContext context;

		private readonly StaticObjectFactory factory;

		private ObjectGraphTraversalStrategyFactory objectGraphTraversalStrategyFactory;

		private readonly LazyComponentRegistrationList<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>> preProcessingPhaseObjectGraphVisitorFactories;

		private readonly LazyComponentRegistrationList<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>> emissionPhaseObjectGraphVisitorFactories;

		private readonly LazyComponentRegistrationList<IEventEmitter, IEventEmitter> eventEmitterFactories;

		private readonly IDictionary<Type, TagName> tagMappings = new Dictionary<Type, TagName>();

		private int maximumRecursion = 50;

		private EmitterSettings emitterSettings = EmitterSettings.Default;

		private DefaultValuesHandling defaultValuesHandlingConfiguration;

		private bool quoteNecessaryStrings;

		private bool quoteYaml1_1Strings;

		private ScalarStyle defaultScalarStyle;

		protected override StaticSerializerBuilder Self => this;

		public StaticSerializerBuilder(StaticContext context)
			: base((ITypeResolver)new DynamicTypeResolver())
		{
			this.context = context;
			factory = context.GetFactory();
			typeInspectorFactories.Add(typeof(CachedTypeInspector), (ITypeInspector inner) => new CachedTypeInspector(inner));
			typeInspectorFactories.Add(typeof(NamingConventionTypeInspector), (ITypeInspector inner) => (!(namingConvention is NullNamingConvention)) ? new NamingConventionTypeInspector(inner, namingConvention) : inner);
			typeInspectorFactories.Add(typeof(YamlAttributesTypeInspector), (ITypeInspector inner) => new YamlAttributesTypeInspector(inner));
			preProcessingPhaseObjectGraphVisitorFactories = new LazyComponentRegistrationList<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>> { 
			{
				typeof(AnchorAssigner),
				(IEnumerable<IYamlTypeConverter> typeConverters) => new AnchorAssigner(typeConverters)
			} };
			emissionPhaseObjectGraphVisitorFactories = new LazyComponentRegistrationList<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>>
			{
				{
					typeof(CustomSerializationObjectGraphVisitor),
					(EmissionPhaseObjectGraphVisitorArgs args) => new CustomSerializationObjectGraphVisitor(args.InnerVisitor, args.TypeConverters, args.NestedObjectSerializer)
				},
				{
					typeof(AnchorAssigningObjectGraphVisitor),
					(EmissionPhaseObjectGraphVisitorArgs args) => new AnchorAssigningObjectGraphVisitor(args.InnerVisitor, args.EventEmitter, args.GetPreProcessingPhaseObjectGraphVisitor<AnchorAssigner>())
				},
				{
					typeof(DefaultValuesObjectGraphVisitor),
					(EmissionPhaseObjectGraphVisitorArgs args) => new DefaultValuesObjectGraphVisitor(defaultValuesHandlingConfiguration, args.InnerVisitor, factory)
				},
				{
					typeof(CommentsObjectGraphVisitor),
					(EmissionPhaseObjectGraphVisitorArgs args) => new CommentsObjectGraphVisitor(args.InnerVisitor)
				}
			};
			eventEmitterFactories = new LazyComponentRegistrationList<IEventEmitter, IEventEmitter> { 
			{
				typeof(TypeAssigningEventEmitter),
				(IEventEmitter inner) => new TypeAssigningEventEmitter(inner, requireTagWhenStaticAndActualTypesAreDifferent: false, tagMappings, quoteNecessaryStrings, quoteYaml1_1Strings, defaultScalarStyle, yamlFormatter)
			} };
			objectGraphTraversalStrategyFactory = (ITypeInspector typeInspector, ITypeResolver typeResolver, IEnumerable<IYamlTypeConverter> typeConverters, int maximumRecursion) => new FullObjectGraphTraversalStrategy(typeInspector, typeResolver, maximumRecursion, namingConvention, factory);
		}

		public StaticSerializerBuilder WithQuotingNecessaryStrings(bool quoteYaml1_1Strings = false)
		{
			quoteNecessaryStrings = true;
			this.quoteYaml1_1Strings = quoteYaml1_1Strings;
			return this;
		}

		public StaticSerializerBuilder WithQuotingNecessaryStrings()
		{
			quoteNecessaryStrings = true;
			return this;
		}

		public StaticSerializerBuilder WithDefaultScalarStyle(ScalarStyle style)
		{
			defaultScalarStyle = style;
			return this;
		}

		public StaticSerializerBuilder WithMaximumRecursion(int maximumRecursion)
		{
			if (maximumRecursion <= 0)
			{
				throw new ArgumentOutOfRangeException("maximumRecursion", $"The maximum recursion specified ({maximumRecursion}) is invalid. It should be a positive integer.");
			}
			this.maximumRecursion = maximumRecursion;
			return this;
		}

		public StaticSerializerBuilder WithEventEmitter<TEventEmitter>(Func<IEventEmitter, TEventEmitter> eventEmitterFactory) where TEventEmitter : IEventEmitter
		{
			return WithEventEmitter(eventEmitterFactory, delegate(IRegistrationLocationSelectionSyntax<IEventEmitter> w)
			{
				w.OnTop();
			});
		}

		public StaticSerializerBuilder WithEventEmitter<TEventEmitter>(Func<IEventEmitter, TEventEmitter> eventEmitterFactory, Action<IRegistrationLocationSelectionSyntax<IEventEmitter>> where) where TEventEmitter : IEventEmitter
		{
			if (eventEmitterFactory == null)
			{
				throw new ArgumentNullException("eventEmitterFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(eventEmitterFactories.CreateRegistrationLocationSelector(typeof(TEventEmitter), (IEventEmitter inner) => eventEmitterFactory(inner)));
			return Self;
		}

		public StaticSerializerBuilder WithEventEmitter<TEventEmitter>(WrapperFactory<IEventEmitter, IEventEmitter, TEventEmitter> eventEmitterFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IEventEmitter>> where) where TEventEmitter : IEventEmitter
		{
			if (eventEmitterFactory == null)
			{
				throw new ArgumentNullException("eventEmitterFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(eventEmitterFactories.CreateTrackingRegistrationLocationSelector(typeof(TEventEmitter), (IEventEmitter wrapped, IEventEmitter inner) => eventEmitterFactory(wrapped, inner)));
			return Self;
		}

		public StaticSerializerBuilder WithoutEventEmitter<TEventEmitter>() where TEventEmitter : IEventEmitter
		{
			return WithoutEventEmitter(typeof(TEventEmitter));
		}

		public StaticSerializerBuilder WithoutEventEmitter(Type eventEmitterType)
		{
			if (eventEmitterType == null)
			{
				throw new ArgumentNullException("eventEmitterType");
			}
			eventEmitterFactories.Remove(eventEmitterType);
			return this;
		}

		public override StaticSerializerBuilder WithTagMapping(TagName tag, Type type)
		{
			if (tag.IsEmpty)
			{
				throw new ArgumentException("Non-specific tags cannot be maped");
			}
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (tagMappings.TryGetValue(type, out var value))
			{
				throw new ArgumentException($"Type already has a registered tag '{value}' for type '{type.FullName}'", "type");
			}
			tagMappings.Add(type, tag);
			return this;
		}

		public StaticSerializerBuilder WithoutTagMapping(Type type)
		{
			if (type == null)
			{
				throw new ArgumentNullException("type");
			}
			if (!tagMappings.Remove(type))
			{
				throw new KeyNotFoundException("Tag for type '" + type.FullName + "' is not registered");
			}
			return this;
		}

		public StaticSerializerBuilder EnsureRoundtrip()
		{
			objectGraphTraversalStrategyFactory = (ITypeInspector typeInspector, ITypeResolver typeResolver, IEnumerable<IYamlTypeConverter> typeConverters, int maximumRecursion) => new RoundtripObjectGraphTraversalStrategy(typeConverters, typeInspector, typeResolver, maximumRecursion, namingConvention, settings, factory);
			WithEventEmitter((IEventEmitter inner) => new TypeAssigningEventEmitter(inner, requireTagWhenStaticAndActualTypesAreDifferent: true, tagMappings, quoteNecessaryStrings), delegate(IRegistrationLocationSelectionSyntax<IEventEmitter> loc)
			{
				loc.InsteadOf<TypeAssigningEventEmitter>();
			});
			return WithTypeInspector((ITypeInspector inner) => new ReadableAndWritablePropertiesTypeInspector(inner), delegate(IRegistrationLocationSelectionSyntax<ITypeInspector> loc)
			{
				loc.OnBottom();
			});
		}

		public StaticSerializerBuilder DisableAliases()
		{
			preProcessingPhaseObjectGraphVisitorFactories.Remove(typeof(AnchorAssigner));
			emissionPhaseObjectGraphVisitorFactories.Remove(typeof(AnchorAssigningObjectGraphVisitor));
			return this;
		}

		[Obsolete("The default behavior is now to always emit default values, thefore calling this method has no effect. This behavior is now controlled by ConfigureDefaultValuesHandling.", true)]
		public StaticSerializerBuilder EmitDefaults()
		{
			return ConfigureDefaultValuesHandling(DefaultValuesHandling.Preserve);
		}

		public StaticSerializerBuilder ConfigureDefaultValuesHandling(DefaultValuesHandling configuration)
		{
			defaultValuesHandlingConfiguration = configuration;
			return this;
		}

		public StaticSerializerBuilder JsonCompatible()
		{
			emitterSettings = emitterSettings.WithMaxSimpleKeyLength(int.MaxValue).WithoutAnchorName();
			return WithTypeConverter(new YamlDotNet.Serialization.Converters.GuidConverter(jsonCompatible: true), delegate(IRegistrationLocationSelectionSyntax<IYamlTypeConverter> w)
			{
				w.InsteadOf<YamlDotNet.Serialization.Converters.GuidConverter>();
			}).WithTypeConverter(new YamlDotNet.Serialization.Converters.DateTimeConverter(DateTimeKind.Utc, null, true)).WithEventEmitter((IEventEmitter inner) => new JsonEventEmitter(inner, yamlFormatter), delegate(IRegistrationLocationSelectionSyntax<IEventEmitter> loc)
			{
				loc.InsteadOf<TypeAssigningEventEmitter>();
			});
		}

		public StaticSerializerBuilder WithNewLine(string newLine)
		{
			emitterSettings = emitterSettings.WithNewLine(newLine);
			return this;
		}

		public StaticSerializerBuilder WithPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>(TObjectGraphVisitor objectGraphVisitor) where TObjectGraphVisitor : IObjectGraphVisitor<Nothing>
		{
			return WithPreProcessingPhaseObjectGraphVisitor(objectGraphVisitor, delegate(IRegistrationLocationSelectionSyntax<IObjectGraphVisitor<Nothing>> w)
			{
				w.OnTop();
			});
		}

		public StaticSerializerBuilder WithPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>(TObjectGraphVisitor objectGraphVisitor, A