Decompiled source of Chaos Valheim Enchantment System v0.1.7

plugins/ChaosValheimEnchantmentSystem/fastJSON.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Dynamic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Xml.Serialization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("fastJSON")]
[assembly: AssemblyDescription("smallest fastest polymorphic json serializer")]
[assembly: AssemblyProduct("fastJSON")]
[assembly: AssemblyCopyright("2010-2020")]
[assembly: AssemblyFileVersion("2.4.0.2")]
[assembly: TargetFramework(".NETFramework,Version=v4.0", FrameworkDisplayName = ".NET Framework 4")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.4.0.0")]
[module: UnverifiableCode]
namespace fastJSON;

internal class DynamicJson : DynamicObject, IEnumerable
{
	private IDictionary<string, object> _dictionary { get; set; }

	private List<object> _list { get; set; }

	public DynamicJson(string json)
	{
		object obj = JSON.Parse(json);
		if (obj is IDictionary<string, object>)
		{
			_dictionary = (IDictionary<string, object>)obj;
		}
		else
		{
			_list = (List<object>)obj;
		}
	}

	private DynamicJson(object dictionary)
	{
		if (dictionary is IDictionary<string, object>)
		{
			_dictionary = (IDictionary<string, object>)dictionary;
		}
	}

	public override IEnumerable<string> GetDynamicMemberNames()
	{
		return _dictionary.Keys.ToList();
	}

	public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
	{
		object obj = indexes[0];
		if (obj is int)
		{
			result = _list[(int)obj];
		}
		else
		{
			result = _dictionary[(string)obj];
		}
		if (result is IDictionary<string, object>)
		{
			result = new DynamicJson(result as IDictionary<string, object>);
		}
		return true;
	}

	public override bool TryGetMember(GetMemberBinder binder, out object result)
	{
		if (!_dictionary.TryGetValue(binder.Name, out result) && !_dictionary.TryGetValue(binder.Name.ToLowerInvariant(), out result))
		{
			return false;
		}
		if (result is IDictionary<string, object>)
		{
			result = new DynamicJson(result as IDictionary<string, object>);
		}
		else if (result is List<object>)
		{
			List<object> list = new List<object>();
			foreach (object item in (List<object>)result)
			{
				if (item is IDictionary<string, object>)
				{
					list.Add(new DynamicJson(item as IDictionary<string, object>));
				}
				else
				{
					list.Add(item);
				}
			}
			result = list;
		}
		return _dictionary.ContainsKey(binder.Name);
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		foreach (object item in _list)
		{
			yield return new DynamicJson(item as IDictionary<string, object>);
		}
	}
}
public sealed class DatasetSchema
{
	public List<string> Info;

	public string Name;
}
public class DataMemberAttribute : Attribute
{
	public string Name { get; set; }
}
internal static class Formatter
{
	private static void AppendIndent(StringBuilder sb, int count, string indent)
	{
		while (count > 0)
		{
			sb.Append(indent);
			count--;
		}
	}

	public static string PrettyPrint(string input)
	{
		return PrettyPrint(input, new string(' ', JSON.Parameters.FormatterIndentSpaces));
	}

	public static string PrettyPrint(string input, string spaces)
	{
		StringBuilder stringBuilder = new StringBuilder();
		int num = 0;
		int length = input.Length;
		char[] array = input.ToCharArray();
		for (int i = 0; i < length; i++)
		{
			char c = array[i];
			if (c == '"')
			{
				bool flag = true;
				while (flag)
				{
					stringBuilder.Append(c);
					c = array[++i];
					switch (c)
					{
					case '\\':
						stringBuilder.Append(c);
						c = array[++i];
						break;
					case '"':
						flag = false;
						break;
					}
				}
			}
			switch (c)
			{
			case '[':
			case '{':
				stringBuilder.Append(c);
				stringBuilder.AppendLine();
				AppendIndent(stringBuilder, ++num, spaces);
				break;
			case ']':
			case '}':
				stringBuilder.AppendLine();
				AppendIndent(stringBuilder, --num, spaces);
				stringBuilder.Append(c);
				break;
			case ',':
				stringBuilder.Append(c);
				stringBuilder.AppendLine();
				AppendIndent(stringBuilder, num, spaces);
				break;
			case ':':
				stringBuilder.Append(" : ");
				break;
			default:
				if (!char.IsWhiteSpace(c))
				{
					stringBuilder.Append(c);
				}
				break;
			}
		}
		return stringBuilder.ToString();
	}
}
public class Helper
{
	public static bool IsNullable(Type t)
	{
		if (!t.IsGenericType)
		{
			return false;
		}
		Type genericTypeDefinition = t.GetGenericTypeDefinition();
		return genericTypeDefinition.Equals(typeof(Nullable<>));
	}

	public static Type UnderlyingTypeOf(Type t)
	{
		return Reflection.Instance.GetGenericArguments(t)[0];
	}

	public static DateTimeOffset CreateDateTimeOffset(int year, int month, int day, int hour, int min, int sec, int milli, int extraTicks, TimeSpan offset)
	{
		DateTimeOffset dateTimeOffset = new DateTimeOffset(year, month, day, hour, min, sec, milli, offset);
		if (extraTicks > 0)
		{
			return dateTimeOffset + TimeSpan.FromTicks(extraTicks);
		}
		return dateTimeOffset;
	}

	public static bool BoolConv(object v)
	{
		bool result = false;
		if (v is bool)
		{
			result = (bool)v;
		}
		else if (v is long)
		{
			result = (((long)v > 0) ? true : false);
		}
		else if (v is string)
		{
			string text = (string)v;
			switch (text.ToLowerInvariant())
			{
			case "1":
			case "true":
			case "yes":
			case "on":
				result = true;
				break;
			}
		}
		return result;
	}

	public static long AutoConv(object value, JSONParameters param)
	{
		if (value is string)
		{
			if (param.AutoConvertStringToNumbers)
			{
				string text = (string)value;
				return CreateLong(text, 0, text.Length);
			}
			throw new Exception("AutoConvertStringToNumbers is disabled for converting string : " + value);
		}
		if (value is long)
		{
			return (long)value;
		}
		return Convert.ToInt64(value);
	}

	public unsafe static long CreateLong(string s, int index, int count)
	{
		long num = 0L;
		int num2 = 1;
		fixed (char* ptr = s)
		{
			char* ptr2 = ptr;
			ptr2 += index;
			if (*ptr2 == '-')
			{
				num2 = -1;
				ptr2++;
				count--;
			}
			if (*ptr2 == '+')
			{
				ptr2++;
				count--;
			}
			while (count > 0)
			{
				num = num * 10 + (*ptr2 - 48);
				ptr2++;
				count--;
			}
		}
		return num * num2;
	}

	public unsafe static long CreateLong(char[] s, int index, int count)
	{
		long num = 0L;
		int num2 = 1;
		fixed (char* ptr = s)
		{
			char* ptr2 = ptr;
			ptr2 += index;
			if (*ptr2 == '-')
			{
				num2 = -1;
				ptr2++;
				count--;
			}
			if (*ptr2 == '+')
			{
				ptr2++;
				count--;
			}
			while (count > 0)
			{
				num = num * 10 + (*ptr2 - 48);
				ptr2++;
				count--;
			}
		}
		return num * num2;
	}

	public unsafe static int CreateInteger(string s, int index, int count)
	{
		int num = 0;
		int num2 = 1;
		fixed (char* ptr = s)
		{
			char* ptr2 = ptr;
			ptr2 += index;
			if (*ptr2 == '-')
			{
				num2 = -1;
				ptr2++;
				count--;
			}
			if (*ptr2 == '+')
			{
				ptr2++;
				count--;
			}
			while (count > 0)
			{
				num = num * 10 + (*ptr2 - 48);
				ptr2++;
				count--;
			}
		}
		return num * num2;
	}

	public static object CreateEnum(Type pt, object v)
	{
		return Enum.Parse(pt, v.ToString(), ignoreCase: true);
	}

	public static Guid CreateGuid(string s)
	{
		if (s.Length > 30)
		{
			return new Guid(s);
		}
		return new Guid(Convert.FromBase64String(s));
	}

	public static StringDictionary CreateSD(Dictionary<string, object> d)
	{
		StringDictionary stringDictionary = new StringDictionary();
		foreach (KeyValuePair<string, object> item in d)
		{
			stringDictionary.Add(item.Key, (string)item.Value);
		}
		return stringDictionary;
	}

	public static NameValueCollection CreateNV(Dictionary<string, object> d)
	{
		NameValueCollection nameValueCollection = new NameValueCollection();
		foreach (KeyValuePair<string, object> item in d)
		{
			nameValueCollection.Add(item.Key, (string)item.Value);
		}
		return nameValueCollection;
	}

	public static object CreateDateTimeOffset(string value)
	{
		int milli = 0;
		int extraTicks = 0;
		int num = 0;
		int num2 = 0;
		int year = CreateInteger(value, 0, 4);
		int month = CreateInteger(value, 5, 2);
		int day = CreateInteger(value, 8, 2);
		int hour = CreateInteger(value, 11, 2);
		int min = CreateInteger(value, 14, 2);
		int sec = CreateInteger(value, 17, 2);
		int num3 = 20;
		if (value.Length > 21 && value[19] == '.')
		{
			milli = CreateInteger(value, num3, 3);
			num3 = 23;
			if (value.Length > 25 && char.IsDigit(value[num3]))
			{
				extraTicks = CreateInteger(value, num3, 4);
				num3 = 27;
			}
		}
		if (value[num3] == 'Z')
		{
			return CreateDateTimeOffset(year, month, day, hour, min, sec, milli, extraTicks, TimeSpan.Zero);
		}
		if (value[num3] == ' ')
		{
			num3++;
		}
		num = CreateInteger(value, num3 + 1, 2);
		num2 = CreateInteger(value, num3 + 1 + 2 + 1, 2);
		if (value[num3] == '-')
		{
			num = -num;
		}
		return CreateDateTimeOffset(year, month, day, hour, min, sec, milli, extraTicks, new TimeSpan(num, num2, 0));
	}

	public static DateTime CreateDateTime(string value, bool UseUTCDateTime)
	{
		if (value.Length < 19)
		{
			return DateTime.MinValue;
		}
		bool flag = false;
		int millisecond = 0;
		int year = CreateInteger(value, 0, 4);
		int month = CreateInteger(value, 5, 2);
		int day = CreateInteger(value, 8, 2);
		int hour = CreateInteger(value, 11, 2);
		int minute = CreateInteger(value, 14, 2);
		int second = CreateInteger(value, 17, 2);
		if (value.Length > 21 && value[19] == '.')
		{
			millisecond = CreateInteger(value, 20, 3);
		}
		if (value[value.Length - 1] == 'Z')
		{
			flag = true;
		}
		if (!UseUTCDateTime && !flag)
		{
			return new DateTime(year, month, day, hour, minute, second, millisecond);
		}
		return new DateTime(year, month, day, hour, minute, second, millisecond, DateTimeKind.Utc).ToLocalTime();
	}
}
internal sealed class JSONSerializer
{
	private StringBuilder _output = new StringBuilder();

	private int _before;

	private int _MAX_DEPTH = 20;

	private int _current_depth;

	private Dictionary<string, int> _globalTypes = new Dictionary<string, int>();

	private Dictionary<object, int> _cirobj;

	private JSONParameters _params;

	private bool _useEscapedUnicode;

	private bool _TypesWritten;

	internal JSONSerializer(JSONParameters param)
	{
		if (param.OverrideObjectHashCodeChecking)
		{
			_cirobj = new Dictionary<object, int>(10, ReferenceEqualityComparer.Default);
		}
		else
		{
			_cirobj = new Dictionary<object, int>();
		}
		_params = param;
		_useEscapedUnicode = _params.UseEscapedUnicode;
		_MAX_DEPTH = _params.SerializerMaxDepth;
	}

	internal string ConvertToJSON(object obj)
	{
		WriteValue(obj);
		if (_params.UsingGlobalTypes && _globalTypes != null && _globalTypes.Count > 0)
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("\"$types\":{");
			bool flag = false;
			foreach (KeyValuePair<string, int> globalType in _globalTypes)
			{
				if (flag)
				{
					stringBuilder.Append(',');
				}
				flag = true;
				stringBuilder.Append('"');
				stringBuilder.Append(globalType.Key);
				stringBuilder.Append("\":\"");
				stringBuilder.Append(globalType.Value);
				stringBuilder.Append('"');
			}
			stringBuilder.Append("},");
			_output.Insert(_before, stringBuilder.ToString());
		}
		return _output.ToString();
	}

	private void WriteValue(object obj)
	{
		if (obj == null || obj is DBNull)
		{
			_output.Append("null");
		}
		else if (obj is string || obj is char)
		{
			WriteString(obj.ToString());
		}
		else if (obj is Guid)
		{
			WriteGuid((Guid)obj);
		}
		else if (obj is bool)
		{
			_output.Append(((bool)obj) ? "true" : "false");
		}
		else if (obj is int || obj is long || obj is decimal || obj is byte || obj is short || obj is sbyte || obj is ushort || obj is uint || obj is ulong)
		{
			_output.Append(((IConvertible)obj).ToString(NumberFormatInfo.InvariantInfo));
		}
		else if (obj is double || obj is double)
		{
			double d = (double)obj;
			if (double.IsNaN(d))
			{
				_output.Append("\"NaN\"");
			}
			else if (double.IsInfinity(d))
			{
				_output.Append('"');
				_output.Append(((IConvertible)obj).ToString(NumberFormatInfo.InvariantInfo));
				_output.Append('"');
			}
			else
			{
				_output.Append(((IConvertible)obj).ToString(NumberFormatInfo.InvariantInfo));
			}
		}
		else if (obj is float || obj is float)
		{
			float f = (float)obj;
			if (float.IsNaN(f))
			{
				_output.Append("\"NaN\"");
			}
			else if (float.IsInfinity(f))
			{
				_output.Append('"');
				_output.Append(((IConvertible)obj).ToString(NumberFormatInfo.InvariantInfo));
				_output.Append('"');
			}
			else
			{
				_output.Append(((IConvertible)obj).ToString(NumberFormatInfo.InvariantInfo));
			}
		}
		else if (obj is DateTime)
		{
			WriteDateTime((DateTime)obj);
		}
		else if (obj is DateTimeOffset)
		{
			WriteDateTimeOffset((DateTimeOffset)obj);
		}
		else if (obj is TimeSpan)
		{
			_output.Append(((TimeSpan)obj).Ticks);
		}
		else if (!_params.KVStyleStringDictionary && obj is IEnumerable<KeyValuePair<string, object>>)
		{
			WriteStringDictionary((IEnumerable<KeyValuePair<string, object>>)obj);
		}
		else if (!_params.KVStyleStringDictionary && obj is IDictionary && obj.GetType().IsGenericType && Reflection.Instance.GetGenericArguments(obj.GetType())[0] == typeof(string))
		{
			WriteStringDictionary((IDictionary)obj);
		}
		else if (obj is IDictionary)
		{
			WriteDictionary((IDictionary)obj);
		}
		else if (obj is byte[])
		{
			WriteBytes((byte[])obj);
		}
		else if (obj is StringDictionary)
		{
			WriteSD((StringDictionary)obj);
		}
		else if (obj is NameValueCollection)
		{
			WriteNV((NameValueCollection)obj);
		}
		else if (obj is Array)
		{
			WriteArrayRanked((Array)obj);
		}
		else if (obj is IEnumerable)
		{
			WriteArray((IEnumerable)obj);
		}
		else if (obj is Enum)
		{
			WriteEnum((Enum)obj);
		}
		else if (Reflection.Instance.IsTypeRegistered(obj.GetType()))
		{
			WriteCustom(obj);
		}
		else
		{
			WriteObject(obj);
		}
	}

	private void WriteDateTimeOffset(DateTimeOffset d)
	{
		DateTime dt = (_params.UseUTCDateTime ? d.UtcDateTime : d.DateTime);
		write_date_value(dt);
		long num = dt.Ticks % 10000000;
		_output.Append('.');
		_output.Append(num.ToString("0000000", NumberFormatInfo.InvariantInfo));
		if (_params.UseUTCDateTime)
		{
			_output.Append('Z');
		}
		else
		{
			if (d.Offset.Hours > 0)
			{
				_output.Append('+');
			}
			else
			{
				_output.Append('-');
			}
			_output.Append(d.Offset.Hours.ToString("00", NumberFormatInfo.InvariantInfo));
			_output.Append(':');
			_output.Append(d.Offset.Minutes.ToString("00", NumberFormatInfo.InvariantInfo));
		}
		_output.Append('"');
	}

	private void WriteNV(NameValueCollection nameValueCollection)
	{
		_output.Append('{');
		bool flag = false;
		foreach (string item in nameValueCollection)
		{
			if (_params.SerializeNullValues || nameValueCollection[item] != null)
			{
				if (flag)
				{
					_output.Append(',');
				}
				if (_params.SerializeToLowerCaseNames)
				{
					WritePair(item.ToLowerInvariant(), nameValueCollection[item]);
				}
				else
				{
					WritePair(item, nameValueCollection[item]);
				}
				flag = true;
			}
		}
		_output.Append('}');
	}

	private void WriteSD(StringDictionary stringDictionary)
	{
		_output.Append('{');
		bool flag = false;
		foreach (DictionaryEntry item in stringDictionary)
		{
			if (_params.SerializeNullValues || item.Value != null)
			{
				if (flag)
				{
					_output.Append(',');
				}
				string text = (string)item.Key;
				if (_params.SerializeToLowerCaseNames)
				{
					WritePair(text.ToLowerInvariant(), item.Value);
				}
				else
				{
					WritePair(text, item.Value);
				}
				flag = true;
			}
		}
		_output.Append('}');
	}

	private void WriteCustom(object obj)
	{
		Reflection.Instance._customSerializer.TryGetValue(obj.GetType(), out var value);
		WriteStringFast(value(obj));
	}

	private void WriteEnum(Enum e)
	{
		if (_params.UseValuesOfEnums)
		{
			WriteValue(Convert.ToInt32(e));
		}
		else
		{
			WriteStringFast(e.ToString());
		}
	}

	private void WriteGuid(Guid g)
	{
		if (!_params.UseFastGuid)
		{
			WriteStringFast(g.ToString());
		}
		else
		{
			WriteBytes(g.ToByteArray());
		}
	}

	private void WriteBytes(byte[] bytes)
	{
		WriteStringFast(Convert.ToBase64String(bytes, 0, bytes.Length, Base64FormattingOptions.None));
	}

	private void WriteDateTime(DateTime dateTime)
	{
		DateTime dt = dateTime;
		if (_params.UseUTCDateTime)
		{
			dt = dateTime.ToUniversalTime();
		}
		write_date_value(dt);
		if (_params.DateTimeMilliseconds)
		{
			_output.Append('.');
			_output.Append(dt.Millisecond.ToString("000", NumberFormatInfo.InvariantInfo));
		}
		if (_params.UseUTCDateTime)
		{
			_output.Append('Z');
		}
		_output.Append('"');
	}

	private void write_date_value(DateTime dt)
	{
		_output.Append('"');
		_output.Append(dt.Year.ToString("0000", NumberFormatInfo.InvariantInfo));
		_output.Append('-');
		_output.Append(dt.Month.ToString("00", NumberFormatInfo.InvariantInfo));
		_output.Append('-');
		_output.Append(dt.Day.ToString("00", NumberFormatInfo.InvariantInfo));
		_output.Append('T');
		_output.Append(dt.Hour.ToString("00", NumberFormatInfo.InvariantInfo));
		_output.Append(':');
		_output.Append(dt.Minute.ToString("00", NumberFormatInfo.InvariantInfo));
		_output.Append(':');
		_output.Append(dt.Second.ToString("00", NumberFormatInfo.InvariantInfo));
	}

	private void WriteObject(object obj)
	{
		int value = 0;
		if (!_cirobj.TryGetValue(obj, out value))
		{
			_cirobj.Add(obj, _cirobj.Count + 1);
		}
		else if (_current_depth > 0 && !_params.InlineCircularReferences)
		{
			_output.Append("{\"$i\":");
			_output.Append(value.ToString());
			_output.Append('}');
			return;
		}
		if (!_params.UsingGlobalTypes)
		{
			_output.Append('{');
		}
		else if (!_TypesWritten)
		{
			_output.Append('{');
			_before = _output.Length;
		}
		else
		{
			_output.Append('{');
		}
		_TypesWritten = true;
		_current_depth++;
		if (_current_depth > _MAX_DEPTH)
		{
			throw new Exception("Serializer encountered maximum depth of " + _MAX_DEPTH);
		}
		Dictionary<string, string> dictionary = new Dictionary<string, string>();
		Type type = obj.GetType();
		bool flag = false;
		if (_params.UseExtensions)
		{
			if (!_params.UsingGlobalTypes)
			{
				WritePairFast("$type", Reflection.Instance.GetTypeAssemblyName(type));
			}
			else
			{
				int value2 = 0;
				string typeAssemblyName = Reflection.Instance.GetTypeAssemblyName(type);
				if (!_globalTypes.TryGetValue(typeAssemblyName, out value2))
				{
					value2 = _globalTypes.Count + 1;
					_globalTypes.Add(typeAssemblyName, value2);
				}
				WritePairFast("$type", value2.ToString());
			}
			flag = true;
		}
		Getters[] getters = Reflection.Instance.GetGetters(type, _params.IgnoreAttributes);
		int num = getters.Length;
		for (int i = 0; i < num; i++)
		{
			Getters getters2 = getters[i];
			if (!_params.ShowReadOnlyProperties && getters2.ReadOnly)
			{
				continue;
			}
			object obj2 = getters2.Getter(obj);
			if (!_params.SerializeNullValues && (obj2 == null || obj2 is DBNull))
			{
				continue;
			}
			if (flag)
			{
				_output.Append(',');
			}
			if (getters2.memberName != null)
			{
				WritePair(getters2.memberName, obj2);
			}
			else if (_params.SerializeToLowerCaseNames)
			{
				WritePair(getters2.lcName, obj2);
			}
			else
			{
				WritePair(getters2.Name, obj2);
			}
			if (obj2 != null && _params.UseExtensions)
			{
				Type type2 = obj2.GetType();
				if (type2 == typeof(object))
				{
					dictionary.Add(getters2.Name, type2.ToString());
				}
			}
			flag = true;
		}
		if (dictionary.Count > 0 && _params.UseExtensions)
		{
			_output.Append(",\"$map\":");
			WriteStringDictionary(dictionary);
		}
		_output.Append('}');
		_current_depth--;
	}

	private void WritePairFast(string name, string value)
	{
		WriteStringFast(name);
		_output.Append(':');
		WriteStringFast(value);
	}

	private void WritePair(string name, object value)
	{
		WriteString(name);
		_output.Append(':');
		WriteValue(value);
	}

	private void WriteArray(IEnumerable array)
	{
		_output.Append('[');
		bool flag = false;
		foreach (object item in array)
		{
			if (flag)
			{
				_output.Append(',');
			}
			WriteValue(item);
			flag = true;
		}
		_output.Append(']');
	}

	private void WriteArrayRanked(Array array)
	{
		if (array.Rank == 1)
		{
			WriteArray(array);
			return;
		}
		_output.Append('[');
		bool flag = false;
		foreach (object item in array)
		{
			if (flag)
			{
				_output.Append(',');
			}
			WriteValue(item);
			flag = true;
		}
		_output.Append(']');
	}

	private void WriteStringDictionary(IDictionary dic)
	{
		_output.Append('{');
		bool flag = false;
		foreach (DictionaryEntry item in dic)
		{
			if (_params.SerializeNullValues || item.Value != null)
			{
				if (flag)
				{
					_output.Append(',');
				}
				string text = (string)item.Key;
				if (_params.SerializeToLowerCaseNames)
				{
					WritePair(text.ToLowerInvariant(), item.Value);
				}
				else
				{
					WritePair(text, item.Value);
				}
				flag = true;
			}
		}
		_output.Append('}');
	}

	private void WriteStringDictionary(IEnumerable<KeyValuePair<string, object>> dic)
	{
		_output.Append('{');
		bool flag = false;
		foreach (KeyValuePair<string, object> item in dic)
		{
			if (_params.SerializeNullValues || item.Value != null)
			{
				if (flag)
				{
					_output.Append(',');
				}
				string key = item.Key;
				if (_params.SerializeToLowerCaseNames)
				{
					WritePair(key.ToLowerInvariant(), item.Value);
				}
				else
				{
					WritePair(key, item.Value);
				}
				flag = true;
			}
		}
		_output.Append('}');
	}

	private void WriteDictionary(IDictionary dic)
	{
		_output.Append('[');
		bool flag = false;
		foreach (DictionaryEntry item in dic)
		{
			if (flag)
			{
				_output.Append(',');
			}
			_output.Append('{');
			WritePair("k", item.Key);
			_output.Append(',');
			WritePair("v", item.Value);
			_output.Append('}');
			flag = true;
		}
		_output.Append(']');
	}

	private void WriteStringFast(string s)
	{
		_output.Append('"');
		_output.Append(s);
		_output.Append('"');
	}

	private void WriteString(string s)
	{
		_output.Append('"');
		int num = -1;
		int length = s.Length;
		for (int i = 0; i < length; i++)
		{
			char c = s[i];
			if (_useEscapedUnicode)
			{
				if (c >= ' ' && c < '\u0080' && c != '"' && c != '\\')
				{
					if (num == -1)
					{
						num = i;
					}
					continue;
				}
			}
			else if (c != '\t' && c != '\n' && c != '\r' && c != '"' && c != '\\' && c != 0)
			{
				if (num == -1)
				{
					num = i;
				}
				continue;
			}
			if (num != -1)
			{
				_output.Append(s, num, i - num);
				num = -1;
			}
			switch (c)
			{
			case '\t':
				_output.Append('\\').Append('t');
				continue;
			case '\r':
				_output.Append('\\').Append('r');
				continue;
			case '\n':
				_output.Append('\\').Append('n');
				continue;
			case '"':
			case '\\':
				_output.Append('\\');
				_output.Append(c);
				continue;
			case '\0':
				_output.Append("\\u0000");
				continue;
			}
			if (_useEscapedUnicode)
			{
				_output.Append("\\u");
				StringBuilder output = _output;
				int num2 = c;
				output.Append(num2.ToString("X4", NumberFormatInfo.InvariantInfo));
			}
			else
			{
				_output.Append(c);
			}
		}
		if (num != -1)
		{
			_output.Append(s, num, s.Length - num);
		}
		_output.Append('"');
	}
}
public sealed class JSONParameters
{
	public bool UseOptimizedDatasetSchema = true;

