Decompiled source of Custom Car Mod v1.1.2

Distance.CustomCar.dll

Decompiled 4 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Distance.CustomCar.Data.Car;
using Distance.CustomCar.Data.Errors;
using Distance.CustomCar.Data.Materials;
using Events;
using Events.Car;
using Events.MainMenu;
using HarmonyLib;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Distance.ModTemplate")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Distance.ModTemplate")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("7bcb2908-b003-45d9-be68-50cba5217603")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
public static class GameObjectExtensions
{
	public static string FullName(this GameObject obj)
	{
		if (!Object.op_Implicit((Object)(object)obj.transform.parent))
		{
			return ((Object)obj).name;
		}
		return ((Component)obj.transform.parent).gameObject.FullName() + "/" + ((Object)obj).name;
	}
}
namespace Distance.CustomCar
{
	public class Assets
	{
		private string _filePath = null;

		private string RootDirectory { get; }

		private string FileName { get; set; }

		private string FilePath => _filePath ?? Path.Combine(Path.Combine(RootDirectory, "Assets"), FileName);

		public object Bundle { get; private set; }

		private Assets()
		{
		}

		public Assets(string fileName)
		{
			RootDirectory = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location);
			FileName = fileName;
			if (!File.Exists(FilePath))
			{
				Mod.Log.LogError((object)("Couldn't find requested asset bundle at " + FilePath));
			}
			else
			{
				Bundle = Load();
			}
		}

		public static Assets FromUnsafePath(string filePath)
		{
			if (!File.Exists(filePath))
			{
				Mod.Log.LogError((object)("Could not find requested asset bundle at " + filePath));
				return null;
			}
			Assets assets = new Assets
			{
				_filePath = filePath,
				FileName = Path.GetFileName(filePath)
			};
			assets.Bundle = assets.Load();
			if (assets.Bundle == null)
			{
				return null;
			}
			return assets;
		}

		private object Load()
		{
			try
			{
				object result = AssetBundleBridge.LoadFrom(FilePath);
				Mod.Log.LogInfo((object)("Loaded asset bundle " + FilePath));
				return result;
			}
			catch (Exception ex)
			{
				Mod.Log.LogInfo((object)ex);
				return null;
			}
		}
	}
	internal static class AssetBundleBridge
	{
		public static Type AssetBundleType => Kernel.FindTypeByFullName("UnityEngine.AssetBundle", "UnityEngine");

		private static MethodInfo LoadFromFile => AssetBundleType.GetMethod("LoadFromFile", new Type[1] { typeof(string) });

		public static object LoadFrom(string path)
		{
			MethodInfo loadFromFile = LoadFromFile;
			object[] parameters = new string[1] { path };
			return loadFromFile.Invoke(null, parameters);
		}
	}
	internal static class Kernel
	{
		internal static Type FindTypeByFullName(string fullName, string assemblyFilter)
		{
			IEnumerable<Assembly> enumerable = from a in AppDomain.CurrentDomain.GetAssemblies()
				where a.GetName().Name.Contains(assemblyFilter)
				select a;
			foreach (Assembly item in enumerable)
			{
				Type type = item.GetTypes().FirstOrDefault((Type t) => t.FullName == fullName);
				if ((object)type == null)
				{
					continue;
				}
				return type;
			}
			Mod.Log.LogError((object)("Type " + fullName + " wasn't found in the main AppDomain at this moment."));
			throw new Exception("Type " + fullName + " wasn't found in the main AppDomain at this moment.");
		}
	}
	public class FileSystem
	{
		public string RootDirectory { get; }

		public string VirtualFileSystemRoot => Path.Combine(RootDirectory, "Data");

		public FileSystem()
		{
			RootDirectory = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location);
			if (!Directory.Exists(VirtualFileSystemRoot))
			{
				Directory.CreateDirectory(VirtualFileSystemRoot);
			}
		}

		public bool FileExists(string path)
		{
			string path2 = Path.Combine(VirtualFileSystemRoot, path);
			return File.Exists(path2);
		}

		public bool DirectoryExists(string path)
		{
			string path2 = Path.Combine(VirtualFileSystemRoot, path);
			return Directory.Exists(path2);
		}

		public bool PathExists(string path)
		{
			return FileExists(path) || DirectoryExists(path);
		}

		public byte[] ReadAllBytes(string filePath)
		{
			string text = Path.Combine(VirtualFileSystemRoot, filePath);
			if (!File.Exists(text))
			{
				Mod.Log.LogInfo((object)("Couldn't read a file for path '" + text + "'. File does not exist."));
				return null;
			}
			return File.ReadAllBytes(text);
		}

		public FileStream CreateFile(string filePath, bool overwrite = false)
		{
			string text = Path.Combine(VirtualFileSystemRoot, filePath);
			if (File.Exists(text))
			{
				if (!overwrite)
				{
					Mod.Log.LogInfo((object)("Couldn't create a mod VFS file for path '" + text + "'. The file already exists."));
					return null;
				}
				Mod.Log.LogInfo((object)("Couldn't delete a mod VFS file for path '" + text + "'. File does not exist."));
				RemoveFile(filePath);
			}
			try
			{
				return File.Create(text);
			}
			catch (Exception ex)
			{
				Mod.Log.LogInfo((object)("Couldn't create a mod VFS file for path '" + text + "'."));
				Mod.Log.LogInfo((object)ex);
				return null;
			}
		}

		public void RemoveFile(string filePath)
		{
			string text = Path.Combine(VirtualFileSystemRoot, filePath);
			if (!File.Exists(text))
			{
				Mod.Log.LogInfo((object)("Couldn't delete a mod VFS file for path '" + text + "'. File does not exist."));
				return;
			}
			try
			{
				File.Delete(text);
			}
			catch (Exception ex)
			{
				Mod.Log.LogInfo((object)("Couldn't delete a mod VFS file for path '" + text + "'."));
				Mod.Log.LogInfo((object)ex);
			}
		}

		public void IterateOver(string directoryPath, Action<string, bool> action, bool sort = true)
		{
			string text = Path.Combine(VirtualFileSystemRoot, directoryPath);
			if (!Directory.Exists(text))
			{
				Mod.Log.LogInfo((object)("Cannot iterate over directory at '" + text + "'. It doesn't exist."));
				return;
			}
			List<string> list = Directory.GetFiles(text).ToList();
			list.AddRange(Directory.GetDirectories(text));
			if (sort)
			{
				list = list.OrderBy((string x) => x).ToList();
			}
			foreach (string item in list)
			{
				try
				{
					bool arg = Directory.Exists(item);
					action(item, arg);
				}
				catch (Exception ex)
				{
					Mod.Log.LogInfo((object)("Action for the element at path '" + item + "' failed. See file system exception log for details."));
					Mod.Log.LogInfo((object)ex);
					break;
				}
			}
		}

		public List<string> GetDirectories(string directoryPath, string searchPattern)
		{
			string text = Path.Combine(VirtualFileSystemRoot, directoryPath);
			if (!Directory.Exists(text))
			{
				Mod.Log.LogInfo((object)("Cannot get directories in directory at '" + text + "'. It doesn't exist."));
				return null;
			}
			return Directory.GetDirectories(text, searchPattern).ToList();
		}

		public List<string> GetDirectories(string directoryPath)
		{
			return GetDirectories(directoryPath, "*");
		}

		public List<string> GetFiles(string directoryPath, string searchPattern)
		{
			string text = Path.Combine(VirtualFileSystemRoot, directoryPath);
			if (!Directory.Exists(text))
			{
				Mod.Log.LogInfo((object)("Cannot get files in directory at '" + text + "'. It doesn't exist."));
				return null;
			}
			return Directory.GetFiles(text, searchPattern).ToList();
		}

		public List<string> GetFiles(string directoryPath)
		{
			return GetFiles(directoryPath, "*");
		}

		public FileStream OpenFile(string filePath, FileMode fileMode, FileAccess fileAccess, FileShare fileShare)
		{
			string text = Path.Combine(VirtualFileSystemRoot, filePath);
			if (!File.Exists(text))
			{
				Mod.Log.LogInfo((object)("Couldn't open a VFS file. The requested file: '" + text + "' does not exist."));
				return null;
			}
			try
			{
				return File.Open(text, fileMode, fileAccess, fileShare);
			}
			catch (Exception ex)
			{
				Mod.Log.LogInfo((object)("Couldn't open a VFS file for path '" + text + "'."));
				Mod.Log.LogInfo((object)ex);
				return null;
			}
		}

		public FileStream OpenFile(string filePath)
		{
			return OpenFile(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
		}

		public string CreateDirectory(string directoryName)
		{
			string text = Path.Combine(VirtualFileSystemRoot, directoryName);
			try
			{
				Directory.CreateDirectory(text);
				return text;
			}
			catch (Exception ex)
			{
				Mod.Log.LogInfo((object)("Couldn't create a VFS directory for path '" + text + "'."));
				Mod.Log.LogInfo((object)ex);
				return string.Empty;
			}
		}

		public void RemoveDirectory(string directoryPath)
		{
			string text = Path.Combine(VirtualFileSystemRoot, directoryPath);
			if (!Directory.Exists(text))
			{
				Mod.Log.LogInfo((object)("Couldn't remove a VFS directory for path '" + text + "'. Directory does not exist."));
				return;
			}
			try
			{
				Directory.Delete(text, recursive: true);
			}
			catch (Exception ex)
			{
				Mod.Log.LogInfo((object)("Couldn't remove a VFS directory for path '" + text + "'."));
				Mod.Log.LogInfo((object)ex);
			}
		}

		public static string GetValidFileName(string dirtyFileName, string replaceInvalidCharsWith = "_")
		{
			return Regex.Replace(dirtyFileName, "[^\\w\\s\\.]", replaceInvalidCharsWith, RegexOptions.None);
		}

		public static string GetValidFileNameToLower(string dirtyFileName, string replaceInvalidCharsWith = "_")
		{
			return GetValidFileName(dirtyFileName, replaceInvalidCharsWith).ToLower();
		}
	}
	public sealed class MessageBox
	{
		private readonly string Message = "";

		private readonly string Title = "";

		private float Time = 0f;

		private ButtonType Buttons = (ButtonType)0;

		private Action Confirm;

		private Action Cancel;

		private MessageBox(string message, string title)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			Message = message;
			Title = title;
			Confirm = EmptyAction;
			Cancel = EmptyAction;
		}

		public static MessageBox Create(string content, string title = "")
		{
			return new MessageBox(content, title);
		}

		public MessageBox SetButtons(MessageButtons buttons)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			Buttons = (ButtonType)buttons;
			return this;
		}

		public MessageBox SetTimeout(float delay)
		{
			Time = delay;
			return this;
		}

		public MessageBox OnConfirm(Action action)
		{
			Confirm = action;
			return this;
		}

		public MessageBox OnCancel(Action action)
		{
			Cancel = action;
			return this;
		}

		public void Show()
		{
			//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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_0042: Expected O, but got Unknown
			G.Sys.MenuPanelManager_.ShowMessage(Message, Title, (OnButtonClicked)delegate
			{
				Confirm();
			}, (OnButtonClicked)delegate
			{
				Cancel();
			}, Buttons, false, (Pivot)4, Time);
		}

		private void EmptyAction()
		{
		}
	}
	[Flags]
	public enum MessageButtons
	{
		Ok = 0,
		OkCancel = 1,
		YesNo = 2
	}
	[BepInPlugin("Distance.CustomCar", "Custom Car", "1.1.2")]
	public sealed class Mod : BaseUnityPlugin
	{
		private const string modGUID = "Distance.CustomCar";

		private const string modName = "Custom Car";

		private const string modVersion = "1.1.2";

		public static string UseTrumpetKey = "Use Trumpet Horn";

		private static readonly Harmony harmony = new Harmony("Distance.CustomCar");

		public static ManualLogSource Log = new ManualLogSource("Custom Car");

		public static Mod Instance;

		private bool displayErrors_ = true;

		public static ConfigEntry<bool> UseTrumpetHorn { get; set; }

		public static int DefaultCarCount { get; private set; }

		public static int ModdedCarCount => TotalCarCount - DefaultCarCount;

		public static int TotalCarCount { get; private set; }

		public ErrorList Errors { get; set; }

		public ProfileCarColors CarColors { get; set; }

		private void Awake()
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			Log = Logger.CreateLogSource("Distance.CustomCar");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Thanks for using Custom Cars!");
			Errors = new ErrorList(((BaseUnityPlugin)this).Logger);
			CarColors = ((Component)this).gameObject.AddComponent<ProfileCarColors>();
			UseTrumpetHorn = ((BaseUnityPlugin)this).Config.Bind<bool>("General", UseTrumpetKey, false, new ConfigDescription("Custom car models will use the encryptor horn (the \"doot!\" trumpet).", (AcceptableValueBase)null, new object[0]));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loading...");
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded!");
		}

		public void Start()
		{
			ProfileManager profileManager_ = G.Sys.ProfileManager_;
			DefaultCarCount = profileManager_.CarInfos_.Length;
			CarInfos carInfos = new CarInfos();
			carInfos.CollectInfos();
			CarBuilder carBuilder = new CarBuilder();
			carBuilder.CreateCars(carInfos);
			TotalCarCount = profileManager_.CarInfos_.Length;
			CarColors.LoadAll();
			Errors.Show();
		}

		private void OnEnable()
		{
			StaticEvent<Data>.Subscribe((Delegate<Data>)OnMainMenuLoaded);
		}

		private void OnDisable()
		{
			StaticEvent<Data>.Unsubscribe((Delegate<Data>)OnMainMenuLoaded);
		}

		private void OnMainMenuLoaded(Data _)
		{
			if (displayErrors_)
			{
				Errors.Show();
				displayErrors_ = false;
			}
		}

		private void OnConfigChanged(object sender, EventArgs e)
		{
			SettingChangedEventArgs val = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null);
			if (val != null)
			{
			}
		}
	}
	public class ProfileCarColors : MonoBehaviour
	{
		internal Settings Config;

		public event Action<ProfileCarColors> OnChanged;

		protected void Load()
		{
			Config = new Settings("CustomCars");
		}

		protected void Awake()
		{
			Load();
			Save();
		}

		protected Section Profile(string profileName)
		{
			return Config.GetOrCreate(profileName, new Section());
		}

		protected Section Vehicle(string profileName, string vehicleName)
		{
			return Profile(profileName).GetOrCreate(vehicleName, new Section());
		}

		protected CarColors GetCarColors(string profileName, string vehicleName)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_0038: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			Section vehicle = Vehicle(profileName, vehicleName);
			CarColors val = default(CarColors);
			val.primary_ = GetColor(vehicle, "primary", Colors.whiteSmoke);
			val.secondary_ = GetColor(vehicle, "secondary", Colors.darkGray);
			val.glow_ = GetColor(vehicle, "glow", Colors.cyan);
			val.sparkle_ = GetColor(vehicle, "sparkle", Colors.lightSlateGray);
			CarColors val2 = val;
			SetCarColors(profileName, vehicleName, val2);
			return val2;
		}

		protected Color GetColor(Section vehicle, string category, Color defaultColor)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			Section orCreate = vehicle.GetOrCreate(category, new Section());
			float orCreate2 = orCreate.GetOrCreate("r", defaultColor.r);
			float orCreate3 = orCreate.GetOrCreate("g", defaultColor.g);
			float orCreate4 = orCreate.GetOrCreate("b", defaultColor.b);
			float orCreate5 = orCreate.GetOrCreate("a", defaultColor.a);
			return new Color(orCreate2, orCreate3, orCreate4, orCreate5);
		}

		protected void SetCarColors(string profileName, string vehicleName, CarColors colors)
		{
			//IL_0011: 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_0029: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			Section section = Vehicle(profileName, vehicleName);
			section["primary"] = ToSection(colors.primary_);
			section["secondary"] = ToSection(colors.secondary_);
			section["glow"] = ToSection(colors.glow_);
			section["sparkle"] = ToSection(colors.sparkle_);
			Section section2 = Profile(profileName);
			section2[vehicleName] = section;
			Config[profileName] = section2;
		}

		protected Section ToSection(Color color)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			return new Section
			{
				["r"] = color.r,
				["g"] = color.g,
				["b"] = color.b,
				["a"] = color.a
			};
		}

		protected void Save()
		{
			Config.Save();
			this.OnChanged?.Invoke(this);
		}

		public void LoadAll()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			ProfileManager profileManager_ = G.Sys.ProfileManager_;
			List<Profile> profiles_ = profileManager_.profiles_;
			foreach (Profile item in profiles_)
			{
				CarColors[] array = (CarColors[])(object)new CarColors[Mod.TotalCarCount];
				for (int i = 0; i < profileManager_.CarInfos_.Length; i++)
				{
					if (i < Mod.DefaultCarCount)
					{
						array[i] = item.carColorsList_[i];
						continue;
					}
					CarInfo val = profileManager_.CarInfos_[i];
					CarColors carColors = GetCarColors(item.FileName_, val.name_);
					array[i] = carColors;
				}
				item.carColorsList_ = array;
			}
		}

		public void SaveAll()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			ProfileManager profileManager_ = G.Sys.ProfileManager_;
			List<Profile> profiles_ = profileManager_.profiles_;
			foreach (Profile item in profiles_)
			{
				for (int i = 0; i < profileManager_.CarInfos_.Length; i++)
				{
					if (i >= Mod.DefaultCarCount)
					{
						CarInfo val = profileManager_.CarInfos_[i];
						CarColors colors = item.carColorsList_[i];
						SetCarColors(item.FileName_, val.name_, colors);
					}
				}
			}
			Save();
		}
	}
	public class Section : Dictionary<string, object>
	{
		public bool Dirty { get; protected set; }

		public new object this[string key]
		{
			get
			{
				if (!ContainsKey(key))
				{
					return null;
				}
				return base[key];
			}
			set
			{
				if (!ContainsKey(key))
				{
					Add(key, value);
					this.ValueChanged?.Invoke(this, new SettingsChangedEventArgs(key, null, base[key]));
				}
				else
				{
					object oldValue = base[key];
					base[key] = value;
					this.ValueChanged?.Invoke(this, new SettingsChangedEventArgs(key, oldValue, base[key]));
				}
				Dirty = true;
			}
		}

		public event EventHandler<SettingsChangedEventArgs> ValueChanged;

		public T GetItem<T>(string key)
		{
			//IL_0084: Expected O, but got Unknown
			if (!ContainsKey(key))
			{
				Mod.Log.LogInfo((object)("The key requested doesn't exist in store: '" + key + "'."));
				throw new KeyNotFoundException("The key requested doesn't exist in store: '" + key + "'.");
			}
			try
			{
				object obj = this[key];
				JToken val = (JToken)((obj is JToken) ? obj : null);
				if (val != null)
				{
					return val.ToObject<T>();
				}
				return (T)Convert.ChangeType(this[key], typeof(T));
			}
			catch (JsonException val2)
			{
				JsonException val3 = val2;
				Mod.Log.LogInfo((object)$"Failed to convert a JSON token to the requested type. String: {key} \n{val3}");
				throw new SettingsException("Failed to convert a JSON token to the requested type.", key, isJsonFailure: true, (Exception)(object)val3);
			}
			catch (Exception ex)
			{
				try
				{
					return (T)Enum.ToObject(typeof(T), (long)this[key]);
				}
				catch
				{
					Mod.Log.LogInfo((object)$".NET type conversion exception has been thrown. String: {key} \n{ex}");
					throw new SettingsException(".NET type conversion exception has been thrown.", key, isJsonFailure: false, ex);
				}
			}
		}

		public T GetOrCreate<T>(string key) where T : new()
		{
			if (!ContainsKey(key))
			{
				this[key] = new T();
				this.ValueChanged?.Invoke(this, new SettingsChangedEventArgs(key, null, this[key]));
			}
			return GetItem<T>(key);
		}

		public T GetOrCreate<T>(string key, T defaultValue)
		{
			if (!ContainsKey(key))
			{
				this[key] = defaultValue;
				this.ValueChanged?.Invoke(this, new SettingsChangedEventArgs(key, null, this[key]));
			}
			return GetItem<T>(key);
		}

		public bool ContainsKey<T>(string key)
		{
			try
			{
				GetItem<T>(key);
				return true;
			}
			catch
			{
				return false;
			}
		}
	}
	public class Settings : Section
	{
		private string FileName { get; }

		private string RootDirectory { get; }

		private string SettingsDirectory => Path.Combine(RootDirectory, "Settings");

		private string FilePath => Path.Combine(SettingsDirectory, FileName);

		public Settings(string fileName)
		{
			//IL_0084: Expected O, but got Unknown
			RootDirectory = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location);
			FileName = fileName + ".json";
			Mod.Log.LogInfo((object)("Settings instance for '" + FilePath + "' initializing..."));
			if (File.Exists(FilePath))
			{
				using StreamReader streamReader = new StreamReader(FilePath);
				string text = streamReader.ReadToEnd();
				Section section = null;
				try
				{
					section = JsonConvert.DeserializeObject<Section>(text);
				}
				catch (JsonException val)
				{
					JsonException val2 = val;
					Mod.Log.LogInfo((object)val2);
				}
				catch (Exception ex)
				{
					Mod.Log.LogInfo((object)ex);
				}
				Mod.Log.LogInfo((object)"Just Deserialized the json");
				if (section != null)
				{
					foreach (string key in section.Keys)
					{
						Add(key, section[key]);
					}
				}
			}
			base.Dirty = false;
		}

		public void Save(bool formatJson = true)
		{
			//IL_0057: Expected O, but got Unknown
			if (!Directory.Exists(SettingsDirectory))
			{
				Directory.CreateDirectory(SettingsDirectory);
			}
			try
			{
				using (StreamWriter streamWriter = new StreamWriter(FilePath, append: false))
				{
					streamWriter.WriteLine(JsonConvert.SerializeObject((object)this, (Formatting)1));
				}
				base.Dirty = false;
			}
			catch (JsonException val)
			{
				JsonException val2 = val;
				Mod.Log.LogInfo((object)val2);
			}
			catch (Exception ex)
			{
				Mod.Log.LogInfo((object)ex);
			}
		}

		public void SaveIfDirty(bool formatJson = true)
		{
			if (base.Dirty)
			{
				Save(formatJson);
			}
		}
	}
	public class SettingsChangedEventArgs : EventArgs
	{
		public string Key { get; }

		public object OldValue { get; }

		public object NewValue { get; }

		public SettingsChangedEventArgs(string key, object oldValue = null, object newValue = null)
		{
			Key = key;
			OldValue = oldValue;
			NewValue = newValue;
		}
	}
	public class SettingsException : Exception
	{
		public string Key { get; }

		public bool IsJsonFailure { get; }

		public SettingsException(string message, string key, bool isJsonFailure, Exception innerException)
			: base(message, innerException)
		{
			Key = key;
			IsJsonFailure = isJsonFailure;
		}

		public SettingsException(string message, string key, bool isJsonFailure)
			: this(message, key, isJsonFailure, null)
		{
		}
	}
}
namespace Distance.CustomCar.Patches
{
	[HarmonyPatch(typeof(CarAudio), "OnCarHornEvent")]
	internal static class OnCarHornEvent
	{
		[HarmonyPrefix]
		internal static bool Prefix(CarAudio __instance, Data data)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			int num = G.Sys.ProfileManager_.knownCars_[__instance.carLogic_.PlayerData_.CarName_];
			if (num >= Mod.DefaultCarCount && Mod.UseTrumpetHorn.Value)
			{
				__instance.phantom_.SetRTPCValue("Horn_volume", Mathf.Clamp01(data.hornPercent_ + 0.5f));
				__instance.phantom_.Play("SpookyHorn", 0f, true);
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(GadgetWithAnimation), "SetAnimationStateValues")]
	internal static class GadgetWithAnimation__SetAnimationStateValues
	{
		[HarmonyPrefix]
		internal static bool Prefix(GadgetWithAnimation __instance)
		{
			Animation componentInChildren = ((Component)__instance).GetComponentInChildren<Animation>(true);
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				return PatchAnimations(componentInChildren, __instance.animationName_);
			}
			return false;
		}