	public bool UseFastGuid = true;

	public bool SerializeNullValues = true;

	public bool UseUTCDateTime = true;

	public bool ShowReadOnlyProperties;

	public bool UsingGlobalTypes = true;

	[Obsolete("Not needed anymore and will always match")]
	public bool IgnoreCaseOnDeserialize;

	public bool EnableAnonymousTypes;

	public bool UseExtensions = true;

	public bool UseEscapedUnicode = true;

	public bool KVStyleStringDictionary;

	public bool UseValuesOfEnums;

	public List<Type> IgnoreAttributes = new List<Type>
	{
		typeof(XmlIgnoreAttribute),
		typeof(NonSerializedAttribute)
	};

	public bool ParametricConstructorOverride;

	public bool DateTimeMilliseconds;

	public byte SerializerMaxDepth = 20;

	public bool InlineCircularReferences;

	public bool SerializeToLowerCaseNames;

	public byte FormatterIndentSpaces = 3;

	public bool AllowNonQuotedKeys;

	public bool AutoConvertStringToNumbers = true;

	public bool OverrideObjectHashCodeChecking;

	[Obsolete("Racist term removed, please use BadListTypeChecking")]
	public bool BlackListTypeChecking = true;

	public bool BadListTypeChecking = true;

	public bool FullyQualifiedDataSetSchema;

	public void FixValues()
	{
		if (!UseExtensions)
		{
			UsingGlobalTypes = false;
			InlineCircularReferences = true;
		}
		if (EnableAnonymousTypes)
		{
			ShowReadOnlyProperties = true;
		}
	}

	public JSONParameters MakeCopy()
	{
		return new JSONParameters
		{
			AllowNonQuotedKeys = AllowNonQuotedKeys,
			DateTimeMilliseconds = DateTimeMilliseconds,
			EnableAnonymousTypes = EnableAnonymousTypes,
			FormatterIndentSpaces = FormatterIndentSpaces,
			IgnoreAttributes = new List<Type>(IgnoreAttributes),
			InlineCircularReferences = InlineCircularReferences,
			KVStyleStringDictionary = KVStyleStringDictionary,
			ParametricConstructorOverride = ParametricConstructorOverride,
			SerializeNullValues = SerializeNullValues,
			SerializerMaxDepth = SerializerMaxDepth,
			SerializeToLowerCaseNames = SerializeToLowerCaseNames,
			ShowReadOnlyProperties = ShowReadOnlyProperties,
			UseEscapedUnicode = UseEscapedUnicode,
			UseExtensions = UseExtensions,
			UseFastGuid = UseFastGuid,
			UseOptimizedDatasetSchema = UseOptimizedDatasetSchema,
			UseUTCDateTime = UseUTCDateTime,
			UseValuesOfEnums = UseValuesOfEnums,
			UsingGlobalTypes = UsingGlobalTypes,
			AutoConvertStringToNumbers = AutoConvertStringToNumbers,
			OverrideObjectHashCodeChecking = OverrideObjectHashCodeChecking,
			FullyQualifiedDataSetSchema = FullyQualifiedDataSetSchema,
			BadListTypeChecking = BadListTypeChecking
		};
	}
}
public static class JSON
{
	public static JSONParameters Parameters = new JSONParameters();

	public static string ToNiceJSON(object obj)
	{
		string input = ToJSON(obj, Parameters);
		return Beautify(input);
	}

	public static string ToNiceJSON(object obj, JSONParameters param)
	{
		string input = ToJSON(obj, param);
		return Beautify(input, param.FormatterIndentSpaces);
	}

	public static string ToJSON(object obj)
	{
		return ToJSON(obj, Parameters);
	}

	public static string ToJSON(object obj, JSONParameters param)
	{
		param.FixValues();
		param = param.MakeCopy();
		Type c = null;
		if (obj == null)
		{
			return "null";
		}
		if (obj.GetType().IsGenericType)
		{
			c = Reflection.Instance.GetGenericTypeDefinition(obj.GetType());
		}
		if (typeof(IDictionary).IsAssignableFrom(c) || typeof(List<>).IsAssignableFrom(c))
		{
			param.UsingGlobalTypes = false;
		}
		if (param.EnableAnonymousTypes)
		{
			param.UseExtensions = false;
			param.UsingGlobalTypes = false;
		}
		return new JSONSerializer(param).ConvertToJSON(obj);
	}

	public static object Parse(string json)
	{
		return new JsonParser(json, Parameters.AllowNonQuotedKeys).Decode(null);
	}

	public static dynamic ToDynamic(string json)
	{
		return new DynamicJson(json);
	}

	public static T ToObject<T>(string json)
	{
		return new deserializer(Parameters).ToObject<T>(json);
	}

	public static T ToObject<T>(string json, JSONParameters param)
	{
		return new deserializer(param).ToObject<T>(json);
	}

	public static object ToObject(string json)
	{
		return new deserializer(Parameters).ToObject(json, null);
	}

	public static object ToObject(string json, JSONParameters param)
	{
		return new deserializer(param).ToObject(json, null);
	}

	public static object ToObject(string json, Type type)
	{
		return new deserializer(Parameters).ToObject(json, type);
	}

	public static object ToObject(string json, Type type, JSONParameters par)
	{
		return new deserializer(par).ToObject(json, type);
	}

	public static object FillObject(object input, string json)
	{
		if (!(new JsonParser(json, Parameters.AllowNonQuotedKeys).Decode(input.GetType()) is Dictionary<string, object> d))
		{
			return null;
		}
		return new deserializer(Parameters).ParseDictionary(d, null, input.GetType(), input);
	}

	public static object DeepCopy(object obj)
	{
		return new deserializer(Parameters).ToObject(ToJSON(obj));
	}

	public static T DeepCopy<T>(T obj)
	{
		return new deserializer(Parameters).ToObject<T>(ToJSON(obj));
	}

	public static string Beautify(string input)
	{
		string spaces = new string(' ', Parameters.FormatterIndentSpaces);
		return Formatter.PrettyPrint(input, spaces);
	}

	public static string Beautify(string input, byte spaces)
	{
		string spaces2 = new string(' ', spaces);
		return Formatter.PrettyPrint(input, spaces2);
	}

	public static void RegisterCustomType(Type type, Reflection.Serialize serializer, Reflection.Deserialize deserializer)
	{
		Reflection.Instance.RegisterCustomType(type, serializer, deserializer);
	}

	public static void ClearReflectionCache()
	{
		Reflection.Instance.ClearReflectionCache();
	}
}
internal class deserializer
{
	private JSONParameters _params;

	private bool _usingglobals;

	private Dictionary<object, int> _circobj;

	private Dictionary<int, object> _cirrev = new Dictionary<int, object>();

	public deserializer(JSONParameters param)
	{
		if (param.OverrideObjectHashCodeChecking)
		{
			_circobj = new Dictionary<object, int>(10, ReferenceEqualityComparer.Default);
		}
		else
		{
			_circobj = new Dictionary<object, int>();
		}
		param.FixValues();
		_params = param.MakeCopy();
	}

	public T ToObject<T>(string json)
	{
		Type typeFromHandle = typeof(T);
		object obj = ToObject(json, typeFromHandle);
		if (typeFromHandle.IsArray)
		{
			if ((obj as ICollection).Count == 0)
			{
				Type elementType = typeFromHandle.GetElementType();
				object obj2 = Array.CreateInstance(elementType, 0);
				return (T)obj2;
			}
			return (T)obj;
		}
		return (T)obj;
	}

	public object ToObject(string json)
	{
		return ToObject(json, null);
	}

	public object ToObject(string json, Type type)
	{
		Type type2 = null;
		if (type != null && type.IsGenericType)
		{
			type2 = Reflection.Instance.GetGenericTypeDefinition(type);
		}
		_usingglobals = _params.UsingGlobalTypes;
		if (typeof(IDictionary).IsAssignableFrom(type2) || typeof(List<>).IsAssignableFrom(type2))
		{
			_usingglobals = false;
		}
		object obj = new JsonParser(json, _params.AllowNonQuotedKeys).Decode(type);
		if (obj == null)
		{
			return null;
		}
		if (obj is IDictionary)
		{
			if (type != null && typeof(Dictionary<, >).IsAssignableFrom(type2))
			{
				return RootDictionary(obj, type);
			}
			return ParseDictionary(obj as Dictionary<string, object>, null, type, null);
		}
		if (obj is List<object>)
		{
			if (!(type != null))
			{
				List<object> list = (List<object>)obj;
				if (list.Count > 0 && list[0].GetType() == typeof(Dictionary<string, object>))
				{
					Dictionary<string, object> globaltypes = new Dictionary<string, object>();
					List<object> list2 = new List<object>();
					{
						foreach (object item in list)
						{
							list2.Add(ParseDictionary((Dictionary<string, object>)item, globaltypes, null, null));
						}
						return list2;
					}
				}
				return list.ToArray();
			}
			if (typeof(Dictionary<, >).IsAssignableFrom(type2))
			{
				return RootDictionary(obj, type);
			}
			if (type2 == typeof(List<>))
			{
				return RootList(obj, type);
			}
			if (type.IsArray)
			{
				return RootArray(obj, type);
			}
			if (type == typeof(Hashtable))
			{
				return RootHashTable((List<object>)obj);
			}
		}
		else if (type != null && obj.GetType() != type)
		{
			return ChangeType(obj, type);
		}
		return obj;
	}

	private object RootHashTable(List<object> o)
	{
		Hashtable hashtable = new Hashtable();
		foreach (Dictionary<string, object> item in o)
		{
			object obj = item["k"];
			object obj2 = item["v"];
			if (obj is Dictionary<string, object>)
			{
				obj = ParseDictionary((Dictionary<string, object>)obj, null, typeof(object), null);
			}
			if (obj2 is Dictionary<string, object>)
			{
				obj2 = ParseDictionary((Dictionary<string, object>)obj2, null, typeof(object), null);
			}
			hashtable.Add(obj, obj2);
		}
		return hashtable;
	}

	private object ChangeType(object value, Type conversionType)
	{
		if (conversionType == typeof(object))
		{
			return value;
		}
		if (conversionType == typeof(int))
		{
			if (!(value is string text))
			{
				return (int)(long)value;
			}
			if (_params.AutoConvertStringToNumbers)
			{
				return Helper.CreateInteger(text, 0, text.Length);
			}
			throw new Exception("AutoConvertStringToNumbers is disabled for converting string : " + value);
		}
		if (conversionType == typeof(long))
		{
			if (!(value is string text2))
			{
				return (long)value;
			}
			if (_params.AutoConvertStringToNumbers)
			{
				return Helper.CreateLong(text2, 0, text2.Length);
			}
			throw new Exception("AutoConvertStringToNumbers is disabled for converting string : " + value);
		}
		if (conversionType == typeof(string))
		{
			return (string)value;
		}
		if (conversionType.IsEnum)
		{
			return Helper.CreateEnum(conversionType, value);
		}
		if (conversionType == typeof(DateTime))
		{
			return Helper.CreateDateTime((string)value, _params.UseUTCDateTime);
		}
		if (conversionType == typeof(DateTimeOffset))
		{
			return Helper.CreateDateTimeOffset((string)value);
		}
		if (Reflection.Instance.IsTypeRegistered(conversionType))
		{
			return Reflection.Instance.CreateCustom((string)value, conversionType);
		}
		if (Helper.IsNullable(conversionType))
		{
			if (value == null)
			{
				return value;
			}
			conversionType = Helper.UnderlyingTypeOf(conversionType);
		}
		if (conversionType == typeof(Guid))
		{
			return Helper.CreateGuid((string)value);
		}
		if (conversionType == typeof(byte[]))
		{
			return Convert.FromBase64String((string)value);
		}
		if (conversionType == typeof(TimeSpan))
		{
			return new TimeSpan((long)value);
		}
		return Convert.ChangeType(value, conversionType, CultureInfo.InvariantCulture);
	}

	private object RootList(object parse, Type type)
	{
		Type[] genericArguments = Reflection.Instance.GetGenericArguments(type);
		IList list = (IList)Reflection.Instance.FastCreateList(type, ((IList)parse).Count);
		DoParseList((IList)parse, genericArguments[0], list);
		return list;
	}

	private void DoParseList(IList parse, Type it, IList o)
	{
		Dictionary<string, object> globaltypes = new Dictionary<string, object>();
		foreach (object item in parse)
		{
			_usingglobals = false;
			object obj = item;
			obj = ((!(item is Dictionary<string, object> d)) ? ChangeType(item, it) : ParseDictionary(d, globaltypes, it, null));
			o.Add(obj);
		}
	}

	private object RootArray(object parse, Type type)
	{
		Type elementType = type.GetElementType();
		IList list = (IList)Reflection.Instance.FastCreateInstance(typeof(List<>).MakeGenericType(elementType));
		DoParseList((IList)parse, elementType, list);
		Array array = Array.CreateInstance(elementType, list.Count);
		list.CopyTo(array, 0);
		return array;
	}

	private object RootDictionary(object parse, Type type)
	{
		Type[] genericArguments = Reflection.Instance.GetGenericArguments(type);
		Type type2 = null;
		Type type3 = null;
		bool flag = false;
		if (genericArguments != null)
		{
			type2 = genericArguments[0];
			type3 = genericArguments[1];
			if (type3 != null)
			{
				flag = type3.Name.StartsWith("Dictionary");
			}
		}
		Type elementType = type3.GetElementType();
		if (parse is Dictionary<string, object>)
		{
			IDictionary dictionary = (IDictionary)Reflection.Instance.FastCreateInstance(type);
			{
				foreach (KeyValuePair<string, object> item in (Dictionary<string, object>)parse)
				{
					object key = ChangeType(item.Key, type2);
					object value = ((!flag) ? ((!(item.Value is Dictionary<string, object>)) ? ((type3.IsArray && type3 != typeof(byte[])) ? CreateArray((List<object>)item.Value, type3, elementType, null) : ((!(item.Value is IList)) ? ChangeType(item.Value, type3) : CreateGenericList((List<object>)item.Value, type3, type2, null))) : ParseDictionary(item.Value as Dictionary<string, object>, null, type3, null)) : RootDictionary(item.Value, type3));
					dictionary.Add(key, value);
				}
				return dictionary;
			}
		}
		if (parse is List<object>)
		{
			return CreateDictionary(parse as List<object>, type, genericArguments, null);
		}
		return null;
	}

	internal object ParseDictionary(Dictionary<string, object> d, Dictionary<string, object> globaltypes, Type type, object input)
	{
		object value = "";
		if (type == typeof(NameValueCollection))
		{
			return Helper.CreateNV(d);
		}
		if (type == typeof(StringDictionary))
		{
			return Helper.CreateSD(d);
		}
		if (d.TryGetValue("$i", out value))
		{
			object value2 = null;
			_cirrev.TryGetValue((int)(long)value, out value2);
			return value2;
		}
		if (d.TryGetValue("$types", out value))
		{
			_usingglobals = true;
			if (globaltypes == null)
			{
				globaltypes = new Dictionary<string, object>();
			}
			foreach (KeyValuePair<string, object> item in (Dictionary<string, object>)value)
			{
				globaltypes.Add((string)item.Value, item.Key);
			}
		}
		if (globaltypes != null)
		{
			_usingglobals = true;
		}
		bool flag = d.TryGetValue("$type", out value);
		if (!flag && type == typeof(object))
		{
			return d;
		}
		if (flag)
		{
			if (_usingglobals)
			{
				object value3 = "";
				if (globaltypes != null && globaltypes.TryGetValue((string)value, out value3))
				{
					value = value3;
				}
			}
			type = Reflection.Instance.GetTypeFromCache((string)value, _params.BadListTypeChecking);
		}
		if (type == null)
		{
			throw new Exception("Cannot determine type : " + value);
		}
		string fullName = type.FullName;
		object obj = input;
		if (obj == null)
		{
			obj = ((!_params.ParametricConstructorOverride) ? Reflection.Instance.FastCreateInstance(type) : FormatterServices.GetUninitializedObject(type));
		}
		int value4 = 0;
		if (!_circobj.TryGetValue(obj, out value4))
		{
			value4 = _circobj.Count + 1;
			_circobj.Add(obj, value4);
			_cirrev.Add(value4, obj);
		}
		Dictionary<string, myPropInfo> dictionary = Reflection.Instance.Getproperties(type, fullName, _params.ShowReadOnlyProperties);
		foreach (KeyValuePair<string, object> item2 in d)
		{
			string key = item2.Key;
			object value5 = item2.Value;
			string text = key;
			if (text == "$map")
			{
				ProcessMap(obj, dictionary, (Dictionary<string, object>)d[text]);
			}
			else
			{
				if ((!dictionary.TryGetValue(text, out var value6) && !dictionary.TryGetValue(text.ToLowerInvariant(), out value6)) || !value6.CanWrite)
				{
					continue;
				}
				object value7 = null;
				if (value5 != null)
				{
					switch (value6.Type)
					{
					case myPropInfoType.Int:
						value7 = (int)Helper.AutoConv(value5, _params);
						break;
					case myPropInfoType.Long:
						value7 = Helper.AutoConv(value5, _params);
						break;
					case myPropInfoType.String:
						value7 = value5.ToString();
						break;
					case myPropInfoType.Bool:
						value7 = Helper.BoolConv(value5);
						break;
					case myPropInfoType.DateTime:
						value7 = Helper.CreateDateTime((string)value5, _params.UseUTCDateTime);
						break;
					case myPropInfoType.Enum:
						value7 = Helper.CreateEnum(value6.pt, value5);
						break;
					case myPropInfoType.Guid:
						value7 = Helper.CreateGuid((string)value5);
						break;
					case myPropInfoType.Array:
						if (!value6.IsValueType)
						{
							value7 = CreateArray((List<object>)value5, value6.pt, value6.bt, globaltypes);
						}
						break;
					case myPropInfoType.ByteArray:
						value7 = Convert.FromBase64String((string)value5);
						break;
					case myPropInfoType.Dictionary:
						value7 = CreateDictionary((List<object>)value5, value6.pt, value6.GenericTypes, globaltypes);
						break;
					case myPropInfoType.StringKeyDictionary:
						value7 = CreateStringKeyDictionary((Dictionary<string, object>)value5, value6.pt, value6.GenericTypes, globaltypes);
						break;
					case myPropInfoType.NameValue:
						value7 = Helper.CreateNV((Dictionary<string, object>)value5);
						break;
					case myPropInfoType.StringDictionary:
						value7 = Helper.CreateSD((Dictionary<string, object>)value5);
						break;
					case myPropInfoType.Custom:
						value7 = Reflection.Instance.CreateCustom((string)value5, value6.pt);
						break;
					default:
						value7 = ((value6.IsGenericType && !value6.IsValueType && value5 is List<object>) ? CreateGenericList((List<object>)value5, value6.pt, value6.bt, globaltypes) : (((value6.IsClass || value6.IsStruct || value6.IsInterface) && value5 is Dictionary<string, object>) ? ParseDictionary((Dictionary<string, object>)value5, globaltypes, value6.pt, null) : ((!(value5 is List<object>)) ? ((!value6.IsValueType) ? value5 : ChangeType(value5, value6.changeType)) : CreateArray((List<object>)value5, value6.pt, typeof(object), globaltypes))));
						break;
					}
				}
				obj = value6.setter(obj, value7);
			}
		}
		return obj;
	}

	private static void ProcessMap(object obj, Dictionary<string, myPropInfo> props, Dictionary<string, object> dic)
	{
		foreach (KeyValuePair<string, object> item in dic)
		{
			myPropInfo myPropInfo2 = props[item.Key];
			object obj2 = myPropInfo2.getter(obj);
			Type typeFromCache = Reflection.Instance.GetTypeFromCache((string)item.Value, badlistChecking: true);
			if (typeFromCache == typeof(Guid))
			{
				myPropInfo2.setter(obj, Helper.CreateGuid((string)obj2));
			}
		}
	}

	private object CreateArray(List<object> data, Type pt, Type bt, Dictionary<string, object> globalTypes)
	{
		if (bt == null)
		{
			bt = typeof(object);
		}
		Array array = Array.CreateInstance(bt, data.Count);
		Type elementType = bt.GetElementType();
		for (int i = 0; i < data.Count; i++)
		{
			object obj = data[i];
			if (obj != null)
			{
				if (obj is IDictionary)
				{
					array.SetValue(ParseDictionary((Dictionary<string, object>)obj, globalTypes, bt, null), i);
				}
				else if (obj is ICollection)
				{
					array.SetValue(CreateArray((List<object>)obj, bt, elementType, globalTypes), i);
				}
				else
				{
					array.SetValue(ChangeType(obj, bt), i);
				}
			}
		}
		return array;
	}

	private object CreateGenericList(List<object> data, Type pt, Type bt, Dictionary<string, object> globalTypes)
	{
		if (pt != typeof(object))
		{
			IList list = (IList)Reflection.Instance.FastCreateList(pt, data.Count);
			Type type = Reflection.Instance.GetGenericArguments(pt)[0];
			{
				foreach (object datum in data)
				{
					if (datum is IDictionary)
					{
						list.Add(ParseDictionary((Dictionary<string, object>)datum, globalTypes, type, null));
					}
					else if (datum is List<object>)
					{
						if (bt.IsGenericType)
						{
							list.Add((List<object>)datum);
						}
						else
						{
							list.Add(((List<object>)datum).ToArray());
						}
					}
					else
					{
						list.Add(ChangeType(datum, type));
					}
				}
				return list;
			}
		}
		return data;
	}

	private object CreateStringKeyDictionary(Dictionary<string, object> reader, Type pt, Type[] types, Dictionary<string, object> globalTypes)
	{
		IDictionary dictionary = (IDictionary)Reflection.Instance.FastCreateInstance(pt);
		Type type = null;
		Type type2 = null;
		if (types != null)
		{
			type2 = types[1];
		}
		Type bt = null;
		Type[] genericArguments = Reflection.Instance.GetGenericArguments(type2);
		if (genericArguments.Length != 0)
		{
			bt = genericArguments[0];
		}
		type = type2.GetElementType();
		foreach (KeyValuePair<string, object> item in reader)
		{
			string key = item.Key;
			object obj = null;
			obj = ((!(item.Value is Dictionary<string, object>)) ? ((types != null && type2.IsArray) ? ((!(item.Value is Array)) ? CreateArray((List<object>)item.Value, type2, type, globalTypes) : item.Value) : ((!(item.Value is IList)) ? ChangeType(item.Value, type2) : CreateGenericList((List<object>)item.Value, type2, bt, globalTypes))) : ParseDictionary((Dictionary<string, object>)item.Value, globalTypes, type2, null));
			dictionary.Add(key, obj);
		}
		return dictionary;
	}

	private object CreateDictionary(List<object> reader, Type pt, Type[] types, Dictionary<string, object> globalTypes)
	{
		IDictionary dictionary = (IDictionary)Reflection.Instance.FastCreateInstance(pt);
		Type type = null;
		Type type2 = null;
		Type bt = null;
		if (types != null)
		{
			type = types[0];
			type2 = types[1];
		}
		Type bt2 = type2;
		if (type2 != null)
		{
			Type[] genericArguments = Reflection.Instance.GetGenericArguments(type2);
			if (genericArguments.Length != 0)
			{
				bt = genericArguments[0];
			}
			bt2 = type2.GetElementType();
		}
		bool flag = typeof(IDictionary).IsAssignableFrom(type2);
		foreach (Dictionary<string, object> item in reader)
		{
			object obj = item["k"];
			object obj2 = item["v"];
			obj = ((!(obj is Dictionary<string, object>)) ? ChangeType(obj, type) : ParseDictionary((Dictionary<string, object>)obj, globalTypes, type, null));
			obj2 = ((!flag) ? ((!(obj2 is Dictionary<string, object>)) ? ((types != null && type2.IsArray) ? CreateArray((List<object>)obj2, type2, bt2, globalTypes) : ((!(obj2 is IList)) ? ChangeType(obj2, type2) : CreateGenericList((List<object>)obj2, type2, bt, globalTypes))) : ParseDictionary((Dictionary<string, object>)obj2, globalTypes, type2, null)) : RootDictionary(obj2, type2));
			dictionary.Add(obj, obj2);
		}
		return dictionary;
	}
}
internal sealed class JsonParser
{
	private enum Token
	{
		None = -1,
		Curly_Open,
		Curly_Close,
		Squared_Open,
		Squared_Close,
		Colon,
		Comma,
		String,
		Number,
		True,
		False,
		Null,
		PosInfinity,
		NegInfinity,
		NaN
	}

	private readonly char[] json;

	private readonly StringBuilder s = new StringBuilder();

	private Token lookAheadToken = Token.None;

	private int index;

	private bool allownonquotedkey;

	private int _len;

	private SafeDictionary<string, bool> _lookup;

	private SafeDictionary<Type, bool> _seen;

	private bool _parseJsonType;

	private bool _parseType;

	internal JsonParser(string json, bool AllowNonQuotedKeys)
	{
		allownonquotedkey = AllowNonQuotedKeys;
		this.json = json.ToCharArray();
		_len = json.Length;
	}

	private void SetupLookup()
	{
		_lookup = new SafeDictionary<string, bool>();
		_seen = new SafeDictionary<Type, bool>();
		_lookup.Add("$types", value: true);
		_lookup.Add("$type", value: true);
		_lookup.Add("$i", value: true);
		_lookup.Add("$map", value: true);
		_lookup.Add("$schema", value: true);
		_lookup.Add("k", value: true);
		_lookup.Add("v", value: true);
	}

	public unsafe object Decode(Type objtype)
	{
		fixed (char* p = json)
		{
			if (objtype != null && !CheckForTypeInJson(p))
			{
				_parseJsonType = true;
				SetupLookup();
				BuildLookup(objtype);
				if (!_parseJsonType || _lookup.Count() == 7)
				{
					_lookup = null;
				}
			}
			return ParseValue(p);
		}
	}

	private unsafe bool CheckForTypeInJson(char* p)
	{
		int i = 0;
		for (int num = ((_len > 1000) ? 1000 : _len); i < num; i++)
		{
			if (p[i] == '$' && p[i + 1] == 't' && p[i + 2] == 'y' && p[i + 3] == 'p' && p[i + 4] == 'e' && p[i + 5] == 's')
			{
				return true;
			}
		}
		return false;
	}

	private void BuildGenericTypeLookup(Type t)
	{
		if (_seen.TryGetValue(t, out var _))
		{
			return;
		}
		Type[] genericArguments = t.GetGenericArguments();
		foreach (Type type in genericArguments)
		{
			if (!type.IsPrimitive)
			{
				bool flag = type.IsValueType && !type.IsEnum;
				if ((type.IsClass || flag || type.IsAbstract) && type != typeof(string) && type != typeof(DateTime) && type != typeof(Guid))
				{
					BuildLookup(type);
				}
			}
		}
	}

	private void BuildArrayTypeLookup(Type t)
	{
		if (!_seen.TryGetValue(t, out var _))
		{
			bool flag = t.IsValueType && !t.IsEnum;
			if ((t.IsClass || flag) && t != typeof(string) && t != typeof(DateTime) && t != typeof(Guid))
			{
				BuildLookup(t.GetElementType());
			}
		}
	}

	private void BuildLookup(Type objtype)
	{
		if (objtype == null || objtype == typeof(NameValueCollection) || objtype == typeof(StringDictionary) || typeof(IDictionary).IsAssignableFrom(objtype) || _seen.TryGetValue(objtype, out var _))
		{
			return;
		}
		if (objtype.IsGenericType)
		{
			BuildGenericTypeLookup(objtype);
			return;
		}
		if (objtype.IsArray)
		{
			BuildArrayTypeLookup(objtype);
			return;
		}
		_seen.Add(objtype, value: true);
		foreach (KeyValuePair<string, myPropInfo> item in Reflection.Instance.Getproperties(objtype, objtype.FullName, ShowReadOnlyProperties: true))
		{
			Type pt = item.Value.pt;
			_lookup.Add(item.Key, value: true);
			if (pt.IsArray)
			{
				BuildArrayTypeLookup(pt);
			}
			if (pt.IsGenericType)
			{
				if (typeof(IDictionary).IsAssignableFrom(pt))
				{
					_parseJsonType = false;
					break;
				}
				BuildGenericTypeLookup(pt);
			}
			if (pt.FullName.IndexOf("System.") == -1)
			{
				BuildLookup(pt);
			}
		}
	}

	private bool InLookup(string name)
	{
		if (_lookup == null)
		{
			return true;
		}
		bool value;
		return _lookup.TryGetValue(name.ToLowerInvariant(), out value);
	}

	private unsafe Dictionary<string, object> ParseObject(char* p)
	{
		Dictionary<string, object> dictionary = new Dictionary<string, object>();
		ConsumeToken();
		while (true)
		{
			switch (LookAhead(p))
			{
			case Token.Comma:
				ConsumeToken();
				continue;
			case Token.Curly_Close:
				ConsumeToken();
				return dictionary;
			}
			string text = ParseKey(p);
			Token token = NextToken(p);
			if (token != Token.Colon)
			{
				throw new Exception("Expected colon at index " + index);
			}
			if (_parseJsonType)
			{
				if (text == "$types")
				{
					_parseType = true;
					Dictionary<string, object> dictionary2 = (Dictionary<string, object>)ParseValue(p);
					_parseType = false;
					if (_lookup == null)
					{
						SetupLookup();
					}
					foreach (string key in dictionary2.Keys)
					{
						BuildLookup(Reflection.Instance.GetTypeFromCache(key, badlistChecking: true));
					}
					dictionary[text] = dictionary2;
				}
				else if (text == "$schema")
				{
					_parseType = true;
					object value = ParseValue(p);
					_parseType = false;
					dictionary[text] = value;
				}
				else if (_parseType || InLookup(text))
				{
					dictionary[text] = ParseValue(p);
				}
				else
				{
					SkipValue(p);
				}
			}
			else
			{
				dictionary[text] = ParseValue(p);
			}
		}
	}

	private unsafe void SkipValue(char* p)
	{
		switch (LookAhead(p))
		{
		case Token.Number:
			ParseNumber(p, skip: true);
			break;
		case Token.String:
			SkipString(p);
			break;
		case Token.Curly_Open:
			SkipObject(p);
			break;
		case Token.Squared_Open:
			SkipArray(p);
			break;
		case Token.True:
		case Token.False:
		case Token.Null:
		case Token.PosInfinity:
		case Token.NegInfinity:
		case Token.NaN:
			ConsumeToken();
			break;
		case Token.Curly_Close:
		case Token.Squared_Close:
		case Token.Colon:
		case Token.Comma:
			break;
		}
	}

	private unsafe void SkipObject(char* p)
	{
		ConsumeToken();
		while (true)
		{
			switch (LookAhead(p))
			{
			case Token.Comma:
				ConsumeToken();
				continue;
			case Token.Curly_Close:
				ConsumeToken();
				return;
			}
			SkipString(p);
			Token token = NextToken(p);
			if (token != Token.Colon)
			{
				throw new Exception("Expected colon at index " + index);
			}
			SkipValue(p);
		}
	}

	private unsafe void SkipArray(char* p)
	{
		ConsumeToken();
		while (true)
		{
			switch (LookAhead(p))
			{
			case Token.Comma:
				ConsumeToken();
				break;
			case Token.Squared_Close:
				ConsumeToken();
				return;
			default:
				SkipValue(p);
				break;
			}
		}
	}

	private unsafe void SkipString(char* p)
	{
		ConsumeToken();
		int len = _len;
		while (index < len)
		{
			switch (p[index++])
			{
			case '"':
				return;
			case '\\':
			{
				char c = p[index++];
				if (c == 'u')
				{
					index += 4;
				}
				break;
			}
			}
		}
	}

	private unsafe List<object> ParseArray(char* p)
	{
		List<object> list = new List<object>();
		ConsumeToken();
		while (true)
		{
			switch (LookAhead(p))
			{
			case Token.Comma:
				ConsumeToken();
				break;
			case Token.Squared_Close:
				ConsumeToken();
				return list;
			default:
				list.Add(ParseValue(p));
				break;
			}
		}
	}

	private unsafe object ParseValue(char* p)
	{
		switch (LookAhead(p))
		{
		case Token.Number:
			return ParseNumber(p, skip: false);
		case Token.String:
			return ParseString(p);
		case Token.Curly_Open:
			return ParseObject(p);
		case Token.Squared_Open:
			return ParseArray(p);
		case Token.True:
			ConsumeToken();
			return true;
		case Token.False:
			ConsumeToken();
			return false;
		case Token.Null:
			ConsumeToken();
			return null;
		case Token.PosInfinity:
			ConsumeToken();
			return double.PositiveInfinity;
		case Token.NegInfinity:
			ConsumeToken();
			return double.NegativeInfinity;
		case Token.NaN:
			ConsumeToken();
			return double.NaN;
		default:
			throw new Exception("Unrecognized token at index " + index);
		}
	}

	private unsafe string ParseKey(char* p)
	{
		if (!allownonquotedkey || p[index - 1] == '"')
		{
			return ParseString(p);
		}
		ConsumeToken();
		int len = _len;
		int num = 0;
		while (index + num < len)
		{
			char c = p[index + num++];
			if (c == ':')
			{
				string result = UnsafeSubstring(p, index, num - 1).Trim();
				index += num - 1;
				return result;
			}
		}
		throw new Exception("Unable to read key");
	}

	private unsafe string ParseString(char* p)
	{
		char c = p[index - 1];
		ConsumeToken();
		if (s.Length > 0)
		{
			s.Length = 0;
		}
		int len = _len;
		int num = 0;
		while (index + num < len)
		{
			char c2 = p[index + num++];
			if (c2 == '\\')
			{
				break;
			}
			if (c2 == c)
			{
				string result = UnsafeSubstring(p, index, num - 1);
				index += num;
				return result;
			}
		}
		while (index < len)
		{
			char c3 = p[index++];
			if (c3 == c)
			{
				return s.ToString();
			}
			if (c3 != '\\')
			{
				s.Append(c3);
				continue;
			}
			c3 = p[index++];
			switch (c3)
			{
			case 'b':
				s.Append('\b');
				continue;
			case 'f':
				s.Append('\f');
				continue;
			case 'n':
				s.Append('\n');
				continue;
			case 'r':
				s.Append('\r');
				continue;
			case 't':
				s.Append('\t');
				continue;
			case 'u':
			{
				uint num2 = ParseUnicode(p[index], p[index + 1], p[index + 2], p[index + 3]);
				s.Append((char)num2);
				index += 4;
				continue;
			}
			}
			if (c3 == '\r' || c3 == '\n' || c3 == ' ' || c3 == '\t')
			{
				while (c3 == '\r' || c3 == '\n' || c3 == ' ' || c3 == '\t')
				{
					index++;
					c3 = p[index];
					if (c3 == '\r' || c3 == '\n')
					{
						c3 = p[index + 1];
						if (c3 == '\r' || c3 == '\n')
						{
							index += 2;
							c3 = p[index];
						}
						break;
					}
				}
			}
			else
			{
				s.Append(c3);
			}
		}
		return s.ToString();
	}

	private unsafe string ParseJson5String(char* p)
	{
		throw new NotImplementedException();
	}

	private uint ParseSingleChar(char c1, uint multipliyer)
	{
		uint result = 0u;
		if (c1 >= '0' && c1 <= '9')
		{
			result = (uint)(c1 - 48) * multipliyer;
		}
		else if (c1 >= 'A' && c1 <= 'F')
		{
			result = (uint)(c1 - 65 + 10) * multipliyer;
		}
		else if (c1 >= 'a' && c1 <= 'f')
		{
			result = (uint)(c1 - 97 + 10) * multipliyer;
		}
		return result;
	}

	private uint ParseUnicode(char c1, char c2, char c3, char c4)
	{
		uint num = ParseSingleChar(c1, 4096u);
		uint num2 = ParseSingleChar(c2, 256u);
		uint num3 = ParseSingleChar(c3, 16u);
		uint num4 = ParseSingleChar(c4, 1u);
		return num + num2 + num3 + num4;
	}

	private unsafe object ParseNumber(char* p, bool skip)
	{
		ConsumeToken();
		int num = index - 1;
		bool flag = false;
		bool flag2 = false;
		bool flag3 = true;
		if (p[num] == '.')
		{
			flag = true;
		}
		while (index != _len)
		{
			switch (p[index])
			{
			case 'X':
			case 'x':
				index++;
				return ReadHexNumber(p);
			case '+':
			case '-':
			case '0':
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				index++;
				break;
			case 'E':
			case 'e':
				flag2 = true;
				index++;
				break;
			case '.':
				index++;
				flag = true;
				break;
			case 'N':
			case 'n':
				index += 3;
				return double.NaN;
			default:
				flag3 = false;
				break;
			}
			if (index == _len)
			{
				flag3 = false;
			}
			if (!flag3)
			{
				break;
			}
		}
		if (skip)
		{
			return 0;
		}
		int num2 = index - num;
		if (flag2 || num2 > 31)
		{
			string text = UnsafeSubstring(p, num, num2);
			return double.Parse(text, NumberFormatInfo.InvariantInfo);
		}
		if (!flag && num2 < 20)
		{
			return Helper.CreateLong(json, num, num2);
		}
		string text2 = UnsafeSubstring(p, num, num2);
		return decimal.Parse(text2, NumberFormatInfo.InvariantInfo);
	}

	private unsafe object ReadHexNumber(char* p)
	{
		long num = 0L;
		bool flag = true;
		while (flag && index < _len)
		{
			char c = p[index];
			switch (c)
			{
			case '0':
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				index++;
				num = (num << 4) + (c - 48);
				break;
			case 'a':
			case 'b':
			case 'c':
			case 'd':
			case 'e':
			case 'f':
				index++;
				num = (num << 4) + (c - 97) + 10;
				break;
			case 'A':
			case 'B':
			case 'C':
			case 'D':
			case 'E':
			case 'F':
				index++;
				num = (num << 4) + (c - 65) + 10;
				break;
			default:
				flag = false;
				break;
			}
		}
		return num;
	}

	private unsafe Token LookAhead(char* p)
	{
		if (lookAheadToken != Token.None)
		{
			return lookAheadToken;
		}
		return lookAheadToken = NextTokenCore(p);
	}

	private void ConsumeToken()
	{
		lookAheadToken = Token.None;
	}

	private unsafe Token NextToken(char* p)
	{
		Token result = ((lookAheadToken != Token.None) ? lookAheadToken : NextTokenCore(p));
		lookAheadToken = Token.None;
		return result;
	}

	private unsafe void SkipWhitespace(char* p)
	{
		char c;
		do
		{
			c = p[index];
			if (c == '/' && p[index + 1] == '/')
			{
				index++;
				index++;
				do
				{
					c = p[index];
				}
				while (c != '\r' && c != '\n' && ++index < _len);
			}
			if (c != '/' || p[index + 1] != '*')
			{
				continue;
			}
			index++;
			index++;
			do
			{
				c = p[index];
				if (c == '*' && p[index + 1] == '/')
				{
					index += 2;
					c = p[index];
					break;
				}
			}
			while (++index < _len);
		}
		while ((c == ' ' || c == '\t' || c == '\n' || c == '\r') && ++index < _len);
	}

	private unsafe Token NextTokenCore(char* p)
	{
		int len = _len;
		SkipWhitespace(p);
		if (index == len)
		{
			throw new Exception("Reached end of string unexpectedly");
		}
		char c = p[index];
		index++;
		switch (c)
		{
		case '{':
			return Token.Curly_Open;
		case '}':
			return Token.Curly_Close;
		case '[':
			return Token.Squared_Open;
		case ']':
			return Token.Squared_Close;
		case ',':
			return Token.Comma;
		case '"':
		case '\'':
			return Token.String;
		case '-':
			if (p[index] == 'i' || p[index] == 'I')
			{
				index += 8;
				return Token.NegInfinity;
			}
			return Token.Number;
		case '+':
			if (p[index] == 'i' || p[index] == 'I')
			{
				index += 8;
				return Token.PosInfinity;
			}
			return Token.Number;
		case '.':
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			return Token.Number;
		case ':':
			return Token.Colon;
		case 'I':
		case 'i':
			index += 7;
			return Token.PosInfinity;
		case 'f':
			if (len - index >= 4 && p[index] == 'a' && p[index + 1] == 'l' && p[index + 2] == 's' && p[index + 3] == 'e')
			{
				index += 4;
				return Token.False;
			}
			break;
		case 't':
			if (len - index >= 3 && p[index] == 'r' && p[index + 1] == 'u' && p[index + 2] == 'e')
			{
				index += 3;
				return Token.True;
			}
			break;
		case 'N':
		case 'n':
			if (len - index >= 3 && p[index] == 'u' && p[index + 1] == 'l' && p[index + 2] == 'l')
			{
				index += 3;
				return Token.Null;
			}
			if (len - index >= 2 && p[index] == 'a' && (p[index + 1] == 'n' || p[index + 1] == 'N'))
			{
				index += 2;
				return Token.NaN;
			}
			break;
		}
		if (allownonquotedkey)
		{
			index--;
			return Token.String;
		}
		throw new Exception("Could not find token at index " + --index + " got '" + p[index].ToString() + "'");
	}

	private unsafe static string UnsafeSubstring(char* p, int startIndex, int length)
	{
		return new string(p, startIndex, length);
	}
}
public struct Getters
{
	public string Name;

	public string lcName;

	public string memberName;

	public Reflection.GenericGetter Getter;

	public bool ReadOnly;
}
public enum myPropInfoType
{
	Int,
	Long,
	String,
	Bool,
	DateTime,
	Enum,
	Guid,
	Array,
	ByteArray,
	Dictionary,
	StringKeyDictionary,
	NameValue,
	StringDictionary,
	Hashtable,
	DataSet,
	DataTable,
	Custom,
	Unknown
}
public class myPropInfo
{
	public Type pt;

	public Type bt;

	public Type changeType;

	public Reflection.GenericSetter setter;

	public Reflection.GenericGetter getter;

	public Type[] GenericTypes;

	public string Name;

	public string memberName;

	public myPropInfoType Type;

	public bool CanWrite;

	public bool IsClass;

	public bool IsValueType;

	public bool IsGenericType;

	public bool IsStruct;

	public bool IsInterface;
}
public sealed class Reflection
{
	public delegate string Serialize(object data);

	public delegate object Deserialize(string data);

	public delegate object GenericSetter(object target, object value);

	public delegate object GenericGetter(object obj);

	private delegate object CreateObject();

	private delegate object CreateList(int capacity);

	private static readonly Reflection instance;

	public static bool RDBMode;

	private SafeDictionary<Type, string> _tyname = new SafeDictionary<Type, string>(10);

	private SafeDictionary<string, Type> _typecache = new SafeDictionary<string, Type>(10);

	private SafeDictionary<Type, CreateObject> _constrcache = new SafeDictionary<Type, CreateObject>(10);

	private SafeDictionary<Type, CreateList> _conlistcache = new SafeDictionary<Type, CreateList>(10);

	private SafeDictionary<Type, Getters[]> _getterscache = new SafeDictionary<Type, Getters[]>(10);

	private SafeDictionary<string, Dictionary<string, myPropInfo>> _propertycache = new SafeDictionary<string, Dictionary<string, myPropInfo>>(10);

	private SafeDictionary<Type, Type[]> _genericTypes = new SafeDictionary<Type, Type[]>(10);

	private SafeDictionary<Type, Type> _genericTypeDef = new SafeDictionary<Type, Type>(10);

	private static SafeDictionary<short, OpCode> _opCodes;

	private static List<string> _badlistTypes;

	private static UTF8Encoding utf8;

	internal SafeDictionary<Type, Serialize> _customSerializer = new SafeDictionary<Type, Serialize>();

	internal SafeDictionary<Type, Deserialize> _customDeserializer = new SafeDictionary<Type, Deserialize>();

	public static Reflection Instance => instance;

	static Reflection()
	{
		instance = new Reflection();
		RDBMode = false;
		_badlistTypes = new List<string> { "system.configuration.install.assemblyinstaller", "system.activities.presentation.workflowdesigner", "system.windows.resourcedictionary", "system.windows.data.objectdataprovider", "system.windows.forms.bindingsource", "microsoft.exchange.management.systemmanager.winforms.exchangesettingsprovider" };
		utf8 = new UTF8Encoding();
	}

	private Reflection()
	{
	}

	private static bool TryGetOpCode(short code, out OpCode opCode)
	{
		if (_opCodes != null)
		{
			return _opCodes.TryGetValue(code, out opCode);
		}
		SafeDictionary<short, OpCode> safeDictionary = new SafeDictionary<short, OpCode>();
		FieldInfo[] fields = typeof(OpCodes).GetFields(BindingFlags.Static | BindingFlags.Public);
		foreach (FieldInfo fieldInfo in fields)
		{
			if (typeof(OpCode).IsAssignableFrom(fieldInfo.FieldType))
			{
				OpCode value = (OpCode)fieldInfo.GetValue(null);
				if (value.OpCodeType != OpCodeType.Nternal)
				{
					safeDictionary.Add(value.Value, value);
				}
			}
		}
		_opCodes = safeDictionary;
		return _opCodes.TryGetValue(code, out opCode);
	}

	public static byte[] UTF8GetBytes(string str)
	{
		return utf8.GetBytes(str);
	}

	public static string UTF8GetString(byte[] bytes, int offset, int len)
	{
		return utf8.GetString(bytes, offset, len);
	}

	public unsafe static byte[] UnicodeGetBytes(string str)
	{
		int num = str.Length * 2;
		byte[] array = new byte[num];
		fixed (void* value = str)
		{
			Marshal.Copy(new IntPtr(value), array, 0, num);
		}
		return array;
	}

	public static string UnicodeGetString(byte[] b)
	{
		return UnicodeGetString(b, 0, b.Length);
	}

	public unsafe static string UnicodeGetString(byte[] bytes, int offset, int buflen)
	{
		string text = "";
		fixed (byte* ptr = bytes)
		{
			char* value = (char*)(ptr + offset);
			text = new string(value, 0, buflen / 2);
		}
		return text;
	}

	internal object CreateCustom(string v, Type type)
	{
		_customDeserializer.TryGetValue(type, out var value);
		return value(v);
	}

	internal void RegisterCustomType(Type type, Serialize serializer, Deserialize deserializer)
	{
		if (type != null && serializer != null && deserializer != null)
		{
			_customSerializer.Add(type, serializer);
			_customDeserializer.Add(type, deserializer);
			Instance.ResetPropertyCache();
		}
	}

	internal bool IsTypeRegistered(Type t)
	{
		if (_customSerializer.Count() == 0)
		{
			return false;
		}
		Serialize value;
		return _customSerializer.TryGetValue(t, out value);
	}

	public Type GetGenericTypeDefinition(Type t)
	{
		Type value = null;
		if (_genericTypeDef.TryGetValue(t, out value))
		{
			return value;
		}
		value = t.GetGenericTypeDefinition();
		_genericTypeDef.Add(t, value);
		return value;
	}

	public Type[] GetGenericArguments(Type t)
	{
		Type[] value = null;
		if (_genericTypes.TryGetValue(t, out value))
		{
			return value;
		}
		value = t.GetGenericArguments();
		_genericTypes.Add(t, value);
		return value;
	}

	public Dictionary<string, myPropInfo> Getproperties(Type type, string typename, bool ShowReadOnlyProperties)
	{
		Dictionary<string, myPropInfo> value = null;
		if (_propertycache.TryGetValue(typename, out value))
		{
			return value;
		}
		value = new Dictionary<string, myPropInfo>(10);
		BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
		PropertyInfo[] properties = type.GetProperties(bindingAttr);
		PropertyInfo[] array = properties;
		foreach (PropertyInfo propertyInfo in array)
		{
			if (propertyInfo.GetIndexParameters().Length != 0)
			{
				continue;
			}
			myPropInfo myPropInfo2 = CreateMyProp(propertyInfo.PropertyType, propertyInfo.Name);
			myPropInfo2.setter = CreateSetMethod(type, propertyInfo, ShowReadOnlyProperties);
			if (myPropInfo2.setter != null)
			{
				myPropInfo2.CanWrite = true;
			}
			myPropInfo2.getter = CreateGetMethod(type, propertyInfo);
			object[] customAttributes = propertyInfo.GetCustomAttributes(inherit: true);
			object[] array2 = customAttributes;
			foreach (object obj in array2)
			{
				if (obj is DataMemberAttribute)
				{
					DataMemberAttribute dataMemberAttribute = (DataMemberAttribute)obj;
					if (dataMemberAttribute.Name != "")
					{
						myPropInfo2.memberName = dataMemberAttribute.Name;
					}
				}
			}
			if (myPropInfo2.memberName != null)
			{
				value.Add(myPropInfo2.memberName, myPropInfo2);
			}
			else
			{
				value.Add(propertyInfo.Name.ToLowerInvariant(), myPropInfo2);
			}
		}
		FieldInfo[] fields = type.GetFields(bindingAttr);
		FieldInfo[] array3 = fields;
		foreach (FieldInfo fieldInfo in array3)
		{
			myPropInfo myPropInfo3 = CreateMyProp(fieldInfo.FieldType, fieldInfo.Name);
			if (fieldInfo.IsLiteral)
			{
				continue;
			}
			if (!fieldInfo.IsInitOnly)
			{
				myPropInfo3.setter = CreateSetField(type, fieldInfo);
			}
			if (myPropInfo3.setter != null)
			{
				myPropInfo3.CanWrite = true;
			}
			myPropInfo3.getter = CreateGetField(type, fieldInfo);
			object[] customAttributes2 = fieldInfo.GetCustomAttributes(inherit: true);
			object[] array4 = customAttributes2;
			foreach (object obj2 in array4)
			{
				if (obj2 is DataMemberAttribute)
				{
					DataMemberAttribute dataMemberAttribute2 = (DataMemberAttribute)obj2;
					if (dataMemberAttribute2.Name != "")
					{
						myPropInfo3.memberName = dataMemberAttribute2.Name;
					}
				}
			}
			if (myPropInfo3.memberName != null)
			{
				value.Add(myPropInfo3.memberName, myPropInfo3);
			}
			else
			{
				value.Add(fieldInfo.Name.ToLowerInvariant(), myPropInfo3);
			}
		}
		_propertycache.Add(typename, value);
		return value;
	}

	private myPropInfo CreateMyProp(Type t, string name)
	{
		myPropInfo myPropInfo2 = new myPropInfo();
		myPropInfoType type = myPropInfoType.Unknown;
		if (t == typeof(int) || t == typeof(int?))
		{
			type = myPropInfoType.Int;
		}
		else if (t == typeof(long) || t == typeof(long?))
		{
			type = myPropInfoType.Long;
		}
		else if (t == typeof(string))
		{
			type = myPropInfoType.String;
		}
		else if (t == typeof(bool) || t == typeof(bool?))
		{
			type = myPropInfoType.Bool;
		}
		else if (t == typeof(DateTime) || t == typeof(DateTime?))
		{
			type = myPropInfoType.DateTime;
		}
		else if (t.IsEnum)
		{
			type = myPropInfoType.Enum;
		}
		else if (t == typeof(Guid) || t == typeof(Guid?))
		{
			type = myPropInfoType.Guid;
		}
		else if (t == typeof(StringDictionary))
		{
			type = myPropInfoType.StringDictionary;
		}
		else if (t == typeof(NameValueCollection))
		{
			type = myPropInfoType.NameValue;
		}
		else if (t.IsArray)
		{
			myPropInfo2.bt = t.GetElementType();
			type = ((!(t == typeof(byte[]))) ? myPropInfoType.Array : myPropInfoType.ByteArray);
		}
		else if (t.Name.Contains("Dictionary"))
		{
			myPropInfo2.GenericTypes = Instance.GetGenericArguments(t);
			type = ((myPropInfo2.GenericTypes.Length == 0 || !(myPropInfo2.GenericTypes[0] == typeof(string))) ? myPropInfoType.Dictionary : myPropInfoType.StringKeyDictionary);
		}
		else if (IsTypeRegistered(t))
		{
			type = myPropInfoType.Custom;
		}
		if (t.IsValueType && !t.IsPrimitive && !t.IsEnum && t != typeof(decimal))
		{
			myPropInfo2.IsStruct = true;
		}
		myPropInfo2.IsInterface = t.IsInterface;
		myPropInfo2.IsClass = t.IsClass;
		myPropInfo2.IsValueType = t.IsValueType;
		if (t.IsGenericType)
		{
			myPropInfo2.IsGenericType = true;
			myPropInfo2.bt = Instance.GetGenericArguments(t)[0];
		}
		myPropInfo2.pt = t;
		myPropInfo2.Name = name;
		myPropInfo2.changeType = GetChangeType(t);
		myPropInfo2.Type = type;
		return myPropInfo2;
	}