		private static bool PatchAnimations(Animation animation, string name)
		{
			if (Object.op_Implicit((Object)(object)animation))
			{
				if (!ChangeBlendModeToBlend(((Component)animation).transform, name))
				{
					return true;
				}
				AnimationState val = animation[name];
				if (TrackedReference.op_Implicit((TrackedReference)(object)val))
				{
					val.layer = 3;
					val.blendMode = (AnimationBlendMode)0;
					val.wrapMode = (WrapMode)8;
					val.enabled = true;
					val.weight = 1f;
					val.speed = 0f;
				}
			}
			return false;
		}

		private static bool ChangeBlendModeToBlend(Transform obj, string animationName)
		{
			for (int i = 0; i < obj.childCount; i++)
			{
				string text = ((Object)((Component)obj.GetChild(i)).gameObject).name.ToLower();
				if (!text.StartsWith("#"))
				{
					continue;
				}
				text = text.Remove(0, 1);
				string[] array = text.Split(new char[1] { ';' });
				if (array.Length == 1)
				{
					if (array[0] == "additive")
					{
						return false;
					}
					if (array[0] == "blend")
					{
						return true;
					}
				}
				if (array[1] == animationName.ToLower())
				{
					if (array[0] == "additive")
					{
						return false;
					}
					if (array[0] == "blend")
					{
						return true;
					}
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Profile), "Awake")]
	internal static class Profile__Awake
	{
		[HarmonyPostfix]
		internal static void Postfix(Profile __instance)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			CarColors[] array = (CarColors[])(object)new CarColors[G.Sys.ProfileManager_.carInfos_.Length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = G.Sys.ProfileManager_.carInfos_[i].colors_;
			}
			__instance.carColorsList_ = array;
		}
	}
	[HarmonyPatch(typeof(Profile), "Save")]
	internal static class Profile__Save
	{
		[HarmonyPostfix]
		internal static void Postfix()
		{
			Mod.Instance.CarColors.SaveAll();
		}
	}
	[HarmonyPatch(typeof(Profile), "SetColorsForAllCars", new Type[] { typeof(CarColors) })]
	internal static class Profile__SetColorsForAllCars
	{
		[HarmonyPrefix]
		internal static bool Prefix(Profile __instance, CarColors cc)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			CarColors[] array = (CarColors[])(object)new CarColors[G.Sys.ProfileManager_.carInfos_.Length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = cc;
			}
			__instance.carColorsList_ = array;
			__instance.dataModified_ = true;
			return false;
		}
	}
}
namespace Distance.CustomCar.Data.Materials
{
	public class MaterialInfos
	{
		public Material material;

		public int diffuseIndex = -1;

		public int normalIndex = -1;

		public int emitIndex = -1;

		public void ReplaceMaterialInRenderer(Renderer renderer, int materialIndex)
		{
			if (!((Object)(object)material == (Object)null) && !((Object)(object)renderer == (Object)null) && materialIndex < renderer.materials.Length)
			{
				ref Material reference = ref renderer.materials[materialIndex];
				Material val = Object.Instantiate<Material>(material);
				if (diffuseIndex >= 0)
				{
					val.SetTexture(diffuseIndex, reference.GetTexture("_MainTex"));
				}
				if (emitIndex >= 0)
				{
					val.SetTexture(emitIndex, reference.GetTexture("_EmissionMap"));
				}
				if (normalIndex >= 0)
				{
					val.SetTexture(normalIndex, reference.GetTexture("_BumpMap"));
				}
				renderer.materials[materialIndex] = val;
			}
		}
	}
	public class MaterialPropertyExport
	{
		public string fromName;

		public string toName;

		public int fromID = -1;

		public int toID = -1;

		public PropertyType type;
	}
	public class MaterialPropertyInfo
	{
		public string shaderName;

		public string name;

		public int diffuseIndex = -1;

		public int normalIndex = -1;

		public int emitIndex = -1;

		public MaterialPropertyInfo(string _shaderName, string _name, int _diffuseIndex, int _normalIndex, int _emitIndex)
		{
			shaderName = _shaderName;
			name = _name;
			diffuseIndex = _diffuseIndex;
			normalIndex = _normalIndex;
			emitIndex = _emitIndex;
		}
	}
	public enum PropertyType
	{
		Color,
		ColorArray,
		Float,
		FloatArray,
		Int,
		Matrix,
		MatrixArray,
		Texture,
		Vector,
		VectorArray
	}
}
namespace Distance.CustomCar.Data.Errors
{
	public class ErrorList : List<string>
	{
		private readonly ManualLogSource logger_;

		public ErrorList(ManualLogSource logger)
		{
			logger_ = logger;
		}

		public new void Add(string value)
		{
			base.Add(value);
			logger_.LogInfo((object)value);
		}

		public void Add(Exception value)
		{
			base.Add(value.ToString());
			logger_.LogInfo((object)value);
		}

		public void Show()
		{
			if (this.Any())
			{
				string arg = ((base.Count < 15) ? string.Join(Environment.NewLine, ToArray()) : "There were too many errors when loading custom cars to be displayed here, please check the logs in your mod installation directory.");
				MessageBox.Create($"Can't load the cars correctly: {base.Count} error(s)\n{arg}", "CUSTOM CARS - ERRORS").SetButtons(MessageButtons.Ok).Show();
			}
		}
	}
}
namespace Distance.CustomCar.Data.Car
{
	public class CarBuilder
	{
		private CarInfos infos_;

		public void CreateCars(CarInfos infos)
		{
			infos_ = infos;
			Dictionary<string, GameObject> dictionary = LoadAssetsBundles();
			List<CreateCarReturnInfos> list = new List<CreateCarReturnInfos>();
			foreach (KeyValuePair<string, GameObject> item in dictionary)
			{
				try
				{
					Mod.Log.LogInfo((object)("Creating car prefab for " + item.Key + " ..."));
					CreateCarReturnInfos createCarReturnInfos = CreateCar(item.Value);
					string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(item.Key.Substring(0, item.Key.LastIndexOf('(') - 1));
					((Object)createCarReturnInfos.car).name = fileNameWithoutExtension;
					list.Add(createCarReturnInfos);
				}
				catch (Exception value)
				{
					Mod.Log.LogError((object)("Could not load car prefab: " + item.Key));
					Mod.Instance.Errors.Add("Could not load car prefab: " + item.Key);
					Mod.Instance.Errors.Add(value);
				}
			}
			RegisterCars(list);
		}

		private void RegisterCars(List<CreateCarReturnInfos> carsInfos)
		{
			//IL_008c: 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)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			Mod.Log.LogInfo((object)$"Registering {carsInfos.Count} car(s)...");
			ProfileManager profileManager_ = G.Sys.ProfileManager_;
			CarInfo[] array = ICollectionEx.ToArray<CarInfo>((ICollection<CarInfo>)profileManager_.carInfos_);
			profileManager_.carInfos_ = (CarInfo[])(object)new CarInfo[array.Length + carsInfos.Count];
			ref Dictionary<string, int> unlockedCars_ = ref profileManager_.unlockedCars_;
			ref Dictionary<string, int> knownCars_ = ref profileManager_.knownCars_;
			for (int i = 0; i < profileManager_.carInfos_.Length; i++)
			{
				if (i < array.Length)
				{
					profileManager_.carInfos_[i] = array[i];
					continue;
				}
				int index = i - array.Length;
				CarInfo val = new CarInfo
				{
					name_ = ((Object)carsInfos[index].car).name,
					prefabs_ = new CarPrefabs
					{
						carPrefab_ = carsInfos[index].car
					},
					colors_ = carsInfos[index].colors
				};
				if (!knownCars_.ContainsKey(val.name_) && !unlockedCars_.ContainsKey(val.name_))
				{
					unlockedCars_.Add(val.name_, i);
					knownCars_.Add(val.name_, i);
				}
				else
				{
					Mod.Instance.Errors.Add("A car with the name " + val.name_ + " is already registered, rename the car file if they're the same.");
					Mod.Log.LogInfo((object)("Generating unique name for car " + val.name_));
					string text = $"#{Guid.NewGuid():B}";
					Mod.Log.LogInfo((object)("Using GUID: " + text));
					val.name_ = "[FFFF00]![-] " + val.name_ + " " + text;
					unlockedCars_.Add(val.name_, i);
					knownCars_.Add(val.name_, i);
				}
				profileManager_.carInfos_[i] = val;
			}
			CarColors[] array2 = (CarColors[])(object)new CarColors[array.Length + carsInfos.Count];
			for (int j = 0; j < array2.Length; j++)
			{
				array2[j] = G.Sys.ProfileManager_.carInfos_[j].colors_;
			}
			for (int k = 0; k < profileManager_.ProfileCount_; k++)
			{
				Profile profile = profileManager_.GetProfile(k);
				CarColors[] carColorsList_ = profile.carColorsList_;
				for (int l = 0; l < carColorsList_.Length && l < array2.Length; l++)
				{
					array2[l] = carColorsList_[l];
				}
				profile.carColorsList_ = array2;
			}
		}

		private Dictionary<string, GameObject> LoadAssetsBundles()
		{
			Dictionary<string, GameObject> dictionary = new Dictionary<string, GameObject>();
			DirectoryInfo localFolder = GetLocalFolder("Assets");
			DirectoryInfo directoryInfo = new DirectoryInfo(Path.Combine(Resource.personalDistanceDirPath_, "CustomCars"));
			if (!directoryInfo.Exists)
			{
				try
				{
					directoryInfo.Create();
				}
				catch (Exception ex)
				{
					Mod.Instance.Errors.Add("Could not create the following folder: " + directoryInfo.FullName);
					Mod.Log.LogError((object)("Could not create the following folder: " + directoryInfo.FullName));
					Mod.Instance.Errors.Add(ex);
					Mod.Log.LogError((object)ex);
				}
			}
			try
			{
				foreach (FileInfo item in from x in ArrayEx.Concat<FileInfo>(localFolder.GetFiles("*", SearchOption.AllDirectories), directoryInfo.GetFiles("*", SearchOption.AllDirectories))
					orderby x.Name
					select x)
				{
					try
					{
						Assets assets = Assets.FromUnsafePath(item.FullName);
						object bundle = assets.Bundle;
						AssetBundle val = (AssetBundle)((bundle is AssetBundle) ? bundle : null);
						int num = 0;
						foreach (string item2 in from name in val.GetAllAssetNames()
							where name.EndsWith(".prefab", StringComparison.InvariantCultureIgnoreCase)
							select name)
						{
							GameObject value = val.LoadAsset<GameObject>(item2);
							string key = item.FullName + " (" + item2 + ")";
							if (!dictionary.ContainsKey(key))
							{
								dictionary.Add(key, value);
								num++;
							}
						}
						if (num == 0)
						{
							Mod.Instance.Errors.Add("Can't find a prefab in the asset bundle: " + item.FullName);
							Mod.Log.LogError((object)("Can't find a prefab in the asset bundle: " + item.FullName));
						}
					}
					catch (Exception ex2)
					{
						Mod.Instance.Errors.Add("Could not load assets file: " + item.FullName);
						Mod.Log.LogError((object)("Could not load assets file: " + item.FullName));
						Mod.Instance.Errors.Add(ex2);
						Mod.Log.LogError((object)ex2);
					}
				}
			}
			catch (Exception)
			{
				Mod.Log.LogWarning((object)"No Assets folder in the custom car folder.");
			}
			try
			{
				DirectoryInfo directoryInfo2 = new DirectoryInfo(Path.Combine(Directory.GetParent(Directory.GetParent(Path.GetDirectoryName(Assembly.GetCallingAssembly().Location)).ToString()).ToString(), "Assets"));
				foreach (FileInfo item3 in from x in ArrayEx.Concat<FileInfo>(directoryInfo2.GetFiles("*", SearchOption.AllDirectories), directoryInfo.GetFiles("*", SearchOption.AllDirectories))
					orderby x.Name
					select x)
				{
					try
					{
						Assets assets2 = Assets.FromUnsafePath(item3.FullName);
						object bundle2 = assets2.Bundle;
						AssetBundle val2 = (AssetBundle)((bundle2 is AssetBundle) ? bundle2 : null);
						int num2 = 0;
						foreach (string item4 in from name in val2.GetAllAssetNames()
							where name.EndsWith(".prefab", StringComparison.InvariantCultureIgnoreCase)
							select name)
						{
							GameObject value2 = val2.LoadAsset<GameObject>(item4);
							string key2 = item3.FullName + " (" + item4 + ")";
							if (!dictionary.ContainsKey(key2))
							{
								dictionary.Add(key2, value2);
								num2++;
							}
						}
						if (num2 == 0)
						{
							Mod.Instance.Errors.Add("Can't find a prefab in the asset bundle: " + item3.FullName);
							Mod.Log.LogError((object)("Can't find a prefab in the asset bundle: " + item3.FullName));
						}
					}
					catch (Exception ex4)
					{
						Mod.Instance.Errors.Add("Could not load assets file: " + item3.FullName);
						Mod.Log.LogError((object)("Could not load assets file: " + item3.FullName));
						Mod.Instance.Errors.Add(ex4);
						Mod.Log.LogError((object)ex4);
					}
				}
			}
			catch (Exception)
			{
				Mod.Log.LogWarning((object)"No Assets folder in toplevel directory.");
			}
			DirectoryInfo directoryInfo3 = new DirectoryInfo(Directory.GetParent(Path.GetDirectoryName(Assembly.GetCallingAssembly().Location)).ToString());
			foreach (FileInfo item5 in from x in ArrayEx.Concat<FileInfo>(directoryInfo3.GetFiles("*", SearchOption.AllDirectories), directoryInfo.GetFiles("*", SearchOption.AllDirectories))
				orderby x.Name
				select x)
			{
				if (!(item5.Extension == ""))
				{
					continue;
				}
				try
				{
					Assets assets3 = Assets.FromUnsafePath(item5.FullName);
					object bundle3 = assets3.Bundle;
					AssetBundle val3 = (AssetBundle)((bundle3 is AssetBundle) ? bundle3 : null);
					int num3 = 0;
					foreach (string item6 in from name in val3.GetAllAssetNames()
						where name.EndsWith(".prefab", StringComparison.InvariantCultureIgnoreCase)
						select name)
					{
						GameObject value3 = val3.LoadAsset<GameObject>(item6);
						string key3 = item5.FullName + " (" + item6 + ")";
						if (!dictionary.ContainsKey(key3))
						{
							dictionary.Add(key3, value3);
							num3++;
						}
					}
					if (num3 == 0)
					{
						Mod.Instance.Errors.Add("Can't find a prefab in the asset bundle: " + item5.FullName);
						Mod.Log.LogError((object)("Can't find a prefab in the asset bundle: " + item5.FullName));
					}
				}
				catch (Exception ex6)
				{
					Mod.Instance.Errors.Add("Could not load assets file: " + item5.FullName);
					Mod.Log.LogError((object)("Could not load assets file: " + item5.FullName));
					Mod.Instance.Errors.Add(ex6);
					Mod.Log.LogError((object)ex6);
				}
			}
			return dictionary;
		}

		public DirectoryInfo GetLocalFolder(string dir)
		{
			FileSystem fileSystem = new FileSystem();
			return new DirectoryInfo(Path.GetDirectoryName(Path.Combine(fileSystem.RootDirectory, dir + (dir.EndsWith($"{Path.DirectorySeparatorChar}") ? string.Empty : $"{Path.DirectorySeparatorChar}"))));
		}

		private CreateCarReturnInfos CreateCar(GameObject car)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			CreateCarReturnInfos createCarReturnInfos = new CreateCarReturnInfos();
			GameObject val = Object.Instantiate<GameObject>(infos_.baseCar);
			((Object)val).name = ((Object)car).name;
			Object.DontDestroyOnLoad((Object)(object)val);
			val.SetActive(false);
			RemoveOldCar(val);
			GameObject car2 = AddNewCarOnPrefab(val, car);
			SetCarDatas(val, car2);
			createCarReturnInfos.car = val;
			createCarReturnInfos.colors = LoadDefaultColors(car2);
			return createCarReturnInfos;
		}