	private Type GetChangeType(Type conversionType)
	{
		if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
		{
			return Instance.GetGenericArguments(conversionType)[0];
		}
		return conversionType;
	}

	public string GetTypeAssemblyName(Type t)
	{
		string value = "";
		if (_tyname.TryGetValue(t, out value))
		{
			return value;
		}
		string assemblyQualifiedName = t.AssemblyQualifiedName;
		_tyname.Add(t, assemblyQualifiedName);
		return assemblyQualifiedName;
	}

	internal Type GetTypeFromCache(string typename, bool badlistChecking)
	{
		Type value = null;
		if (_typecache.TryGetValue(typename, out value))
		{
			return value;
		}
		if (badlistChecking)
		{
			string text = typename.Trim().ToLowerInvariant();
			foreach (string badlistType in _badlistTypes)
			{
				if (text.StartsWith(badlistType, StringComparison.Ordinal))
				{
					throw new Exception("Black list type encountered, possible attack vector when using $type : " + typename);
				}
			}
		}
		Type type = Type.GetType(typename);
		_typecache.Add(typename, type);
		return type;
	}

	internal object FastCreateList(Type objtype, int capacity)
	{
		try
		{
			int capacity2 = 10;
			if (capacity > 10)
			{
				capacity2 = capacity;
			}
			CreateList value = null;
			if (_conlistcache.TryGetValue(objtype, out value))
			{
				if (value != null)
				{
					return value(capacity2);
				}
				return FastCreateInstance(objtype);
			}
			ConstructorInfo constructor = objtype.GetConstructor(new Type[1] { typeof(int) });
			if (constructor != null)
			{
				DynamicMethod dynamicMethod = new DynamicMethod("_fcil", objtype, new Type[1] { typeof(int) }, restrictedSkipVisibility: true);
				ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Newobj, objtype.GetConstructor(new Type[1] { typeof(int) }));
				iLGenerator.Emit(OpCodes.Ret);
				value = (CreateList)dynamicMethod.CreateDelegate(typeof(CreateList));
				_conlistcache.Add(objtype, value);
				return value(capacity2);
			}
			_conlistcache.Add(objtype, null);
			return FastCreateInstance(objtype);
		}
		catch (Exception innerException)
		{
			throw new Exception($"Failed to fast create instance for type '{objtype.FullName}' from assembly '{objtype.AssemblyQualifiedName}'", innerException);
		}
	}

	internal object FastCreateInstance(Type objtype)
	{
		try
		{
			CreateObject value = null;
			if (_constrcache.TryGetValue(objtype, out value))
			{
				return value();
			}
			if (objtype.IsClass)
			{
				DynamicMethod dynamicMethod = new DynamicMethod("_fcic", objtype, null, restrictedSkipVisibility: true);
				ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
				iLGenerator.Emit(OpCodes.Newobj, objtype.GetConstructor(Type.EmptyTypes));
				iLGenerator.Emit(OpCodes.Ret);
				value = (CreateObject)dynamicMethod.CreateDelegate(typeof(CreateObject));
				_constrcache.Add(objtype, value);
			}
			else
			{
				DynamicMethod dynamicMethod2 = new DynamicMethod("_fcis", typeof(object), null, restrictedSkipVisibility: true);
				ILGenerator iLGenerator2 = dynamicMethod2.GetILGenerator();
				LocalBuilder local = iLGenerator2.DeclareLocal(objtype);
				iLGenerator2.Emit(OpCodes.Ldloca_S, local);
				iLGenerator2.Emit(OpCodes.Initobj, objtype);
				iLGenerator2.Emit(OpCodes.Ldloc_0);
				iLGenerator2.Emit(OpCodes.Box, objtype);
				iLGenerator2.Emit(OpCodes.Ret);
				value = (CreateObject)dynamicMethod2.CreateDelegate(typeof(CreateObject));
				_constrcache.Add(objtype, value);
			}
			return value();
		}
		catch (Exception innerException)
		{
			throw new Exception($"Failed to fast create instance for type '{objtype.FullName}' from assembly '{objtype.AssemblyQualifiedName}'", innerException);
		}
	}

	internal static GenericSetter CreateSetField(Type type, FieldInfo fieldInfo)
	{
		Type[] array = new Type[2];
		array[0] = (array[1] = typeof(object));
		DynamicMethod dynamicMethod = new DynamicMethod("_csf", typeof(object), array, type, skipVisibility: true);
		ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
		if (!type.IsClass)
		{
			LocalBuilder local = iLGenerator.DeclareLocal(type);
			iLGenerator.Emit(OpCodes.Ldarg_0);
			iLGenerator.Emit(OpCodes.Unbox_Any, type);
			iLGenerator.Emit(OpCodes.Stloc_0);
			iLGenerator.Emit(OpCodes.Ldloca_S, local);
			iLGenerator.Emit(OpCodes.Ldarg_1);
			if (fieldInfo.FieldType.IsClass)
			{
				iLGenerator.Emit(OpCodes.Castclass, fieldInfo.FieldType);
			}
			else
			{
				iLGenerator.Emit(OpCodes.Unbox_Any, fieldInfo.FieldType);
			}
			iLGenerator.Emit(OpCodes.Stfld, fieldInfo);
			iLGenerator.Emit(OpCodes.Ldloc_0);
			iLGenerator.Emit(OpCodes.Box, type);
			iLGenerator.Emit(OpCodes.Ret);
		}
		else
		{
			iLGenerator.Emit(OpCodes.Ldarg_0);
			iLGenerator.Emit(OpCodes.Ldarg_1);
			if (fieldInfo.FieldType.IsValueType)
			{
				iLGenerator.Emit(OpCodes.Unbox_Any, fieldInfo.FieldType);
			}
			iLGenerator.Emit(OpCodes.Stfld, fieldInfo);
			iLGenerator.Emit(OpCodes.Ldarg_0);
			iLGenerator.Emit(OpCodes.Ret);
		}
		return (GenericSetter)dynamicMethod.CreateDelegate(typeof(GenericSetter));
	}

	internal static FieldInfo GetGetterBackingField(PropertyInfo autoProperty)
	{
		MethodInfo getMethod = autoProperty.GetGetMethod();
		if (!getMethod.IsDefined(typeof(CompilerGeneratedAttribute), inherit: false))
		{
			return null;
		}
		byte[] array = getMethod.GetMethodBody()?.GetILAsByteArray() ?? new byte[0];
		OpCode opCode;
		for (int i = 0; i < array.Length; i += ((opCode.OperandType != OperandType.InlineNone) ? ((opCode.OperandType == OperandType.ShortInlineBrTarget || opCode.OperandType == OperandType.ShortInlineI || opCode.OperandType == OperandType.ShortInlineVar) ? 1 : ((opCode.OperandType == OperandType.InlineVar) ? 2 : ((opCode.OperandType == OperandType.InlineI8 || opCode.OperandType == OperandType.InlineR) ? 8 : ((opCode.OperandType == OperandType.InlineSwitch) ? (4 * (BitConverter.ToInt32(array, i) + 1)) : 4)))) : 0))
		{
			byte b = array[i++];
			if (!TryGetOpCode(b, out opCode) && (i >= array.Length || !TryGetOpCode((short)(b * 256 + array[i++]), out opCode)))
			{
				throw new NotSupportedException("Unknown IL code detected.");
			}
			if (opCode == OpCodes.Ldfld && opCode.OperandType == OperandType.InlineField && i + 4 <= array.Length)
			{
				return getMethod.Module.ResolveMember(BitConverter.ToInt32(array, i), getMethod.DeclaringType?.GetGenericArguments(), null) as FieldInfo;
			}
		}
		return null;
	}

	internal static GenericSetter CreateSetMethod(Type type, PropertyInfo propertyInfo, bool ShowReadOnlyProperties)
	{
		MethodInfo setMethod = propertyInfo.GetSetMethod(ShowReadOnlyProperties);
		if (setMethod == null)
		{
			if (!ShowReadOnlyProperties)
			{
				return null;
			}
			FieldInfo getterBackingField = GetGetterBackingField(propertyInfo);
			if (!(getterBackingField != null))
			{
				return null;
			}
			return CreateSetField(type, getterBackingField);
		}
		Type[] array = new Type[2];
		array[0] = (array[1] = typeof(object));
		DynamicMethod dynamicMethod = new DynamicMethod("_csm", typeof(object), array, restrictedSkipVisibility: true);
		ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
		if (!type.IsClass)
		{
			LocalBuilder local = iLGenerator.DeclareLocal(type);
			iLGenerator.Emit(OpCodes.Ldarg_0);
			iLGenerator.Emit(OpCodes.Unbox_Any, type);
			iLGenerator.Emit(OpCodes.Stloc_0);
			iLGenerator.Emit(OpCodes.Ldloca_S, local);
			iLGenerator.Emit(OpCodes.Ldarg_1);
			if (propertyInfo.PropertyType.IsClass)
			{
				iLGenerator.Emit(OpCodes.Castclass, propertyInfo.PropertyType);
			}
			else
			{
				iLGenerator.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType);
			}
			iLGenerator.EmitCall(OpCodes.Call, setMethod, null);
			iLGenerator.Emit(OpCodes.Ldloc_0);
			iLGenerator.Emit(OpCodes.Box, type);
		}
		else if (!setMethod.IsStatic)
		{
			iLGenerator.Emit(OpCodes.Ldarg_0);
			iLGenerator.Emit(OpCodes.Castclass, propertyInfo.DeclaringType);
			iLGenerator.Emit(OpCodes.Ldarg_1);
			if (propertyInfo.PropertyType.IsClass)
			{
				iLGenerator.Emit(OpCodes.Castclass, propertyInfo.PropertyType);
			}
			else
			{
				iLGenerator.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType);
			}
			iLGenerator.EmitCall(OpCodes.Callvirt, setMethod, null);
			iLGenerator.Emit(OpCodes.Ldarg_0);
		}
		else
		{
			iLGenerator.Emit(OpCodes.Ldarg_0);
			iLGenerator.Emit(OpCodes.Ldarg_1);
			if (propertyInfo.PropertyType.IsClass)
			{
				iLGenerator.Emit(OpCodes.Castclass, propertyInfo.PropertyType);
			}
			else
			{
				iLGenerator.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType);
			}
			iLGenerator.Emit(OpCodes.Call, setMethod);
		}
		iLGenerator.Emit(OpCodes.Ret);
		return (GenericSetter)dynamicMethod.CreateDelegate(typeof(GenericSetter));
	}

	internal static GenericGetter CreateGetField(Type type, FieldInfo fieldInfo)
	{
		DynamicMethod dynamicMethod = new DynamicMethod("_cgf", typeof(object), new Type[1] { typeof(object) }, type, skipVisibility: true);
		ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
		if (!type.IsClass)
		{
			LocalBuilder local = iLGenerator.DeclareLocal(type);
			iLGenerator.Emit(OpCodes.Ldarg_0);
			iLGenerator.Emit(OpCodes.Unbox_Any, type);
			iLGenerator.Emit(OpCodes.Stloc_0);
			iLGenerator.Emit(OpCodes.Ldloca_S, local);
			iLGenerator.Emit(OpCodes.Ldfld, fieldInfo);
			if (fieldInfo.FieldType.IsValueType)
			{
				iLGenerator.Emit(OpCodes.Box, fieldInfo.FieldType);
			}
		}
		else
		{
			iLGenerator.Emit(OpCodes.Ldarg_0);
			iLGenerator.Emit(OpCodes.Ldfld, fieldInfo);
			if (fieldInfo.FieldType.IsValueType)
			{
				iLGenerator.Emit(OpCodes.Box, fieldInfo.FieldType);
			}
		}
		iLGenerator.Emit(OpCodes.Ret);
		return (GenericGetter)dynamicMethod.CreateDelegate(typeof(GenericGetter));
	}

	internal static GenericGetter CreateGetMethod(Type type, PropertyInfo propertyInfo)
	{
		MethodInfo getMethod = propertyInfo.GetGetMethod();
		if (getMethod == null)
		{
			return null;
		}
		DynamicMethod dynamicMethod = new DynamicMethod("_cgm", typeof(object), new Type[1] { typeof(object) }, type, skipVisibility: true);
		ILGenerator iLGenerator = dynamicMethod.GetILGenerator();
		if (!type.IsClass)
		{
			LocalBuilder local = iLGenerator.DeclareLocal(type);
			iLGenerator.Emit(OpCodes.Ldarg_0);
			iLGenerator.Emit(OpCodes.Unbox_Any, type);
			iLGenerator.Emit(OpCodes.Stloc_0);
			iLGenerator.Emit(OpCodes.Ldloca_S, local);
			iLGenerator.EmitCall(OpCodes.Call, getMethod, null);
			if (propertyInfo.PropertyType.IsValueType)
			{
				iLGenerator.Emit(OpCodes.Box, propertyInfo.PropertyType);
			}
		}
		else
		{
			if (!getMethod.IsStatic)
			{
				iLGenerator.Emit(OpCodes.Ldarg_0);
				iLGenerator.Emit(OpCodes.Castclass, propertyInfo.DeclaringType);
				iLGenerator.EmitCall(OpCodes.Callvirt, getMethod, null);
			}
			else
			{
				iLGenerator.Emit(OpCodes.Call, getMethod);
			}
			if (propertyInfo.PropertyType.IsValueType)
			{
				iLGenerator.Emit(OpCodes.Box, propertyInfo.PropertyType);
			}
		}
		iLGenerator.Emit(OpCodes.Ret);
		return (GenericGetter)dynamicMethod.CreateDelegate(typeof(GenericGetter));
	}

	public Getters[] GetGetters(Type type, List<Type> IgnoreAttributes)
	{
		Getters[] value = null;
		if (_getterscache.TryGetValue(type, out value))
		{
			return value;
		}
		BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
		PropertyInfo[] properties = type.GetProperties(bindingAttr);
		List<Getters> list = new List<Getters>();
		PropertyInfo[] array = properties;
		foreach (PropertyInfo propertyInfo in array)
		{
			bool readOnly = false;
			if (propertyInfo.GetIndexParameters().Length != 0)
			{
				continue;
			}
			if (!propertyInfo.CanWrite)
			{
				readOnly = true;
			}
			if (IgnoreAttributes != null)
			{
				bool flag = false;
				foreach (Type IgnoreAttribute in IgnoreAttributes)
				{
					if (propertyInfo.IsDefined(IgnoreAttribute, inherit: false))
					{
						flag = true;
						break;
					}
				}
				if (flag)
				{
					continue;
				}
			}
			string memberName = null;
			object[] customAttributes = propertyInfo.GetCustomAttributes(inherit: true);
			object[] array2 = customAttributes;
			foreach (object obj in array2)
			{
				if (obj is DataMemberAttribute)
				{
					DataMemberAttribute dataMemberAttribute = (DataMemberAttribute)obj;
					if (dataMemberAttribute.Name != "")
					{
						memberName = dataMemberAttribute.Name;
					}
				}
			}
			GenericGetter genericGetter = CreateGetMethod(type, propertyInfo);
			if (genericGetter != null)
			{
				list.Add(new Getters
				{
					Getter = genericGetter,
					Name = propertyInfo.Name,
					lcName = propertyInfo.Name.ToLowerInvariant(),
					memberName = memberName,
					ReadOnly = readOnly
				});
			}
		}
		FieldInfo[] fields = type.GetFields(bindingAttr);
		FieldInfo[] array3 = fields;
		foreach (FieldInfo fieldInfo in array3)
		{
			bool readOnly2 = false;
			if (fieldInfo.IsInitOnly)
			{
				readOnly2 = true;
			}
			if (IgnoreAttributes != null)
			{
				bool flag2 = false;
				foreach (Type IgnoreAttribute2 in IgnoreAttributes)
				{
					if (fieldInfo.IsDefined(IgnoreAttribute2, inherit: false))
					{
						flag2 = true;
						break;
					}
				}
				if (flag2)
				{
					continue;
				}
			}
			string memberName2 = null;
			object[] customAttributes2 = fieldInfo.GetCustomAttributes(inherit: true);
			object[] array4 = customAttributes2;
			foreach (object obj2 in array4)
			{
				if (obj2 is DataMemberAttribute)
				{
					DataMemberAttribute dataMemberAttribute2 = (DataMemberAttribute)obj2;
					if (dataMemberAttribute2.Name != "")
					{
						memberName2 = dataMemberAttribute2.Name;
					}
				}
			}
			if (!fieldInfo.IsLiteral)
			{
				GenericGetter genericGetter2 = CreateGetField(type, fieldInfo);
				if (genericGetter2 != null)
				{
					list.Add(new Getters
					{
						Getter = genericGetter2,
						Name = fieldInfo.Name,
						lcName = fieldInfo.Name.ToLowerInvariant(),
						memberName = memberName2,
						ReadOnly = readOnly2
					});
				}
			}
		}
		value = list.ToArray();
		_getterscache.Add(type, value);
		return value;
	}

	internal void ResetPropertyCache()
	{
		_propertycache = new SafeDictionary<string, Dictionary<string, myPropInfo>>();
	}

	internal void ClearReflectionCache()
	{
		_tyname = new SafeDictionary<Type, string>(10);
		_typecache = new SafeDictionary<string, Type>(10);
		_constrcache = new SafeDictionary<Type, CreateObject>(10);
		_getterscache = new SafeDictionary<Type, Getters[]>(10);
		_propertycache = new SafeDictionary<string, Dictionary<string, myPropInfo>>(10);
		_genericTypes = new SafeDictionary<Type, Type[]>(10);
		_genericTypeDef = new SafeDictionary<Type, Type>(10);
	}
}
public class ReferenceEqualityComparer : IEqualityComparer, IEqualityComparer<object>
{
	public static ReferenceEqualityComparer Default { get; } = new ReferenceEqualityComparer();


	public new bool Equals(object x, object y)
	{
		return x.Equals(y);
	}

	public int GetHashCode(object obj)
	{
		return RuntimeHelpers.GetHashCode(obj);
	}
}
public sealed class SafeDictionary<TKey, TValue>
{
	private readonly object _Padlock = new object();

	private readonly Dictionary<TKey, TValue> _Dictionary;

	public TValue this[TKey key]
	{
		get
		{
			lock (_Padlock)
			{
				return _Dictionary[key];
			}
		}
		set
		{
			lock (_Padlock)
			{
				_Dictionary[key] = value;
			}
		}
	}

	public SafeDictionary(int capacity)
	{
		_Dictionary = new Dictionary<TKey, TValue>(capacity);
	}

	public SafeDictionary()
	{
		_Dictionary = new Dictionary<TKey, TValue>();
	}

	public bool TryGetValue(TKey key, out TValue value)
	{
		lock (_Padlock)
		{
			return _Dictionary.TryGetValue(key, out value);
		}
	}

	public int Count()
	{
		lock (_Padlock)
		{
			return _Dictionary.Count;
		}
	}

	public void Add(TKey key, TValue value)
	{
		lock (_Padlock)
		{
			if (!_Dictionary.ContainsKey(key))
			{
				_Dictionary.Add(key, value);
			}
		}
	}
}

plugins/ChaosValheimEnchantmentSystem/Jewelcrafting.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx.Configuration;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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 Jewelcrafting
{
	[PublicAPI]
	public static class API
	{
		[PublicAPI]
		public class GemInfo
		{
			public readonly string gemPrefab;

			public readonly Sprite gemSprite;

			public readonly Dictionary<string, float> gemEffects;

			public GemInfo(string gemPrefab, Sprite gemSprite, Dictionary<string, float> gemEffects)
			{
				this.gemPrefab = gemPrefab;
				this.gemSprite = gemSprite;
				this.gemEffects = gemEffects;
			}
		}

		public delegate bool GemBreakHandler(ItemData? container, ItemData gem, int count = 1);

		public delegate bool ItemBreakHandler(ItemData? container);

		public delegate bool ItemMirroredHandler(ItemData? item);

		public static event Action? OnEffectRecalc;

		public static bool IsLoaded()
		{
			return false;
		}

		internal static void InvokeEffectRecalc()
		{
			API.OnEffectRecalc?.Invoke();
		}

		public static GameObject CreateNecklaceFromTemplate(string colorName, Color color)
		{
			return null;
		}

		public static GameObject CreateNecklaceFromTemplate(string colorName, Material material)
		{
			return null;
		}

		public static GameObject CreateRingFromTemplate(string colorName, Color color)
		{
			return null;
		}

		public static GameObject CreateRingFromTemplate(string colorName, Material material)
		{
			return null;
		}

		public static void MarkJewelry(GameObject jewelry)
		{
		}

		public static void AddGems(string type, string colorName, Color color)
		{
		}

		public static List<GameObject> AddGems(string type, string colorName, Material material, Color color)
		{
			return null;
		}

		public static GameObject AddDestructibleFromTemplate(string type, string colorName, Color color)
		{
			return null;
		}

		public static GameObject AddDestructibleFromTemplate(string type, string colorName, Material material)
		{
			return null;
		}

		public static GameObject AddUncutFromTemplate(string type, string colorName, Color color)
		{
			return null;
		}

		public static GameObject AddUncutFromTemplate(string type, string colorName, Material material)
		{
			return null;
		}

		public static GameObject AddAndRegisterUncutFromTemplate(string type, string colorName, Color color)
		{
			return null;
		}

		public static GameObject AddAndRegisterUncutFromTemplate(string type, string colorName, Material material)
		{
			return null;
		}

		public static GameObject AddShardFromTemplate(string type, string colorName, Color color)
		{
			return null;
		}

		public static GameObject AddShardFromTemplate(string type, string colorName, Material material)
		{
			return null;
		}

		public static GameObject[] AddTieredGemFromTemplate(string type, string colorName, Color color)
		{
			return null;
		}

		public static GameObject[] AddTieredGemFromTemplate(string type, string colorName, Material material, Color color)
		{
			return null;
		}

		public static void AddGem(GameObject prefab, string colorName)
		{
		}

		public static void AddShard(GameObject prefab, string colorName)
		{
		}

		public static void AddDestructible(GameObject prefab, string colorName)
		{
		}

		public static void AddUncutGem(GameObject prefab, string colorName, ConfigEntry<float>? dropChance = null)
		{
		}

		public static void AddGemEffect<T>(string name, string? englishDescription = null, string? englishDescriptionDetailed = null) where T : struct
		{
		}

		public static void AddGemConfig(string yaml)
		{
		}

		public static T GetEffectPower<T>(this Player player, string name) where T : struct
		{
			return default(T);
		}

		public static List<GemInfo?> GetGems(ItemData item)
		{
			return new List<GemInfo>();
		}

		public static bool SetGems(ItemData item, List<GemInfo?> gems)
		{
			return false;
		}

		public static Sprite GetSocketBorder()
		{
			return null;
		}

		public static GameObject GetGemcuttersTable()
		{
			return null;
		}

		public static void AddParticleEffect(string prefabName, GameObject effect, VisualEffectCondition displayCondition)
		{
		}

		public static void SetSocketsLock(ItemData item, bool enabled)
		{
		}

		public static void OnGemBreak(GemBreakHandler callback)
		{
		}

		public static void OnItemBreak(ItemBreakHandler callback)
		{
		}

		public static void OnItemMirrored(ItemMirroredHandler callback)
		{
		}

		public static bool IsJewelryEquipped(Player player, string prefabName)
		{
			return false;
		}
	}
	[AttributeUsage(AttributeTargets.Field)]
	public abstract class PowerAttribute : Attribute
	{
		public abstract float Add(float a, float b);
	}
	public class AdditivePowerAttribute : PowerAttribute
	{
		public override float Add(float a, float b)
		{
			return a + b;
		}
	}
	public class MultiplicativePercentagePowerAttribute : PowerAttribute
	{
		public override float Add(float a, float b)
		{
			return ((1f + a / 100f) * (1f + b / 100f) - 1f) * 100f;
		}
	}
	public class InverseMultiplicativePercentagePowerAttribute : PowerAttribute
	{
		public override float Add(float a, float b)
		{
			return (1f - (1f - a / 100f) * (1f - b / 100f)) * 100f;
		}
	}
	public class MinPowerAttribute : PowerAttribute
	{
		public override float Add(float a, float b)
		{
			return Mathf.Min(a, b);
		}
	}
	public class MaxPowerAttribute : PowerAttribute
	{
		public override float Add(float a, float b)
		{
			return Mathf.Max(a, b);
		}
	}
	[AttributeUsage(AttributeTargets.Field)]
	public class OptionalPowerAttribute : Attribute
	{
		public readonly float DefaultValue;

		public OptionalPowerAttribute(float defaultValue)
		{
			DefaultValue = defaultValue;
		}
	}
	[Flags]
	public enum VisualEffectCondition : uint
	{
		IsSkill = 0xFFFu,
		Swords = 1u,
		Knives = 2u,
		Clubs = 3u,
		Polearms = 4u,
		Spears = 5u,
		Blocking = 6u,
		Axes = 7u,
		Bows = 8u,
		Unarmed = 0xBu,
		Pickaxes = 0xCu,
		WoodCutting = 0xDu,
		Crossbows = 0xEu,
		IsItem = 0xFF000u,
		Helmet = 0x6000u,
		Chest = 0x7000u,
		Legs = 0xB000u,
		Hands = 0xC000u,
		Shoulder = 0x11000u,
		Tool = 0x13000u,
		GenericExtraAttributes = 0xFF000000u,
		Blackmetal = 0x40000000u,
		TwoHanded = 0x80000000u,
		SpecificExtraAttributes = 0xF00000u,
		Hammer = 0x113000u,
		Hoe = 0x213000u,
		Buckler = 0x100006u,
		Towershield = 0x200006u,
		FineWoodBow = 0x100008u,
		BowHuntsman = 0x200008u,
		BowDraugrFang = 0x300008u,
		PickaxeIron = 0x10000Cu,
		Club = 0x100003u
	}
}

plugins/ChaosValheimEnchantmentSystem/kg.ValheimEnchantmentSystem.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using AutoISP;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using ItemDataManager;
using ItemManager;
using JetBrains.Annotations;
using Jewelcrafting;
using LocalizationManager;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using ServerSync;
using SkillManager;
using TMPro;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.Events;
using UnityEngine.UI;
using Valheim.SettingsGui;
using YamlDotNet.Serialization;
using fastJSON;
using kg.ValheimEnchantmentSystem;
using kg.ValheimEnchantmentSystem.Configs;
using kg.ValheimEnchantmentSystem.Misc;
using kg.ValheimEnchantmentSystem.UI;

[assembly: Guid("02E7D016-77BE-40E0-9D13-8656CD0A4FD3")]
[assembly: ComVisible(false)]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyProduct("ValheimEnchantmentSystem")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyTitle("ValheimEnchantmentSystem")]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyCompany("")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: <0bc0a785-c8b8-484c-a221-82fecf0c9f00>RefSafetyRules(11)]
[module: UnverifiableCode]
internal class <Module>
{
	static <Module>()
	{
		ISP_Patcher.Init();
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[<0f8f2c22-fa54-4e1d-b3bb-bb603cd8fad9>Embedded]
	internal sealed class <0f8f2c22-fa54-4e1d-b3bb-bb603cd8fad9>EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	[CompilerGenerated]
	[<0f8f2c22-fa54-4e1d-b3bb-bb603cd8fad9>Embedded]
	internal sealed class <e9fa47f9-ebe8-4038-b99a-9fc150020e95>NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public <e9fa47f9-ebe8-4038-b99a-9fc150020e95>NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public <e9fa47f9-ebe8-4038-b99a-9fc150020e95>NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[<0f8f2c22-fa54-4e1d-b3bb-bb603cd8fad9>Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	[CompilerGenerated]
	internal sealed class <e20af6a3-5cd6-43e6-8516-fbc0bbda7606>NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public <e20af6a3-5cd6-43e6-8516-fbc0bbda7606>NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	[<0f8f2c22-fa54-4e1d-b3bb-bb603cd8fad9>Embedded]
	[CompilerGenerated]
	internal sealed class <0bc0a785-c8b8-484c-a221-82fecf0c9f00>RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public <0bc0a785-c8b8-484c-a221-82fecf0c9f00>RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public static class AnimationSpeedManager
{
	public delegate double Handler(Character character, double speed);

	private static readonly Harmony harmony = new Harmony("AnimationSpeedManager");

	private static bool hasMarkerPatch = false;

	private static readonly MethodInfo method = AccessTools.DeclaredMethod(typeof(CharacterAnimEvent), "CustomFixedUpdate", (Type[])null, (Type[])null);

	private static int index = 0;

	private static bool changed = false;

	private static Handler[][] handlers = Array.Empty<Handler[]>();

	private static readonly Dictionary<int, List<Handler>> handlersPriorities = new Dictionary<int, List<Handler>>();

	[PublicAPI]
	public static void Add(Handler handler, int priority = 400)
	{
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Expected O, but got Unknown
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Expected O, but got Unknown
		if (!hasMarkerPatch)
		{
			harmony.Patch((MethodBase)method, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(AnimationSpeedManager), "markerPatch", (Type[])null, (Type[])null)), (HarmonyMethod)null);
			hasMarkerPatch = true;
		}
		if (!handlersPriorities.TryGetValue(priority, out var value))
		{
			handlersPriorities.Add(priority, value = new List<Handler>());
			harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(AnimationSpeedManager), "wrapper", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
		value.Add(handler);
		handlers = (from kv in handlersPriorities
			orderby kv.Key
			select kv.Value.ToArray()).ToArray();
	}

	private static void wrapper(Character ___m_character, Animator ___m_animator)
	{
		double num = (double)___m_animator.speed * 10000000.0 % 100.0;
		if ((!(num > 10.0) || !(num < 30.0)) && !(___m_animator.speed <= 0.001f))
		{
			double num2 = ___m_animator.speed;
			double num3 = handlers[index++].Aggregate(num2, (double current, Handler handler) => handler(___m_character, current));
			if (num3 != num2)
			{
				___m_animator.speed = (float)(num3 - num3 % 1E-05);
				changed = true;
			}
		}
	}

	private static void markerPatch(Animator ___m_animator)
	{
		if (changed)
		{
			float speed = ___m_animator.speed;
			double num = (double)speed * 10000000.0 % 100.0;
			if ((num < 10.0 || num > 30.0) ? true : false)
			{
				___m_animator.speed += 1.9E-06f;
			}
			changed = false;
		}
		index = 0;
	}
}
namespace SkillManager
{
	[PublicAPI]
	public class Skill
	{
		public static class LocalizationCache
		{
			private static readonly Dictionary<string, Localization> localizations = new Dictionary<string, Localization>();

			internal static void LocalizationPostfix(Localization __instance, string language)
			{
				string key = localizations.FirstOrDefault((KeyValuePair<string, Localization> l) => l.Value == __instance).Key;
				if (key != null)
				{
					localizations.Remove(key);
				}
				if (!localizations.ContainsKey(language))
				{
					localizations.Add(language, __instance);
				}
			}

			public static Localization ForLanguage([<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)] string language = null)
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Expected O, but got Unknown
				if (localizations.TryGetValue(language ?? PlayerPrefs.GetString("language", "English"), out var value))
				{
					return value;
				}
				value = new Localization();
				if (language != null)
				{
					value.SetupLanguage(language);
				}
				return value;
			}
		}

		[PublicAPI]
		public class LocalizeKey
		{
			private static readonly List<LocalizeKey> keys = new List<LocalizeKey>();

			public readonly string Key;

			public readonly Dictionary<string, string> Localizations = new Dictionary<string, string>();

			public LocalizeKey(string key)
			{
				Key = key.Replace("$", "");
			}

			public void Alias(string alias)
			{
				Localizations.Clear();
				if (!alias.Contains("$"))
				{
					alias = "$" + alias;
				}
				Localizations["alias"] = alias;
				Localization.instance.AddWord(Key, Localization.instance.Localize(alias));
			}

			public LocalizeKey English(string key)
			{
				return addForLang("English", key);
			}

			public LocalizeKey Swedish(string key)
			{
				return addForLang("Swedish", key);
			}

			public LocalizeKey French(string key)
			{
				return addForLang("French", key);
			}

			public LocalizeKey Italian(string key)
			{
				return addForLang("Italian", key);
			}

			public LocalizeKey German(string key)
			{
				return addForLang("German", key);
			}

			public LocalizeKey Spanish(string key)
			{
				return addForLang("Spanish", key);
			}

			public LocalizeKey Russian(string key)
			{
				return addForLang("Russian", key);
			}

			public LocalizeKey Romanian(string key)
			{
				return addForLang("Romanian", key);
			}

			public LocalizeKey Bulgarian(string key)
			{
				return addForLang("Bulgarian", key);
			}

			public LocalizeKey Macedonian(string key)
			{
				return addForLang("Macedonian", key);
			}

			public LocalizeKey Finnish(string key)
			{
				return addForLang("Finnish", key);
			}

			public LocalizeKey Danish(string key)
			{
				return addForLang("Danish", key);
			}

			public LocalizeKey Norwegian(string key)
			{
				return addForLang("Norwegian", key);
			}

			public LocalizeKey Icelandic(string key)
			{
				return addForLang("Icelandic", key);
			}

			public LocalizeKey Turkish(string key)
			{
				return addForLang("Turkish", key);
			}

			public LocalizeKey Lithuanian(string key)
			{
				return addForLang("Lithuanian", key);
			}

			public LocalizeKey Czech(string key)
			{
				return addForLang("Czech", key);
			}

			public LocalizeKey Hungarian(string key)
			{
				return addForLang("Hungarian", key);
			}

			public LocalizeKey Slovak(string key)
			{
				return addForLang("Slovak", key);
			}

			public LocalizeKey Polish(string key)
			{
				return addForLang("Polish", key);
			}

			public LocalizeKey Dutch(string key)
			{
				return addForLang("Dutch", key);
			}

			public LocalizeKey Portuguese_European(string key)
			{
				return addForLang("Portuguese_European", key);
			}

			public LocalizeKey Portuguese_Brazilian(string key)
			{
				return addForLang("Portuguese_Brazilian", key);
			}

			public LocalizeKey Chinese(string key)
			{
				return addForLang("Chinese", key);
			}

			public LocalizeKey Japanese(string key)
			{
				return addForLang("Japanese", key);
			}

			public LocalizeKey Korean(string key)
			{
				return addForLang("Korean", key);
			}

			public LocalizeKey Hindi(string key)
			{
				return addForLang("Hindi", key);
			}

			public LocalizeKey Thai(string key)
			{
				return addForLang("Thai", key);
			}

			public LocalizeKey Abenaki(string key)
			{
				return addForLang("Abenaki", key);
			}

			public LocalizeKey Croatian(string key)
			{
				return addForLang("Croatian", key);
			}

			public LocalizeKey Georgian(string key)
			{
				return addForLang("Georgian", key);
			}

			public LocalizeKey Greek(string key)
			{
				return addForLang("Greek", key);
			}

			public LocalizeKey Serbian(string key)
			{
				return addForLang("Serbian", key);
			}

			public LocalizeKey Ukrainian(string key)
			{
				return addForLang("Ukrainian", key);
			}

			private LocalizeKey addForLang(string lang, string value)
			{
				Localizations[lang] = value;
				if (Localization.instance.GetSelectedLanguage() == lang)
				{
					Localization.instance.AddWord(Key, value);
				}
				else if (lang == "English" && !Localization.instance.m_translations.ContainsKey(Key))
				{
					Localization.instance.AddWord(Key, value);
				}
				return this;
			}

			[HarmonyPriority(300)]
			internal static void AddLocalizedKeys(Localization __instance, string language)
			{
				foreach (LocalizeKey key in keys)
				{
					string value2;
					if (key.Localizations.TryGetValue(language, out var value) || key.Localizations.TryGetValue("English", out value))
					{
						__instance.AddWord(key.Key, value);
					}
					else if (key.Localizations.TryGetValue("alias", out value2))
					{
						Localization.instance.AddWord(key.Key, Localization.instance.Localize(value2));
					}
				}
			}
		}

		private class ConfigurationManagerAttributes
		{
			[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
			[UsedImplicitly]
			public string Category;
		}

		[HarmonyPatch(typeof(Skills), "IsSkillValid")]
		private static class Patch_Skills_IsSkillValid
		{
			private static void Postfix(SkillType type, ref bool __result)
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				if (!__result && skills.ContainsKey(type))
				{
					__result = true;
				}
			}
		}

		private static readonly Dictionary<SkillType, Skill> skills;

		internal static readonly Dictionary<string, Skill> skillByName;

		private readonly string skillName;

		private readonly string internalSkillName;

		private readonly SkillDef skillDef;

		public readonly LocalizeKey Name;

		public readonly LocalizeKey Description;

		private float skillEffectFactor = 1f;

		private int skillLoss = 5;

		public bool Configurable;

		private static bool InitializedTerminal;

		[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
		private static Localization _english;

		[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
		private static BaseUnityPlugin _plugin;

		private static bool hasConfigSync;

		[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
		private static object _configSync;

		public float SkillGainFactor
		{
			get
			{
				return skillDef.m_increseStep;
			}
			set
			{
				skillDef.m_increseStep = value;
				this.SkillGainFactorChanged?.Invoke(value);
			}
		}

		public float SkillEffectFactor
		{
			get
			{
				return skillEffectFactor;
			}
			set
			{
				skillEffectFactor = value;
				this.SkillEffectFactorChanged?.Invoke(value);
			}
		}

		public int SkillLoss
		{
			get
			{
				return skillLoss;
			}
			set
			{
				skillLoss = value;
				this.SkillLossChanged?.Invoke(value);
			}
		}

		private static Localization english => _english ?? (_english = LocalizationCache.ForLanguage("English"));

		private static BaseUnityPlugin plugin
		{
			get
			{
				//IL_0041: 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)
				//IL_004c: Expected O, but got Unknown
				object obj = _plugin;
				if (obj == null)
				{
					BaseUnityPlugin val = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)Assembly.GetExecutingAssembly().DefinedTypes.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
					_plugin = val;
					obj = (object)val;
				}
				return (BaseUnityPlugin)obj;
			}
		}

		[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
		private static object configSync
		{
			[<e20af6a3-5cd6-43e6-8516-fbc0bbda7606>NullableContext(2)]
			get
			{
				if (_configSync == null && hasConfigSync)
				{
					Type type = Assembly.GetExecutingAssembly().GetType("ServerSync.ConfigSync");
					if ((object)type != null)
					{
						_configSync = Activator.CreateInstance(type, plugin.Info.Metadata.GUID + " SkillManager");
						type.GetField("CurrentVersion").SetValue(_configSync, plugin.Info.Metadata.Version.ToString());
						type.GetProperty("IsLocked").SetValue(_configSync, true);
					}
					else
					{
						hasConfigSync = false;
					}
				}
				return _configSync;
			}
		}

		[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
		[method: <e20af6a3-5cd6-43e6-8516-fbc0bbda7606>NullableContext(2)]
		[field: <e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
		public event Action<float> SkillGainFactorChanged;

		[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
		[method: <e20af6a3-5cd6-43e6-8516-fbc0bbda7606>NullableContext(2)]
		[field: <e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
		public event Action<float> SkillEffectFactorChanged;

		[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
		[method: <e20af6a3-5cd6-43e6-8516-fbc0bbda7606>NullableContext(2)]
		[field: <e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
		public event Action<float> SkillLossChanged;

		public Skill(string englishName, string icon)
			: this(englishName, loadSprite(icon, 64, 64))
		{
		}

		public Skill(string englishName, Sprite icon)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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_0053: 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_006b: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			SkillType val = fromName(englishName);
			string text = new Regex("[^a-zA-Z]").Replace(englishName, "_");
			skills[val] = this;
			skillByName[englishName] = this;
			skillDef = new SkillDef
			{
				m_description = "$skilldesc_" + text,
				m_icon = icon,
				m_increseStep = 1f,
				m_skill = val
			};
			internalSkillName = text;
			skillName = englishName;
			Name = new LocalizeKey("skill_" + ((object)(SkillType)(ref val)).ToString());
			Description = new LocalizeKey("skilldesc_" + text);
		}

		public static SkillType fromName(string englishName)
		{
			return (SkillType)Math.Abs(StringExtensionMethods.GetStableHashCode(englishName));
		}

		static Skill()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Expected O, but got Unknown
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Expected O, but got Unknown
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Expected O, but got Unknown
			//IL_01ac: Expected O, but got Unknown
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Expected O, but got Unknown
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Expected O, but got Unknown
			//IL_023e: Expected O, but got Unknown
			skills = new Dictionary<SkillType, Skill>();
			skillByName = new Dictionary<string, Skill>();
			InitializedTerminal = false;
			hasConfigSync = true;
			Harmony val = new Harmony("org.bepinex.helpers.skillmanager");
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_FejdStartup", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "GetSkillDef", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_GetSkillDef", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "CheatRaiseSkill", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_CheatRaiseskill", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "CheatResetSkill", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_CheatResetSkill", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(LocalizeKey), "AddLocalizedKeys", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Terminal), "InitTerminal", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Terminal_InitTerminal_Prefix", (Type[])null, (Type[])null)), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Terminal_InitTerminal", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(LocalizationCache), "LocalizationPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Skills), "OnDeath", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_OnDeath_Prefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Skill), "Patch_Skills_OnDeath_Finalizer", (Type[])null, (Type[])null)), (HarmonyMethod)null);
		}

		private static void Patch_FejdStartup()
		{
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Expected O, but got Unknown
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Expected O, but got Unknown
			foreach (Skill skill in skills.Values)
			{
				if (skill.Configurable)
				{
					string key = skill.Name.Key;
					string group = new Regex("['[\"\\]]").Replace(english.Localize(key), "").Trim();
					string category = Localization.instance.Localize(key).Trim();
					ConfigEntry<float> skillGain = config(group, "Skill gain factor", skill.SkillGainFactor, new ConfigDescription("The rate at which you gain experience for the skill.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 5f), new object[1]
					{
						new ConfigurationManagerAttributes
						{
							Category = category
						}
					}));
					skill.SkillGainFactor = skillGain.Value;
					skillGain.SettingChanged += delegate
					{
						skill.SkillGainFactor = skillGain.Value;
					};
					ConfigEntry<float> skillEffect = config(group, "Skill effect factor", skill.SkillEffectFactor, new ConfigDescription("The power of the skill, based on the default power.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 5f), new object[1]
					{
						new ConfigurationManagerAttributes
						{
							Category = category
						}
					}));
					skill.SkillEffectFactor = skillEffect.Value;
					skillEffect.SettingChanged += delegate
					{
						skill.SkillEffectFactor = skillEffect.Value;
					};
					ConfigEntry<int> skillLoss = config(group, "Skill loss", skill.skillLoss, new ConfigDescription("How much experience to lose on death.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), new object[1]
					{
						new ConfigurationManagerAttributes
						{
							Category = category
						}
					}));
					skill.skillLoss = skillLoss.Value;
					skillLoss.SettingChanged += delegate
					{
						skill.skillLoss = skillLoss.Value;
					};
				}
			}
		}

		private static void Patch_Skills_GetSkillDef([<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)] ref SkillDef __result, List<SkillDef> ___m_skills, SkillType type)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			if (__result == null)
			{
				SkillDef val = GetSkillDef(type);
				if (val != null)
				{
					___m_skills.Add(val);
					__result = val;
				}
			}
		}

		private static bool Patch_Skills_CheatRaiseskill(Skills __instance, string name, float value, Player ___m_player)
		{
			//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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			foreach (SkillType key in skills.Keys)
			{
				SkillType current = key;
				Skill skill = skills[current];
				if (string.Equals(skill.internalSkillName, name, StringComparison.CurrentCultureIgnoreCase))
				{
					Skill skill2 = __instance.GetSkill(current);
					skill2.m_level += value;
					skill2.m_level = Mathf.Clamp(skill2.m_level, 0f, 100f);
					((Character)___m_player).Message((MessageType)1, "Skill increased " + Localization.instance.Localize("$skill_" + ((object)(SkillType)(ref current)).ToString()) + ": " + (int)skill2.m_level, 0, skill2.m_info.m_icon);
					Console.instance.Print("Skill " + skill.internalSkillName + " = " + skill2.m_level);
					return false;
				}
			}
			return true;
		}

		private static bool Patch_Skills_CheatResetSkill(Skills __instance, string name)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			foreach (SkillType key in skills.Keys)
			{
				Skill skill = skills[key];
				if (string.Equals(skill.internalSkillName, name, StringComparison.CurrentCultureIgnoreCase))
				{
					__instance.ResetSkill(key);
					Console.instance.Print("Skill " + skill.internalSkillName + " reset");
					return false;
				}
			}
			return true;
		}

		private static void Patch_Skills_OnDeath_Prefix(Skills __instance, [<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(new byte[] { 2, 0 })] ref Dictionary<SkillType, Skill> __state)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			if (__state == null)
			{
				__state = new Dictionary<SkillType, Skill>();
			}
			foreach (KeyValuePair<SkillType, Skill> skill in skills)
			{
				if (__instance.m_skillData.TryGetValue(skill.Key, out var value))
				{
					__state[skill.Key] = value;
					if (skill.Value.skillLoss > 0)
					{
						Skill obj = value;
						obj.m_level -= value.m_level * (float)skill.Value.SkillLoss / 100f;
						value.m_accumulator = 0f;
					}
					__instance.m_skillData.Remove(skill.Key);
				}
			}
		}

		private static void Patch_Skills_OnDeath_Finalizer(Skills __instance, [<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(new byte[] { 2, 0 })] ref Dictionary<SkillType, Skill> __state)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (__state == null)
			{
				return;
			}
			foreach (KeyValuePair<SkillType, Skill> item in __state)
			{
				__instance.m_skillData[item.Key] = item.Value;
			}
			__state = null;
		}

		private static void Patch_Terminal_InitTerminal_Prefix()
		{
			InitializedTerminal = Terminal.m_terminalInitialized;
		}

		private static void Patch_Terminal_InitTerminal()
		{
			if (!InitializedTerminal)
			{
				AddSkill(Terminal.commands["raiseskill"]);
				AddSkill(Terminal.commands["resetskill"]);
			}
			static void AddSkill(ConsoleCommand command)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Expected O, but got Unknown
				ConsoleOptionsFetcher fetcher = command.m_tabOptionsFetcher;
				command.m_tabOptionsFetcher = (ConsoleOptionsFetcher)delegate
				{
					List<string> list = fetcher.Invoke();
					list.AddRange(skills.Values.Select((Skill skill) => skill.internalSkillName));
					return list;
				};
			}
		}

		[<e20af6a3-5cd6-43e6-8516-fbc0bbda7606>NullableContext(2)]
		private static SkillDef GetSkillDef(SkillType skillType)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (!skills.ContainsKey(skillType))
			{
				return null;
			}
			Skill skill = skills[skillType];
			return skill.skillDef;
		}

		private static byte[] ReadEmbeddedFileBytes(string name)
		{
			using MemoryStream memoryStream = new MemoryStream();
			Assembly.GetExecutingAssembly().GetManifestResourceStream(Assembly.GetExecutingAssembly().GetName().Name + "." + name).CopyTo(memoryStream);
			return memoryStream.ToArray();
		}

		private static Texture2D loadTexture(string name)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			Texture2D val = new Texture2D(0, 0);
			ImageConversion.LoadImage(val, ReadEmbeddedFileBytes("icons." + name));
			return val;
		}

		private static Sprite loadSprite(string name, int width, int height)
		{
			//IL_0014: 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)
			return Sprite.Create(loadTexture(name), new Rect(0f, 0f, (float)width, (float)height), Vector2.zero);
		}

		private static ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description)
		{
			ConfigEntry<T> val = ValheimEnchantmentSystem.SyncedConfig.Bind<T>(group, name, value, description);
			configSync?.GetType().GetMethod("AddConfigEntry").MakeGenericMethod(typeof(T))
				.Invoke(configSync, new object[1] { val });
			return val;
		}

		private static ConfigEntry<T> config<T>(string group, string name, T value, string description)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
		}
	}
	[PublicAPI]
	public static class SkillExtensions
	{
		public static float GetSkillFactor(this Character character, string name)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return character.GetSkillFactor(Skill.fromName(name)) * Skill.skillByName[name].SkillEffectFactor;
		}

		public static float GetSkillFactor(this Skills skills, string name)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return skills.GetSkillFactor(Skill.fromName(name)) * Skill.skillByName[name].SkillEffectFactor;
		}

		public static void RaiseSkill(this Character character, string name, float value = 1f)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			character.RaiseSkill(Skill.fromName(name), value);
		}

		public static void RaiseSkill(this Skills skill, string name, float value = 1f)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			skill.RaiseSkill(Skill.fromName(name), value);
		}

		public static void LowerSkill(this Character character, string name, float factor = 1f)
		{
			character.GetSkills().LowerSkill(name, factor);
		}

		public static void LowerSkill(this Skills skills, string name, float factor)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (factor > 0f && skills.m_skillData.TryGetValue(Skill.fromName(name), out var value))
			{
				Skill obj = value;
				obj.m_level -= value.m_level * factor;
				value.m_accumulator = 0f;
			}
		}
	}
}
namespace ItemManager
{
	[PublicAPI]
	public enum CraftingTable
	{
		Disabled,
		Inventory,
		[InternalName("piece_workbench")]
		Workbench,
		[InternalName("piece_cauldron")]
		Cauldron,
		[InternalName("forge")]
		Forge,
		[InternalName("piece_artisanstation")]
		ArtisanTable,
		[InternalName("piece_stonecutter")]
		StoneCutter,
		[InternalName("piece_magetable")]
		MageTable,
		[InternalName("blackforge")]
		BlackForge,
		Custom
	}
	[PublicAPI]
	public enum ConversionPiece
	{
		Disabled,
		[InternalName("smelter")]
		Smelter,
		[InternalName("charcoal_kiln")]
		CharcoalKiln,
		[InternalName("blastfurnace")]
		BlastFurnace,
		[InternalName("windmill")]
		Windmill,
		[InternalName("piece_spinningwheel")]
		SpinningWheel,
		[InternalName("eitrrefinery")]
		EitrRefinery,
		Custom
	}
	public class InternalName : Attribute
	{
		public readonly string internalName;

		public InternalName(string internalName)
		{
			this.internalName = internalName;
		}
	}
	[PublicAPI]
	public class RequiredResourceList
	{
		public readonly List<Requirement> Requirements = new List<Requirement>();

		public bool Free;

		public void Add(string itemName, int amount, int quality = 0)
		{
			Requirements.Add(new Requirement
			{
				itemName = itemName,
				amount = amount,
				quality = quality
			});
		}

		public void Add(string itemName, ConfigEntry<int> amountConfig, int quality = 0)
		{
			Requirements.Add(new Requirement
			{
				itemName = itemName,
				amountConfig = amountConfig,
				quality = quality
			});
		}
	}
	[PublicAPI]
	public class CraftingStationList
	{
		public readonly List<CraftingStationConfig> Stations = new List<CraftingStationConfig>();

		public void Add(CraftingTable table, int level)
		{
			Stations.Add(new CraftingStationConfig
			{
				Table = table,
				level = level
			});
		}

		public void Add(string customTable, int level)
		{
			Stations.Add(new CraftingStationConfig
			{
				Table = CraftingTable.Custom,
				level = level,
				custom = customTable
			});
		}
	}
	[PublicAPI]
	public class ItemRecipe
	{
		public readonly RequiredResourceList RequiredItems = new RequiredResourceList();

		public readonly RequiredResourceList RequiredUpgradeItems = new RequiredResourceList();

		public readonly CraftingStationList Crafting = new CraftingStationList();

		public int CraftAmount = 1;

		public bool RequireOnlyOneIngredient;

		public float QualityResultAmountMultiplier = 1f;

		[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
		public ConfigEntryBase RecipeIsActive;
	}
	[PublicAPI]
	public class Trade
	{
		public Trader Trader;

		public uint Price;

		public uint Stack = 1u;

		[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
		public string RequiredGlobalKey;
	}
	[Flags]
	[PublicAPI]
	public enum Trader
	{
		None = 0,
		Haldor = 1,
		Hildir = 2
	}
	public struct Requirement
	{
		public string itemName;

		public int amount;

		[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
		public ConfigEntry<int> amountConfig;

		[Description("Set to a non-zero value to apply the requirement only for a specific quality")]
		public int quality;
	}
	public struct CraftingStationConfig
	{
		public CraftingTable Table;

		public int level;