		private void RemoveOldCar(GameObject obj)
		{
			List<GameObject> list = new List<GameObject>();
			for (int i = 0; i < obj.transform.childCount; i++)
			{
				GameObject gameObject = ((Component)obj.transform.GetChild(i)).gameObject;
				if (((Object)gameObject).name.IndexOf("wheel", StringComparison.InvariantCultureIgnoreCase) >= 0)
				{
					list.Add(gameObject);
				}
			}
			if (list.Count != 4)
			{
				Mod.Instance.Errors.Add($"Found {list.Count} wheels on base prefabs, expected 4");
				Mod.Log.LogError((object)$"Found {list.Count} wheels on base prefabs, expected 4");
			}
			Transform val = obj.transform.Find("Refractor");
			if ((Object)(object)val == (Object)null)
			{
				Mod.Instance.Errors.Add("Can't find the Refractor object on the base car prefab");
				Mod.Log.LogError((object)"Can't find the Refractor object on the base car prefab");
				return;
			}
			Object.Destroy((Object)(object)((Component)val).gameObject);
			foreach (GameObject item in list)
			{
				Object.Destroy((Object)(object)item);
			}
		}

		private GameObject AddNewCarOnPrefab(GameObject obj, GameObject car)
		{
			return Object.Instantiate<GameObject>(car, obj.transform);
		}

		private void SetCarDatas(GameObject obj, GameObject car)
		{
			SetColorChanger(obj.GetComponent<ColorChanger>(), car);
			SetCarVisuals(obj.GetComponent<CarVisuals>(), car);
		}

		private void SetColorChanger(ColorChanger colorChanger, GameObject car)
		{
			if ((Object)(object)colorChanger == (Object)null)
			{
				Mod.Instance.Errors.Add("Can't find the ColorChanger component on the base car");
				Mod.Log.LogError((object)"Can't find the ColorChanger component on the base car");
				return;
			}
			colorChanger.rendererChangers_ = (RendererChanger[])(object)new RendererChanger[0];
			Renderer[] componentsInChildren = car.GetComponentsInChildren<Renderer>();
			foreach (Renderer val in componentsInChildren)
			{
				ReplaceMaterials(val);
				if ((Object)(object)colorChanger != (Object)null)
				{
					AddMaterialColorChanger(colorChanger, ((Component)val).transform);
				}
			}
		}

		private void ReplaceMaterials(Renderer renderer)
		{
			string[] array = new string[renderer.materials.Length];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = "wheel";
			}
			List<MaterialPropertyExport>[] array2 = new List<MaterialPropertyExport>[renderer.materials.Length];
			for (int j = 0; j < array2.Length; j++)
			{
				array2[j] = new List<MaterialPropertyExport>();
			}
			FillMaterialInfos(renderer, array, array2);
			Material[] array3 = ICollectionEx.ToArray<Material>((ICollection<Material>)renderer.materials);
			for (int k = 0; k < renderer.materials.Length; k++)
			{
				if (!infos_.materials.TryGetValue(array[k], out var value))
				{
					Mod.Instance.Errors.Add("Can't find the material " + array[k] + " on " + ((Component)renderer).gameObject.FullName());
					Mod.Log.LogError((object)("Can't find the material " + array[k] + " on " + ((Component)renderer).gameObject.FullName()));
				}
				else
				{
					if (value == null || (Object)(object)value.material == (Object)null)
					{
						continue;
					}
					Material val = Object.Instantiate<Material>(value.material);
					if (value.diffuseIndex >= 0)
					{
						val.SetTexture(value.diffuseIndex, renderer.materials[k].GetTexture("_MainTex"));
					}
					if (value.normalIndex >= 0)
					{
						val.SetTexture(value.normalIndex, renderer.materials[k].GetTexture("_BumpMap"));
					}
					if (value.emitIndex >= 0)
					{
						val.SetTexture(value.emitIndex, renderer.materials[k].GetTexture("_EmissionMap"));
					}
					foreach (MaterialPropertyExport item in array2[k])
					{
						CopyMaterialProperty(renderer.materials[k], val, item);
					}
					array3[k] = val;
				}
			}
			renderer.materials = array3;
		}

		private void FillMaterialInfos(Renderer renderer, string[] matNames, List<MaterialPropertyExport>[] materialProperties)
		{
			int childCount = ((Component)renderer).transform.childCount;
			for (int i = 0; i < childCount; i++)
			{
				string text = ((Object)((Component)renderer).transform.GetChild(i)).name.ToLower();
				if (!text.StartsWith("#"))
				{
					continue;
				}
				text = text.Remove(0, 1);
				string[] array = text.Split(new char[1] { ';' });
				if (array.Length == 0)
				{
					continue;
				}
				if (array[0].Contains("mat"))
				{
					int result;
					if (array.Length != 3)
					{
						Mod.Instance.Errors.Add(array[0] + " property on " + ((Component)renderer).gameObject.FullName() + " must have 2 arguments");
						Mod.Log.LogError((object)(array[0] + " property on " + ((Component)renderer).gameObject.FullName() + " must have 2 arguments"));
					}
					else if (!int.TryParse(array[1], out result))
					{
						Mod.Instance.Errors.Add("First argument of " + array[0] + " on " + ((Component)renderer).gameObject.FullName() + " property must be a number");
						Mod.Log.LogError((object)("First argument of " + array[0] + " on " + ((Component)renderer).gameObject.FullName() + " property must be a number"));
					}
					else if (result < matNames.Length)
					{
						matNames[result] = array[2];
					}
				}
				else
				{
					if (!array[0].Contains("export"))
					{
						continue;
					}
					int result2;
					if (array.Length != 5)
					{
						Mod.Instance.Errors.Add(array[0] + " property on " + ((Component)renderer).gameObject.FullName() + " must have 4 arguments");
						Mod.Log.LogError((object)(array[0] + " property on " + ((Component)renderer).gameObject.FullName() + " must have 4 arguments"));
					}
					else if (!int.TryParse(array[1], out result2))
					{
						Mod.Instance.Errors.Add("First argument of " + array[0] + " on " + ((Component)renderer).gameObject.FullName() + " property must be a number");
						Mod.Log.LogError((object)("First argument of " + array[0] + " on " + ((Component)renderer).gameObject.FullName() + " property must be a number"));
					}
					else
					{
						if (result2 >= matNames.Length)
						{
							continue;
						}
						MaterialPropertyExport materialPropertyExport = new MaterialPropertyExport();
						bool flag = false;
						foreach (PropertyType value in Enum.GetValues(typeof(PropertyType)))
						{
							if (array[2] == value.ToString().ToLower())
							{
								flag = true;
								materialPropertyExport.type = value;
								break;
							}
						}
						if (!flag)
						{
							Mod.Instance.Errors.Add("The property " + array[2] + " on " + ((Component)renderer).gameObject.FullName() + " is not valid");
							Mod.Log.LogError((object)("The property " + array[2] + " on " + ((Component)renderer).gameObject.FullName() + " is not valid"));
						}
						else
						{
							if (!int.TryParse(array[3], out materialPropertyExport.fromID))
							{
								materialPropertyExport.fromName = array[3];
							}
							if (!int.TryParse(array[4], out materialPropertyExport.toID))
							{
								materialPropertyExport.toName = array[4];
							}
							materialProperties[result2].Add(materialPropertyExport);
						}
					}
				}
			}
		}

		private void CopyMaterialProperty(Material from, Material to, MaterialPropertyExport property)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			int num = property.fromID;
			if (num == -1)
			{
				num = Shader.PropertyToID(property.fromName);
			}
			int num2 = property.toID;
			if (num2 == -1)
			{
				num2 = Shader.PropertyToID(property.toName);
			}
			switch (property.type)
			{
			case PropertyType.Color:
				to.SetColor(num2, from.GetColor(num));
				break;
			case PropertyType.ColorArray:
				to.SetColorArray(num2, from.GetColorArray(num));
				break;
			case PropertyType.Float:
				to.SetFloat(num2, from.GetFloat(num));
				break;
			case PropertyType.FloatArray:
				to.SetFloatArray(num2, from.GetFloatArray(num));
				break;
			case PropertyType.Int:
				to.SetInt(num2, from.GetInt(num));
				break;
			case PropertyType.Matrix:
				to.SetMatrix(num2, from.GetMatrix(num));
				break;
			case PropertyType.MatrixArray:
				to.SetMatrixArray(num2, from.GetMatrixArray(num));
				break;
			case PropertyType.Texture:
				to.SetTexture(num2, from.GetTexture(num));
				break;
			case PropertyType.Vector:
				to.SetVector(num2, from.GetVector(num));
				break;
			case PropertyType.VectorArray:
				to.SetVectorArray(num2, from.GetVectorArray(num));
				break;
			}
		}

		private void AddMaterialColorChanger(ColorChanger colorChanger, Transform transform)
		{
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Expected O, but got Unknown
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Expected O, but got Unknown
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			Renderer component = ((Component)transform).GetComponent<Renderer>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			List<UniformChanger> list = new List<UniformChanger>();
			for (int i = 0; i < transform.childCount; i++)
			{
				GameObject gameObject = ((Component)transform.GetChild(i)).gameObject;
				string text = ((Object)gameObject).name.ToLower();
				if (!text.StartsWith("#"))
				{
					continue;
				}
				text = text.Remove(0, 1);
				string[] array = text.Split(new char[1] { ';' });
				if (array.Length != 0 && array[0].Contains("color"))
				{
					if (array.Length != 6)
					{
						Mod.Instance.Errors.Add(array[0] + " property on " + ((Component)transform).gameObject.FullName() + " must have 5 arguments");
						Mod.Log.LogError((object)(array[0] + " property on " + ((Component)transform).gameObject.FullName() + " must have 5 arguments"));
						continue;
					}
					UniformChanger val = new UniformChanger();
					int.TryParse(array[1], out var result);
					val.materialIndex_ = result;
					val.colorType_ = ColorType(array[2]);
					val.name_ = UniformName(array[3]);
					float.TryParse(array[4], out var result2);
					val.mul_ = result2;
					val.alpha_ = string.Equals(array[5], "true", StringComparison.InvariantCultureIgnoreCase);
					list.Add(val);
				}
			}
			if (list.Count != 0)
			{
				RendererChanger item = new RendererChanger
				{
					renderer_ = component,
					uniformChangers_ = list.ToArray()
				};
				List<RendererChanger> list2 = colorChanger.rendererChangers_.ToList();
				list2.Add(item);
				colorChanger.rendererChangers_ = list2.ToArray();
			}
		}

		private ColorType ColorType(string name)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			name = name.ToLower();
			return (ColorType)(name switch
			{
				"primary" => 0, 
				"secondary" => 1, 
				"glow" => 2, 
				"sparkle" => 3, 
				_ => 0, 
			});
		}

		private SupportedUniform UniformName(string name)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			name = name.ToLower();
			return (SupportedUniform)(name switch
			{
				"color" => 0, 
				"color2" => 1, 
				"emitcolor" => 2, 
				"reflectcolor" => 4, 
				"speccolor" => 5, 
				_ => 0, 
			});
		}

		private void SetCarVisuals(CarVisuals visuals, GameObject car)
		{
			if ((Object)(object)visuals == (Object)null)
			{
				Mod.Instance.Errors.Add("Can't find the CarVisuals component on the base car");
				Mod.Log.LogInfo((object)"Can't find the CarVisuals component on the base car");
				return;
			}
			SkinnedMeshRenderer componentInChildren = car.GetComponentInChildren<SkinnedMeshRenderer>();
			MakeMeshSkinned(componentInChildren);
			visuals.carBodyRenderer_ = componentInChildren;
			List<JetFlame> list = new List<JetFlame>();
			List<JetFlame> list2 = new List<JetFlame>();
			List<JetFlame> list3 = new List<JetFlame>();
			PlaceJets(car, list, list2, list3);
			visuals.boostJetFlames_ = list.ToArray();
			visuals.wingJetFlames_ = list2.ToArray();
			visuals.rotationJetFlames_ = list3.ToArray();
			visuals.driverPosition_ = FindCarDriver(car.transform);
			PlaceCarWheelsVisuals(visuals, car);
		}

		private void MakeMeshSkinned(SkinnedMeshRenderer renderer)
		{
			//IL_0181: 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_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			Mesh sharedMesh = renderer.sharedMesh;
			if ((Object)(object)sharedMesh == (Object)null)
			{
				Mod.Instance.Errors.Add("The mesh on " + ((Component)renderer).gameObject.FullName() + " is null");
				Mod.Log.LogError((object)("The mesh on " + ((Component)renderer).gameObject.FullName() + " is null"));
			}
			else if (!sharedMesh.isReadable)
			{
				Mod.Instance.Errors.Add("Can't read the car mesh " + ((Object)sharedMesh).name + " on " + ((Component)renderer).gameObject.FullName() + "You must allow reading on it's unity inspector !");
				Mod.Log.LogError((object)("Can't read the car mesh " + ((Object)sharedMesh).name + " on " + ((Component)renderer).gameObject.FullName() + "You must allow reading on it's unity inspector !"));
			}
			else if (sharedMesh.vertices.Length != sharedMesh.boneWeights.Length)
			{
				BoneWeight[] array = (BoneWeight[])(object)new BoneWeight[sharedMesh.vertices.Length];
				for (int i = 0; i < array.Length; i++)
				{
					((BoneWeight)(ref array[i])).weight0 = 1f;
				}
				sharedMesh.boneWeights = array;
				Transform transform = ((Component)renderer).transform;
				sharedMesh.bindposes = (Matrix4x4[])(object)new Matrix4x4[1] { transform.worldToLocalMatrix * ((Component)renderer).transform.localToWorldMatrix };
				renderer.bones = (Transform[])(object)new Transform[1] { transform };
			}
		}

		private void PlaceJets(GameObject obj, List<JetFlame> boostJets, List<JetFlame> wingJets, List<JetFlame> rotationJets)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			int childCount = obj.transform.childCount;
			for (int i = 0; i < childCount; i++)
			{
				GameObject gameObject = GameObjectEx.GetChild(obj, i).gameObject;
				string text = ((Object)gameObject).name.ToLower();
				if ((Object)(object)infos_.boostJet != (Object)null && text.Contains("boostjet"))
				{
					GameObject val = Object.Instantiate<GameObject>(infos_.boostJet, gameObject.transform);
					val.transform.localPosition = Vector3.zero;
					val.transform.localRotation = Quaternion.identity;
					boostJets.Add(val.GetComponentInChildren<JetFlame>());
				}
				else if ((Object)(object)infos_.wingJet != (Object)null && text.Contains("wingjet"))
				{
					GameObject val2 = Object.Instantiate<GameObject>(infos_.wingJet, gameObject.transform);
					val2.transform.localPosition = Vector3.zero;
					val2.transform.localRotation = Quaternion.identity;
					wingJets.Add(val2.GetComponentInChildren<JetFlame>());
					ListEx.Last<JetFlame>(wingJets).rotationAxis_ = JetDirection(gameObject.transform);
				}
				else if ((Object)(object)infos_.rotationJet != (Object)null && text.Contains("rotationjet"))
				{
					GameObject val3 = Object.Instantiate<GameObject>(infos_.rotationJet, gameObject.transform);
					val3.transform.localPosition = Vector3.zero;
					val3.transform.localRotation = Quaternion.identity;
					rotationJets.Add(val3.GetComponentInChildren<JetFlame>());
					ListEx.Last<JetFlame>(rotationJets).rotationAxis_ = JetDirection(gameObject.transform);
				}
				else if ((Object)(object)infos_.wingTrail != (Object)null && text.Contains("wingtrail"))
				{
					GameObject val4 = Object.Instantiate<GameObject>(infos_.wingTrail, gameObject.transform);
					val4.transform.localPosition = Vector3.zero;
					val4.transform.localRotation = Quaternion.identity;
				}
				else
				{
					PlaceJets(gameObject, boostJets, wingJets, rotationJets);
				}
			}
		}

		private Vector3 JetDirection(Transform transform)
		{
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			int childCount = transform.childCount;
			for (int i = 0; i < childCount; i++)
			{
				string text = ((Object)((Component)transform.GetChild(i)).gameObject).name.ToLower();
				if (!text.StartsWith("#"))
				{
					continue;
				}
				text = text.Remove(0, 1);
				string[] array = text.Split(new char[1] { ';' });
				if (array.Length != 0 && array[0].Contains("dir") && array.Length >= 2)
				{
					if (array[1] == "front")
					{
						return new Vector3(-1f, 0f, 0f);
					}
					if (array[1] == "back")
					{
						return new Vector3(1f, 0f, 0f);
					}
					if (array[1] == "left")
					{
						return new Vector3(0f, 1f, -1f);
					}
					if (array[1] == "right")
					{
						return new Vector3(0f, -1f, 1f);
					}
					if (array.Length == 4 && array[0].Contains("dir"))
					{
						Vector3 zero = Vector3.zero;
						float.TryParse(array[1], out zero.x);
						float.TryParse(array[2], out zero.y);
						float.TryParse(array[3], out zero.z);
						return zero;
					}
				}
			}
			return Vector3.zero;
		}

		private Transform FindCarDriver(Transform parent)
		{
			for (int i = 0; i < parent.childCount; i++)
			{
				Transform child = parent.GetChild(i);
				Transform val = ((((Object)((Component)child).gameObject).name.IndexOf("driverposition", StringComparison.InvariantCultureIgnoreCase) >= 0) ? child : FindCarDriver(child));
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}

		private void PlaceCarWheelsVisuals(CarVisuals visual, GameObject car)
		{
			for (int i = 0; i < car.transform.childCount; i++)
			{
				GameObject gameObject = ((Component)car.transform.GetChild(i)).gameObject;
				string text = ((Object)gameObject).name.ToLower();
				if (!text.Contains("wheel"))
				{
					continue;
				}
				CarWheelVisuals val = gameObject.AddComponent<CarWheelVisuals>();
				MeshRenderer[] componentsInChildren = gameObject.GetComponentsInChildren<MeshRenderer>();
				foreach (MeshRenderer val2 in componentsInChildren)
				{
					if (((Object)((Component)val2).gameObject).name.IndexOf("tire", StringComparison.InvariantCultureIgnoreCase) >= 0)
					{
						val.tire_ = val2;
						break;
					}
				}
				if (text.Contains("front"))
				{
					if (text.Contains("left"))
					{
						visual.wheelFL_ = val;
					}
					else if (text.Contains("right"))
					{
						visual.wheelFR_ = val;
					}
				}
				else if (text.Contains("back"))
				{
					if (text.Contains("left"))
					{
						visual.wheelBL_ = val;
					}
					else if (text.Contains("right"))
					{
						visual.wheelBR_ = val;
					}
				}
			}
		}

		private CarColors LoadDefaultColors(GameObject car)
		{
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			CarColors val2 = default(CarColors);
			for (int i = 0; i < car.transform.childCount; i++)
			{
				GameObject gameObject = ((Component)car.transform.GetChild(i)).gameObject;
				string text = ((Object)gameObject).name.ToLower();
				if (!text.Contains("defaultcolor"))
				{
					continue;
				}
				for (int j = 0; j < gameObject.transform.childCount; j++)
				{
					GameObject gameObject2 = ((Component)gameObject.transform.GetChild(j)).gameObject;
					string text2 = ((Object)gameObject2).name.ToLower();
					if (!text2.StartsWith("#"))
					{
						continue;
					}
					text2 = text2.Remove(0, 1);
					string[] array = text2.Split(new char[1] { ';' });
					if (array.Length == 2)
					{
						Color val = ColorEx.HexToColor(array[1], byte.MaxValue);
						val.a = 1f;
						if (array[0] == "primary")
						{
							val2.primary_ = val;
						}
						else if (array[0] == "secondary")
						{
							val2.secondary_ = val;
						}
						else if (array[0] == "glow")
						{
							val2.glow_ = val;
						}
						else if (array[0] == "sparkle")
						{
							val2.sparkle_ = val;
						}
					}
				}
			}
			return infos_.defaultColors;
		}
	}
	public class CarInfos
	{
		public Dictionary<string, MaterialInfos> materials = new Dictionary<string, MaterialInfos>();

		public GameObject boostJet = null;

		public GameObject wingJet = null;

		public GameObject rotationJet = null;

		public GameObject wingTrail = null;

		public GameObject baseCar = null;

		public CarColors defaultColors;

		public void CollectInfos()
		{
			GetBaseCar();
			GetJetsAndTrail();
			GetMaterials();
		}

		private void GetBaseCar()
		{
			//IL_0059: 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)
			GameObject carPrefab_ = G.Sys.ProfileManager_.carInfos_[0].prefabs_.carPrefab_;
			if ((Object)(object)carPrefab_ == (Object)null)
			{
				Mod.Instance.Errors.Add("Can't find the refractor base car prefab");
				return;
			}
			baseCar = carPrefab_;
			defaultColors = G.Sys.ProfileManager_.carInfos_[0].colors_;
		}

		private void GetJetsAndTrail()
		{
			if ((Object)(object)baseCar == (Object)null)
			{
				return;
			}
			JetFlame[] componentsInChildren = baseCar.GetComponentsInChildren<JetFlame>();
			foreach (JetFlame val in componentsInChildren)
			{
				switch (((Object)((Component)val).gameObject).name)
				{
				case "BoostJetFlameCenter":
					boostJet = ((Component)val).gameObject;
					break;
				case "JetFlameBackLeft":
					rotationJet = ((Component)val).gameObject;
					break;
				case "WingJetFlameLeft1":
					wingJet = ((Component)val).gameObject;
					break;
				}
			}
			wingTrail = ((Component)baseCar.GetComponentInChildren<WingTrail>()).gameObject;
			if ((Object)(object)boostJet == (Object)null)
			{
				Mod.Instance.Errors.Add("No valid BoostJet found on Refractor");
			}
			if ((Object)(object)rotationJet == (Object)null)
			{
				Mod.Instance.Errors.Add("No valid RotationJet found on Refractor");
			}
			if ((Object)(object)wingJet == (Object)null)
			{
				Mod.Instance.Errors.Add("No valid WingJet found on Refractor");
			}
			if ((Object)(object)wingTrail == (Object)null)
			{
				Mod.Instance.Errors.Add("No valid WingTrail found on Refractor");
			}
		}

		private void GetMaterials()
		{
			List<MaterialPropertyInfo> list = new List<MaterialPropertyInfo>
			{
				new MaterialPropertyInfo("Custom/LaserCut/CarPaint", "carpaint", 5, -1, -1),
				new MaterialPropertyInfo("Custom/LaserCut/CarWindow", "carwindow", -1, 218, 219),
				new MaterialPropertyInfo("Custom/Reflective/Bump Glow LaserCut", "wheel", 5, 218, 255),
				new MaterialPropertyInfo("Custom/LaserCut/CarPaintBump", "carpaintbump", 5, 218, -1),
				new MaterialPropertyInfo("Custom/Reflective/Bump Glow Interceptor Special", "interceptor", 5, 218, 255),
				new MaterialPropertyInfo("Custom/LaserCut/CarWindowTrans2Sided", "transparentglow", -1, 218, 219)
			};
			CarInfo[] carInfos_ = G.Sys.ProfileManager_.carInfos_;
			foreach (CarInfo val in carInfos_)
			{
				GameObject carPrefab_ = val.prefabs_.carPrefab_;
				Renderer[] componentsInChildren = carPrefab_.GetComponentsInChildren<Renderer>();
				foreach (Renderer val2 in componentsInChildren)
				{
					Material[] array = val2.materials;
					foreach (Material val3 in array)
					{
						foreach (MaterialPropertyInfo item in list)
						{
							if (!materials.ContainsKey(item.name) && ((Object)val3.shader).name == item.shaderName)
							{
								MaterialInfos value = new MaterialInfos
								{
									material = val3,
									diffuseIndex = item.diffuseIndex,
									normalIndex = item.normalIndex,
									emitIndex = item.emitIndex
								};
								materials.Add(item.name, value);
							}
						}
					}
				}
			}
			foreach (MaterialPropertyInfo item2 in list)
			{
				if (!materials.ContainsKey(item2.name))
				{
					Mod.Instance.Errors.Add("Can't find the material: " + item2.name + " - shader: " + item2.shaderName);
				}
			}
			materials.Add("donotreplace", new MaterialInfos());
		}
	}
	public class CreateCarReturnInfos
	{
		public GameObject car;

		public CarColors colors;
	}
}