		[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
		public string custom;
	}
	[Flags]
	public enum Configurability
	{
		Disabled = 0,
		Recipe = 1,
		Stats = 2,
		Drop = 4,
		Trader = 8,
		Full = 0xF
	}
	[PublicAPI]
	public class DropTargets
	{
		public readonly List<DropTarget> Drops = new List<DropTarget>();

		public void Add(string creatureName, float chance, int min = 1, int? max = null, bool levelMultiplier = true)
		{
			Drops.Add(new DropTarget
			{
				creature = creatureName,
				chance = chance,
				min = min,
				max = max.GetValueOrDefault(min),
				levelMultiplier = levelMultiplier
			});
		}
	}
	public struct DropTarget
	{
		public string creature;

		public int min;

		public int max;

		public float chance;

		public bool levelMultiplier;
	}
	public enum Toggle
	{
		On = 1,
		Off = 0
	}
	[PublicAPI]
	public class Item
	{
		private class ItemConfig
		{
			[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(new byte[] { 2, 0 })]
			public ConfigEntry<string> craft;

			[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(new byte[] { 2, 0 })]
			public ConfigEntry<string> upgrade;

			public ConfigEntry<CraftingTable> table;

			public ConfigEntry<int> tableLevel;

			public ConfigEntry<string> customTable;

			[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
			public ConfigEntry<int> maximumTableLevel;

			public ConfigEntry<Toggle> requireOneIngredient;

			public ConfigEntry<float> qualityResultAmountMultiplier;
		}

		private class TraderConfig
		{
			public ConfigEntry<Trader> trader;

			public ConfigEntry<uint> price;

			public ConfigEntry<uint> stack;

			public ConfigEntry<string> requiredGlobalKey;
		}

		private class RequirementQuality
		{
			public int quality;
		}

		[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(0)]
		[<e20af6a3-5cd6-43e6-8516-fbc0bbda7606>NullableContext(2)]
		private class ConfigurationManagerAttributes
		{
			[UsedImplicitly]
			public int? Order;

			[UsedImplicitly]
			public bool? Browsable;

			[UsedImplicitly]
			public string Category;

			[UsedImplicitly]
			[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(new byte[] { 2, 0 })]
			public Action<ConfigEntryBase> CustomDrawer;

			public Func<bool> browsability;
		}

		[PublicAPI]
		public enum DamageModifier
		{
			Normal,
			Resistant,
			Weak,
			Immune,
			Ignore,
			VeryResistant,
			VeryWeak,
			None
		}

		private delegate void setDmgFunc(ref DamageTypes dmg, float value);

		private class SerializedRequirements
		{
			public readonly List<Requirement> Reqs;

			public SerializedRequirements(List<Requirement> reqs)
			{
				Reqs = reqs;
			}

			public SerializedRequirements(string reqs)
				: this(reqs.Split(new char[1] { ',' }).Select(delegate(string r)
				{
					string[] array = r.Split(new char[1] { ':' });
					Requirement result = default(Requirement);
					result.itemName = array[0];
					result.amount = ((array.Length <= 1 || !int.TryParse(array[1], out var result2)) ? 1 : result2);
					result.quality = ((array.Length > 2 && int.TryParse(array[2], out var result3)) ? result3 : 0);
					return result;
				}).ToList())
			{
			}

			public override string ToString()
			{
				return string.Join(",", Reqs.Select((Requirement r) => $"{r.itemName}:{r.amount}" + ((r.quality > 0) ? $":{r.quality}" : "")));
			}

			[return: <e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
			public static ItemDrop fetchByName(ObjectDB objectDB, string name)
			{
				GameObject itemPrefab = objectDB.GetItemPrefab(name);
				ItemDrop val = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null);
				if ((Object)(object)val == (Object)null)
				{
					Debug.LogWarning((object)("The required item '" + name + "' does not exist."));
				}
				return val;
			}

			public static Requirement[] toPieceReqs(ObjectDB objectDB, SerializedRequirements craft, SerializedRequirements upgrade)
			{
				//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
				//IL_0178: Unknown result type (might be due to invalid IL or missing references)
				//IL_017d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0185: Unknown result type (might be due to invalid IL or missing references)
				//IL_018c: Unknown result type (might be due to invalid IL or missing references)
				//IL_018f: Expected O, but got Unknown
				//IL_0194: Expected O, but got Unknown
				//IL_011c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0125: Expected O, but got Unknown
				Dictionary<string, Requirement> dictionary = craft.Reqs.Where((Requirement r) => r.itemName != "").ToDictionary((Func<Requirement, string>)((Requirement r) => r.itemName), (Func<Requirement, Requirement>)delegate(Requirement r)
				{
					//IL_000d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0012: Unknown result type (might be due to invalid IL or missing references)
					//IL_002f: 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_003e: Expected O, but got Unknown
					ItemDrop val6 = ResItem(r);
					return (val6 != null) ? new Requirement
					{
						m_amount = (r.amountConfig?.Value ?? r.amount),
						m_resItem = val6,
						m_amountPerLevel = 0
					} : ((Requirement)null);
				});
				List<Requirement> list = dictionary.Values.Where((Requirement v) => v != null).ToList();
				foreach (Requirement item in upgrade.Reqs.Where((Requirement r) => r.itemName != ""))
				{
					if (item.quality > 0)
					{
						ItemDrop val = ResItem(item);
						if (val != null)
						{
							Requirement val2 = new Requirement
							{
								m_resItem = val,
								m_amountPerLevel = (item.amountConfig?.Value ?? item.amount),
								m_amount = 0
							};
							list.Add(val2);
							requirementQuality.Add(val2, new RequirementQuality
							{
								quality = item.quality
							});
						}
						continue;
					}
					if (!dictionary.TryGetValue(item.itemName, out var value) || value == null)
					{
						ItemDrop val3 = ResItem(item);
						if (val3 != null)
						{
							string itemName = item.itemName;
							Requirement val4 = new Requirement
							{
								m_resItem = val3,
								m_amount = 0
							};
							Requirement val5 = val4;
							dictionary[itemName] = val4;
							value = val5;
							list.Add(value);
						}
					}
					if (value != null)
					{
						value.m_amountPerLevel = item.amountConfig?.Value ?? item.amount;
					}
				}
				return list.ToArray();
				[<e20af6a3-5cd6-43e6-8516-fbc0bbda7606>NullableContext(2)]
				ItemDrop ResItem(Requirement r)
				{
					return fetchByName(objectDB, r.itemName);
				}
			}
		}

		private class SerializedDrop
		{
			public readonly List<DropTarget> Drops;

			public SerializedDrop(List<DropTarget> drops)
			{
				Drops = drops;
			}

			public SerializedDrop(string drops)
			{
				Drops = ((drops == "") ? ((IEnumerable<string>)Array.Empty<string>()) : ((IEnumerable<string>)drops.Split(new char[1] { ',' }))).Select(delegate(string r)
				{
					string[] array = r.Split(new char[1] { ':' });
					if (array.Length <= 2 || !int.TryParse(array[2], out var result))
					{
						result = 1;
					}
					if (array.Length <= 3 || !int.TryParse(array[3], out var result2))
					{
						result2 = result;
					}
					bool levelMultiplier = array.Length <= 4 || array[4] != "0";
					DropTarget result3 = default(DropTarget);
					result3.creature = array[0];
					result3.chance = ((array.Length > 1 && float.TryParse(array[1], out var result4)) ? result4 : 1f);
					result3.min = result;
					result3.max = result2;
					result3.levelMultiplier = levelMultiplier;
					return result3;
				}).ToList();
			}

			public override string ToString()
			{
				return string.Join(",", Drops.Select((DropTarget r) => $"{r.creature}:{r.chance.ToString(CultureInfo.InvariantCulture)}:{r.min}:" + ((r.min == r.max) ? "" : $"{r.max}") + (r.levelMultiplier ? "" : ":0")));
			}

			[return: <e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
			private static Character fetchByName(ZNetScene netScene, string name)
			{
				GameObject prefab = netScene.GetPrefab(name);
				Character val = ((prefab != null) ? prefab.GetComponent<Character>() : null);
				if ((Object)(object)val == (Object)null)
				{
					Debug.LogWarning((object)("The drop target character '" + name + "' does not exist."));
				}
				return val;
			}

			public Dictionary<Character, Drop> toCharacterDrops(ZNetScene netScene, GameObject item)
			{
				//IL_002e: 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_003a: 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)
				//IL_0052: 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_006f: Expected O, but got Unknown
				Dictionary<Character, Drop> dictionary = new Dictionary<Character, Drop>();
				foreach (DropTarget drop in Drops)
				{
					Character val = fetchByName(netScene, drop.creature);
					if (val != null)
					{
						dictionary[val] = new Drop
						{
							m_prefab = item,
							m_amountMin = drop.min,
							m_amountMax = drop.max,
							m_chance = drop.chance,
							m_levelMultiplier = drop.levelMultiplier
						};
					}
				}
				return dictionary;
			}
		}

		private static readonly List<Item> registeredItems = new List<Item>();

		private static readonly Dictionary<ItemDrop, Item> itemDropMap = new Dictionary<ItemDrop, Item>();

		private static Dictionary<Item, Dictionary<string, List<Recipe>>> activeRecipes = new Dictionary<Item, Dictionary<string, List<Recipe>>>();

		[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(new byte[] { 0, 0, 2 })]
		private static Dictionary<Recipe, ConfigEntryBase> hiddenCraftRecipes = new Dictionary<Recipe, ConfigEntryBase>();

		[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(new byte[] { 0, 0, 2 })]
		private static Dictionary<Recipe, ConfigEntryBase> hiddenUpgradeRecipes = new Dictionary<Recipe, ConfigEntryBase>();

		private static Dictionary<Item, Dictionary<string, ItemConfig>> itemCraftConfigs = new Dictionary<Item, Dictionary<string, ItemConfig>>();

		private static Dictionary<Item, ConfigEntry<string>> itemDropConfigs = new Dictionary<Item, ConfigEntry<string>>();

		private Dictionary<CharacterDrop, Drop> characterDrops = new Dictionary<CharacterDrop, Drop>();

		private readonly Dictionary<ConfigEntryBase, Action> statsConfigs = new Dictionary<ConfigEntryBase, Action>();

		private static readonly ConditionalWeakTable<Requirement, RequirementQuality> requirementQuality = new ConditionalWeakTable<Requirement, RequirementQuality>();

		public static Configurability DefaultConfigurability = Configurability.Full;

		public Configurability? Configurable;

		private Configurability configurationVisible = Configurability.Full;

		[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
		private TraderConfig traderConfig;

		public readonly GameObject Prefab;

		[Description("Specifies the maximum required crafting station level to upgrade and repair the item.\nDefault is calculated from crafting station level and maximum quality.")]
		public int MaximumRequiredStationLevel = int.MaxValue;

		[Description("Assigns the item as a drop item to a creature.\nUses a creature name, a drop chance and a minimum and maximum amount.")]
		public readonly DropTargets DropsFrom = new DropTargets();

		[Description("Configures whether the item can be bought at the trader.\nDon't forget to set cost to something above 0 or the item will be sold for free.")]
		public readonly Trade Trade = new Trade();

		internal List<Conversion> Conversions = new List<Conversion>();

		internal List<ItemConversion> conversions = new List<ItemConversion>();

		public Dictionary<string, ItemRecipe> Recipes = new Dictionary<string, ItemRecipe>();

		[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
		private LocalizeKey _name;

		[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
		private LocalizeKey _description;

		[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
		private static object configManager;

		[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
		private static Localization _english;

		[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
		private static BaseUnityPlugin _plugin;

		private static bool hasConfigSync = true;

		[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
		private static object _configSync;

		private Configurability configurability => Configurable ?? DefaultConfigurability;

		[Description("Specifies the resources needed to craft the item.\nUse .Add to add resources with their internal ID and an amount.\nUse one .Add for each resource type the item should need.")]
		public RequiredResourceList RequiredItems => this[""].RequiredItems;

		[Description("Specifies the resources needed to upgrade the item.\nUse .Add to add resources with their internal ID and an amount. This amount will be multipled by the item quality level.\nUse one .Add for each resource type the upgrade should need.")]
		public RequiredResourceList RequiredUpgradeItems => this[""].RequiredUpgradeItems;

		[Description("Specifies the crafting station needed to craft the item.\nUse .Add to add a crafting station, using the CraftingTable enum and a minimum level for the crafting station.\nUse one .Add for each crafting station.")]
		public CraftingStationList Crafting => this[""].Crafting;

		[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
		[Description("Specifies a config entry which toggles whether a recipe is active.")]
		public ConfigEntryBase RecipeIsActive
		{
			[<e20af6a3-5cd6-43e6-8516-fbc0bbda7606>NullableContext(2)]
			get
			{
				return this[""].RecipeIsActive;
			}
			[<e20af6a3-5cd6-43e6-8516-fbc0bbda7606>NullableContext(2)]
			set
			{
				this[""].RecipeIsActive = value;
			}
		}

		[Description("Specifies the number of items that should be given to the player with a single craft of the item.\nDefaults to 1.")]
		public int CraftAmount
		{
			get
			{
				return this[""].CraftAmount;
			}
			set
			{
				this[""].CraftAmount = value;
			}
		}

		public bool RequireOnlyOneIngredient
		{
			get
			{
				return this[""].RequireOnlyOneIngredient;
			}
			set
			{
				this[""].RequireOnlyOneIngredient = value;
			}
		}

		public float QualityResultAmountMultiplier
		{
			get
			{
				return this[""].QualityResultAmountMultiplier;
			}
			set
			{
				this[""].QualityResultAmountMultiplier = value;
			}
		}

		public ItemRecipe this[string name]
		{
			get
			{
				if (Recipes.TryGetValue(name, out var value))
				{
					return value;
				}
				return Recipes[name] = new ItemRecipe();
			}
		}

		public LocalizeKey Name
		{
			get
			{
				LocalizeKey name = _name;
				if (name != null)
				{
					return name;
				}
				SharedData shared = Prefab.GetComponent<ItemDrop>().m_itemData.m_shared;
				if (shared.m_name.StartsWith("$"))
				{
					_name = new LocalizeKey(shared.m_name);
				}
				else
				{
					string text = "$item_" + ((Object)Prefab).name.Replace(" ", "_");
					_name = new LocalizeKey(text).English(shared.m_name);
					shared.m_name = text;
				}
				return _name;
			}
		}

		public LocalizeKey Description
		{
			get
			{
				LocalizeKey description = _description;
				if (description != null)
				{
					return description;
				}
				SharedData shared = Prefab.GetComponent<ItemDrop>().m_itemData.m_shared;
				if (shared.m_description.StartsWith("$"))
				{
					_description = new LocalizeKey(shared.m_description);
				}
				else
				{
					string text = "$itemdesc_" + ((Object)Prefab).name.Replace(" ", "_");
					_description = new LocalizeKey(text).English(shared.m_description);
					shared.m_description = text;
				}
				return _description;
			}
		}

		private static Localization english => _english ?? (_english = LocalizationCache.ForLanguage("English"));

		private static BaseUnityPlugin plugin
		{
			get
			{
				//IL_009d: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a7: Expected O, but got Unknown
				if (_plugin == null)
				{
					IEnumerable<TypeInfo> source;
					try
					{
						source = Assembly.GetExecutingAssembly().DefinedTypes.ToList();
					}
					catch (ReflectionTypeLoadException ex)
					{
						source = from t in ex.Types
							where t != null
							select t.GetTypeInfo();
					}
					_plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
				}
				return _plugin;
			}
		}

		[<e9fa47f9-ebe8-4038-b99a-9fc150020e95>Nullable(2)]
		private static object configSync
		{
			[<e20af6a3-5cd6-43e6-8516-fbc0bbda7606>NullableContext(2)]
			get
			{
				if (_configSync == null && hasConfigSync)
				{
					Type type = Assembly.GetExecutingAssembly().GetType("ServerSync.ConfigSync");
					if ((object)type != null)
					{
						_configSync = Activator.CreateInstance(type, plugin.Info.Metadata.GUID + " ItemManager");
						type.GetField("CurrentVersion").SetValue(_configSync, plugin.Info.Metadata.Version.ToString());
						type.GetProperty("IsLocked").SetValue(_configSync, true);
					}
					else
					{
						hasConfigSync = false;
					}
				}
				return _configSync;
			}
		}

		public Item(string assetBundleFileName, string prefabName, string folderName = "assets")
			: this(PrefabManager.RegisterAssetBundle(assetBundleFileName, folderName), prefabName)
		{
		}

		public Item(AssetBundle bundle, string prefabName)
			: this(PrefabManager.RegisterPrefab(bundle, prefabName, addToObjectDb: true), skipRegistering: true)
		{
		}

		public Item(GameObject prefab, bool skipRegistering = false)
		{
			if (!skipRegistering)
			{
				PrefabManager.RegisterPrefab(prefab, addToObjectDb: true);
			}
			Prefab = prefab;
			registeredItems.Add(this);
			itemDropMap[Prefab.GetComponent<ItemDrop>()] = this;
			Prefab.GetComponent<ItemDrop>().m_itemData.m_dropPrefab = Prefab;
		}

		public void ToggleConfigurationVisibility(Configurability visible)
		{
			configurationVisible = visible;
			if (itemDropConfigs.TryGetValue(this, out var value))
			{
				Toggle((ConfigEntryBase)(object)value, Configurability.Drop);
			}
			if (itemCraftConfigs.TryGetValue(this, out var value2))
			{
				foreach (ItemConfig value4 in value2.Values)
				{
					ToggleObj(value4, Configurability.Recipe);
				}
			}
			foreach (Conversion conversion in Conversions)
			{
				if (conversion.config != null)
				{
					ToggleObj(conversion.config, Configurability.Recipe);
				}
			}
			foreach (KeyValuePair<ConfigEntryBase, Action> statsConfig in statsConfigs)
			{
				Toggle(statsConfig.Key, Configurability.Stats);
				if ((visible & Configurability.Stats) != 0)
				{
					statsConfig.Value();
				}
			}
			reloadConfigDisplay();
			void Toggle(ConfigEntryBase cfg, Configurability check)
			{
				object[] tags = cfg.Description.Tags;
				foreach (object obj2 in tags)
				{
					if (obj2 is ConfigurationManagerAttributes configurationManagerAttributes)
					{
						configurationManagerAttributes.Browsable = (visible & check) != 0 && (configurationManagerAttributes.browsability == null || configurationManagerAttributes.browsability());
					}
				}
			}
			void ToggleObj(object obj, Configurability check)
			{
				FieldInfo[] fields = obj.GetType().GetFields();
				foreach (FieldInfo fieldInfo in fields)
				{
					object? value3 = fieldInfo.GetValue(obj);
					ConfigEntryBase val = (ConfigEntryBase)((value3 is ConfigEntryBase) ? value3 : null);
					if (val != null)
					{
						Toggle(val, check);
					}
				}
			}
		}

		internal static void reloadConfigDisplay()
		{
			configManager?.GetType().GetMethod("BuildSettingList").Invoke(configManager, Array.Empty<object>());
		}

		private void UpdateItemTableConfig(string recipeKey, CraftingTable table, string customTableValue)
		{
			if (activeRecipes.ContainsKey(this) && activeRecipes[this].TryGetValue(recipeKey, out var value))
			{
				value.First().m_enabled = table != CraftingTable.Disabled;
				if ((uint)table <= 1u)
				{
					value.First().m_craftingStation = null;
				}
				else if (table == CraftingTable.Custom)
				{
					Recipe obj = value.First();
					GameObject prefab = ZNetScene.instance.GetPrefab(customTableValue);
					obj.m_craftingStation = ((prefab != null) ? prefab.GetComponent<CraftingStation>() : null);
				}
				else
				{
					value.First().m_craftingStation = ZNetScene.instance.GetPrefab(getInternalName(table)).GetComponent<CraftingStation>();
				}
			}
		}

		private void UpdateCraftConfig(string recipeKey, SerializedRequirements craftRequirements, SerializedRequirements upgradeRequirements)
		{
			if (!Object.op_Implicit((Object)(object)ObjectDB.instance) || !activeRecipes.ContainsKey(this) || !activeRecipes[this].TryGetValue(recipeKey, out var value))
			{
				return;
			}
			foreach (Recipe item in value)
			{
				item.m_resources = SerializedRequirements.toPieceReqs(ObjectDB.instance, craftRequirements, upgradeRequirements);
			}
		}

		internal static void Patch_FejdStartup()
		{
			//IL_0eb6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ebb: Unknown result type (might be due to invalid IL or missing references)
			//IL_21af: Unknown result type (might be due to invalid IL or missing references)
			//IL_21b9: Expected O, but got Unknown
			//IL_0f81: Unknown result type (might be due to invalid IL or missing references)
			//IL_0f84: Unknown result type (might be due to invalid IL or missing references)
			//IL_0fda: Expected I4, but got Unknown
			//IL_0b9b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ba5: Expected O, but got Unknown
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_031d: Expected O, but got Unknown
			//IL_1111: Unknown result type (might be due to invalid IL or missing references)
			//IL_1114: Unknown result type (might be due to invalid IL or missing references)
			//IL_1116: Invalid comparison between Unknown and I4
			//IL_1118: Unknown result type (might be due to invalid IL or missing references)
			//IL_111c: Invalid comparison between Unknown and I4
			//IL_0cc4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cce: Expected O, but got Unknown
			//IL_0d6f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d79: Expected O, but got Unknown
			//IL_111e: Unknown result type (might be due to invalid IL or missing references)
			//IL_1122: Invalid comparison between Unknown and I4
			//IL_0406: Unknown result type (might be due to invalid IL or missing references)
			//IL_0410: Expected O, but got Unknown
			//IL_0e23: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e2d: Expected O, but got Unknown
			//IL_1322: Unknown result type (might be due to invalid IL or missing references)
			//IL_1325: Unknown result type (might be due to invalid IL or missing references)
			//IL_1327: Invalid comparison between Unknown and I4
			//IL_1329: Unknown result type (might be due to invalid IL or missing references)
			//IL_132d: Unknown result type (might be due to invalid IL or missing references)
			//IL_132f: Invalid comparison between Unknown and I4
			//IL_0541: Unknown result type (might be due to invalid IL or missing references)
			//IL_054b: Expected O, but got Unknown
			//IL_1331: Unknown result type (might be due to invalid IL or missing references)
			//IL_1335: Invalid comparison between Unknown and I4
			//IL_140c: Unknown result type (might be due to invalid IL or missing references)
			//IL_1411: Unknown result type (might be due to invalid IL or missing references)
			//IL_1413: Unknown result type (might be due to invalid IL or missing references)
			//IL_1416: Invalid comparison between Unknown and I4
			//IL_1418: Unknown result type (might be due to invalid IL or missing references)
			//IL_141c: Invalid comparison between Unknown and I4
			//IL_06f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0702: Expected O, but got Unknown
			//IL_0659: Unknown result type (might be due to invalid IL or missing references)
			//IL_0663: Expected O, but got Unknown
			//IL_148c: Unknown result type (might be due to invalid IL or missing references)
			//IL_148f: Unknown result type (might be due to invalid IL or missing references)
			//IL_1491: Invalid comparison between Unknown and I4
			//IL_0802: Unknown result type (might be due to invalid IL or missing references)
			//IL_080c: Expected O, but got Unknown
			//IL_1493: Unknown result type (might be due to invalid IL or missing references)
			//IL_1497: Unknown result type (might be due to invalid IL or missing references)
			//IL_1499: Invalid comparison between Unknown and I4
			//IL_149b: Unknown result type (might be due to invalid IL or missing references)
			//IL_149f: Invalid comparison between Unknown and I4
			//IL_15dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_15e0: Invalid comparison between Unknown and I4
			//IL_17e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_17e9: Invalid comparison between Unknown and I4
			//IL_18b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_18b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_18bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_18bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_18c1: Invalid comparison between Unknown and I4
			//IL_1931: Unknown result type (might be due to invalid IL or missing references)
			//IL_1934: Unknown result type (might be due to invalid IL or missing references)
			//IL_1936: Invalid comparison between Unknown and I4
			//IL_1552: Unknown result type (might be due to invalid IL or missing references)
			//IL_1557: Unknown result type (might be due to invalid IL or missing references)
			//IL_1938: Unknown result type (might be due to invalid IL or missing references)
			//IL_193c: Invalid comparison between Unknown and I4
			//IL_193e: Unknown result type (might be due to invalid IL or missing references)
			//IL_1942: Invalid comparison between Unknown and I4
			//IL_1dbd: Unknown result type (might be due to invalid IL or missing references)
			//IL_1dc0: Invalid comparison between Unknown and I4
			Type type = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "ConfigurationManager")?.GetType("ConfigurationManager.ConfigurationManager");
			if (DefaultConfigurability != 0)
			{
				bool saveOnConfigSet = plugin.Config.SaveOnConfigSet;
				plugin.Config.SaveOnConfigSet = false;
				foreach (Item item4 in registeredItems.Where((Item i) => i.configurability != Configurability.Disabled))
				{
					Item item3 = item4;
					string name2 = item3.Prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_name;
					string englishName = new Regex("['\\[\"\\]]").Replace(english.Localize(name2), "").Trim();
					string localizedName = Localization.instance.Localize(name2).Trim();
					int order = 0;
					if ((item3.configurability & Configurability.Recipe) != 0)
					{
						itemCraftConfigs[item3] = new Dictionary<string, ItemConfig>();
						foreach (string item5 in item3.Recipes.Keys.DefaultIfEmpty(""))
						{
							string configKey = item5;
							string text = ((configKey == "") ? "" : (" (" + configKey + ")"));
							if (!item3.Recipes.ContainsKey(configKey) || item3.Recipes[configKey].Crafting.Stations.Count <= 0)
							{
								continue;
							}
							ItemConfig itemConfig2 = (itemCraftConfigs[item3][configKey] = new ItemConfig());
							ItemConfig cfg = itemConfig2;
							List<ConfigurationManagerAttributes> hideWhenNoneAttributes = new List<ConfigurationManagerAttributes>();
							cfg.table = config(englishName, "Crafting Station" + text, item3.Recipes[configKey].Crafting.Stations.First().Table, new ConfigDescription("Crafting station where " + englishName + " is available.", (AcceptableValueBase)null, new object[1]
							{
								new ConfigurationManagerAttributes
								{
									Order = (order -= 1),
									Browsable = ((item3.configurationVisible & Configurability.Recipe) != 0),
									Category = localizedName
								}
							}));
							ConfigurationManagerAttributes customTableAttributes = new ConfigurationManagerAttributes
							{
								Order = (order -= 1),
								browsability = CustomTableBrowsability,
								Browsable = (CustomTableBrowsability() && (item3.configurationVisible & Configurability.Recipe) != 0),
								Category = localizedName
							};
							cfg.customTable = config(englishName, "Custom Crafting Station" + text, item3.Recipes[configKey].Crafting.Stations.First().custom ?? "", new ConfigDescription("", (AcceptableValueBase)null, new object[1] { customTableAttributes }));
							cfg.table.SettingChanged += TableConfigChanged;
							cfg.customTable.SettingChanged += TableConfigChanged;
							ConfigurationManagerAttributes configurationManagerAttributes = new ConfigurationManagerAttributes
							{
								Order = (order -= 1),
								browsability = TableLevelBrowsability,
								Browsable = (TableLevelBrowsability() && (item3.configurationVisible & Configurability.Recipe) != 0),
								Category = localizedName
							};
							hideWhenNoneAttributes.Add(configurationManagerAttributes);
							cfg.tableLevel = config(englishName, "Crafting Station Level" + text, item3.Recipes[configKey].Crafting.Stations.First().level, new ConfigDescription("Required crafting station level to craft " + englishName + ".", (AcceptableValueBase)null, new object[1] { configurationManagerAttributes }));
							cfg.tableLevel.SettingChanged += delegate
							{
								if (activeRecipes.ContainsKey(item3) && activeRecipes[item3].TryGetValue(configKey, out var value6))
								{
									value6.First().m_minStationLevel = cfg.tableLevel.Value;
								}
							};
							if (item3.Prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_maxQuality > 1)
							{
								cfg.maximumTableLevel = config(englishName, "Maximum Crafting Station Level" + text, (item3.MaximumRequiredStationLevel == int.MaxValue) ? (item3.Recipes[configKey].Crafting.Stations.First().level + item3.Prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_maxQuality - 1) : item3.MaximumRequiredStationLevel, new ConfigDescription("Maximum crafting station level to upgrade and repair " + englishName + ".", (AcceptableValueBase)null, new object[1] { configurationManagerAttributes }));
							}
							cfg.requireOneIngredient = config(englishName, "Require only one resource" + text, item3.Recipes[configKey].RequireOnlyOneIngredient ? Toggle.On : Toggle.Off, new ConfigDescription("Whether only one of the ingredients is needed to craft " + englishName, (AcceptableValueBase)null, new object[1]
							{
								new ConfigurationManagerAttributes
								{
									Order = (order -= 1),
									Category = localizedName
								}
							}));
							ConfigurationManagerAttributes qualityResultAttributes = new ConfigurationManagerAttributes
							{
								Order = (order -= 1),
								browsability = QualityResultBrowsability,
								Browsable = (QualityResultBrowsability() && (item3.configurationVisible & Configurability.Recipe) != 0),
								Category = localizedName
							};
							cfg.requireOneIngredient.SettingChanged += delegate
							{
								if (activeRecipes.ContainsKey(item3) && activeRecipes[item3].TryGetValue(configKey, out var value5))
								{
									foreach (Recipe item6 in value5)
									{
										item6.m_requireOnlyOneIngredient = cfg.requireOneIngredient.Value == Toggle.On;
									}
								}
								qualityResultAttributes.Browsable = QualityResultBrowsability();
								reloadConfigDisplay();
							};
							cfg.qualityResultAmountMultiplier = config(englishName, "Quality Multiplier" + text, item3.Recipes[configKey].QualityResultAmountMultiplier, new ConfigDescription("Multiplies the crafted amount based on the quality of the resources when crafting " + englishName + ". Only works, if Require Only One Resource is true.", (AcceptableValueBase)null, new object[1] { qualityResultAttributes }));
							cfg.qualityResultAmountMultiplier.SettingChanged += delegate
							{
								if (activeRecipes.ContainsKey(item3) && activeRecipes[item3].TryGetValue(configKey, out var value4))
								{
									foreach (Recipe item7 in value4)
									{
										item7.m_qualityResultAmountMultiplier = cfg.qualityResultAmountMultiplier.Value;
									}
								}
							};
							if ((!item3.Recipes[configKey].RequiredItems.Free || item3.Recipes[configKey].RequiredItems.Requirements.Count > 0) && item3.Recipes[configKey].RequiredItems.Requirements.All((Requirement r) => r.amountConfig == null))
							{
								cfg.craft = itemConfig("Crafting Costs" + text, new SerializedRequirements(item3.Recipes[configKey].RequiredItems.Requirements).ToString(), "Item costs to craft " + englishName, isUpgrade: false);
							}
							if (item3.Prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_maxQuality > 1 && (!item3.Recipes[configKey].RequiredUpgradeItems.Free || item3.Recipes[configKey].RequiredUpgradeItems.Requirements.Count > 0) && item3.Recipes[configKey].RequiredUpgradeItems.Requirements.All((Requirement r) => r.amountConfig == null))
							{
								cfg.upgrade = itemConfig("Upgrading Costs" + text, new SerializedRequirements(item3.Recipes[configKey].RequiredUpgradeItems.Requirements).ToString(), "Item costs per level to upgrade " + englishName, isUpgrade: true);
							}
							if (cfg.craft != null)
							{
								cfg.craft.SettingChanged += ConfigChanged;
							}
							if (cfg.upgrade != null)
							{
								cfg.upgrade.SettingChanged += ConfigChanged;
							}
							void ConfigChanged(object o, EventArgs e)
							{
								item3.UpdateCraftConfig(configKey, new SerializedRequirements(cfg.craft?.Value ?? ""), new SerializedRequirements(cfg.upgrade?.Value ?? ""));
							}
							bool CustomTableBrowsability()
							{
								return cfg.table.Value == CraftingTable.Custom;
							}
							bool ItemBrowsability()
							{
								return cfg.table.Value != CraftingTable.Disabled;
							}
							bool QualityResultBrowsability()
							{
								return cfg.requireOneIngredient.Value == Toggle.On;
							}
							void TableConfigChanged(object o, EventArgs e)
							{
								item3.UpdateItemTableConfig(configKey, cfg.table.Value, cfg.customTable.Value);
								customTableAttributes.Browsable = cfg.table.Value == CraftingTable.Custom;
								foreach (ConfigurationManagerAttributes item8 in hideWhenNoneAttributes)
								{
									item8.Browsable = cfg.table.Value != CraftingTable.Disabled;
								}
								reloadConfigDisplay();
							}
							bool TableLevelBrowsability()
							{
								return cfg.table.Value != CraftingTable.Disabled;
							}
							ConfigEntry<string> itemConfig(string name, string value, string desc, bool isUpgrade)
							{
								//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
								//IL_00b1: Expected O, but got Unknown
								ConfigurationManagerAttributes configurationManagerAttributes3 = new ConfigurationManagerAttributes
								{
									CustomDrawer = drawRequirementsConfigTable(item3, isUpgrade),
									Order = (order -= 1),
									browsability = ItemBrowsability,
									Browsable = (ItemBrowsability() && (item3.configurationVisible & Configurability.Recipe) != 0),
									Category = localizedName
								};
								hideWhenNoneAttributes.Add(configurationManagerAttributes3);
								return config(englishName, name, value, new ConfigDescription(desc, (AcceptableValueBase)null, new object[1] { configurationManagerAttributes3 }));
							}
						}
						if ((item3.configurability & Configurability.Drop) != 0)
						{
							ConfigEntry<string> val3 = (itemDropConfigs[item3] = config(englishName, "Drops from", new SerializedDrop(item3.DropsFrom.Drops).ToString(), new ConfigDescription(englishName + " drops from this creature.", (AcceptableValueBase)null, new object[1]
							{
								new ConfigurationManagerAttributes
								{
									CustomDrawer = drawDropsConfigTable,
									Category = localizedName,
									Browsable = ((item3.configurationVisible & Configurability.Drop) != 0)
								}
							})));
							ConfigEntry<string> val4 = val3;
							val4.SettingChanged += delegate
							{
								item3.UpdateCharacterDrop();
							};
						}
						for (int j = 0; j < item3.Conversions.Count; j++)
						{
							string text2 = ((item3.Conversions.Count > 1) ? $"{j + 1}. " : "");
							Conversion conversion = item3.Conversions[j];
							conversion.config = new Conversion.ConversionConfig();
							int index = j;
							conversion.config.input = config(englishName, text2 + "Conversion Input Item", conversion.Input, new ConfigDescription("Input item to create " + englishName, (AcceptableValueBase)null, new object[1]
							{
								new ConfigurationManagerAttributes
								{
									Category = localizedName,
									Browsable = ((item3.configurationVisible & Configurability.Recipe) != 0)
								}
							}));
							conversion.config.input.SettingChanged += delegate
							{
								if (index < item3.conversions.Count)
								{
									ObjectDB instance = ObjectDB.instance;
									if (instance != null)
									{
										ItemDrop from = SerializedRequirements.fetchByName(instance, conversion.config.input.Value);
										item3.conversions[index].m_from = from;
										UpdatePiece();
									}
								}
							};
							conversion.config.piece = config(englishName, text2 + "Conversion Piece", conversion.Piece, new ConfigDescription("Conversion piece used to create " + englishName, (AcceptableValueBase)null, new object[1]
							{
								new ConfigurationManagerAttributes
								{
									Category = localizedName,
									Browsable = ((item3.configurationVisible & Configurability.Recipe) != 0)
								}
							}));
							conversion.config.piece.SettingChanged += delegate
							{
								UpdatePiece();
							};
							conversion.config.customPiece = config(englishName, text2 + "Conversion Custom Piece", conversion.customPiece ?? "", new ConfigDescription("Custom conversion piece to create " + englishName, (AcceptableValueBase)null, new object[1]
							{
								new ConfigurationManagerAttributes
								{
									Category = localizedName,
									Browsable = ((item3.configurationVisible & Configurability.Recipe) != 0)
								}
							}));
							conversion.config.customPiece.SettingChanged += delegate
							{
								UpdatePiece();
							};
							void UpdatePiece()
							{
								if (index < item3.conversions.Count && Object.op_Implicit((Object)(object)ZNetScene.instance))
								{
									string text3 = ((conversion.config.piece.Value == ConversionPiece.Disabled) ? null : ((conversion.config.piece.Value == ConversionPiece.Custom) ? conversion.config.customPiece.Value : getInternalName(conversion.config.piece.Value)));
									string activePiece = conversion.config.activePiece;
									if (conversion.config.activePiece != null)
									{
										Smelter component = ZNetScene.instance.GetPrefab(conversion.config.activePiece).GetComponent<Smelter>();
										int num = component.m_conversion.IndexOf(item3.conversions[index]);
										if (num >= 0)
										{
											Smelter[] array3 = Resources.FindObjectsOfTypeAll<Smelter>();
											foreach (Smelter val6 in array3)
											{
												if (Utils.GetPrefabName(((Component)val6).gameObject) == activePiece)
												{
													val6.m_conversion.RemoveAt(num);
												}
											}
										}
										conversion.config.activePiece = null;
									}
									if (item3.conversions[index].m_from != null && conversion.config.piece.Value != 0)
									{
										GameObject prefab = ZNetScene.instance.GetPrefab(text3);
										if (((prefab != null) ? prefab.GetComponent<Smelter>() : null) != null)
										{
											conversion.config.activePiece = text3;
											Smelter[] array4 = Resources.FindObjectsOfTypeAll<Smelter>();
											foreach (Smelter val7 in array4)
											{
												if (Utils.GetPrefabName(((Component)val7).gameObject) == text3)
												{
													val7.m_conversion.Add(item3.conversions[index]);
												}
											}
										}
									}
								}
							}
						}
					}
					if ((item3.configurability & Configurability.Stats) != 0)
					{
						item3.statsConfigs.Clear();
						SharedData shared2 = item3.Prefab.GetComponent<ItemDrop>().m_itemData.m_shared;
						ItemType itemType = shared2.m_itemType;
						statcfg<float>("Weight", "Weight of " + englishName + ".", (SharedData shared) => shared.m_weight, delegate(SharedData shared, float value)
						{
							shared.m_weight = value;
						});
						statcfg<int>("Trader Value", "Trader value of " + englishName + ".", (SharedData shared) => shared.m_value, delegate(SharedData shared, int value)
						{
							shared.m_value = value;
						});
						bool flag;
						switch (itemType - 3)
						{
						case 0:
						case 1:
						case 2:
						case 3:
						case 4:
						case 8:
						case 9:
						case 11:
						case 14:
						case 16:
						case 19:
							flag = true;
							break;
						default:
							flag = false;
							break;
						}
						if (flag)
						{
							statcfg<float>("Durability", "Durability of " + englishName + ".", (SharedData shared) => shared.m_maxDurability, delegate(SharedData shared, float value)
							{
								shared.m_maxDurability = value;
							});
							statcfg<float>("Durability per Level", "Durability gain per level of " + englishName + ".", (SharedData shared) => shared.m_durabilityPerLevel, delegate(SharedData shared, float value)
							{
								shared.m_durabilityPerLevel = value;
							});
							statcfg<float>("Movement Speed Modifier", "Movement speed modifier of " + englishName + ".", (SharedData shared) => shared.m_movementModifier, delegate(SharedData shared, float value)
							{
								shared.m_movementModifier = value;
							});
						}
						if ((itemType - 3 <= 2 || (int)itemType == 14 || (int)itemType == 22) ? true : false)
						{
							statcfg<float>("Block Armor", "Block armor of " + englishName + ".", (SharedData shared) => shared.m_blockPower, delegate(SharedData shared, float value)
							{
								shared.m_blockPower = value;
							});
							statcfg<float>("Block Armor per Level", "Block armor per level for " + englishName + ".", (SharedData shared) => shared.m_blockPowerPerLevel, delegate(SharedData shared, float value)
							{
								shared.m_blockPowerPerLevel = value;
							});
							statcfg<float>("Block Force", "Block force of " + englishName + ".", (SharedData shared) => shared.m_deflectionForce, delegate(SharedData shared, float value)
							{
								shared.m_deflectionForce = value;
							});
							statcfg<float>("Block Force per Level", "Block force per level for " + englishName + ".", (SharedData shared) => shared.m_deflectionForcePerLevel, delegate(SharedData shared, float value)
							{
								shared.m_deflectionForcePerLevel = value;
							});
							statcfg<float>("Parry Bonus", "Parry bonus of " + englishName + ".", (SharedData shared) => shared.m_timedBlockBonus, delegate(SharedData shared, float value)
							{
								shared.m_timedBlockBonus = value;
							});
						}
						else if ((itemType - 6 <= 1 || itemType - 11 <= 1 || (int)itemType == 17) ? true : false)
						{
							statcfg<float>("Armor", "Armor of " + englishName + ".", (SharedData shared) => shared.m_armor, delegate(SharedData shared, float value)
							{
								shared.m_armor = value;
							});
							statcfg<float>("Armor per Level", "Armor per level for " + englishName + ".", (SharedData shared) => shared.m_armorPerLevel, delegate(SharedData shared, float value)
							{
								shared.m_armorPerLevel = value;
							});
						}
						SkillType skillType = shared2.m_skillType;
						if (((int)skillType == 7 || (int)skillType == 12) ? true : false)
						{
							statcfg<int>("Tool tier", "Tool tier of " + englishName + ".", (SharedData shared) => shared.m_toolTier, delegate(SharedData shared, int value)
							{
								shared.m_toolTier = value;
							});
						}
						if ((itemType - 5 <= 2 || itemType - 11 <= 1 || (int)itemType == 17) ? true : false)
						{
							Dictionary<DamageType, DamageModifier> modifiers = shared2.m_damageModifiers.ToDictionary((DamageModPair d) => d.m_type, (DamageModPair d) => (DamageModifier)d.m_modifier);
							DamageType[] first = (DamageType[])Enum.GetValues(typeof(DamageType));
							DamageType[] array = new DamageType[5];
							RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
							foreach (DamageType item9 in first.Except((IEnumerable<DamageType>)(object)array))
							{
								DamageType damageType = item9;
								statcfg<DamageModifier>(((object)(DamageType)(ref damageType)).ToString() + " Resistance", ((object)(DamageType)(ref damageType)).ToString() + " resistance of " + englishName + ".", (SharedData _) => (!modifiers.TryGetValue(damageType, out var value3)) ? DamageModifier.None : value3, delegate(SharedData shared, DamageModifier value)
								{
									//IL_0002: 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_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_001e: 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_002f: 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_0077: 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)
									DamageModPair val8 = default(DamageModPair);
									val8.m_type = damageType;
									val8.m_modifier = (DamageModifier)value;
									DamageModPair val9 = val8;
									for (int num2 = 0; num2 < shared.m_damageModifiers.Count; num2++)
									{
										if (shared.m_damageModifiers[num2].m_type == damageType)
										{
											if (value == DamageModifier.None)
											{
												shared.m_damageModifiers.RemoveAt(num2);
											}
											else
											{
												shared.m_damageModifiers[num2] = val9;
											}
											return;
										}
									}
									if (value != DamageModifier.None)
									{
										shared.m_damageModifiers.Add(val9);
									}
								});
							}
						}
						if ((int)itemType == 2 && shared2.m_food > 0f)
						{
							statcfg<float>("Health", "Health value of " + englishName + ".", (SharedData shared) => shared.m_food, delegate(SharedData shared, float value)
							{
								shared.m_food = value;
							});
							statcfg<float>("Stamina", "Stamina value of " + englishName + ".", (SharedData shared) => shared.m_foodStamina, delegate(SharedData shared, float value)
							{
								shared.m_foodStamina = value;
							});
							statcfg<float>("Eitr", "Eitr value of " + englishName + ".", (SharedData shared) => shared.m_foodEitr, delegate(SharedData shared, float value)
							{
								shared.m_foodEitr = value;
							});
							statcfg<float>("Duration", "Duration of " + englishName + ".", (SharedData shared) => shared.m_foodBurnTime, delegate(SharedData shared, float value)
							{
								shared.m_foodBurnTime = value;
							});
							statcfg<float>("Health Regen", "Health regen value of " + englishName + ".", (SharedData shared) => shared.m_foodRegen, delegate(SharedData shared, float value)
							{
								shared.m_foodRegen = value;
							});
						}
						if ((int)shared2.m_skillType == 10)
						{
							statcfg<float>("Health Cost", "Health cost of " + englishName + ".", (SharedData shared) => shared.m_attack.m_attackHealth, delegate(SharedData shared, float value)
							{
								shared.m_attack.m_attackHealth = value;
							});
							statcfg<float>("Health Cost Percentage", "Health cost percentage of " + englishName + ".", (SharedData shared) => shared.m_attack.m_attackHealthPercentage, delegate(SharedData shared, float value)
							{
								shared.m_attack.m_attackHealthPercentage = value;
							});
						}
						skillType = shared2.m_skillType;
						if (skillType - 9 <= 1)
						{
							statcfg<float>("Eitr Cost", "Eitr cost of " + englishName + ".", (SharedData shared) => shared.m_attack.m_attackEitr, delegate(SharedData shared, float value)
							{
								shared.m_attack.m_attackEitr = value;
							});
						}
						if ((itemType - 3 <= 1 || (int)itemType == 14 || (int)itemType == 22) ? true : false)
						{
							statcfg<float>("Knockback", "Knockback of " + englishName + ".", (SharedData shared) => shared.m_attackForce, delegate(SharedData shared, float value)
							{
								shared.m_attackForce = value;
							});
							statcfg<float>("Backstab Bonus", "Backstab bonus of " + englishName + ".", (SharedData shared) => shared.m_backstabBonus, delegate(SharedData shared, float value)
							{
								shared.m_backstabBonus = value;
							});
							statcfg<float>("Attack Stamina", "Attack stamina of " + englishName + ".", (SharedData shared) => shared.m_attack.m_attackStamina, delegate(SharedData shared, float value)
							{
								shared.m_attack.m_attackStamina = value;
							});
							SetDmg("True", (DamageTypes dmg) => dmg.m_damage, delegate(ref DamageTypes dmg, float val)
							{
								dmg.m_damage = val;
							});
							SetDmg("Slash", (DamageTypes dmg) => dmg.m_slash, delegate(ref DamageTypes dmg, float val)
							{
								dmg.m_slash = val;
							});
							SetDmg("Pierce", (DamageTypes dmg) => dmg.m_pierce, delegate(ref DamageTypes dmg, float val)
							{
								dmg.m_pierce = val;
							});
							SetDmg("Blunt", (DamageTypes dmg) => dmg.m_blunt, delegate(ref DamageTypes dmg, float val)
							{
								dmg.m_blunt = val;
							});
							SetDmg("Chop", (DamageTypes dmg) => dmg.m_chop, delegate(ref DamageTypes dmg, float val)
							{
								dmg.m_chop = val;
							});
							SetDmg("Pickaxe", (DamageTypes dmg) => dmg.m_pickaxe, delegate(ref DamageTypes dmg, float val)
							{
								dmg.m_pickaxe = val;
							});
							SetDmg("Fire", (DamageTypes dmg) => dmg.m_fire, delegate(ref DamageTypes dmg, float val)
							{
								dmg.m_fire = val;
							});
							SetDmg("Poison", (DamageTypes dmg) => dmg.m_poison, delegate(ref DamageTypes dmg, float val)
							{
								dmg.m_poison = val;
							});
							SetDmg("Frost", (DamageTypes dmg) => dmg.m_frost, delegate(ref DamageTypes dmg, float val)
							{
								dmg.m_frost = val;
							});
							SetDmg("Lightning", (DamageTypes dmg) => dmg.m_lightning, delegate(ref DamageTypes dmg, float val)
							{
								dmg.m_lightning = val;
							});
							SetDmg("Spirit", (DamageTypes dmg) => dmg.m_spirit, delegate(ref DamageTypes dmg, float val)
							{
								dmg.m_spirit = val;
							});
							if ((int)itemType == 4)
							{
								statcfg<int>("Projectiles", "Number of projectiles that " + englishName + " shoots at once.", (SharedData shared) => shared.m_attack.m_projectileBursts, delegate(SharedData shared, int value)
								{
									shared.m_attack.m_projectileBursts = value;
								});
								statcfg<float>("Burst Interval", "Time between the projectiles " + englishName + " shoots at once.", (SharedData shared) => shared.m_attack.m_burstInterval, delegate(SharedData shared, float value)
								{
									shared.m_attack.m_burstInterval = value;
								});
								statcfg<float>("Minimum Accuracy", "Minimum accuracy for " + englishName + ".", (SharedData shared) => shared.m_attack.m_projectileAccuracyMin, delegate(SharedData shared, float value)
								{
									shared.m_attack.m_projectileAccuracyMin = value;
								});
								statcfg<float>("Accuracy", "Accuracy for " + englishName + ".", (SharedData shared) => shared.m_attack.m_projectileAccuracy, delegate(SharedData shared, float value)
								{
									shared.m_attack.m_projectileAccuracy = value;
								});
								statcfg<float>("Minimum Velocity", "Minimum velocity for " + englishName + ".", (SharedData shared) => shared.m_attack.m_projectileVelMin, delegate(SharedData shared, float value)
								{
									shared.m_attack.m_projectileVelMin = value;
								});
								statcfg<float>("Velocity", "Velocity for " + englishName + ".", (SharedData shared) => shared.m_attack.m_projectileVel, delegate(SharedData shared, float value)
								{
									shared.m_attack.m_projectileVel = value;
								});
								statcfg<float>("Maximum Draw Time", "Time until " + englishName + " is fully drawn at skill level 0.", (SharedData shared) => shared.m_attack.m_drawDurationMin, delegate(SharedData shared, float value)
								{
									shared.m_attack.m_drawDurationMin = value;
								});
								statcfg<float>("Stamina Drain", "Stamina drain per second while drawing " + englishName + ".", (SharedData shared) => shared.m_attack.m_drawStaminaDrain, delegate(SharedData shared, float value)
								{
									shared.m_attack.m_drawStaminaDrain = value;
								});
							}
						}
					}
					List<ConfigurationManagerAttributes> traderAttributes;
					if ((item3.configurability & Configurability.Trader) != 0)
					{
						traderAttributes = new List<ConfigurationManagerAttributes>();
						item3.traderConfig = new TraderConfig
						{
							trader = config(englishName, "Trader Selling", item3.Trade.Trader, new ConfigDescription("Which traders sell " + englishName + ".", (AcceptableValueBase)null, new object[1]
							{
								new ConfigurationManagerAttributes
								{
									Order = (order -= 1),
									Browsable = ((item3.configurationVisible & Configurability.Trader) != 0),
									Category = localizedName
								}
							}))
						};
						item3.traderConfig.trader.SettingChanged += delegate
						{
							item3.ReloadTraderConfiguration();
							foreach (ConfigurationManagerAttributes item10 in traderAttributes)
							{
								item10.Browsable = TraderBrowsability();
							}
							reloadConfigDisplay();
						};
						item3.traderConfig.price = traderConfig<uint>("Trader Price", item3.Trade.Price, "Price of " + englishName + " at the trader.");
						item3.traderConfig.stack = traderConfig<uint>("Trader Stack", item3.Trade.Stack, "Stack size of " + englishName + " in the trader. Also known as the number of items sold by a trader in one transaction.");
						item3.traderConfig.requiredGlobalKey = traderConfig<string>("Trader Required Global Key", item3.Trade.RequiredGlobalKey ?? "", "Required global key to unlock " + englishName + " at the trader.");
						if (item3.traderConfig.trader.Value != 0)
						{
							PrefabManager.AddItemToTrader(item3.Prefab, item3.traderConfig.trader.Value, item3.traderConfig.price.Value, item3.traderConfig.stack.Value, item3.traderConfig.requiredGlobalKey.Value);
						}
					}
					else if (item3.Trade.Trader != 0)
					{
						PrefabManager.AddItemToTrader(item3.Prefab, item3.Trade.Trader, item3.Trade.Price, item3.Trade.Stack, item3.Trade.RequiredGlobalKey);
					}
					void SetDmg(string dmgType, Func<DamageTypes, float> readDmg, setDmgFunc setDmg)
					{
						statcfg<float>(dmgType + " Damage", dmgType + " damage dealt by " + englishName + ".", (SharedData shared) => readDmg(shared.m_damages), delegate(SharedData shared, float val)
						{
							setDmg(ref shared.m_damages, val);
						});
						statcfg<float>(dmgType + " Damage Per Level", dmgType + " damage dealt increase per level for " + englishName + ".", (SharedData shared) => readDmg(shared.m_damagesPerLevel), delegate(SharedData shared, float val)
						{
							setDmg(ref shared.m_damagesPerLevel, val);
						});
					}
					bool TraderBrowsability()
					{
						return item3.traderConfig.trader.Value != Trader.None;
					}
					void statcfg<T>(string configName, string description, Func<SharedData, T> readDefault, Action<SharedData, T> setValue)
					{
						//IL_0078: Unknown result type (might be due to invalid IL or missing references)
						//IL_0082: Expected O, but got Unknown
						SharedData shared3 = item3.Prefab.GetComponent<ItemDrop>().m_itemData.m_shared;
						ConfigEntry<T> cfg2 = config(englishName, configName, readDefault(shared3), new ConfigDescription(description, (AcceptableValueBase)null, new object[1]
						{
							new ConfigurationManagerAttributes
							{
								Category = localizedName,
								Browsable = ((item3.configurationVisible & Configurability.Stats) != 0)
							}
						}));
						if ((item3.configurationVisible & Configurability.Stats) != 0)
						{
							setValue(shared3, cfg2.Value);
						}
						item3.statsConfigs.Add((ConfigEntryBase)(object)cfg2, ApplyConfig);
						cfg2.SettingChanged += delegate
						{
							if ((item3.configurationVisible & Configurability.Stats) != 0)
							{
								ApplyConfig();
							}
						};
						void ApplyConfig()
						{
							item3.ApplyToAllInstances(delegate(ItemData item)
							{
								setValue(item.m_shared, cfg2.Value);
							});
						}
					}
					ConfigEntry<T> traderConfig<T>(string name, T value, string desc)
					{
						//IL_0099: Unknown result type (might be due to invalid IL or missing references)
						//IL_00a3: Expected O, but got Unknown
						ConfigurationManagerAttributes configurationManagerAttributes2 = new ConfigurationManagerAttributes
						{
							Order = (order -= 1),
							browsability = TraderBrowsability,
							Browsable = (TraderBrowsability() && (item3.configurationVisible & Configurability.Trader) != 0),
							Category = localizedName
						};
						traderAttributes.Add(configurationManagerAttributes2);
						ConfigEntry<T> val5 = config(englishName, name, value, new ConfigDescription(desc, (AcceptableValueBase)null, new object[1] { configurationManagerAttributes2 }));
						val5.SettingChanged += delegate
						{
							item3.ReloadTraderConfiguration();
						};
						return val5;
					}
				}
				if (saveOnConfigSet)
				{
					plugin.Config.SaveOnConfigSet = true;
					plugin.Config.Save();
				}
			}
			configManager = ((type == null) ? null : Chainloader.ManagerObject.GetComponent(type));
			foreach (Item registeredItem in registeredItems)
			{
				Item item2 = registeredItem;
				foreach (KeyValuePair<string, ItemRecipe> recipe in item2.Recipes)
				{
					KeyValuePair<string, ItemRecipe> kv = recipe;
					RequiredResourceList[] array2 = new RequiredResourceList[2]
					{
						kv.Value.RequiredItems,
						kv.Value.RequiredUpgradeItems
					};
					foreach (RequiredResourceList requiredResourceList in array2)
					{
						for (int l = 0; l < requiredResourceList.Requirements.Count; l++)
						{
							ConfigEntry<int> amountCfg;
							int resourceIndex;
							if ((item2.configurability & Configurability.Recipe) != 0)
							{
								amountCfg = requiredResourceList.Requirements[l].amountConfig;
								if (amountCfg != null)
								{
									resourceIndex = l;
									amountCfg.SettingChanged += ConfigChanged;
								}
							}
							void ConfigChanged(object o, EventArgs e)
							{
								if (Object.op_Implicit((Object)(object)ObjectDB.instance) && activeRecipes.ContainsKey(item2) && activeRecipes[item2].TryGetValue(kv.Key, out var value2))
								{
									foreach (Recipe item11 in value2)
									{
										item11.m_resources[resourceIndex].m_amount = amountCfg.Value;
									}
								}
							}
						}
					}
				}
				item2.InitializeNewRegisteredItem();
			}
		}

		private void InitializeNewRegisteredItem()
		{
			foreach (KeyValuePair<string, ItemRecipe> recipe in Recipes)
			{
				KeyValuePair<string, ItemRecipe> kv = recipe;
				ConfigEntryBase enabledCfg = kv.Value.RecipeIsActive;
				if (enabledCfg != null)
				{
					((object)enabledCfg).GetType().GetEvent("SettingChanged").AddEventHandler(enabledCfg, new EventHandler(ConfigChanged));
				}
				void ConfigChanged(object o, EventArgs e)
				{
					if (Object.op_Implicit((Object)(object)ObjectDB.instance) && activeRecipes.ContainsKey(this) && activeRecipes[this].TryGetValue(kv.Key, out var value))
					{
						foreach (Recipe item in value)
						{
							item.m_enabled = (int)enabledCfg.BoxedValue != 0;
						}
					}
				}
			}
		}

		public void ReloadCraftingConfiguration()
		{
			if (Object.op_Implicit((Object)(object)ObjectDB.instance) && ObjectDB.instance.GetItemPrefab(StringExtensionMethods.GetStableHashCode(((Object)Prefab).name)) == null)
			{
				registerRecipesInObjectDB(ObjectDB.instance);
				ObjectDB.instance.m_items.Add(Prefab);
				ObjectDB.instance.m_itemByHash.Add(StringExtensionMethods.GetStableHashCode(((Object)Prefab).name), Prefab);
				ZNetScene.instance.m_prefabs.Add(Prefab);
				ZNetScene.instance.m_namedPrefabs.Add(StringExtensionMethods.GetStableHashCode(((Object)Prefab).name), Prefab);
			}
			foreach (string item in Recipes.Keys.DefaultIfEmpty(""))
			{
				if (Recipes.TryGetValue(item, out var value) && value.Crafting.Stations.Count > 0)
				{
					UpdateItemTableConfig(item, value.Crafting.Stations.First().Table, value.Crafting.Stations.First().custom ?? "");
					UpdateCraftConfig(item, new SerializedRequirements(value.RequiredItems.Requirements), new SerializedRequirements(value.RequiredUpgradeItems.Requirements));
				}
			}
		}

		private void ReloadTraderConfiguration()
		{
			if (traderConfig.trader.Value == Trader.None)
			{
				PrefabManager.RemoveItemFromTrader(Prefab);
			}
			else
			{
				PrefabManager.AddItemToTrader(Prefab, traderConfig.trader.Value, traderConfig.price.Value, traderConfig.stack.Value, traderConfig.requiredGlobalKey.Value);
			}
		}

		public static void ApplyToAllInstances(GameObject prefab, Action<ItemData> callback)
		{
			callback(prefab.GetComponent<ItemDrop>().m_itemData);
			string name = prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_name;
			Inventory[] source = (from c in Player.s_players.Select((Player p) => ((Humanoid)p).GetInventory()).Concat(from c in Object.FindObjectsOfType<Container>()
					select c.GetInventory())
				where c != null
				select c).ToArray();
			foreach (ItemData item in (from i in (from p in ObjectDB.instance.m_items
					select p.GetComponent<ItemDrop>() into c
					where Object.op_Implicit((Object)(object)c) && Object.op_Implicit((Object)(object)((Component)c).GetComponent<ZNetView>())
					select c).Concat(ItemDrop.s_instances)
				select i.m_itemData).Concat(source.SelectMany((Inventory i) => i.GetAllItems())))
			{
				if (item.m_shared.m_name == name)
				{
					callback(item);
				}
			}
		}

		public void ApplyToAllInstances(Action<ItemData> callback)
		{
			ApplyToAllInstances(Prefab, callback);
		}

		private static string getInternalName<T>(T value) where T : struct
		{
			return ((InternalName)typeof(T).GetMember(value.ToString())[0].GetCustomAttributes(typeof(InternalName)).First()).internalName;
		}

		private void registerRecipesInObjectDB(ObjectDB objectDB)
		{
			//IL_044e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0453: Unknown result type (might be due to invalid IL or missing references)
			//IL_0486: Unknown result type (might be due to invalid IL or missing references)
			//IL_049c: Expected O, but got Unknown
			activeRecipes[this] = new Dictionary<string, List<Recipe>>();
			itemCraftConfigs.TryGetValue(this, out var value);
			foreach (KeyValuePair<string, ItemRecipe> recipe in Recipes)
			{
				List<Recipe> list = new List<Recipe>();
				foreach (CraftingStationConfig station in recipe.Value.Crafting.Stations)
				{
					ItemConfig itemConfig = value?[recipe.Key];
					Recipe val = ScriptableObject.CreateInstance<Recipe>();
					string name = ((Object)Prefab).name;
					CraftingTable table = station.Table;
					((Object)val).name = name + "_Recipe_" + table;
					val.m_amount = recipe.Value.CraftAmount;
					bool enabled;
					if (itemConfig != null)
					{
						enabled = itemConfig.table.Value != CraftingTable.Disabled;
					}
					else
					{
						ConfigEntryBase recipeIsActive = recipe.Value.RecipeIsActive;
						enabled = (int)(((recipeIsActive != null) ? recipeIsActive.BoxedValue : null) ?? ((object)1)) != 0;
					}
					val.m_enabled = enabled;
					val.m_item = Prefab.GetComponent<ItemDrop>();
					val.m_resources = SerializedRequirements.toPieceReqs(objectDB, (itemConfig?.craft == null) ? new SerializedRequirements(recipe.Value.RequiredItems.Requirements) : new SerializedRequirements(itemConfig.craft.Value), (itemConfig?.upgrade == null) ? new SerializedRequirements(recipe.Value.RequiredUpgradeItems.Requirements) : new SerializedRequirements(itemConfig.upgrade.Value));
					table = ((itemConfig == null || list.Count > 0) ? station.Table : itemConfig.table.Value);
					if ((uint)table <= 1u)
					{
						val.m_craftingSta

plugins/ChaosValheimEnchantmentSystem/YamlDotNet.dll

Decompiled 2 weeks 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("15.1.2.0")]
[assembly: AssemblyInformationalVersion("15.1.2")]
[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(".NETFramework,Version=v4.7", FrameworkDisplayName = ".NET Framework 4.7")]
[assembly: AssemblyVersion("15.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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 PropertyInfoExtensions
	{
		public static object? ReadValue(this PropertyInfo property, object target)
		{
			return property.GetValue(target, null);
		}
	}
	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)
		{
			BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public;
			if (allowPrivateConstructors)
			{
				bindingFlags |= BindingFlags.NonPublic;
			}
			if (!type.IsValueType)
			{
				return type.GetConstructor(bindingFlags, null, Type.EmptyTypes, null) != null;
			}
			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)
		{
			string name2 = name;
			return type.GetRuntimeMethods().FirstOrDefault((MethodInfo m) => !m.IsPublic && m.IsStatic && m.Name.Equals(name2)) ?? throw new MissingMethodException("Expected to find a method named '" + name2 + "' in '" + type.FullName + "'.");
		}

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

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

		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 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 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 INamingConvention enumNamingConvention = 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 WithEnumNamingConvention(INamingConvention enumNamingConvention)
		{
			this.enumNamingConvention = enumNamingConvention;
			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)
		{
			IYamlTypeConverter typeConverter2 = typeConverter;
			if (typeConverter2 == null)
			{
				throw new ArgumentNullException("typeConverter");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeConverterFactories.CreateRegistrationLocationSelector(typeConverter2.GetType(), (Nothing _) => typeConverter2));
			return Self;
		}

		public TBuilder WithTypeConverter<TYamlTypeConverter>(WrapperFactory<IYamlTypeConverter, IYamlTypeConverter> typeConverterFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IYamlTypeConverter>> where) where TYamlTypeConverter : IYamlTypeConverter
		{
			WrapperFactory<IYamlTypeConverter, IYamlTypeConverter> typeConverterFactory2 = typeConverterFactory;
			if (typeConverterFactory2 == null)
			{
				throw new ArgumentNullException("typeConverterFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeConverterFactories.CreateTrackingRegistrationLocationSelector(typeof(TYamlTypeConverter), (IYamlTypeConverter wrapped, Nothing _) => typeConverterFactory2(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
		{
			Func<ITypeInspector, TTypeInspector> typeInspectorFactory2 = typeInspectorFactory;
			if (typeInspectorFactory2 == null)
			{
				throw new ArgumentNullException("typeInspectorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeInspectorFactories.CreateRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector inner) => typeInspectorFactory2(inner)));
			return Self;
		}

		public TBuilder WithTypeInspector<TTypeInspector>(WrapperFactory<ITypeInspector, ITypeInspector, TTypeInspector> typeInspectorFactory, Action<ITrackingRegistrationLocationSelectionSyntax<ITypeInspector>> where) where TTypeInspector : ITypeInspector
		{
			WrapperFactory<ITypeInspector, ITypeInspector, TTypeInspector> typeInspectorFactory2 = typeInspectorFactory;
			if (typeInspectorFactory2 == null)
			{
				throw new ArgumentNullException("typeInspectorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeInspectorFactories.CreateTrackingRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector wrapped, ITypeInspector inner) => typeInspectorFactory2(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, enumNamingConvention)
				},
				{
					typeof(ArrayNodeDeserializer),
					(Nothing _) => new ArrayNodeDeserializer(enumNamingConvention)
				},
				{
					typeof(DictionaryNodeDeserializer),
					(Nothing _) => new DictionaryNodeDeserializer(objectFactory.Value, duplicateKeyChecking)
				},
				{
					typeof(CollectionNodeDeserializer),
					(Nothing _) => new CollectionNodeDeserializer(objectFactory.Value, enumNamingConvention)
				},
				{
					typeof(EnumerableNodeDeserializer),
					(Nothing _) => new EnumerableNodeDeserializer()
				},
				{
					typeof(ObjectNodeDeserializer),
					(Nothing _) => new ObjectNodeDeserializer(objectFactory.Value, BuildTypeInspector(), ignoreUnmatched, duplicateKeyChecking, typeConverter, enumNamingConvention)
				}
			};
			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)
		{
			IObjectFactory objectFactory2 = objectFactory;
			if (objectFactory2 == null)
			{
				throw new ArgumentNullException("objectFactory");
			}
			this.objectFactory = new Lazy<IObjectFactory>(() => objectFactory2, 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)
		{
			INodeDeserializer nodeDeserializer2 = nodeDeserializer;
			if (nodeDeserializer2 == null)
			{
				throw new ArgumentNullException("nodeDeserializer");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeDeserializerFactories.CreateRegistrationLocationSelector(nodeDeserializer2.GetType(), (Nothing _) => nodeDeserializer2));
			return this;
		}

		public DeserializerBuilder WithNodeDeserializer<TNodeDeserializer>(WrapperFactory<INodeDeserializer, TNodeDeserializer> nodeDeserializerFactory, Action<ITrackingRegistrationLocationSelectionSyntax<INodeDeserializer>> where) where TNodeDeserializer : INodeDeserializer
		{
			WrapperFactory<INodeDeserializer, TNodeDeserializer> nodeDeserializerFactory2 = nodeDeserializerFactory;
			if (nodeDeserializerFactory2 == null)
			{
				throw new ArgumentNullException("nodeDeserializerFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeDeserializerFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeDeserializer), (INodeDeserializer wrapped, Nothing _) => nodeDeserializerFactory2(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)
		{
			INodeTypeResolver nodeTypeResolver2 = nodeTypeResolver;
			if (nodeTypeResolver2 == null)
			{
				throw new ArgumentNullException("nodeTypeResolver");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeTypeResolverFactories.CreateRegistrationLocationSelector(nodeTypeResolver2.GetType(), (Nothing _) => nodeTypeResolver2));
			return this;
		}

		public DeserializerBuilder WithNodeTypeResolver<TNodeTypeResolver>(WrapperFactory<INodeTypeResolver, TNodeTypeResolver> nodeTypeResolverFactory, Action<ITrackingRegistrationLocationSelectionSyntax<INodeTypeResolver>> where) where TNodeTypeResolver : INodeTypeResolver
		{
			WrapperFactory<INodeTypeResolver, TNodeTypeResolver> nodeTypeResolverFactory2 = nodeTypeResolverFactory;
			if (nodeTypeResolverFactory2 == null)
			{
				throw new ArgumentNullException("nodeTypeResolverFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeTypeResolverFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeTypeResolver), (INodeTypeResolver wrapped, Nothing _) => nodeTypeResolverFactory2(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, enumNamingConvention));
		}
	}
	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);

		string Reverse(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)
		{
			Func<TComponent, TArgument> argumentBuilder2 = argumentBuilder;
			return registrations.InReverseOrder.Aggregate(innerComponent, (TComponent inner, Func<TArgument, TComponent> factory) => factory(argumentBuilder2(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)
		{
			TArgument argument2 = argument;
			return registrations.Select((Func<TArgument, TComponent> factory) => factory(argument2)).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)
			{
				IEmitter emitter2 = emitter;
				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, emitter2);
				void NestedObjectSerializer(object? v, Type? t)
				{
					SerializeValue(emitter2, 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, tagMappings, quoteNecessaryStrings, quoteYaml1_1Strings, defaultScalarStyle, yamlFormatter, enumNamingConvention)
			} };
			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
		{
			Func<IEventEmitter, TEventEmitter> eventEmitterFactory2 = eventEmitterFactory;
			if (eventEmitterFactory2 == null)
			{
				throw new ArgumentNullException("eventEmitterFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(eventEmitterFactories.CreateRegistrationLocationSelector(typeof(TEventEmitter), (IEventEmitter inner) => eventEmitterFactory2(inner)));
			return Self;
		}

		public SerializerBuilder WithEventEmitter<TEventEmitter>(WrapperFactory<IEventEmitter, IEventEmitter, TEventEmitter> eventEmitterFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IEventEmitter>> where) where TEventEmitter : IEventEmitter
		{
			WrapperFactory<IEventEmitter, IEventEmitter, TEventEmitter> eventEmitterFactory2 = eventEmitterFactory;
			if (eventEmitterFactory2 == null)
			{
				throw new ArgumentNullException("eventEmitterFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(eventEmitterFactories.CreateTrackingRegistrationLocationSelector(typeof(TEventEmitter), (IEventEmitter wrapped, IEventEmitter inner) => eventEmitterFactory2(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, tagMappings, quoteNecessaryStrings, quoteYaml1_1Strings, defaultScalarStyle, yamlFormatter, enumNamingConvention), 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, enumNamingConvention), 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>(Func<IEnumerable<IYamlTypeConverter>, TObjectGraphVisitor> objectGraphVisitorFactory) where TObjectGraphVisitor : IObjectGraphVisitor<Nothing>
		{
			return WithPreProcessingPhaseObjectGraphVisitor(objectGraphVisitorFactory, delegate(IRegistrationLocationSelectionSyntax<IObjectGraphVisitor<Nothing>> w)
			{
				w.OnTop();
			});
		}

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

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

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

		public SerializerBuilder WithPreProcessingPhaseObjectGraphVisitor<TObjectGraphVisitor>(WrapperFactory<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>, TObjectGraphVisitor> objectGraphVisitorFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IObjectGraphVisitor<Nothing>>> where) where TObjectGraphVisitor : IObjectGraphVisitor<Nothing>
		{
			WrapperFactory<IEnumerable<IYamlTypeConverter>, IObjectGraphVisitor<Nothing>, TObjectGraphVisitor> objectGraphVisitorFactory2 = objectGraphVisitorFactory;
			if (objectGraphVisitorFactory2 == null)
			{
				throw new ArgumentNullException("objectGraphVisitorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(preProcessingPhaseObjectGraphVisitorFactories.CreateTrackingRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IObjectGraphVisitor<Nothing> wrapped, IEnumerable<IYamlTypeConverter> typeConverters) => objectGraphVisitorFactory2(wrapped, typeConverters)));
			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>
		{
			Func<EmissionPhaseObjectGraphVisitorArgs, TObjectGraphVisitor> objectGraphVisitorFactory2 = objectGraphVisitorFactory;
			if (objectGraphVisitorFactory2 == null)
			{
				throw new ArgumentNullException("objectGraphVisitorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(emissionPhaseObjectGraphVisitorFactories.CreateRegistrationLocationSelector(typeof(TObjectGraphVisitor), (EmissionPhaseObjectGraphVisitorArgs args) => objectGraphVisitorFactory2(args)));
			return this;
		}

		public SerializerBuilder WithEmissionPhaseObjectGraphVisitor<TObjectGraphVisitor>(WrapperFactory<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>, TObjectGraphVisitor> objectGraphVisitorFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IObjectGraphVisitor<IEmitter>>> where) where TObjectGraphVisitor : IObjectGraphVisitor<IEmitter>
		{
			WrapperFactory<EmissionPhaseObjectGraphVisitorArgs, IObjectGraphVisitor<IEmitter>, TObjectGraphVisitor> objectGraphVisitorFactory2 = objectGraphVisitorFactory;
			if (objectGraphVisitorFactory2 == null)
			{
				throw new ArgumentNullException("objectGraphVisitorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(emissionPhaseObjectGraphVisitorFactories.CreateTrackingRegistrationLocationSelector(typeof(TObjectGraphVisitor), (IObjectGraphVisitor<IEmitter> wrapped, EmissionPhaseObjectGraphVisitorArgs args) => objectGraphVisitorFactory2(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 INamingConvention enumNamingConvention = 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 WithEnumNamingConvention(INamingConvention enumNamingConvention)
		{
			this.enumNamingConvention = enumNamingConvention ?? throw new ArgumentNullException("enumNamingConvention");
			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)
		{
			IYamlTypeConverter typeConverter2 = typeConverter;
			if (typeConverter2 == null)
			{
				throw new ArgumentNullException("typeConverter");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeConverterFactories.CreateRegistrationLocationSelector(typeConverter2.GetType(), (Nothing _) => typeConverter2));
			return Self;
		}

		public TBuilder WithTypeConverter<TYamlTypeConverter>(WrapperFactory<IYamlTypeConverter, IYamlTypeConverter> typeConverterFactory, Action<ITrackingRegistrationLocationSelectionSyntax<IYamlTypeConverter>> where) where TYamlTypeConverter : IYamlTypeConverter
		{
			WrapperFactory<IYamlTypeConverter, IYamlTypeConverter> typeConverterFactory2 = typeConverterFactory;
			if (typeConverterFactory2 == null)
			{
				throw new ArgumentNullException("typeConverterFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeConverterFactories.CreateTrackingRegistrationLocationSelector(typeof(TYamlTypeConverter), (IYamlTypeConverter wrapped, Nothing _) => typeConverterFactory2(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
		{
			Func<ITypeInspector, TTypeInspector> typeInspectorFactory2 = typeInspectorFactory;
			if (typeInspectorFactory2 == null)
			{
				throw new ArgumentNullException("typeInspectorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeInspectorFactories.CreateRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector inner) => typeInspectorFactory2(inner)));
			return Self;
		}

		public TBuilder WithTypeInspector<TTypeInspector>(WrapperFactory<ITypeInspector, ITypeInspector, TTypeInspector> typeInspectorFactory, Action<ITrackingRegistrationLocationSelectionSyntax<ITypeInspector>> where) where TTypeInspector : ITypeInspector
		{
			WrapperFactory<ITypeInspector, ITypeInspector, TTypeInspector> typeInspectorFactory2 = typeInspectorFactory;
			if (typeInspectorFactory2 == null)
			{
				throw new ArgumentNullException("typeInspectorFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(typeInspectorFactories.CreateTrackingRegistrationLocationSelector(typeof(TTypeInspector), (ITypeInspector wrapped, ITypeInspector inner) => typeInspectorFactory2(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, enumNamingConvention)
				},
				{
					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, enumNamingConvention)
				}
			};
			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)
		{
			INodeDeserializer nodeDeserializer2 = nodeDeserializer;
			if (nodeDeserializer2 == null)
			{
				throw new ArgumentNullException("nodeDeserializer");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeDeserializerFactories.CreateRegistrationLocationSelector(nodeDeserializer2.GetType(), (Nothing _) => nodeDeserializer2));
			return this;
		}

		public StaticDeserializerBuilder WithNodeDeserializer<TNodeDeserializer>(WrapperFactory<INodeDeserializer, TNodeDeserializer> nodeDeserializerFactory, Action<ITrackingRegistrationLocationSelectionSyntax<INodeDeserializer>> where) where TNodeDeserializer : INodeDeserializer
		{
			WrapperFactory<INodeDeserializer, TNodeDeserializer> nodeDeserializerFactory2 = nodeDeserializerFactory;
			if (nodeDeserializerFactory2 == null)
			{
				throw new ArgumentNullException("nodeDeserializerFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeDeserializerFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeDeserializer), (INodeDeserializer wrapped, Nothing _) => nodeDeserializerFactory2(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)
		{
			INodeTypeResolver nodeTypeResolver2 = nodeTypeResolver;
			if (nodeTypeResolver2 == null)
			{
				throw new ArgumentNullException("nodeTypeResolver");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeTypeResolverFactories.CreateRegistrationLocationSelector(nodeTypeResolver2.GetType(), (Nothing _) => nodeTypeResolver2));
			return this;
		}

		public StaticDeserializerBuilder WithNodeTypeResolver<TNodeTypeResolver>(WrapperFactory<INodeTypeResolver, TNodeTypeResolver> nodeTypeResolverFactory, Action<ITrackingRegistrationLocationSelectionSyntax<INodeTypeResolver>> where) where TNodeTypeResolver : INodeTypeResolver
		{
			WrapperFactory<INodeTypeResolver, TNodeTypeResolver> nodeTypeResolverFactory2 = nodeTypeResolverFactory;
			if (nodeTypeResolverFactory2 == null)
			{
				throw new ArgumentNullException("nodeTypeResolverFactory");
			}
			if (where == null)
			{
				throw new ArgumentNullException("where");
			}
			where(nodeTypeResolverFactories.CreateTrackingRegistrationLocationSelector(typeof(TNodeTypeResolver), (INodeTypeResolver wrapped, Nothing _) => nodeTypeResolverFactory2(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, enumNamingConvention));
		}
	}
	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)
			{
				IEmitter emitter2 = emitter;
				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, emitter2);
				void NestedObjectSerializer(object? v, Type? t)
				{
					SerializeValue(emitter2, 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, tagMappings, quoteNecessaryStrings, quoteYaml1_1Strings, defaultScalarStyle, yamlFormatter, enumNamingConvention)
			} };
			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(IRegistration