Newtonsoft.Json.dll

Decompiled 4 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using Newtonsoft.Json.Bson;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Linq.JsonPath;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Utilities;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Json.NET Unity3D")]
[assembly: AllowPartiallyTrustedCallers]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Schema")]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests")]
[assembly: InternalsVisibleTo("Assembly-CSharp")]
[assembly: InternalsVisibleTo("Assembly-CSharp-Editor")]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Dynamic, PublicKey=0024000004800000940000000602000000240000525341310004000001000100cbd8d53b9d7de30f1f1278f636ec462cf9c254991291e66ebb157a885638a517887633b898ccbcf0d5c5ff7be85a6abe9e765d0ac7cd33c68dac67e7e64530e8222101109f154ab14a941c490ac155cd1d4fcba0fabb49016b4ef28593b015cab5937da31172f03f67d09edda404b88a60023f062ae71d0b2e4438b74cc11dc9")]
[assembly: AssemblyDescription("Json.NET is a popular high-performance JSON framework for .NET")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Newtonsoft")]
[assembly: AssemblyProduct("Json.NET")]
[assembly: AssemblyCopyright("Copyright © James Newton-King 2008")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9ca358aa-317b-4925-8ada-4a29e943a363")]
[assembly: AssemblyFileVersion("9.0.1.19813")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyVersion("9.0.0.0")]
namespace Newtonsoft.Json
{
	public enum ConstructorHandling
	{
		Default,
		AllowNonPublicDefaultConstructor
	}
	public enum DateFormatHandling
	{
		IsoDateFormat,
		MicrosoftDateFormat
	}
	public enum DateParseHandling
	{
		None,
		DateTime,
		DateTimeOffset
	}
	public enum DateTimeZoneHandling
	{
		Local,
		Utc,
		Unspecified,
		RoundtripKind
	}
	[Flags]
	public enum DefaultValueHandling
	{
		Include = 0,
		Ignore = 1,
		Populate = 2,
		IgnoreAndPopulate = 3
	}
	public enum FloatFormatHandling
	{
		String,
		Symbol,
		DefaultValue
	}
	public enum FloatParseHandling
	{
		Double,
		Decimal
	}
	public enum Formatting
	{
		None,
		Indented
	}
	public interface IArrayPool<T>
	{
		T[] Rent(int minimumLength);

		void Return(T[] array);
	}
	public interface IJsonLineInfo
	{
		int LineNumber { get; }

		int LinePosition { get; }

		bool HasLineInfo();
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
	public sealed class JsonArrayAttribute : JsonContainerAttribute
	{
		private bool _allowNullItems;

		public bool AllowNullItems
		{
			get
			{
				return _allowNullItems;
			}
			set
			{
				_allowNullItems = value;
			}
		}

		public JsonArrayAttribute()
		{
		}

		public JsonArrayAttribute(bool allowNullItems)
		{
			_allowNullItems = allowNullItems;
		}

		public JsonArrayAttribute(string id)
			: base(id)
		{
		}
	}
	[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false)]
	public sealed class JsonConstructorAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
	public abstract class JsonContainerAttribute : Attribute
	{
		internal bool? _isReference;

		internal bool? _itemIsReference;

		internal ReferenceLoopHandling? _itemReferenceLoopHandling;

		internal TypeNameHandling? _itemTypeNameHandling;

		private Type _namingStrategyType;

		private object[] _namingStrategyParameters;

		public string Id { get; set; }

		public string Title { get; set; }

		public string Description { get; set; }

		public Type ItemConverterType { get; set; }

		public object[] ItemConverterParameters { get; set; }

		public Type NamingStrategyType
		{
			get
			{
				return _namingStrategyType;
			}
			set
			{
				_namingStrategyType = value;
				NamingStrategyInstance = null;
			}
		}

		public object[] NamingStrategyParameters
		{
			get
			{
				return _namingStrategyParameters;
			}
			set
			{
				_namingStrategyParameters = value;
				NamingStrategyInstance = null;
			}
		}

		internal NamingStrategy NamingStrategyInstance { get; set; }

		public bool IsReference
		{
			get
			{
				return _isReference ?? false;
			}
			set
			{
				_isReference = value;
			}
		}

		public bool ItemIsReference
		{
			get
			{
				return _itemIsReference ?? false;
			}
			set
			{
				_itemIsReference = value;
			}
		}

		public ReferenceLoopHandling ItemReferenceLoopHandling
		{
			get
			{
				return _itemReferenceLoopHandling ?? ReferenceLoopHandling.Error;
			}
			set
			{
				_itemReferenceLoopHandling = value;
			}
		}

		public TypeNameHandling ItemTypeNameHandling
		{
			get
			{
				return _itemTypeNameHandling ?? TypeNameHandling.None;
			}
			set
			{
				_itemTypeNameHandling = value;
			}
		}

		protected JsonContainerAttribute()
		{
		}

		protected JsonContainerAttribute(string id)
		{
			Id = id;
		}
	}
	public static class JsonConvert
	{
		public static readonly string True = "true";

		public static readonly string False = "false";

		public static readonly string Null = "null";

		public static readonly string Undefined = "undefined";

		public static readonly string PositiveInfinity = "Infinity";

		public static readonly string NegativeInfinity = "-Infinity";

		public static readonly string NaN = "NaN";

		public static Func<JsonSerializerSettings> DefaultSettings { get; set; }

		public static string ToString(DateTime value)
		{
			return ToString(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.RoundtripKind);
		}

		public static string ToString(DateTime value, DateFormatHandling format, DateTimeZoneHandling timeZoneHandling)
		{
			DateTime value2 = DateTimeUtils.EnsureDateTime(value, timeZoneHandling);
			using StringWriter stringWriter = StringUtils.CreateStringWriter(64);
			stringWriter.Write('"');
			DateTimeUtils.WriteDateTimeString(stringWriter, value2, format, null, CultureInfo.InvariantCulture);
			stringWriter.Write('"');
			return stringWriter.ToString();
		}

		public static string ToString(DateTimeOffset value)
		{
			return ToString(value, DateFormatHandling.IsoDateFormat);
		}

		public static string ToString(DateTimeOffset value, DateFormatHandling format)
		{
			using StringWriter stringWriter = StringUtils.CreateStringWriter(64);
			stringWriter.Write('"');
			DateTimeUtils.WriteDateTimeOffsetString(stringWriter, value, format, null, CultureInfo.InvariantCulture);
			stringWriter.Write('"');
			return stringWriter.ToString();
		}

		public static string ToString(bool value)
		{
			if (!value)
			{
				return False;
			}
			return True;
		}

		public static string ToString(char value)
		{
			return ToString(char.ToString(value));
		}

		public static string ToString(Enum value)
		{
			return value.ToString("D");
		}

		public static string ToString(int value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(short value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(ushort value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(uint value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(long value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(ulong value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(float value)
		{
			return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
		}

		internal static string ToString(float value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
		{
			return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable);
		}

		private static string EnsureFloatFormat(double value, string text, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
		{
			if (floatFormatHandling == FloatFormatHandling.Symbol || (!double.IsInfinity(value) && !double.IsNaN(value)))
			{
				return text;
			}
			if (floatFormatHandling == FloatFormatHandling.DefaultValue)
			{
				if (nullable)
				{
					return Null;
				}
				return "0.0";
			}
			return quoteChar + text + quoteChar;
		}

		public static string ToString(double value)
		{
			return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
		}

		internal static string ToString(double value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
		{
			return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable);
		}

		private static string EnsureDecimalPlace(double value, string text)
		{
			if (double.IsNaN(value) || double.IsInfinity(value) || text.IndexOf('.') != -1 || text.IndexOf('E') != -1 || text.IndexOf('e') != -1)
			{
				return text;
			}
			return text + ".0";
		}

		private static string EnsureDecimalPlace(string text)
		{
			if (text.IndexOf('.') != -1)
			{
				return text;
			}
			return text + ".0";
		}

		public static string ToString(byte value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		[CLSCompliant(false)]
		public static string ToString(sbyte value)
		{
			return value.ToString(null, CultureInfo.InvariantCulture);
		}

		public static string ToString(decimal value)
		{
			return EnsureDecimalPlace(value.ToString(null, CultureInfo.InvariantCulture));
		}

		public static string ToString(Guid value)
		{
			return ToString(value, '"');
		}

		internal static string ToString(Guid value, char quoteChar)
		{
			string text = value.ToString("D", CultureInfo.InvariantCulture);
			string text2 = quoteChar.ToString(CultureInfo.InvariantCulture);
			return text2 + text + text2;
		}

		public static string ToString(TimeSpan value)
		{
			return ToString(value, '"');
		}

		internal static string ToString(TimeSpan value, char quoteChar)
		{
			return ToString(value.ToString(), quoteChar);
		}

		public static string ToString(Uri value)
		{
			if (value == null)
			{
				return Null;
			}
			return ToString(value, '"');
		}

		internal static string ToString(Uri value, char quoteChar)
		{
			return ToString(value.OriginalString, quoteChar);
		}

		public static string ToString(string value)
		{
			return ToString(value, '"');
		}

		public static string ToString(string value, char delimiter)
		{
			return ToString(value, delimiter, StringEscapeHandling.Default);
		}

		public static string ToString(string value, char delimiter, StringEscapeHandling stringEscapeHandling)
		{
			if (delimiter != '"' && delimiter != '\'')
			{
				throw new ArgumentException("Delimiter must be a single or double quote.", "delimiter");
			}
			return JavaScriptUtils.ToEscapedJavaScriptString(value, delimiter, appendDelimiters: true, stringEscapeHandling);
		}

		public static string ToString(object value)
		{
			if (value == null)
			{
				return Null;
			}
			return ConvertUtils.GetTypeCode(value.GetType()) switch
			{
				PrimitiveTypeCode.String => ToString((string)value), 
				PrimitiveTypeCode.Char => ToString((char)value), 
				PrimitiveTypeCode.Boolean => ToString((bool)value), 
				PrimitiveTypeCode.SByte => ToString((sbyte)value), 
				PrimitiveTypeCode.Int16 => ToString((short)value), 
				PrimitiveTypeCode.UInt16 => ToString((ushort)value), 
				PrimitiveTypeCode.Int32 => ToString((int)value), 
				PrimitiveTypeCode.Byte => ToString((byte)value), 
				PrimitiveTypeCode.UInt32 => ToString((uint)value), 
				PrimitiveTypeCode.Int64 => ToString((long)value), 
				PrimitiveTypeCode.UInt64 => ToString((ulong)value), 
				PrimitiveTypeCode.Single => ToString((float)value), 
				PrimitiveTypeCode.Double => ToString((double)value), 
				PrimitiveTypeCode.DateTime => ToString((DateTime)value), 
				PrimitiveTypeCode.Decimal => ToString((decimal)value), 
				PrimitiveTypeCode.DBNull => Null, 
				PrimitiveTypeCode.DateTimeOffset => ToString((DateTimeOffset)value), 
				PrimitiveTypeCode.Guid => ToString((Guid)value), 
				PrimitiveTypeCode.Uri => ToString((Uri)value), 
				PrimitiveTypeCode.TimeSpan => ToString((TimeSpan)value), 
				_ => throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType())), 
			};
		}

		public static string SerializeObject(object value)
		{
			return SerializeObject(value, (Type)null, (JsonSerializerSettings)null);
		}

		public static string SerializeObject(object value, Formatting formatting)
		{
			return SerializeObject(value, formatting, (JsonSerializerSettings)null);
		}

		public static string SerializeObject(object value, params JsonConverter[] converters)
		{
			JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
			{
				Converters = converters
			} : null);
			return SerializeObject(value, null, settings);
		}

		public static string SerializeObject(object value, Formatting formatting, params JsonConverter[] converters)
		{
			JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
			{
				Converters = converters
			} : null);
			return SerializeObject(value, null, formatting, settings);
		}

		public static string SerializeObject(object value, JsonSerializerSettings settings)
		{
			return SerializeObject(value, null, settings);
		}

		public static string SerializeObject(object value, Type type, JsonSerializerSettings settings)
		{
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			return SerializeObjectInternal(value, type, jsonSerializer);
		}

		public static string SerializeObject(object value, Formatting formatting, JsonSerializerSettings settings)
		{
			return SerializeObject(value, null, formatting, settings);
		}

		public static string SerializeObject(object value, Type type, Formatting formatting, JsonSerializerSettings settings)
		{
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			jsonSerializer.Formatting = formatting;
			return SerializeObjectInternal(value, type, jsonSerializer);
		}

		private static string SerializeObjectInternal(object value, Type type, JsonSerializer jsonSerializer)
		{
			StringWriter stringWriter = new StringWriter(new StringBuilder(256), CultureInfo.InvariantCulture);
			using (JsonTextWriter jsonTextWriter = new JsonTextWriter(stringWriter))
			{
				jsonTextWriter.Formatting = jsonSerializer.Formatting;
				jsonSerializer.Serialize(jsonTextWriter, value, type);
			}
			return stringWriter.ToString();
		}

		public static object DeserializeObject(string value)
		{
			return DeserializeObject(value, (Type)null, (JsonSerializerSettings)null);
		}

		public static object DeserializeObject(string value, JsonSerializerSettings settings)
		{
			return DeserializeObject(value, null, settings);
		}

		public static object DeserializeObject(string value, Type type)
		{
			return DeserializeObject(value, type, (JsonSerializerSettings)null);
		}

		public static T DeserializeObject<T>(string value)
		{
			return JsonConvert.DeserializeObject<T>(value, (JsonSerializerSettings)null);
		}

		public static T DeserializeAnonymousType<T>(string value, T anonymousTypeObject)
		{
			return DeserializeObject<T>(value);
		}

		public static T DeserializeAnonymousType<T>(string value, T anonymousTypeObject, JsonSerializerSettings settings)
		{
			return DeserializeObject<T>(value, settings);
		}

		public static T DeserializeObject<T>(string value, params JsonConverter[] converters)
		{
			return (T)DeserializeObject(value, typeof(T), converters);
		}

		public static T DeserializeObject<T>(string value, JsonSerializerSettings settings)
		{
			return (T)DeserializeObject(value, typeof(T), settings);
		}

		public static object DeserializeObject(string value, Type type, params JsonConverter[] converters)
		{
			JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
			{
				Converters = converters
			} : null);
			return DeserializeObject(value, type, settings);
		}

		public static object DeserializeObject(string value, Type type, JsonSerializerSettings settings)
		{
			ValidationUtils.ArgumentNotNull(value, "value");
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			if (!jsonSerializer.IsCheckAdditionalContentSet())
			{
				jsonSerializer.CheckAdditionalContent = true;
			}
			using JsonTextReader reader = new JsonTextReader(new StringReader(value));
			return jsonSerializer.Deserialize(reader, type);
		}

		public static void PopulateObject(string value, object target)
		{
			PopulateObject(value, target, null);
		}

		public static void PopulateObject(string value, object target, JsonSerializerSettings settings)
		{
			JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
			using JsonReader jsonReader = new JsonTextReader(new StringReader(value));
			jsonSerializer.Populate(jsonReader, target);
			if (jsonReader.Read() && jsonReader.TokenType != JsonToken.Comment)
			{
				throw new JsonSerializationException("Additional text found in JSON string after finishing deserializing object.");
			}
		}
	}
	public abstract class JsonConverter
	{
		public virtual bool CanRead => true;

		public virtual bool CanWrite => true;

		public abstract void WriteJson(JsonWriter writer, object value, JsonSerializer serializer);

		public abstract object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer);

		public abstract bool CanConvert(Type objectType);
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Parameter, AllowMultiple = false)]
	public sealed class JsonConverterAttribute : Attribute
	{
		private readonly Type _converterType;

		public Type ConverterType => _converterType;

		public object[] ConverterParameters { get; private set; }

		public JsonConverterAttribute(Type converterType)
		{
			if ((object)converterType == null)
			{
				throw new ArgumentNullException("converterType");
			}
			_converterType = converterType;
		}

		public JsonConverterAttribute(Type converterType, params object[] converterParameters)
			: this(converterType)
		{
			ConverterParameters = converterParameters;
		}
	}
	public class JsonConverterCollection : Collection<JsonConverter>
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
	public sealed class JsonDictionaryAttribute : JsonContainerAttribute
	{
		public JsonDictionaryAttribute()
		{
		}

		public JsonDictionaryAttribute(string id)
			: base(id)
		{
		}
	}
	[Serializable]
	public class JsonException : Exception
	{
		public JsonException()
		{
		}

		public JsonException(string message)
			: base(message)
		{
		}

		public JsonException(string message, Exception innerException)
			: base(message, innerException)
		{
		}

		public JsonException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		internal static JsonException Create(IJsonLineInfo lineInfo, string path, string message)
		{
			message = JsonPosition.FormatMessage(lineInfo, path, message);
			return new JsonException(message);
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public class JsonExtensionDataAttribute : Attribute
	{
		public bool WriteData { get; set; }

		public bool ReadData { get; set; }

		public JsonExtensionDataAttribute()
		{
			WriteData = true;
			ReadData = true;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public sealed class JsonIgnoreAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)]
	public sealed class JsonObjectAttribute : JsonContainerAttribute
	{
		private MemberSerialization _memberSerialization;

		internal Required? _itemRequired;

		public MemberSerialization MemberSerialization
		{
			get
			{
				return _memberSerialization;
			}
			set
			{
				_memberSerialization = value;
			}
		}

		public Required ItemRequired
		{
			get
			{
				return _itemRequired ?? Required.Default;
			}
			set
			{
				_itemRequired = value;
			}
		}

		public JsonObjectAttribute()
		{
		}

		public JsonObjectAttribute(MemberSerialization memberSerialization)
		{
			MemberSerialization = memberSerialization;
		}

		public JsonObjectAttribute(string id)
			: base(id)
		{
		}
	}
	internal enum JsonContainerType
	{
		None,
		Object,
		Array,
		Constructor
	}
	internal struct JsonPosition
	{
		private static readonly char[] SpecialCharacters = new char[6] { '.', ' ', '[', ']', '(', ')' };

		internal JsonContainerType Type;

		internal int Position;

		internal string PropertyName;

		internal bool HasIndex;

		public JsonPosition(JsonContainerType type)
		{
			Type = type;
			HasIndex = TypeHasIndex(type);
			Position = -1;
			PropertyName = null;
		}

		internal int CalculateLength()
		{
			switch (Type)
			{
			case JsonContainerType.Object:
				return PropertyName.Length + 5;
			case JsonContainerType.Array:
			case JsonContainerType.Constructor:
				return MathUtils.IntLength((ulong)Position) + 2;
			default:
				throw new ArgumentOutOfRangeException("Type");
			}
		}

		internal void WriteTo(StringBuilder sb)
		{
			switch (Type)
			{
			case JsonContainerType.Object:
			{
				string propertyName = PropertyName;
				if (propertyName.IndexOfAny(SpecialCharacters) != -1)
				{
					sb.Append("['");
					sb.Append(propertyName);
					sb.Append("']");
					break;
				}
				if (sb.Length > 0)
				{
					sb.Append('.');
				}
				sb.Append(propertyName);
				break;
			}
			case JsonContainerType.Array:
			case JsonContainerType.Constructor:
				sb.Append('[');
				sb.Append(Position);
				sb.Append(']');
				break;
			}
		}

		internal static bool TypeHasIndex(JsonContainerType type)
		{
			if (type != JsonContainerType.Array)
			{
				return type == JsonContainerType.Constructor;
			}
			return true;
		}

		internal static string BuildPath(List<JsonPosition> positions, JsonPosition? currentPosition)
		{
			int num = 0;
			if (positions != null)
			{
				for (int i = 0; i < positions.Count; i++)
				{
					num += positions[i].CalculateLength();
				}
			}
			if (currentPosition.HasValue)
			{
				num += currentPosition.GetValueOrDefault().CalculateLength();
			}
			StringBuilder stringBuilder = new StringBuilder(num);
			if (positions != null)
			{
				foreach (JsonPosition position in positions)
				{
					position.WriteTo(stringBuilder);
				}
			}
			currentPosition?.WriteTo(stringBuilder);
			return stringBuilder.ToString();
		}

		internal static string FormatMessage(IJsonLineInfo lineInfo, string path, string message)
		{
			if (!message.EndsWith(Environment.NewLine, StringComparison.Ordinal))
			{
				message = message.Trim();
				if (!StringUtils.EndsWith(message, '.'))
				{
					message += ".";
				}
				message += " ";
			}
			message += "Path '{0}'".FormatWith(CultureInfo.InvariantCulture, path);
			if (lineInfo != null && lineInfo.HasLineInfo())
			{
				message += ", line {0}, position {1}".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition);
			}
			message += ".";
			return message;
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
	public sealed class JsonPropertyAttribute : Attribute
	{
		internal NullValueHandling? _nullValueHandling;

		internal DefaultValueHandling? _defaultValueHandling;

		internal ReferenceLoopHandling? _referenceLoopHandling;

		internal ObjectCreationHandling? _objectCreationHandling;

		internal TypeNameHandling? _typeNameHandling;

		internal bool? _isReference;

		internal int? _order;

		internal Required? _required;

		internal bool? _itemIsReference;

		internal ReferenceLoopHandling? _itemReferenceLoopHandling;

		internal TypeNameHandling? _itemTypeNameHandling;

		public Type ItemConverterType { get; set; }

		public object[] ItemConverterParameters { get; set; }

		public Type NamingStrategyType { get; set; }

		public object[] NamingStrategyParameters { get; set; }

		public NullValueHandling NullValueHandling
		{
			get
			{
				return _nullValueHandling ?? NullValueHandling.Include;
			}
			set
			{
				_nullValueHandling = value;
			}
		}

		public DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling ?? DefaultValueHandling.Include;
			}
			set
			{
				_defaultValueHandling = value;
			}
		}

		public ReferenceLoopHandling ReferenceLoopHandling
		{
			get
			{
				return _referenceLoopHandling ?? ReferenceLoopHandling.Error;
			}
			set
			{
				_referenceLoopHandling = value;
			}
		}

		public ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling ?? ObjectCreationHandling.Auto;
			}
			set
			{
				_objectCreationHandling = value;
			}
		}

		public TypeNameHandling TypeNameHandling
		{
			get
			{
				return _typeNameHandling ?? TypeNameHandling.None;
			}
			set
			{
				_typeNameHandling = value;
			}
		}

		public bool IsReference
		{
			get
			{
				return _isReference ?? false;
			}
			set
			{
				_isReference = value;
			}
		}

		public int Order
		{
			get
			{
				return _order ?? 0;
			}
			set
			{
				_order = value;
			}
		}

		public Required Required
		{
			get
			{
				return _required ?? Required.Default;
			}
			set
			{
				_required = value;
			}
		}

		public string PropertyName { get; set; }

		public ReferenceLoopHandling ItemReferenceLoopHandling
		{
			get
			{
				return _itemReferenceLoopHandling ?? ReferenceLoopHandling.Error;
			}
			set
			{
				_itemReferenceLoopHandling = value;
			}
		}

		public TypeNameHandling ItemTypeNameHandling
		{
			get
			{
				return _itemTypeNameHandling ?? TypeNameHandling.None;
			}
			set
			{
				_itemTypeNameHandling = value;
			}
		}

		public bool ItemIsReference
		{
			get
			{
				return _itemIsReference ?? false;
			}
			set
			{
				_itemIsReference = value;
			}
		}

		public JsonPropertyAttribute()
		{
		}

		public JsonPropertyAttribute(string propertyName)
		{
			PropertyName = propertyName;
		}
	}
	public abstract class JsonReader : IDisposable
	{
		protected internal enum State
		{
			Start,
			Complete,
			Property,
			ObjectStart,
			Object,
			ArrayStart,
			Array,
			Closed,
			PostValue,
			ConstructorStart,
			Constructor,
			Error,
			Finished
		}

		private JsonToken _tokenType;

		private object _value;

		internal char _quoteChar;

		internal State _currentState;

		private JsonPosition _currentPosition;

		private CultureInfo _culture;

		private DateTimeZoneHandling _dateTimeZoneHandling;

		private int? _maxDepth;

		private bool _hasExceededMaxDepth;

		internal DateParseHandling _dateParseHandling;

		internal FloatParseHandling _floatParseHandling;

		private string _dateFormatString;

		private List<JsonPosition> _stack;

		protected State CurrentState => _currentState;

		public bool CloseInput { get; set; }

		public bool SupportMultipleContent { get; set; }

		public virtual char QuoteChar
		{
			get
			{
				return _quoteChar;
			}
			protected internal set
			{
				_quoteChar = value;
			}
		}

		public DateTimeZoneHandling DateTimeZoneHandling
		{
			get
			{
				return _dateTimeZoneHandling;
			}
			set
			{
				if (value < DateTimeZoneHandling.Local || value > DateTimeZoneHandling.RoundtripKind)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_dateTimeZoneHandling = value;
			}
		}

		public DateParseHandling DateParseHandling
		{
			get
			{
				return _dateParseHandling;
			}
			set
			{
				if (value < DateParseHandling.None || value > DateParseHandling.DateTimeOffset)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_dateParseHandling = value;
			}
		}

		public FloatParseHandling FloatParseHandling
		{
			get
			{
				return _floatParseHandling;
			}
			set
			{
				if (value < FloatParseHandling.Double || value > FloatParseHandling.Decimal)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_floatParseHandling = value;
			}
		}

		public string DateFormatString
		{
			get
			{
				return _dateFormatString;
			}
			set
			{
				_dateFormatString = value;
			}
		}

		public int? MaxDepth
		{
			get
			{
				return _maxDepth;
			}
			set
			{
				if (value <= 0)
				{
					throw new ArgumentException("Value must be positive.", "value");
				}
				_maxDepth = value;
			}
		}

		public virtual JsonToken TokenType => _tokenType;

		public virtual object Value => _value;

		public virtual Type ValueType
		{
			get
			{
				if (_value == null)
				{
					return null;
				}
				return _value.GetType();
			}
		}

		public virtual int Depth
		{
			get
			{
				int num = ((_stack != null) ? _stack.Count : 0);
				if (JsonTokenUtils.IsStartToken(TokenType) || _currentPosition.Type == JsonContainerType.None)
				{
					return num;
				}
				return num + 1;
			}
		}

		public virtual string Path
		{
			get
			{
				if (_currentPosition.Type == JsonContainerType.None)
				{
					return string.Empty;
				}
				JsonPosition? currentPosition = ((_currentState != State.ArrayStart && _currentState != State.ConstructorStart && _currentState != State.ObjectStart) ? new JsonPosition?(_currentPosition) : null);
				return JsonPosition.BuildPath(_stack, currentPosition);
			}
		}

		public CultureInfo Culture
		{
			get
			{
				return _culture ?? CultureInfo.InvariantCulture;
			}
			set
			{
				_culture = value;
			}
		}

		internal JsonPosition GetPosition(int depth)
		{
			if (_stack != null && depth < _stack.Count)
			{
				return _stack[depth];
			}
			return _currentPosition;
		}

		protected JsonReader()
		{
			_currentState = State.Start;
			_dateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
			_dateParseHandling = DateParseHandling.DateTime;
			_floatParseHandling = FloatParseHandling.Double;
			CloseInput = true;
		}

		private void Push(JsonContainerType value)
		{
			UpdateScopeWithFinishedValue();
			if (_currentPosition.Type == JsonContainerType.None)
			{
				_currentPosition = new JsonPosition(value);
				return;
			}
			if (_stack == null)
			{
				_stack = new List<JsonPosition>();
			}
			_stack.Add(_currentPosition);
			_currentPosition = new JsonPosition(value);
			if (_maxDepth.HasValue)
			{
				int num = Depth + 1;
				int? maxDepth = _maxDepth;
				if (num > maxDepth.GetValueOrDefault() && maxDepth.HasValue && !_hasExceededMaxDepth)
				{
					_hasExceededMaxDepth = true;
					throw JsonReaderException.Create(this, "The reader's MaxDepth of {0} has been exceeded.".FormatWith(CultureInfo.InvariantCulture, _maxDepth));
				}
			}
		}

		private JsonContainerType Pop()
		{
			JsonPosition currentPosition;
			if (_stack != null && _stack.Count > 0)
			{
				currentPosition = _currentPosition;
				_currentPosition = _stack[_stack.Count - 1];
				_stack.RemoveAt(_stack.Count - 1);
			}
			else
			{
				currentPosition = _currentPosition;
				_currentPosition = default(JsonPosition);
			}
			if (_maxDepth.HasValue && Depth <= _maxDepth)
			{
				_hasExceededMaxDepth = false;
			}
			return currentPosition.Type;
		}

		private JsonContainerType Peek()
		{
			return _currentPosition.Type;
		}

		public abstract bool Read();

		public virtual int? ReadAsInt32()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
				if (!(Value is int))
				{
					SetToken(JsonToken.Integer, Convert.ToInt32(Value, CultureInfo.InvariantCulture), updateIndex: false);
				}
				return (int)Value;
			case JsonToken.String:
			{
				string s = (string)Value;
				return ReadInt32String(s);
			}
			default:
				throw JsonReaderException.Create(this, "Error reading integer. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal int? ReadInt32String(string s)
		{
			if (string.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (int.TryParse(s, NumberStyles.Integer, Culture, out var result))
			{
				SetToken(JsonToken.Integer, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual string ReadAsString()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.String:
				return (string)Value;
			default:
				if (JsonTokenUtils.IsPrimitiveToken(contentToken) && Value != null)
				{
					string text = ((Value is IFormattable) ? ((IFormattable)Value).ToString(null, Culture) : ((!(Value is Uri)) ? Value.ToString() : ((Uri)Value).OriginalString));
					SetToken(JsonToken.String, text, updateIndex: false);
					return text;
				}
				throw JsonReaderException.Create(this, "Error reading string. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		public virtual byte[] ReadAsBytes()
		{
			JsonToken contentToken = GetContentToken();
			if (contentToken == JsonToken.None)
			{
				return null;
			}
			if (TokenType == JsonToken.StartObject)
			{
				ReadIntoWrappedTypeObject();
				byte[] array = ReadAsBytes();
				ReaderReadAndAssert();
				if (TokenType != JsonToken.EndObject)
				{
					throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
				}
				SetToken(JsonToken.Bytes, array, updateIndex: false);
				return array;
			}
			switch (contentToken)
			{
			case JsonToken.String:
			{
				string text = (string)Value;
				Guid g;
				byte[] array3 = ((text.Length == 0) ? new byte[0] : ((!ConvertUtils.TryConvertGuid(text, out g)) ? Convert.FromBase64String(text) : g.ToByteArray()));
				SetToken(JsonToken.Bytes, array3, updateIndex: false);
				return array3;
			}
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Bytes:
				if ((object)ValueType == typeof(Guid))
				{
					byte[] array2 = ((Guid)Value).ToByteArray();
					SetToken(JsonToken.Bytes, array2, updateIndex: false);
					return array2;
				}
				return (byte[])Value;
			case JsonToken.StartArray:
				return ReadArrayIntoByteArray();
			default:
				throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal byte[] ReadArrayIntoByteArray()
		{
			List<byte> list = new List<byte>();
			while (true)
			{
				JsonToken contentToken = GetContentToken();
				switch (contentToken)
				{
				case JsonToken.None:
					throw JsonReaderException.Create(this, "Unexpected end when reading bytes.");
				case JsonToken.Integer:
					break;
				case JsonToken.EndArray:
				{
					byte[] array = list.ToArray();
					SetToken(JsonToken.Bytes, array, updateIndex: false);
					return array;
				}
				default:
					throw JsonReaderException.Create(this, "Unexpected token when reading bytes: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
				}
				list.Add(Convert.ToByte(Value, CultureInfo.InvariantCulture));
			}
		}

		public virtual double? ReadAsDouble()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
				if (!(Value is double))
				{
					double num = Convert.ToDouble(Value, CultureInfo.InvariantCulture);
					SetToken(JsonToken.Float, num, updateIndex: false);
				}
				return (double)Value;
			case JsonToken.String:
				return ReadDoubleString((string)Value);
			default:
				throw JsonReaderException.Create(this, "Error reading double. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal double? ReadDoubleString(string s)
		{
			if (string.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (double.TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, Culture, out var result))
			{
				SetToken(JsonToken.Float, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to double: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual bool? ReadAsBoolean()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
			{
				bool flag = Convert.ToBoolean(Value, CultureInfo.InvariantCulture);
				SetToken(JsonToken.Boolean, flag, updateIndex: false);
				return flag;
			}
			case JsonToken.String:
				return ReadBooleanString((string)Value);
			case JsonToken.Boolean:
				return (bool)Value;
			default:
				throw JsonReaderException.Create(this, "Error reading boolean. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal bool? ReadBooleanString(string s)
		{
			if (string.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (bool.TryParse(s, out var result))
			{
				SetToken(JsonToken.Boolean, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to boolean: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual decimal? ReadAsDecimal()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Integer:
			case JsonToken.Float:
				if (!(Value is decimal))
				{
					SetToken(JsonToken.Float, Convert.ToDecimal(Value, CultureInfo.InvariantCulture), updateIndex: false);
				}
				return (decimal)Value;
			case JsonToken.String:
				return ReadDecimalString((string)Value);
			default:
				throw JsonReaderException.Create(this, "Error reading decimal. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal decimal? ReadDecimalString(string s)
		{
			if (string.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (decimal.TryParse(s, NumberStyles.Number, Culture, out var result))
			{
				SetToken(JsonToken.Float, result, updateIndex: false);
				return result;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual DateTime? ReadAsDateTime()
		{
			switch (GetContentToken())
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Date:
				if (Value is DateTimeOffset)
				{
					SetToken(JsonToken.Date, ((DateTimeOffset)Value).DateTime, updateIndex: false);
				}
				return (DateTime)Value;
			case JsonToken.String:
			{
				string s = (string)Value;
				return ReadDateTimeString(s);
			}
			default:
				throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
			}
		}

		internal DateTime? ReadDateTimeString(string s)
		{
			if (string.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (DateTimeUtils.TryParseDateTime(s, DateTimeZoneHandling, _dateFormatString, Culture, out var dt))
			{
				dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling);
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			if (DateTime.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt))
			{
				dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling);
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			throw JsonReaderException.Create(this, "Could not convert string to DateTime: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		public virtual DateTimeOffset? ReadAsDateTimeOffset()
		{
			JsonToken contentToken = GetContentToken();
			switch (contentToken)
			{
			case JsonToken.None:
			case JsonToken.Null:
			case JsonToken.EndArray:
				return null;
			case JsonToken.Date:
				if (Value is DateTime)
				{
					SetToken(JsonToken.Date, new DateTimeOffset((DateTime)Value), updateIndex: false);
				}
				return (DateTimeOffset)Value;
			case JsonToken.String:
			{
				string s = (string)Value;
				return ReadDateTimeOffsetString(s);
			}
			default:
				throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
			}
		}

		internal DateTimeOffset? ReadDateTimeOffsetString(string s)
		{
			if (string.IsNullOrEmpty(s))
			{
				SetToken(JsonToken.Null, null, updateIndex: false);
				return null;
			}
			if (DateTimeUtils.TryParseDateTimeOffset(s, _dateFormatString, Culture, out var dt))
			{
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			if (DateTimeOffset.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt))
			{
				SetToken(JsonToken.Date, dt, updateIndex: false);
				return dt;
			}
			SetToken(JsonToken.String, s, updateIndex: false);
			throw JsonReaderException.Create(this, "Could not convert string to DateTimeOffset: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
		}

		internal void ReaderReadAndAssert()
		{
			if (!Read())
			{
				throw CreateUnexpectedEndException();
			}
		}

		internal JsonReaderException CreateUnexpectedEndException()
		{
			return JsonReaderException.Create(this, "Unexpected end when reading JSON.");
		}

		internal void ReadIntoWrappedTypeObject()
		{
			ReaderReadAndAssert();
			if (Value.ToString() == "$type")
			{
				ReaderReadAndAssert();
				if (Value != null && Value.ToString().StartsWith("System.Byte[]", StringComparison.Ordinal))
				{
					ReaderReadAndAssert();
					if (Value.ToString() == "$value")
					{
						return;
					}
				}
			}
			throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, JsonToken.StartObject));
		}

		public void Skip()
		{
			if (TokenType == JsonToken.PropertyName)
			{
				Read();
			}
			if (JsonTokenUtils.IsStartToken(TokenType))
			{
				int depth = Depth;
				while (Read() && depth < Depth)
				{
				}
			}
		}

		protected void SetToken(JsonToken newToken)
		{
			SetToken(newToken, null, updateIndex: true);
		}

		protected void SetToken(JsonToken newToken, object value)
		{
			SetToken(newToken, value, updateIndex: true);
		}

		internal void SetToken(JsonToken newToken, object value, bool updateIndex)
		{
			_tokenType = newToken;
			_value = value;
			switch (newToken)
			{
			case JsonToken.StartObject:
				_currentState = State.ObjectStart;
				Push(JsonContainerType.Object);
				break;
			case JsonToken.StartArray:
				_currentState = State.ArrayStart;
				Push(JsonContainerType.Array);
				break;
			case JsonToken.StartConstructor:
				_currentState = State.ConstructorStart;
				Push(JsonContainerType.Constructor);
				break;
			case JsonToken.EndObject:
				ValidateEnd(JsonToken.EndObject);
				break;
			case JsonToken.EndArray:
				ValidateEnd(JsonToken.EndArray);
				break;
			case JsonToken.EndConstructor:
				ValidateEnd(JsonToken.EndConstructor);
				break;
			case JsonToken.PropertyName:
				_currentState = State.Property;
				_currentPosition.PropertyName = (string)value;
				break;
			case JsonToken.Raw:
			case JsonToken.Integer:
			case JsonToken.Float:
			case JsonToken.String:
			case JsonToken.Boolean:
			case JsonToken.Null:
			case JsonToken.Undefined:
			case JsonToken.Date:
			case JsonToken.Bytes:
				SetPostValueState(updateIndex);
				break;
			case JsonToken.Comment:
				break;
			}
		}

		internal void SetPostValueState(bool updateIndex)
		{
			if (Peek() != 0)
			{
				_currentState = State.PostValue;
			}
			else
			{
				SetFinished();
			}
			if (updateIndex)
			{
				UpdateScopeWithFinishedValue();
			}
		}

		private void UpdateScopeWithFinishedValue()
		{
			if (_currentPosition.HasIndex)
			{
				_currentPosition.Position++;
			}
		}

		private void ValidateEnd(JsonToken endToken)
		{
			JsonContainerType jsonContainerType = Pop();
			if (GetTypeForCloseToken(endToken) != jsonContainerType)
			{
				throw JsonReaderException.Create(this, "JsonToken {0} is not valid for closing JsonType {1}.".FormatWith(CultureInfo.InvariantCulture, endToken, jsonContainerType));
			}
			if (Peek() != 0)
			{
				_currentState = State.PostValue;
			}
			else
			{
				SetFinished();
			}
		}

		protected void SetStateBasedOnCurrent()
		{
			JsonContainerType jsonContainerType = Peek();
			switch (jsonContainerType)
			{
			case JsonContainerType.Object:
				_currentState = State.Object;
				break;
			case JsonContainerType.Array:
				_currentState = State.Array;
				break;
			case JsonContainerType.Constructor:
				_currentState = State.Constructor;
				break;
			case JsonContainerType.None:
				SetFinished();
				break;
			default:
				throw JsonReaderException.Create(this, "While setting the reader state back to current object an unexpected JsonType was encountered: {0}".FormatWith(CultureInfo.InvariantCulture, jsonContainerType));
			}
		}

		private void SetFinished()
		{
			if (SupportMultipleContent)
			{
				_currentState = State.Start;
			}
			else
			{
				_currentState = State.Finished;
			}
		}

		private JsonContainerType GetTypeForCloseToken(JsonToken token)
		{
			return token switch
			{
				JsonToken.EndObject => JsonContainerType.Object, 
				JsonToken.EndArray => JsonContainerType.Array, 
				JsonToken.EndConstructor => JsonContainerType.Constructor, 
				_ => throw JsonReaderException.Create(this, "Not a valid close JsonToken: {0}".FormatWith(CultureInfo.InvariantCulture, token)), 
			};
		}

		void IDisposable.Dispose()
		{
			Dispose(disposing: true);
			GC.SuppressFinalize(this);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (_currentState != State.Closed && disposing)
			{
				Close();
			}
		}

		public virtual void Close()
		{
			_currentState = State.Closed;
			_tokenType = JsonToken.None;
			_value = null;
		}

		internal void ReadAndAssert()
		{
			if (!Read())
			{
				throw JsonSerializationException.Create(this, "Unexpected end when reading JSON.");
			}
		}

		internal bool ReadAndMoveToContent()
		{
			if (Read())
			{
				return MoveToContent();
			}
			return false;
		}

		internal bool MoveToContent()
		{
			JsonToken tokenType = TokenType;
			while (tokenType == JsonToken.None || tokenType == JsonToken.Comment)
			{
				if (!Read())
				{
					return false;
				}
				tokenType = TokenType;
			}
			return true;
		}

		private JsonToken GetContentToken()
		{
			JsonToken tokenType;
			do
			{
				if (!Read())
				{
					SetToken(JsonToken.None);
					return JsonToken.None;
				}
				tokenType = TokenType;
			}
			while (tokenType == JsonToken.Comment);
			return tokenType;
		}
	}
	[Serializable]
	public class JsonReaderException : JsonException
	{
		public int LineNumber { get; private set; }

		public int LinePosition { get; private set; }

		public string Path { get; private set; }

		public JsonReaderException()
		{
		}

		public JsonReaderException(string message)
			: base(message)
		{
		}

		public JsonReaderException(string message, Exception innerException)
			: base(message, innerException)
		{
		}

		public JsonReaderException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		internal JsonReaderException(string message, Exception innerException, string path, int lineNumber, int linePosition)
			: base(message, innerException)
		{
			Path = path;
			LineNumber = lineNumber;
			LinePosition = linePosition;
		}

		internal static JsonReaderException Create(JsonReader reader, string message)
		{
			return Create(reader, message, null);
		}

		internal static JsonReaderException Create(JsonReader reader, string message, Exception ex)
		{
			return Create(reader as IJsonLineInfo, reader.Path, message, ex);
		}

		internal static JsonReaderException Create(IJsonLineInfo lineInfo, string path, string message, Exception ex)
		{
			message = JsonPosition.FormatMessage(lineInfo, path, message);
			int lineNumber;
			int linePosition;
			if (lineInfo != null && lineInfo.HasLineInfo())
			{
				lineNumber = lineInfo.LineNumber;
				linePosition = lineInfo.LinePosition;
			}
			else
			{
				lineNumber = 0;
				linePosition = 0;
			}
			return new JsonReaderException(message, ex, path, lineNumber, linePosition);
		}
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
	public sealed class JsonRequiredAttribute : Attribute
	{
	}
	[Serializable]
	public class JsonSerializationException : JsonException
	{
		public JsonSerializationException()
		{
		}

		public JsonSerializationException(string message)
			: base(message)
		{
		}

		public JsonSerializationException(string message, Exception innerException)
			: base(message, innerException)
		{
		}

		public JsonSerializationException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
		}

		internal static JsonSerializationException Create(JsonReader reader, string message)
		{
			return Create(reader, message, null);
		}

		internal static JsonSerializationException Create(JsonReader reader, string message, Exception ex)
		{
			return Create(reader as IJsonLineInfo, reader.Path, message, ex);
		}

		internal static JsonSerializationException Create(IJsonLineInfo lineInfo, string path, string message, Exception ex)
		{
			message = JsonPosition.FormatMessage(lineInfo, path, message);
			return new JsonSerializationException(message, ex);
		}
	}
	public class JsonSerializer
	{
		internal TypeNameHandling _typeNameHandling;

		internal FormatterAssemblyStyle _typeNameAssemblyFormat;

		internal PreserveReferencesHandling _preserveReferencesHandling;

		internal ReferenceLoopHandling _referenceLoopHandling;

		internal MissingMemberHandling _missingMemberHandling;

		internal ObjectCreationHandling _objectCreationHandling;

		internal NullValueHandling _nullValueHandling;

		internal DefaultValueHandling _defaultValueHandling;

		internal ConstructorHandling _constructorHandling;

		internal MetadataPropertyHandling _metadataPropertyHandling;

		internal JsonConverterCollection _converters;

		internal IContractResolver _contractResolver;

		internal ITraceWriter _traceWriter;

		internal IEqualityComparer _equalityComparer;

		internal SerializationBinder _binder;

		internal StreamingContext _context;

		private IReferenceResolver _referenceResolver;

		private Formatting? _formatting;

		private DateFormatHandling? _dateFormatHandling;

		private DateTimeZoneHandling? _dateTimeZoneHandling;

		private DateParseHandling? _dateParseHandling;

		private FloatFormatHandling? _floatFormatHandling;

		private FloatParseHandling? _floatParseHandling;

		private StringEscapeHandling? _stringEscapeHandling;

		private CultureInfo _culture;

		private int? _maxDepth;

		private bool _maxDepthSet;

		private bool? _checkAdditionalContent;

		private string _dateFormatString;

		private bool _dateFormatStringSet;

		public virtual IReferenceResolver ReferenceResolver
		{
			get
			{
				return GetReferenceResolver();
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value", "Reference resolver cannot be null.");
				}
				_referenceResolver = value;
			}
		}

		public virtual SerializationBinder Binder
		{
			get
			{
				return _binder;
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value", "Serialization binder cannot be null.");
				}
				_binder = value;
			}
		}

		public virtual ITraceWriter TraceWriter
		{
			get
			{
				return _traceWriter;
			}
			set
			{
				_traceWriter = value;
			}
		}

		public virtual IEqualityComparer EqualityComparer
		{
			get
			{
				return _equalityComparer;
			}
			set
			{
				_equalityComparer = value;
			}
		}

		public virtual TypeNameHandling TypeNameHandling
		{
			get
			{
				return _typeNameHandling;
			}
			set
			{
				if (value < TypeNameHandling.None || value > TypeNameHandling.Auto)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_typeNameHandling = value;
			}
		}

		public virtual FormatterAssemblyStyle TypeNameAssemblyFormat
		{
			get
			{
				return _typeNameAssemblyFormat;
			}
			set
			{
				if (value < FormatterAssemblyStyle.Simple || value > FormatterAssemblyStyle.Full)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_typeNameAssemblyFormat = value;
			}
		}

		public virtual PreserveReferencesHandling PreserveReferencesHandling
		{
			get
			{
				return _preserveReferencesHandling;
			}
			set
			{
				if (value < PreserveReferencesHandling.None || value > PreserveReferencesHandling.All)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_preserveReferencesHandling = value;
			}
		}

		public virtual ReferenceLoopHandling ReferenceLoopHandling
		{
			get
			{
				return _referenceLoopHandling;
			}
			set
			{
				if (value < ReferenceLoopHandling.Error || value > ReferenceLoopHandling.Serialize)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_referenceLoopHandling = value;
			}
		}

		public virtual MissingMemberHandling MissingMemberHandling
		{
			get
			{
				return _missingMemberHandling;
			}
			set
			{
				if (value < MissingMemberHandling.Ignore || value > MissingMemberHandling.Error)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_missingMemberHandling = value;
			}
		}

		public virtual NullValueHandling NullValueHandling
		{
			get
			{
				return _nullValueHandling;
			}
			set
			{
				if (value < NullValueHandling.Include || value > NullValueHandling.Ignore)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_nullValueHandling = value;
			}
		}

		public virtual DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling;
			}
			set
			{
				if (value < DefaultValueHandling.Include || value > DefaultValueHandling.IgnoreAndPopulate)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_defaultValueHandling = value;
			}
		}

		public virtual ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling;
			}
			set
			{
				if (value < ObjectCreationHandling.Auto || value > ObjectCreationHandling.Replace)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_objectCreationHandling = value;
			}
		}

		public virtual ConstructorHandling ConstructorHandling
		{
			get
			{
				return _constructorHandling;
			}
			set
			{
				if (value < ConstructorHandling.Default || value > ConstructorHandling.AllowNonPublicDefaultConstructor)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_constructorHandling = value;
			}
		}

		public virtual MetadataPropertyHandling MetadataPropertyHandling
		{
			get
			{
				return _metadataPropertyHandling;
			}
			set
			{
				if (value < MetadataPropertyHandling.Default || value > MetadataPropertyHandling.Ignore)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				_metadataPropertyHandling = value;
			}
		}

		public virtual JsonConverterCollection Converters
		{
			get
			{
				if (_converters == null)
				{
					_converters = new JsonConverterCollection();
				}
				return _converters;
			}
		}

		public virtual IContractResolver ContractResolver
		{
			get
			{
				return _contractResolver;
			}
			set
			{
				_contractResolver = value ?? DefaultContractResolver.Instance;
			}
		}

		public virtual StreamingContext Context
		{
			get
			{
				return _context;
			}
			set
			{
				_context = value;
			}
		}

		public virtual Formatting Formatting
		{
			get
			{
				return _formatting ?? Formatting.None;
			}
			set
			{
				_formatting = value;
			}
		}

		public virtual DateFormatHandling DateFormatHandling
		{
			get
			{
				return _dateFormatHandling ?? DateFormatHandling.IsoDateFormat;
			}
			set
			{
				_dateFormatHandling = value;
			}
		}

		public virtual DateTimeZoneHandling DateTimeZoneHandling
		{
			get
			{
				return _dateTimeZoneHandling ?? DateTimeZoneHandling.RoundtripKind;
			}
			set
			{
				_dateTimeZoneHandling = value;
			}
		}

		public virtual DateParseHandling DateParseHandling
		{
			get
			{
				return _dateParseHandling ?? DateParseHandling.DateTime;
			}
			set
			{
				_dateParseHandling = value;
			}
		}

		public virtual FloatParseHandling FloatParseHandling
		{
			get
			{
				return _floatParseHandling ?? FloatParseHandling.Double;
			}
			set
			{
				_floatParseHandling = value;
			}
		}

		public virtual FloatFormatHandling FloatFormatHandling
		{
			get
			{
				return _floatFormatHandling ?? FloatFormatHandling.String;
			}
			set
			{
				_floatFormatHandling = value;
			}
		}

		public virtual StringEscapeHandling StringEscapeHandling
		{
			get
			{
				return _stringEscapeHandling ?? StringEscapeHandling.Default;
			}
			set
			{
				_stringEscapeHandling = value;
			}
		}

		public virtual string DateFormatString
		{
			get
			{
				return _dateFormatString ?? "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
			}
			set
			{
				_dateFormatString = value;
				_dateFormatStringSet = true;
			}
		}

		public virtual CultureInfo Culture
		{
			get
			{
				return _culture ?? JsonSerializerSettings.DefaultCulture;
			}
			set
			{
				_culture = value;
			}
		}

		public virtual int? MaxDepth
		{
			get
			{
				return _maxDepth;
			}
			set
			{
				if (value <= 0)
				{
					throw new ArgumentException("Value must be positive.", "value");
				}
				_maxDepth = value;
				_maxDepthSet = true;
			}
		}

		public virtual bool CheckAdditionalContent
		{
			get
			{
				return _checkAdditionalContent ?? false;
			}
			set
			{
				_checkAdditionalContent = value;
			}
		}

		public virtual event EventHandler<Newtonsoft.Json.Serialization.ErrorEventArgs> Error;

		internal bool IsCheckAdditionalContentSet()
		{
			return _checkAdditionalContent.HasValue;
		}

		public JsonSerializer()
		{
			_referenceLoopHandling = ReferenceLoopHandling.Error;
			_missingMemberHandling = MissingMemberHandling.Ignore;
			_nullValueHandling = NullValueHandling.Include;
			_defaultValueHandling = DefaultValueHandling.Include;
			_objectCreationHandling = ObjectCreationHandling.Auto;
			_preserveReferencesHandling = PreserveReferencesHandling.None;
			_constructorHandling = ConstructorHandling.Default;
			_typeNameHandling = TypeNameHandling.None;
			_metadataPropertyHandling = MetadataPropertyHandling.Default;
			_context = JsonSerializerSettings.DefaultContext;
			_binder = DefaultSerializationBinder.Instance;
			_culture = JsonSerializerSettings.DefaultCulture;
			_contractResolver = DefaultContractResolver.Instance;
		}

		public static JsonSerializer Create()
		{
			return new JsonSerializer();
		}

		public static JsonSerializer Create(JsonSerializerSettings settings)
		{
			JsonSerializer jsonSerializer = Create();
			if (settings != null)
			{
				ApplySerializerSettings(jsonSerializer, settings);
			}
			return jsonSerializer;
		}

		public static JsonSerializer CreateDefault()
		{
			return Create(JsonConvert.DefaultSettings?.Invoke());
		}

		public static JsonSerializer CreateDefault(JsonSerializerSettings settings)
		{
			JsonSerializer jsonSerializer = CreateDefault();
			if (settings != null)
			{
				ApplySerializerSettings(jsonSerializer, settings);
			}
			return jsonSerializer;
		}

		private static void ApplySerializerSettings(JsonSerializer serializer, JsonSerializerSettings settings)
		{
			if (!CollectionUtils.IsNullOrEmpty(settings.Converters))
			{
				for (int i = 0; i < settings.Converters.Count; i++)
				{
					serializer.Converters.Insert(i, settings.Converters[i]);
				}
			}
			if (settings._typeNameHandling.HasValue)
			{
				serializer.TypeNameHandling = settings.TypeNameHandling;
			}
			if (settings._metadataPropertyHandling.HasValue)
			{
				serializer.MetadataPropertyHandling = settings.MetadataPropertyHandling;
			}
			if (settings._typeNameAssemblyFormat.HasValue)
			{
				serializer.TypeNameAssemblyFormat = settings.TypeNameAssemblyFormat;
			}
			if (settings._preserveReferencesHandling.HasValue)
			{
				serializer.PreserveReferencesHandling = settings.PreserveReferencesHandling;
			}
			if (settings._referenceLoopHandling.HasValue)
			{
				serializer.ReferenceLoopHandling = settings.ReferenceLoopHandling;
			}
			if (settings._missingMemberHandling.HasValue)
			{
				serializer.MissingMemberHandling = settings.MissingMemberHandling;
			}
			if (settings._objectCreationHandling.HasValue)
			{
				serializer.ObjectCreationHandling = settings.ObjectCreationHandling;
			}
			if (settings._nullValueHandling.HasValue)
			{
				serializer.NullValueHandling = settings.NullValueHandling;
			}
			if (settings._defaultValueHandling.HasValue)
			{
				serializer.DefaultValueHandling = settings.DefaultValueHandling;
			}
			if (settings._constructorHandling.HasValue)
			{
				serializer.ConstructorHandling = settings.ConstructorHandling;
			}
			if (settings._context.HasValue)
			{
				serializer.Context = settings.Context;
			}
			if (settings._checkAdditionalContent.HasValue)
			{
				serializer._checkAdditionalContent = settings._checkAdditionalContent;
			}
			if (settings.Error != null)
			{
				serializer.Error += settings.Error;
			}
			if (settings.ContractResolver != null)
			{
				serializer.ContractResolver = settings.ContractResolver;
			}
			if (settings.ReferenceResolverProvider != null)
			{
				serializer.ReferenceResolver = settings.ReferenceResolverProvider();
			}
			if (settings.TraceWriter != null)
			{
				serializer.TraceWriter = settings.TraceWriter;
			}
			if (settings.EqualityComparer != null)
			{
				serializer.EqualityComparer = settings.EqualityComparer;
			}
			if (settings.Binder != null)
			{
				serializer.Binder = settings.Binder;
			}
			if (settings._formatting.HasValue)
			{
				serializer._formatting = settings._formatting;
			}
			if (settings._dateFormatHandling.HasValue)
			{
				serializer._dateFormatHandling = settings._dateFormatHandling;
			}
			if (settings._dateTimeZoneHandling.HasValue)
			{
				serializer._dateTimeZoneHandling = settings._dateTimeZoneHandling;
			}
			if (settings._dateParseHandling.HasValue)
			{
				serializer._dateParseHandling = settings._dateParseHandling;
			}
			if (settings._dateFormatStringSet)
			{
				serializer._dateFormatString = settings._dateFormatString;
				serializer._dateFormatStringSet = settings._dateFormatStringSet;
			}
			if (settings._floatFormatHandling.HasValue)
			{
				serializer._floatFormatHandling = settings._floatFormatHandling;
			}
			if (settings._floatParseHandling.HasValue)
			{
				serializer._floatParseHandling = settings._floatParseHandling;
			}
			if (settings._stringEscapeHandling.HasValue)
			{
				serializer._stringEscapeHandling = settings._stringEscapeHandling;
			}
			if (settings._culture != null)
			{
				serializer._culture = settings._culture;
			}
			if (settings._maxDepthSet)
			{
				serializer._maxDepth = settings._maxDepth;
				serializer._maxDepthSet = settings._maxDepthSet;
			}
		}

		public void Populate(TextReader reader, object target)
		{
			Populate(new JsonTextReader(reader), target);
		}

		public void Populate(JsonReader reader, object target)
		{
			PopulateInternal(reader, target);
		}

		internal virtual void PopulateInternal(JsonReader reader, object target)
		{
			ValidationUtils.ArgumentNotNull(reader, "reader");
			ValidationUtils.ArgumentNotNull(target, "target");
			SetupReader(reader, out var previousCulture, out var previousDateTimeZoneHandling, out var previousDateParseHandling, out var previousFloatParseHandling, out var previousMaxDepth, out var previousDateFormatString);
			TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? new TraceJsonReader(reader) : null);
			new JsonSerializerInternalReader(this).Populate(traceJsonReader ?? reader, target);
			if (traceJsonReader != null)
			{
				TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null);
			}
			ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString);
		}

		public object Deserialize(JsonReader reader)
		{
			return Deserialize(reader, null);
		}

		public object Deserialize(TextReader reader, Type objectType)
		{
			return Deserialize(new JsonTextReader(reader), objectType);
		}

		public T Deserialize<T>(JsonReader reader)
		{
			return (T)Deserialize(reader, typeof(T));
		}

		public object Deserialize(JsonReader reader, Type objectType)
		{
			return DeserializeInternal(reader, objectType);
		}

		internal virtual object DeserializeInternal(JsonReader reader, Type objectType)
		{
			ValidationUtils.ArgumentNotNull(reader, "reader");
			SetupReader(reader, out var previousCulture, out var previousDateTimeZoneHandling, out var previousDateParseHandling, out var previousFloatParseHandling, out var previousMaxDepth, out var previousDateFormatString);
			TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? new TraceJsonReader(reader) : null);
			object result = new JsonSerializerInternalReader(this).Deserialize(traceJsonReader ?? reader, objectType, CheckAdditionalContent);
			if (traceJsonReader != null)
			{
				TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null);
			}
			ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString);
			return result;
		}

		private void SetupReader(JsonReader reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString)
		{
			if (_culture != null && !_culture.Equals(reader.Culture))
			{
				previousCulture = reader.Culture;
				reader.Culture = _culture;
			}
			else
			{
				previousCulture = null;
			}
			if (_dateTimeZoneHandling.HasValue && reader.DateTimeZoneHandling != _dateTimeZoneHandling)
			{
				previousDateTimeZoneHandling = reader.DateTimeZoneHandling;
				reader.DateTimeZoneHandling = _dateTimeZoneHandling.GetValueOrDefault();
			}
			else
			{
				previousDateTimeZoneHandling = null;
			}
			if (_dateParseHandling.HasValue && reader.DateParseHandling != _dateParseHandling)
			{
				previousDateParseHandling = reader.DateParseHandling;
				reader.DateParseHandling = _dateParseHandling.GetValueOrDefault();
			}
			else
			{
				previousDateParseHandling = null;
			}
			if (_floatParseHandling.HasValue && reader.FloatParseHandling != _floatParseHandling)
			{
				previousFloatParseHandling = reader.FloatParseHandling;
				reader.FloatParseHandling = _floatParseHandling.GetValueOrDefault();
			}
			else
			{
				previousFloatParseHandling = null;
			}
			if (_maxDepthSet && reader.MaxDepth != _maxDepth)
			{
				previousMaxDepth = reader.MaxDepth;
				reader.MaxDepth = _maxDepth;
			}
			else
			{
				previousMaxDepth = null;
			}
			if (_dateFormatStringSet && reader.DateFormatString != _dateFormatString)
			{
				previousDateFormatString = reader.DateFormatString;
				reader.DateFormatString = _dateFormatString;
			}
			else
			{
				previousDateFormatString = null;
			}
			if (reader is JsonTextReader jsonTextReader && _contractResolver is DefaultContractResolver defaultContractResolver)
			{
				jsonTextReader.NameTable = defaultContractResolver.GetState().NameTable;
			}
		}

		private void ResetReader(JsonReader reader, CultureInfo previousCulture, DateTimeZoneHandling? previousDateTimeZoneHandling, DateParseHandling? previousDateParseHandling, FloatParseHandling? previousFloatParseHandling, int? previousMaxDepth, string previousDateFormatString)
		{
			if (previousCulture != null)
			{
				reader.Culture = previousCulture;
			}
			if (previousDateTimeZoneHandling.HasValue)
			{
				reader.DateTimeZoneHandling = previousDateTimeZoneHandling.GetValueOrDefault();
			}
			if (previousDateParseHandling.HasValue)
			{
				reader.DateParseHandling = previousDateParseHandling.GetValueOrDefault();
			}
			if (previousFloatParseHandling.HasValue)
			{
				reader.FloatParseHandling = previousFloatParseHandling.GetValueOrDefault();
			}
			if (_maxDepthSet)
			{
				reader.MaxDepth = previousMaxDepth;
			}
			if (_dateFormatStringSet)
			{
				reader.DateFormatString = previousDateFormatString;
			}
			if (reader is JsonTextReader jsonTextReader)
			{
				jsonTextReader.NameTable = null;
			}
		}

		public void Serialize(TextWriter textWriter, object value)
		{
			Serialize(new JsonTextWriter(textWriter), value);
		}

		public void Serialize(JsonWriter jsonWriter, object value, Type objectType)
		{
			SerializeInternal(jsonWriter, value, objectType);
		}

		public void Serialize(TextWriter textWriter, object value, Type objectType)
		{
			Serialize(new JsonTextWriter(textWriter), value, objectType);
		}

		public void Serialize(JsonWriter jsonWriter, object value)
		{
			SerializeInternal(jsonWriter, value, null);
		}

		internal virtual void SerializeInternal(JsonWriter jsonWriter, object value, Type objectType)
		{
			ValidationUtils.ArgumentNotNull(jsonWriter, "jsonWriter");
			Formatting? formatting = null;
			if (_formatting.HasValue && jsonWriter.Formatting != _formatting)
			{
				formatting = jsonWriter.Formatting;
				jsonWriter.Formatting = _formatting.GetValueOrDefault();
			}
			DateFormatHandling? dateFormatHandling = null;
			if (_dateFormatHandling.HasValue && jsonWriter.DateFormatHandling != _dateFormatHandling)
			{
				dateFormatHandling = jsonWriter.DateFormatHandling;
				jsonWriter.DateFormatHandling = _dateFormatHandling.GetValueOrDefault();
			}
			DateTimeZoneHandling? dateTimeZoneHandling = null;
			if (_dateTimeZoneHandling.HasValue && jsonWriter.DateTimeZoneHandling != _dateTimeZoneHandling)
			{
				dateTimeZoneHandling = jsonWriter.DateTimeZoneHandling;
				jsonWriter.DateTimeZoneHandling = _dateTimeZoneHandling.GetValueOrDefault();
			}
			FloatFormatHandling? floatFormatHandling = null;
			if (_floatFormatHandling.HasValue && jsonWriter.FloatFormatHandling != _floatFormatHandling)
			{
				floatFormatHandling = jsonWriter.FloatFormatHandling;
				jsonWriter.FloatFormatHandling = _floatFormatHandling.GetValueOrDefault();
			}
			StringEscapeHandling? stringEscapeHandling = null;
			if (_stringEscapeHandling.HasValue && jsonWriter.StringEscapeHandling != _stringEscapeHandling)
			{
				stringEscapeHandling = jsonWriter.StringEscapeHandling;
				jsonWriter.StringEscapeHandling = _stringEscapeHandling.GetValueOrDefault();
			}
			CultureInfo cultureInfo = null;
			if (_culture != null && !_culture.Equals(jsonWriter.Culture))
			{
				cultureInfo = jsonWriter.Culture;
				jsonWriter.Culture = _culture;
			}
			string dateFormatString = null;
			if (_dateFormatStringSet && jsonWriter.DateFormatString != _dateFormatString)
			{
				dateFormatString = jsonWriter.DateFormatString;
				jsonWriter.DateFormatString = _dateFormatString;
			}
			TraceJsonWriter traceJsonWriter = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? new TraceJsonWriter(jsonWriter) : null);
			new JsonSerializerInternalWriter(this).Serialize(traceJsonWriter ?? jsonWriter, value, objectType);
			if (traceJsonWriter != null)
			{
				TraceWriter.Trace(TraceLevel.Verbose, traceJsonWriter.GetSerializedJsonMessage(), null);
			}
			if (formatting.HasValue)
			{
				jsonWriter.Formatting = formatting.GetValueOrDefault();
			}
			if (dateFormatHandling.HasValue)
			{
				jsonWriter.DateFormatHandling = dateFormatHandling.GetValueOrDefault();
			}
			if (dateTimeZoneHandling.HasValue)
			{
				jsonWriter.DateTimeZoneHandling = dateTimeZoneHandling.GetValueOrDefault();
			}
			if (floatFormatHandling.HasValue)
			{
				jsonWriter.FloatFormatHandling = floatFormatHandling.GetValueOrDefault();
			}
			if (stringEscapeHandling.HasValue)
			{
				jsonWriter.StringEscapeHandling = stringEscapeHandling.GetValueOrDefault();
			}
			if (_dateFormatStringSet)
			{
				jsonWriter.DateFormatString = dateFormatString;
			}
			if (cultureInfo != null)
			{
				jsonWriter.Culture = cultureInfo;
			}
		}

		internal IReferenceResolver GetReferenceResolver()
		{
			if (_referenceResolver == null)
			{
				_referenceResolver = new DefaultReferenceResolver();
			}
			return _referenceResolver;
		}

		internal JsonConverter GetMatchingConverter(Type type)
		{
			return GetMatchingConverter(_converters, type);
		}

		internal static JsonConverter GetMatchingConverter(IList<JsonConverter> converters, Type objectType)
		{
			if (converters != null)
			{
				for (int i = 0; i < converters.Count; i++)
				{
					JsonConverter jsonConverter = converters[i];
					if (jsonConverter.CanConvert(objectType))
					{
						return jsonConverter;
					}
				}
			}
			return null;
		}

		internal void OnError(Newtonsoft.Json.Serialization.ErrorEventArgs e)
		{
			this.Error?.Invoke(this, e);
		}
	}
	public class JsonSerializerSettings
	{
		internal const ReferenceLoopHandling DefaultReferenceLoopHandling = ReferenceLoopHandling.Error;

		internal const MissingMemberHandling DefaultMissingMemberHandling = MissingMemberHandling.Ignore;

		internal const NullValueHandling DefaultNullValueHandling = NullValueHandling.Include;

		internal const DefaultValueHandling DefaultDefaultValueHandling = DefaultValueHandling.Include;

		internal const ObjectCreationHandling DefaultObjectCreationHandling = ObjectCreationHandling.Auto;

		internal const PreserveReferencesHandling DefaultPreserveReferencesHandling = PreserveReferencesHandling.None;

		internal const ConstructorHandling DefaultConstructorHandling = ConstructorHandling.Default;

		internal const TypeNameHandling DefaultTypeNameHandling = TypeNameHandling.None;

		internal const MetadataPropertyHandling DefaultMetadataPropertyHandling = MetadataPropertyHandling.Default;

		internal const FormatterAssemblyStyle DefaultTypeNameAssemblyFormat = FormatterAssemblyStyle.Simple;

		internal static readonly StreamingContext DefaultContext;

		internal const Formatting DefaultFormatting = Formatting.None;

		internal const DateFormatHandling DefaultDateFormatHandling = DateFormatHandling.IsoDateFormat;

		internal const DateTimeZoneHandling DefaultDateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;

		internal const DateParseHandling DefaultDateParseHandling = DateParseHandling.DateTime;

		internal const FloatParseHandling DefaultFloatParseHandling = FloatParseHandling.Double;

		internal const FloatFormatHandling DefaultFloatFormatHandling = FloatFormatHandling.String;

		internal const StringEscapeHandling DefaultStringEscapeHandling = StringEscapeHandling.Default;

		internal const FormatterAssemblyStyle DefaultFormatterAssemblyStyle = FormatterAssemblyStyle.Simple;

		internal static readonly CultureInfo DefaultCulture;

		internal const bool DefaultCheckAdditionalContent = false;

		internal const string DefaultDateFormatString = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";

		internal Formatting? _formatting;

		internal DateFormatHandling? _dateFormatHandling;

		internal DateTimeZoneHandling? _dateTimeZoneHandling;

		internal DateParseHandling? _dateParseHandling;

		internal FloatFormatHandling? _floatFormatHandling;

		internal FloatParseHandling? _floatParseHandling;

		internal StringEscapeHandling? _stringEscapeHandling;

		internal CultureInfo _culture;

		internal bool? _checkAdditionalContent;

		internal int? _maxDepth;

		internal bool _maxDepthSet;

		internal string _dateFormatString;

		internal bool _dateFormatStringSet;

		internal FormatterAssemblyStyle? _typeNameAssemblyFormat;

		internal DefaultValueHandling? _defaultValueHandling;

		internal PreserveReferencesHandling? _preserveReferencesHandling;

		internal NullValueHandling? _nullValueHandling;

		internal ObjectCreationHandling? _objectCreationHandling;

		internal MissingMemberHandling? _missingMemberHandling;

		internal ReferenceLoopHandling? _referenceLoopHandling;

		internal StreamingContext? _context;

		internal ConstructorHandling? _constructorHandling;

		internal TypeNameHandling? _typeNameHandling;

		internal MetadataPropertyHandling? _metadataPropertyHandling;

		public ReferenceLoopHandling ReferenceLoopHandling
		{
			get
			{
				return _referenceLoopHandling ?? ReferenceLoopHandling.Error;
			}
			set
			{
				_referenceLoopHandling = value;
			}
		}

		public MissingMemberHandling MissingMemberHandling
		{
			get
			{
				return _missingMemberHandling ?? MissingMemberHandling.Ignore;
			}
			set
			{
				_missingMemberHandling = value;
			}
		}

		public ObjectCreationHandling ObjectCreationHandling
		{
			get
			{
				return _objectCreationHandling ?? ObjectCreationHandling.Auto;
			}
			set
			{
				_objectCreationHandling = value;
			}
		}

		public NullValueHandling NullValueHandling
		{
			get
			{
				return _nullValueHandling ?? NullValueHandling.Include;
			}
			set
			{
				_nullValueHandling = value;
			}
		}

		public DefaultValueHandling DefaultValueHandling
		{
			get
			{
				return _defaultValueHandling ?? DefaultValueHandling.Include;
			}
			set
			{
				_defaultValueHandling = value;
			}
		}

		public IList<JsonConverter> Converters { get; set; }

		public PreserveReferencesHandling PreserveReferencesHandling
		{
			get
			{
				return _preserveReferencesHandling ?? PreserveReferencesHandling.None;
			}
			set
			{
				_preserveReferencesHandling = value;
			}
		}

		public TypeNameHandling TypeNameHandling
		{
			get
			{
				return _typeNameHandling ?? TypeNameHandling.None;
			}
			set
			{
				_typeNameHandling = value;
			}
		}

		public MetadataPropertyHandling MetadataPropertyHandling
		{
			get
			{
				return _metadataPropertyHandling ?? MetadataPropertyHandling.Default;
			}
			set
			{
				_metadataPropertyHandling = value;
			}
		}

		public FormatterAssemblyStyle TypeNameAssemblyFormat
		{
			get
			{
				return _typeNameAssemblyFormat ?? FormatterAssemblyStyle.Simple;
			}
			set
			{
				_typeNameAssemblyFormat = value;
			}
		}

		public ConstructorHandling ConstructorHandling
		{
			get
			{
				return _constructorHandling ?? ConstructorHandling.Default;
			}
			set
			{
				_constructorHandling = value;
			}
		}

		public IContractResolver ContractResolver { get; set; }

		public IEqualityComparer EqualityComparer { get; set; }

		[Obsolete("ReferenceResolver property is obsolete. Use the ReferenceResolverProvider property to set the IReferenceResolver: settings.ReferenceResolverProvider = () => resolver")]
		public IReferenceResolver ReferenceResolver
		{
			get
			{
				if (ReferenceResolverProvider == null)
				{
					return null;
				}
				return ReferenceResolverProvider();
			}
			set
			{
				ReferenceResolverProvider = ((value != null) ? ((Func<IReferenceResolver>)(() => value)) : null);
			}
		}

		public Func<IReferenceResolver> ReferenceResolverProvider { get; set; }

		public ITraceWriter TraceWriter { get; set; }

		public SerializationBinder Binder { get; set; }

		public EventHandler<Newtonsoft.Json.Serialization.ErrorEventArgs> Error { get; set; }

		public StreamingContext Context
		{
			get
			{
				return _context ?? DefaultContext;
			}
			set
			{
				_context = value;
			}
		}

		public string DateFormatString
		{
			get
			{
				return _dateFormatString ?? "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
			}
			set
			{
				_dateFormatString = value;
				_dateFormatStringSet = true;
			}
		}

		public int? MaxDepth
		{
			get
			{
				return _maxDepth;
			}
			set
			{
				if (value <= 0)
				{
					throw new ArgumentException("Value must be positive.", "value");
				}
				_maxDepth = value;
				_maxDepthSet = true;
			}
		}

		public Formatting Formatting
		{
			get
			{
				return _formatting ?? Formatting.None;
			}
			set
			{
				_formatting = value;
			}
		}

		public DateFormatHandling DateFormatHandling
		{
			get
			{
				return _dateFormatHandling ?? DateFormatHandling.IsoDateFormat;
			}
			set
			{
				_dateFormatHandling = value;
			}
		}

		public DateTimeZoneHandling DateTimeZoneHandling
		{
			get
			{
				return _dateTimeZoneHandling ?? DateTimeZoneHandling.RoundtripKind;
			}
			set
			{
				_dateTimeZoneHandling = value;
			}
		}

		public DateParseHandling DateParseHandling
		{
			get
			{
				return _dateParseHandling ?? DateParseHandling.DateTime;
			}
			set
			{
				_dateParseHandling = value;
			}
		}

		public FloatFormatHandling FloatFormatHandling
		{
			get
			{
				return _floatFormatHandling ?? FloatFormatHandling.String;
			}
			set
			{
				_floatFormatHandling = value;
			}
		}

		public FloatParseHandling FloatParseHandling
		{
			get
			{
				return _floatParseHandling ?? FloatParseHandling.Double;
			}
			set
			{
				_floatParseHandling = value;
			}
		}

		public StringEscapeHandling StringEscapeHandling
		{
			get
			{
				return _stringEscapeHandling ?? StringEscapeHandling.Default;
			}
			set
			{
				_stringEscapeHandling = value;
			}
		}

		public CultureInfo Culture
		{
			get
			{
				return _culture ?? DefaultCulture;
			}
			set
			{
				_culture = value;
			}
		}

		public bool CheckAdditionalContent
		{
			get
			{
				return _checkAdditionalContent ?? false;
			}
			set
			{
				_checkAdditionalContent = value;
			}
		}

		static JsonSerializerSettings()
		{
			DefaultContext = default(StreamingContext);
			DefaultCulture = CultureInfo.InvariantCulture;
		}

		public JsonSerializerSettings()
		{
			Converters = new List<JsonConverter>();
		}
	}
	internal enum ReadType
	{
		Read,
		ReadAsInt32,
		ReadAsBytes,
		ReadAsString,
		ReadAsDecimal,
		ReadAsDateTime,
		ReadAsDateTimeOffset,
		ReadAsDouble,
		ReadAsBoolean
	}
	public class JsonTextReader : JsonReader, IJsonLineInfo
	{
		private const char UnicodeReplacementChar = '\ufffd';

		private const int MaximumJavascriptIntegerCharacterLength = 380;

		private readonly TextReader _reader;

		private char[] _chars;

		private int _charsUsed;

		private int _charPos;

		private int _lineStartPos;

		private int _lineNumber;

		private bool _isEndOfFile;

		private StringBuffer _stringBuffer;

		private StringReference _stringReference;

		private IArrayPool<char> _arrayPool;

		internal PropertyNameTable NameTable;

		public IArrayPool<char> ArrayPool
		{
			get
			{
				return _arrayPool;
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException("value");
				}
				_arrayPool = value;
			}
		}

		public int LineNumber
		{
			get
			{
				if (base.CurrentState == State.Start && LinePosition == 0 && TokenType != JsonToken.Comment)
				{
					return 0;
				}
				return _lineNumber;
			}
		}

		public int LinePosition => _charPos - _lineStartPos;

		public JsonTextReader(TextReader reader)
		{
			if (reader == null)
			{
				throw new ArgumentNullException("reader");
			}
			_reader = reader;
			_lineNumber = 1;
		}

		private void EnsureBufferNotEmpty()
		{
			if (_stringBuffer.IsEmpty)
			{
				_stringBuffer = new StringBuffer(_arrayPool, 1024);
			}
		}

		private void OnNewLine(int pos)
		{
			_lineNumber++;
			_lineStartPos = pos;
		}

		private void ParseString(char quote, ReadType readType)
		{
			_charPos++;
			ShiftBufferIfNeeded();
			ReadStringIntoBuffer(quote);
			SetPostValueState(updateIndex: true);
			switch (readType)
			{
			case ReadType.ReadAsBytes:
			{
				Guid g;
				byte[] value2 = ((_stringReference.Length == 0) ? new byte[0] : ((_stringReference.Length != 36 || !ConvertUtils.TryConvertGuid(_stringReference.ToString(), out g)) ? Convert.FromBase64CharArray(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length) : g.ToByteArray()));
				SetToken(JsonToken.Bytes, value2, updateIndex: false);
				return;
			}
			case ReadType.ReadAsString:
			{
				string value = _stringReference.ToString();
				SetToken(JsonToken.String, value, updateIndex: false);
				_quoteChar = quote;
				return;
			}
			case ReadType.ReadAsInt32:
			case ReadType.ReadAsDecimal:
			case ReadType.ReadAsBoolean:
				return;
			}
			if (_dateParseHandling != 0)
			{
				DateTimeOffset dt2;
				if (readType switch
				{
					ReadType.ReadAsDateTime => 1, 
					ReadType.ReadAsDateTimeOffset => 2, 
					_ => (int)_dateParseHandling, 
				} == 1)
				{
					if (DateTimeUtils.TryParseDateTime(_stringReference, base.DateTimeZoneHandling, base.DateFormatString, base.Culture, out var dt))
					{
						SetToken(JsonToken.Date, dt, updateIndex: false);
						return;
					}
				}
				else if (DateTimeUtils.TryParseDateTimeOffset(_stringReference, base.DateFormatString, base.Culture, out dt2))
				{
					SetToken(JsonToken.Date, dt2, updateIndex: false);
					return;
				}
			}
			SetToken(JsonToken.String, _stringReference.ToString(), updateIndex: false);
			_quoteChar = quote;
		}

		private static void BlockCopyChars(char[] src, int srcOffset, char[] dst, int dstOffset, int count)
		{
			Buffer.BlockCopy(src, srcOffset * 2, dst, dstOffset * 2, count * 2);
		}

		private void ShiftBufferIfNeeded()
		{
			int num = _chars.Length;
			if ((double)(num - _charPos) <= (double)num * 0.1)
			{
				int num2 = _charsUsed - _charPos;
				if (num2 > 0)
				{
					BlockCopyChars(_chars, _charPos, _chars, 0, num2);
				}
				_lineStartPos -= _charPos;
				_charPos = 0;
				_charsUsed = num2;
				_chars[_charsUsed] = '\0';
			}
		}

		private int ReadData(bool append)
		{
			return ReadData(append, 0);
		}

		private int ReadData(bool append, int charsRequired)
		{
			if (_isEndOfFile)
			{
				return 0;
			}
			if (_charsUsed + charsRequired >= _chars.Length - 1)
			{
				if (append)
				{
					int minSize = Math.Max(_chars.Length * 2, _charsUsed + charsRequired + 1);
					char[] array = BufferUtils.RentBuffer(_arrayPool, minSize);
					BlockCopyChars(_chars, 0, array, 0, _chars.Length);
					BufferUtils.ReturnBuffer(_arrayPool, _chars);
					_chars = array;
				}
				else
				{
					int num = _charsUsed - _charPos;
					if (num + charsRequired + 1 >= _chars.Length)
					{
						char[] array2 = BufferUtils.RentBuffer(_arrayPool, num + charsRequired + 1);
						if (num > 0)
						{
							BlockCopyChars(_chars, _charPos, array2, 0, num);
						}
						BufferUtils.ReturnBuffer(_arrayPool, _chars);
						_chars = array2;
					}
					else if (num > 0)
					{
						BlockCopyChars(_chars, _charPos, _chars, 0, num);
					}
					_lineStartPos -= _charPos;
					_charPos = 0;
					_charsUsed = num;
				}
			}
			int count = _chars.Length - _charsUsed - 1;
			int num2 = _reader.Read(_chars, _charsUsed, count);
			_charsUsed += num2;
			if (num2 == 0)
			{
				_isEndOfFile = true;
			}
			_chars[_charsUsed] = '\0';
			return num2;
		}

		private bool EnsureChars(int relativePosition, bool append)
		{
			if (_charPos + relativePosition >= _charsUsed)
			{
				return ReadChars(relativePosition, append);
			}
			return true;
		}

		private bool ReadChars(int relativePosition, bool append)
		{
			if (_isEndOfFile)
			{
				return false;
			}
			int num = _charPos + relativePosition - _charsUsed + 1;
			int num2 = 0;
			do
			{
				int num3 = ReadData(append, num - num2);
				if (num3 == 0)
				{
					break;
				}
				num2 += num3;
			}
			while (num2 < num);
			if (num2 < num)
			{
				return false;
			}
			return true;
		}

		public override bool Read()
		{
			EnsureBuffer();
			do
			{
				switch (_currentState)
				{
				case State.Start:
				case State.Property:
				case State.ArrayStart:
				case State.Array:
				case State.ConstructorStart:
				case State.Constructor:
					return ParseValue();
				case State.ObjectStart:
				case State.Object:
					return ParseObject();
				case State.PostValue:
					break;
				case State.Finished:
					if (EnsureChars(0, append: false))
					{
						EatWhitespace(oneOrMore: false);
						if (_isEndOfFile)
						{
							SetToken(JsonToken.None);
							return false;
						}
						if (_chars[_charPos] == '/')
						{
							ParseComment(setToken: true);
							return true;
						}
						throw JsonReaderException.Create(this, "Additional text encountered after finished reading JSON content: {0}.".FormatWith(CultureInfo.InvariantCulture, _chars[_charPos]));
					}
					SetToken(JsonToken.None);
					return false;
				default:
					throw JsonReaderException.Create(this, "Unexpected state: {0}.".FormatWith(CultureInfo.InvariantCulture, base.CurrentState));
				}
			}
			while (!ParsePostValue());
			return true;
		}

		public override int? ReadAsInt32()
		{
			return (int?)ReadNumberValue(ReadType.ReadAsInt32);
		}

		public override DateTime? ReadAsDateTime()
		{
			return (DateTime?)ReadStringValue(ReadType.ReadAsDateTime);
		}

		public override string ReadAsString()
		{
			return (string)ReadStringValue(ReadType.ReadAsString);
		}

		public override byte[] ReadAsBytes()
		{
			EnsureBuffer();
			bool flag = false;
			switch (_currentState)
			{
			case State.Start:
			case State.Property:
			case State.ArrayStart:
			case State.Array:
			case State.PostValue:
			case State.ConstructorStart:
			case State.Constructor:
				while (true)
				{
					char c = _chars[_charPos];
					switch (c)
					{
					case '\0':
						if (ReadNullChar())
						{
							SetToken(JsonToken.None, null, updateIndex: false);
							return null;
						}
						break;
					case '"':
					case '\'':
					{
						ParseString(c, ReadType.ReadAsBytes);
						byte[] array = (byte[])Value;
						if (flag)
						{
							ReaderReadAndAssert();
							if (TokenType != JsonToken.EndObject)
							{
								throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
							}
							SetToken(JsonToken.Bytes, array, updateIndex: false);
						}
						return array;
					}
					case '{':
						_charPos++;
						SetToken(JsonToken.StartObject);
						ReadIntoWrappedTypeObject();
						flag = true;
						break;
					case '[':
						_charPos++;
						SetToken(JsonToken.StartArray);
						return ReadArrayIntoByteArray();
					case 'n':
						HandleNull();
						return null;
					case '/':
						ParseComment(setToken: false);
						break;
					case ',':
						ProcessValueComma();
						break;
					case ']':
						_charPos++;
						if (_currentState == State.Array || _currentState == State.ArrayStart || _currentState == State.PostValue)
						{
							SetToken(JsonToken.EndArray);
							return null;
						}
						throw CreateUnexpectedCharacterException(c);
					case '\r':
						ProcessCarriageReturn(append: false);
						break;
					case '\n':
						ProcessLineFeed();
						break;
					case '\t':
					case ' ':
						_charPos++;
						break;
					default:
						_charPos++;
						if (!char.IsWhiteSpace(c))
						{
							throw CreateUnexpectedCharacterException(c);
						}
						break;
					}
				}
			case State.Finished:
				ReadFinished();
				return null;
			default:
				throw JsonReaderException.Create(this, "Unexpected state: {0}.".FormatWith(CultureInfo.InvariantCulture, base.CurrentState));
			}
		}

		private object ReadStringValue(ReadType readType)
		{
			EnsureBuffer();
			switch (_currentState)
			{
			case State.Start:
			case State.Property:
			case State.ArrayStart:
			case State.Array:
			case State.PostValue:
			case State.ConstructorStart:
			case State.Constructor:
				while (true)
				{
					char c = _chars[_charPos];
					switch (c)
					{
					case '\0':
						if (ReadNullChar())
						{
							SetToken(JsonToken.None, null, updateIndex: false);
							return null;
						}
						break;
					case '"':
					case '\'':
						ParseString(c, readType);
						switch (readType)
						{
						case ReadType.ReadAsBytes:
							return Value;
						case ReadType.ReadAsString:
							return Value;
						case ReadType.ReadAsDateTime:
							if (Value is DateTime)
							{
								return (DateTime)Value;
							}
							return ReadDateTimeString((string)Value);
						case ReadType.ReadAsDateTimeOffset:
							if (Value is DateTimeOffset)
							{
								return (DateTimeOffset)Value;
							}
							return ReadDateTimeOffsetString((string)Value);
						default:
							throw new ArgumentOutOfRangeException("readType");
						}
					case '-':
						if (EnsureChars(1, append: true) && _chars[_charPos + 1] == 'I')
						{
							return ParseNumberNegativeInfinity(readType);
						}
						ParseNumber(readType);
						return Value;
					case '.':
					case '0':
					case '1':
					case '2':
					case '3':
					case '4':
					case '5':
					case '6':
					case '7':
					case '8':
					case '9':
						if (readType != ReadType.ReadAsString)
						{
							_charPos++;
							throw CreateUnexpectedCharacterException(c);
						}
						ParseNumber(ReadType.ReadAsString);
						return Value;
					case 'f':
					case 't':
					{
						if (readType != ReadType.ReadAsString)
						{
							_charPos++;
							throw CreateUnexpectedCharacterException(c);
						}
						string text = ((c == 't') ? JsonConvert.True : JsonConvert.False);
						if (!MatchValueWithTrailingSeparator(text))
						{
							throw CreateUnexpectedCharacterException(_chars[_charPos]);
						}
						SetToken(JsonToken.String, text);
						return text;
					}
					case 'I':
						return ParseNumberPositiveInfinity(readType);
					case 'N':
						return ParseNumberNaN(readType);
					case 'n':
						HandleNull();
						return null;
					case '/':
						ParseComment(setToken: false);
						break;
					case ',':
						ProcessValueComma();
						break;
					case ']':
						_charPos++;
						if (_currentState == State.Array || _currentState == State.ArrayStart || _currentState == State.PostValue)
						{
							SetToken(JsonToken.EndArray);
							return null;
						}
						throw CreateUnexpectedCharacterException(c);
					case '\r':
						ProcessCarriageReturn(append: false);
						break;
					case '\n':
						ProcessLineFeed();
						break;
					case '\t':
					case ' ':
						_charPos++;
						break;
					default:
						_charPos++;
						if (!char.IsWhiteSpace(c))
						{
							throw CreateUnexpectedCharacterException(c);
						}
						break;
					}
				}
			case State.Finished:
				ReadFinished();
				return null;
			default:
				throw JsonReaderException.Create(this, "Unexpected state: {0}.".FormatWith(CultureInfo.InvariantCulture, base.CurrentState));
			}
		}

		private JsonReaderException CreateUnexpectedCharacterException(char c)
		{
			return JsonReaderException.Create(this, "Unexpected character encountered while parsing value: {0}.".FormatWith(CultureInfo.InvariantCulture, c));
		}

		public override bool? ReadAsBoolean()
		{
			EnsureBuffer();
			switch (_currentState)
			{
			case State.Start:
			case State.Property:
			case State.ArrayStart:
			case State.Array:
			case State.PostValue:
			case State.ConstructorStart:
			case State.Constructor:
				while (true)
				{
					char c = _chars[_charPos];
					switch (c)
					{
					case '\0':
						if (ReadNullChar())
						{
							SetToken(JsonToken.None, null, updateIndex: false);
							return null;
						}
						break;
					case '"':
					case '\'':
						ParseString(c, ReadType.Read);
						return ReadBooleanString(_stringReference.ToString());
					case 'n':
						HandleNull();
						return null;
					case '-':
					case '.':
					case '0':
					case '1':
					case '2':
					case '3':
					case '4':
					case '5':
					case '6':
					case '7':
					case '8':
					case '9':
					{
						ParseNumber(ReadType.Read);
						bool flag2 = Convert.ToBoolean(Value, CultureInfo.InvariantCulture);
						SetToken(JsonToken.Boolean, flag2, updateIndex: false);
						return flag2;
					}
					case 'f':
					case 't':
					{
						bool flag = c == 't';
						string value = (flag ? JsonConvert.True : JsonConvert.False);
						if (!MatchValueWithTrailingSeparator(value))
						{
							throw CreateUnexpectedCharacterException(_chars[_charPos]);
						}
						SetToken(JsonToken.Boolean, flag);
						return flag;
					}
					case '/':
						ParseComment(setToken: false);
						break;
					case ',':
						ProcessValueComma();
						break;
					case ']':
						_charPos++;
						if (_currentState == State.Array || _currentState == State.ArrayStart || _currentState == State.PostValue)
						{
							SetToken(JsonToken.EndArray);
							return null;
						}
						throw CreateUnexpectedCharacterException(c);
					case '\r':
						ProcessCarriageReturn(append: false);
						break;
					case '\n':
						ProcessLineFeed();
						break;
					case '\t':
					case ' ':
						_charPos++;
						break;
					default:
						_charPos++;
						if (!char.IsWhiteSpace(c))
						{
							throw CreateUnexpectedCharacterException(c);
						}
						break;
					}
				}
			case State.Finished:
				ReadFinished();
				return null;
			default:
				throw JsonReaderException.Create(this, "Unexpected state: {0}.".FormatWith(CultureInfo.InvariantCulture, base.CurrentState));
			}
		}

		private void ProcessValueComma()
		{
			_charPos++;
			if (_currentState != State.PostValue)
			{
				SetToken(JsonToken.Undefined);
				throw CreateUnexpectedCharacterException(',');
			}
			SetStateBasedOnCurrent();
		}

		private object ReadNumberValue(ReadType readType)
		{
			EnsureBuffer();
			switch (_currentState)
			{
			case State.Start:
			case State.Property:
			case State.ArrayStart:
			case State.Array:
			case State.PostValue:
			case State.ConstructorStart:
			case State.Constructor:
				while (true)
				{
					char c = _chars[_charPos];
					switch (c)
					{
					case '\0':
						if (ReadNullChar())
						{
							SetToken(JsonToken.None, null, updateIndex: false);
							return null;
						}
						break;
					case '"':
					case '\'':
						ParseString(c, readType);
						return readType switch
						{
							ReadType.ReadAsInt32 => ReadInt32String(_stringReference.ToString()), 
							ReadType.ReadAsDecimal => ReadDecimalString(_stringReference.ToString()), 
							ReadType.ReadAsDouble => ReadDoubleString(_stringReference.ToString()), 
							_ => throw new ArgumentOutOfRangeException("readType"), 
						};
					case 'n':
						HandleNull();
						return null;
					case 'N':
						return ParseNumberNaN(readType);
					case 'I':
						return ParseNumberPositiveInfinity(readType);
					case '-':
						if (EnsureChars(1, append: true) && _chars[_charPos + 1] == 'I')
						{
							return ParseNumberNegativeInfinity(readType);
						}
						ParseNumber(readType);
						return Value;
					case '.':
					case '0':
					case '1':
					case '2':
					case '3':
					case '4':
					case '5':
					case '6':
					case '7':
					case '8':
					case '9':
						ParseNumber(readType);
						return Value;
					case '/':
						ParseComment(setToken: false);
						break;
					case ',':
						ProcessValueComma();
						break;
					case ']':
						_charPos++;
						if (_currentState == State.Array || _currentState == State.ArrayStart || _currentState == State.PostValue)
						{
							SetToken(JsonToken.EndArray);
							return null;
						}
						throw CreateUnexpectedCharacterException(c);
					case '\r':
						ProcessCarriageReturn(append: false);
						break;
					case '\n':
						ProcessLineFeed();
						break;
					case '\t':
					case ' ':
						_charPos++;
						break;
					default:
						_charPos++;
						if (!char.IsWhiteSpace(c))
						{
							throw CreateUnexpectedCharacterException(c);
						}
						break;
					}
				}
			case State.Finished:
				ReadFinished();
				return null;
			default:
				throw JsonReaderException.Create(this, "Unexpected state: {0}.".FormatWith(CultureInfo.InvariantCulture, base.CurrentState));
			}
		}

		public override DateTimeOffset? ReadAsDateTimeOffset()
		{
			return (DateTimeOffset?)ReadStringValue(ReadType.ReadAsDateTimeOffset);
		}

		public override decimal? ReadAsDecimal()
		{
			return (decimal?)ReadNumberValue(ReadType.ReadAsDecimal);
		}

		public override double? ReadAsDouble()
		{
			return (double?)ReadNumberValue(ReadType.ReadAsDouble);
		}

		private void HandleNull()
		{
			if (EnsureChars(1, append: true))
			{
				if (_chars[_charPos + 1] == 'u')
				{
					ParseNull();
					return;
				}
				_charPos += 2;
				throw CreateUnexpectedCharacterException(_chars[_charPos - 1]);
			}
			_charPos = _charsUsed;
			throw CreateUnexpectedEndException();
		}

		private void ReadF