Decompiled source of SmoothServer v0.3.1

SmoothServer.dll

Decompiled 4 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using ServerSync;
using SmoothServer.Map;
using SmoothServer.Net;
using Splatform;
using Steamworks;
using TMPro;
using UnityEngine;
using ZstdSharp;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: IgnoresAccessChecksTo("com.rlabrecque.steamworks.net")]
[assembly: AssemblyCompany("SmoothServer")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.3.1.0")]
[assembly: AssemblyInformationalVersion("0.3.1+ddd86e171e72d6f9592d3315cc1062b43d8e8398")]
[assembly: AssemblyProduct("SmoothServer")]
[assembly: AssemblyTitle("SmoothServer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ServerSync
{
	[PublicAPI]
	public abstract class OwnConfigEntryBase
	{
		public object? LocalBaseValue;

		public bool SynchronizedConfig = true;

		public abstract ConfigEntryBase BaseConfig { get; }
	}
	[PublicAPI]
	public class SyncedConfigEntry<T>(ConfigEntry<T> sourceConfig) : OwnConfigEntryBase()
	{
		public readonly ConfigEntry<T> SourceConfig = sourceConfig;

		public override ConfigEntryBase BaseConfig => (ConfigEntryBase)(object)SourceConfig;

		public T Value
		{
			get
			{
				return SourceConfig.Value;
			}
			set
			{
				SourceConfig.Value = value;
			}
		}

		public void AssignLocalValue(T value)
		{
			if (LocalBaseValue == null)
			{
				Value = value;
			}
			else
			{
				LocalBaseValue = value;
			}
		}
	}
	public abstract class CustomSyncedValueBase
	{
		public object? LocalBaseValue;

		public readonly string Identifier;

		public readonly Type Type;

		private object? boxedValue;

		protected bool localIsOwner;

		public readonly int Priority;

		public object? BoxedValue
		{
			get
			{
				return boxedValue;
			}
			set
			{
				boxedValue = value;
				this.ValueChanged?.Invoke();
			}
		}

		public event Action? ValueChanged;

		protected CustomSyncedValueBase(ConfigSync configSync, string identifier, Type type, int priority)
		{
			Priority = priority;
			Identifier = identifier;
			Type = type;
			configSync.AddCustomValue(this);
			localIsOwner = configSync.IsSourceOfTruth;
			configSync.SourceOfTruthChanged += delegate(bool truth)
			{
				localIsOwner = truth;
			};
		}
	}
	[PublicAPI]
	public sealed class CustomSyncedValue<T> : CustomSyncedValueBase
	{
		public T Value
		{
			get
			{
				return (T)base.BoxedValue;
			}
			set
			{
				base.BoxedValue = value;
			}
		}

		public CustomSyncedValue(ConfigSync configSync, string identifier, T value = default(T), int priority = 0)
			: base(configSync, identifier, typeof(T), priority)
		{
			Value = value;
		}

		public void AssignLocalValue(T value)
		{
			if (localIsOwner)
			{
				Value = value;
			}
			else
			{
				LocalBaseValue = value;
			}
		}
	}
	internal class ConfigurationManagerAttributes
	{
		[UsedImplicitly]
		public bool? ReadOnly = false;
	}
	[PublicAPI]
	public class ConfigSync
	{
		[HarmonyPatch(typeof(ZRpc), "HandlePackage")]
		private static class SnatchCurrentlyHandlingRPC
		{
			public static ZRpc? currentRpc;

			[HarmonyPrefix]
			private static void Prefix(ZRpc __instance)
			{
				currentRpc = __instance;
			}
		}

		[HarmonyPatch(typeof(ZNet), "Awake")]
		internal static class RegisterRPCPatch
		{
			[HarmonyPostfix]
			private static void Postfix(ZNet __instance)
			{
				isServer = __instance.IsServer();
				foreach (ConfigSync configSync2 in configSyncs)
				{
					ZRoutedRpc.instance.Register<ZPackage>(configSync2.Name + " ConfigSync", (Action<long, ZPackage>)configSync2.RPC_FromOtherClientConfigSync);
					if (isServer)
					{
						configSync2.InitialSyncDone = true;
						Debug.Log((object)("Registered '" + configSync2.Name + " ConfigSync' RPC - waiting for incoming connections"));
					}
				}
				if (isServer)
				{
					((MonoBehaviour)__instance).StartCoroutine(WatchAdminListChanges());
				}
				static void SendAdmin(List<ZNetPeer> peers, bool isAdmin)
				{
					ZPackage package = ConfigsToPackage(null, null, new PackageEntry[1]
					{
						new PackageEntry
						{
							section = "Internal",
							key = "lockexempt",
							type = typeof(bool),
							value = isAdmin
						}
					});
					ConfigSync configSync = configSyncs.First();
					if (configSync != null)
					{
						((MonoBehaviour)ZNet.instance).StartCoroutine(configSync.sendZPackage(peers, package));
					}
				}
				static IEnumerator WatchAdminListChanges()
				{
					MethodInfo listContainsId = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null);
					SyncedList adminList = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance);
					List<string> CurrentList = new List<string>(adminList.GetList());
					while (true)
					{
						yield return (object)new WaitForSeconds(30f);
						if (!adminList.GetList().SequenceEqual(CurrentList))
						{
							CurrentList = new List<string>(adminList.GetList());
							List<ZNetPeer> list = ZNet.instance.GetPeers().Where(delegate(ZNetPeer p)
							{
								string hostName = p.m_rpc.GetSocket().GetHostName();
								return ((object)listContainsId != null) ? ((bool)listContainsId.Invoke(ZNet.instance, new object[2] { adminList, hostName })) : adminList.Contains(hostName);
							}).ToList();
							SendAdmin(ZNet.instance.GetPeers().Except(list).ToList(), isAdmin: false);
							SendAdmin(list, isAdmin: true);
						}
					}
				}
			}
		}

		[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
		private static class RegisterClientRPCPatch
		{
			[HarmonyPostfix]
			private static void Postfix(ZNet __instance, ZNetPeer peer)
			{
				if (__instance.IsServer())
				{
					return;
				}
				foreach (ConfigSync configSync in configSyncs)
				{
					peer.m_rpc.Register<ZPackage>(configSync.Name + " ConfigSync", (Action<ZRpc, ZPackage>)configSync.RPC_FromServerConfigSync);
				}
			}
		}

		private class ParsedConfigs
		{
			public readonly Dictionary<OwnConfigEntryBase, object?> configValues = new Dictionary<OwnConfigEntryBase, object>();

			public readonly Dictionary<CustomSyncedValueBase, object?> customValues = new Dictionary<CustomSyncedValueBase, object>();
		}

		[HarmonyPatch(typeof(ZNet), "Shutdown")]
		private class ResetConfigsOnShutdown
		{
			[HarmonyPostfix]
			private static void Postfix()
			{
				ProcessingServerUpdate = true;
				foreach (ConfigSync configSync in configSyncs)
				{
					configSync.resetConfigsFromServer();
					configSync.IsSourceOfTruth = true;
					configSync.InitialSyncDone = false;
				}
				ProcessingServerUpdate = false;
			}
		}

		[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
		private class SendConfigsAfterLogin
		{
			private class BufferingSocket : ZPlayFabSocket, ISocket
			{
				public volatile bool finished;

				public volatile int versionMatchQueued = -1;

				public readonly List<ZPackage> Package = new List<ZPackage>();

				public readonly ISocket Original;

				public BufferingSocket(ISocket original)
				{
					Original = original;
					((ZPlayFabSocket)this)..ctor();
				}

				public bool IsConnected()
				{
					return Original.IsConnected();
				}

				public ZPackage Recv()
				{
					return Original.Recv();
				}

				public int GetSendQueueSize()
				{
					return Original.GetSendQueueSize();
				}

				public int GetCurrentSendRate()
				{
					return Original.GetCurrentSendRate();
				}

				public bool IsHost()
				{
					return Original.IsHost();
				}

				public void Dispose()
				{
					Original.Dispose();
				}

				public bool GotNewData()
				{
					return Original.GotNewData();
				}

				public void Close()
				{
					Original.Close();
				}

				public string GetEndPointString()
				{
					return Original.GetEndPointString();
				}

				public void GetAndResetStats(out int totalSent, out int totalRecv)
				{
					Original.GetAndResetStats(ref totalSent, ref totalRecv);
				}

				public void GetConnectionQuality(out float localQuality, out float remoteQuality, out int ping, out float outByteSec, out float inByteSec)
				{
					Original.GetConnectionQuality(ref localQuality, ref remoteQuality, ref ping, ref outByteSec, ref inByteSec);
				}

				public ISocket Accept()
				{
					return Original.Accept();
				}

				public int GetHostPort()
				{
					return Original.GetHostPort();
				}

				public bool Flush()
				{
					return Original.Flush();
				}

				public string GetHostName()
				{
					return Original.GetHostName();
				}

				public void VersionMatch()
				{
					if (finished)
					{
						Original.VersionMatch();
					}
					else
					{
						versionMatchQueued = Package.Count;
					}
				}

				public void Send(ZPackage pkg)
				{
					//IL_004c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0052: Expected O, but got Unknown
					int pos = pkg.GetPos();
					pkg.SetPos(0);
					int num = pkg.ReadInt();
					if ((num == StringExtensionMethods.GetStableHashCode("PeerInfo") || num == StringExtensionMethods.GetStableHashCode("RoutedRPC") || num == StringExtensionMethods.GetStableHashCode("ZDOData")) && !finished)
					{
						ZPackage val = new ZPackage(pkg.GetArray());
						val.SetPos(pos);
						Package.Add(val);
					}
					else
					{
						pkg.SetPos(pos);
						Original.Send(pkg);
					}
				}
			}

			[HarmonyPriority(800)]
			[HarmonyPrefix]
			private static void Prefix(ref Dictionary<Assembly, BufferingSocket>? __state, ZNet __instance, ZRpc rpc)
			{
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				if (!__instance.IsServer())
				{
					return;
				}
				BufferingSocket bufferingSocket = new BufferingSocket(rpc.GetSocket());
				AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc, bufferingSocket);
				object? obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance, new object[1] { rpc });
				ZNetPeer val = (ZNetPeer)((obj is ZNetPeer) ? obj : null);
				if (val != null && (int)ZNet.m_onlineBackend != 0)
				{
					FieldInfo fieldInfo = AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket");
					object? value = fieldInfo.GetValue(val);
					ZPlayFabSocket val2 = (ZPlayFabSocket)((value is ZPlayFabSocket) ? value : null);
					if (val2 != null)
					{
						typeof(ZPlayFabSocket).GetField("m_remotePlayerId").SetValue(bufferingSocket, val2.m_remotePlayerId);
					}
					fieldInfo.SetValue(val, bufferingSocket);
				}
				if (__state == null)
				{
					__state = new Dictionary<Assembly, BufferingSocket>();
				}
				__state[Assembly.GetExecutingAssembly()] = bufferingSocket;
			}

			[HarmonyPostfix]
			private static void Postfix(Dictionary<Assembly, BufferingSocket> __state, ZNet __instance, ZRpc rpc)
			{
				ZNetPeer peer;
				if (__instance.IsServer())
				{
					object obj = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance, new object[1] { rpc });
					peer = (ZNetPeer)((obj is ZNetPeer) ? obj : null);
					if (peer == null)
					{
						SendBufferedData();
					}
					else
					{
						((MonoBehaviour)__instance).StartCoroutine(sendAsync());
					}
				}
				void SendBufferedData()
				{
					if (rpc.GetSocket() is BufferingSocket bufferingSocket)
					{
						AccessTools.DeclaredField(typeof(ZRpc), "m_socket").SetValue(rpc, bufferingSocket.Original);
						object? obj2 = AccessTools.DeclaredMethod(typeof(ZNet), "GetPeer", new Type[1] { typeof(ZRpc) }, (Type[])null).Invoke(__instance, new object[1] { rpc });
						ZNetPeer val = (ZNetPeer)((obj2 is ZNetPeer) ? obj2 : null);
						if (val != null)
						{
							AccessTools.DeclaredField(typeof(ZNetPeer), "m_socket").SetValue(val, bufferingSocket.Original);
						}
					}
					BufferingSocket bufferingSocket2 = __state[Assembly.GetExecutingAssembly()];
					bufferingSocket2.finished = true;
					for (int i = 0; i < bufferingSocket2.Package.Count; i++)
					{
						if (i == bufferingSocket2.versionMatchQueued)
						{
							bufferingSocket2.Original.VersionMatch();
						}
						bufferingSocket2.Original.Send(bufferingSocket2.Package[i]);
					}
					if (bufferingSocket2.Package.Count == bufferingSocket2.versionMatchQueued)
					{
						bufferingSocket2.Original.VersionMatch();
					}
				}
				IEnumerator sendAsync()
				{
					foreach (ConfigSync configSync in configSyncs)
					{
						List<PackageEntry> list = new List<PackageEntry>();
						if (configSync.CurrentVersion != null)
						{
							list.Add(new PackageEntry
							{
								section = "Internal",
								key = "serverversion",
								type = typeof(string),
								value = configSync.CurrentVersion
							});
						}
						MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null);
						SyncedList val = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance);
						list.Add(new PackageEntry
						{
							section = "Internal",
							key = "lockexempt",
							type = typeof(bool),
							value = (((object)methodInfo == null) ? ((object)val.Contains(rpc.GetSocket().GetHostName())) : methodInfo.Invoke(ZNet.instance, new object[2]
							{
								val,
								rpc.GetSocket().GetHostName()
							}))
						});
						ZPackage package = ConfigsToPackage(configSync.allConfigs.Select((OwnConfigEntryBase c) => c.BaseConfig), configSync.allCustomValues, list, partial: false);
						yield return ((MonoBehaviour)__instance).StartCoroutine(configSync.sendZPackage(new List<ZNetPeer> { peer }, package));
					}
					SendBufferedData();
				}
			}
		}

		private class PackageEntry
		{
			public string section;

			public string key;

			public Type type;

			public object? value;
		}

		[HarmonyPatch(typeof(ConfigEntryBase), "GetSerializedValue")]
		private static class PreventSavingServerInfo
		{
			[HarmonyPrefix]
			private static bool Prefix(ConfigEntryBase __instance, ref string __result)
			{
				OwnConfigEntryBase ownConfigEntryBase = configData(__instance);
				if (ownConfigEntryBase == null || isWritableConfig(ownConfigEntryBase))
				{
					return true;
				}
				__result = TomlTypeConverter.ConvertToString(ownConfigEntryBase.LocalBaseValue, __instance.SettingType);
				return false;
			}
		}

		[HarmonyPatch(typeof(ConfigEntryBase), "SetSerializedValue")]
		private static class PreventConfigRereadChangingValues
		{
			[HarmonyPrefix]
			private static bool Prefix(ConfigEntryBase __instance, string value)
			{
				OwnConfigEntryBase ownConfigEntryBase = configData(__instance);
				if (ownConfigEntryBase == null || ownConfigEntryBase.LocalBaseValue == null)
				{
					return true;
				}
				try
				{
					ownConfigEntryBase.LocalBaseValue = TomlTypeConverter.ConvertToValue(value, __instance.SettingType);
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)$"Config value of setting \"{__instance.Definition}\" could not be parsed and will be ignored. Reason: {ex.Message}; Value: {value}");
				}
				return false;
			}
		}

		private class InvalidDeserializationTypeException : Exception
		{
			public string expected;

			public string received;

			public string field = "";
		}

		public static bool ProcessingServerUpdate;

		public readonly string Name;

		public string? DisplayName;

		public string? CurrentVersion;

		public string? MinimumRequiredVersion;

		public bool ModRequired;

		private bool? forceConfigLocking;

		private bool isSourceOfTruth = true;

		private static readonly HashSet<ConfigSync> configSyncs;

		private readonly HashSet<OwnConfigEntryBase> allConfigs = new HashSet<OwnConfigEntryBase>();

		private HashSet<CustomSyncedValueBase> allCustomValues = new HashSet<CustomSyncedValueBase>();

		private static bool isServer;

		private static bool lockExempt;

		private OwnConfigEntryBase? lockedConfig;

		private const byte PARTIAL_CONFIGS = 1;

		private const byte FRAGMENTED_CONFIG = 2;

		private const byte COMPRESSED_CONFIG = 4;

		private readonly Dictionary<string, SortedDictionary<int, byte[]>> configValueCache = new Dictionary<string, SortedDictionary<int, byte[]>>();

		private readonly List<KeyValuePair<long, string>> cacheExpirations = new List<KeyValuePair<long, string>>();

		private static long packageCounter;

		public bool IsLocked
		{
			get
			{
				bool? flag = forceConfigLocking;
				bool num;
				if (!flag.HasValue)
				{
					if (lockedConfig == null)
					{
						goto IL_0051;
					}
					num = ((IConvertible)lockedConfig.BaseConfig.BoxedValue).ToInt32(CultureInfo.InvariantCulture) != 0;
				}
				else
				{
					num = flag == true;
				}
				if (num)
				{
					return !lockExempt;
				}
				goto IL_0051;
				IL_0051:
				return false;
			}
			set
			{
				forceConfigLocking = value;
			}
		}

		public bool IsAdmin
		{
			get
			{
				if (!lockExempt)
				{
					return isSourceOfTruth;
				}
				return true;
			}
		}

		public bool IsSourceOfTruth
		{
			get
			{
				return isSourceOfTruth;
			}
			private set
			{
				if (value != isSourceOfTruth)
				{
					isSourceOfTruth = value;
					this.SourceOfTruthChanged?.Invoke(value);
				}
			}
		}

		public bool InitialSyncDone { get; private set; }

		public event Action<bool>? SourceOfTruthChanged;

		private event Action? lockedConfigChanged;

		static ConfigSync()
		{
			ProcessingServerUpdate = false;
			configSyncs = new HashSet<ConfigSync>();
			lockExempt = false;
			packageCounter = 0L;
			RuntimeHelpers.RunClassConstructor(typeof(VersionCheck).TypeHandle);
		}

		public ConfigSync(string name)
		{
			Name = name;
			configSyncs.Add(this);
			new VersionCheck(this);
		}

		public SyncedConfigEntry<T> AddConfigEntry<T>(ConfigEntry<T> configEntry)
		{
			OwnConfigEntryBase ownConfigEntryBase = configData((ConfigEntryBase)(object)configEntry);
			SyncedConfigEntry<T> syncedEntry = ownConfigEntryBase as SyncedConfigEntry<T>;
			if (syncedEntry == null)
			{
				syncedEntry = new SyncedConfigEntry<T>(configEntry);
				AccessTools.DeclaredField(typeof(ConfigDescription), "<Tags>k__BackingField").SetValue(((ConfigEntryBase)configEntry).Description, new object[1]
				{
					new ConfigurationManagerAttributes()
				}.Concat(((ConfigEntryBase)configEntry).Description.Tags ?? Array.Empty<object>()).Concat(new SyncedConfigEntry<T>[1] { syncedEntry }).ToArray());
				configEntry.SettingChanged += delegate
				{
					if (!ProcessingServerUpdate && syncedEntry.SynchronizedConfig)
					{
						Broadcast(ZRoutedRpc.Everybody, (ConfigEntryBase)configEntry);
					}
				};
				allConfigs.Add(syncedEntry);
			}
			return syncedEntry;
		}

		public SyncedConfigEntry<T> AddLockingConfigEntry<T>(ConfigEntry<T> lockingConfig) where T : IConvertible
		{
			if (lockedConfig != null)
			{
				throw new Exception("Cannot initialize locking ConfigEntry twice");
			}
			lockedConfig = AddConfigEntry<T>(lockingConfig);
			lockingConfig.SettingChanged += delegate
			{
				this.lockedConfigChanged?.Invoke();
			};
			return (SyncedConfigEntry<T>)lockedConfig;
		}

		internal void AddCustomValue(CustomSyncedValueBase customValue)
		{
			if (allCustomValues.Select((CustomSyncedValueBase v) => v.Identifier).Concat(new string[1] { "serverversion" }).Contains(customValue.Identifier))
			{
				throw new Exception("Cannot have multiple settings with the same name or with a reserved name (serverversion)");
			}
			allCustomValues.Add(customValue);
			allCustomValues = new HashSet<CustomSyncedValueBase>(allCustomValues.OrderByDescending((CustomSyncedValueBase v) => v.Priority));
			customValue.ValueChanged += delegate
			{
				if (!ProcessingServerUpdate)
				{
					Broadcast(ZRoutedRpc.Everybody, customValue);
				}
			};
		}

		private void RPC_FromServerConfigSync(ZRpc rpc, ZPackage package)
		{
			lockedConfigChanged += serverLockedSettingChanged;
			IsSourceOfTruth = false;
			if (HandleConfigSyncRPC(0L, package, clientUpdate: false))
			{
				InitialSyncDone = true;
			}
		}

		private void RPC_FromOtherClientConfigSync(long sender, ZPackage package)
		{
			HandleConfigSyncRPC(sender, package, clientUpdate: true);
		}

		private bool HandleConfigSyncRPC(long sender, ZPackage package, bool clientUpdate)
		{
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Expected O, but got Unknown
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			try
			{
				if (isServer && IsLocked)
				{
					ZRpc? currentRpc = SnatchCurrentlyHandlingRPC.currentRpc;
					object obj;
					if (currentRpc == null)
					{
						obj = null;
					}
					else
					{
						ISocket socket = currentRpc.GetSocket();
						obj = ((socket != null) ? socket.GetHostName() : null);
					}
					string text = (string)obj;
					if (text != null)
					{
						MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null);
						SyncedList val = (SyncedList)AccessTools.DeclaredField(typeof(ZNet), "m_adminList").GetValue(ZNet.instance);
						if (!(((object)methodInfo == null) ? val.Contains(text) : ((bool)methodInfo.Invoke(ZNet.instance, new object[2] { val, text }))))
						{
							return false;
						}
					}
				}
				cacheExpirations.RemoveAll(delegate(KeyValuePair<long, string> kv)
				{
					if (kv.Key < DateTimeOffset.Now.Ticks)
					{
						configValueCache.Remove(kv.Value);
						return true;
					}
					return false;
				});
				byte b = package.ReadByte();
				if ((b & 2) != 0)
				{
					long num = package.ReadLong();
					string text2 = sender.ToString() + num;
					if (!configValueCache.TryGetValue(text2, out SortedDictionary<int, byte[]> value))
					{
						value = new SortedDictionary<int, byte[]>();
						configValueCache[text2] = value;
						cacheExpirations.Add(new KeyValuePair<long, string>(DateTimeOffset.Now.AddSeconds(60.0).Ticks, text2));
					}
					int key = package.ReadInt();
					int num2 = package.ReadInt();
					value.Add(key, package.ReadByteArray());
					if (value.Count < num2)
					{
						return false;
					}
					configValueCache.Remove(text2);
					package = new ZPackage(value.Values.SelectMany((byte[] a) => a).ToArray());
					b = package.ReadByte();
				}
				ProcessingServerUpdate = true;
				if ((b & 4) != 0)
				{
					MemoryStream stream = new MemoryStream(package.ReadByteArray());
					MemoryStream memoryStream = new MemoryStream();
					using (DeflateStream deflateStream = new DeflateStream(stream, CompressionMode.Decompress))
					{
						deflateStream.CopyTo(memoryStream);
					}
					package = new ZPackage(memoryStream.ToArray());
					b = package.ReadByte();
				}
				if ((b & 1) == 0)
				{
					resetConfigsFromServer();
				}
				ParsedConfigs parsedConfigs = ReadConfigsFromPackage(package);
				ConfigFile val2 = null;
				bool saveOnConfigSet = false;
				foreach (KeyValuePair<OwnConfigEntryBase, object> configValue in parsedConfigs.configValues)
				{
					if (!isServer && configValue.Key.LocalBaseValue == null)
					{
						configValue.Key.LocalBaseValue = configValue.Key.BaseConfig.BoxedValue;
					}
					if (val2 == null)
					{
						val2 = configValue.Key.BaseConfig.ConfigFile;
						saveOnConfigSet = val2.SaveOnConfigSet;
						val2.SaveOnConfigSet = false;
					}
					configValue.Key.BaseConfig.BoxedValue = configValue.Value;
				}
				if (val2 != null)
				{
					val2.SaveOnConfigSet = saveOnConfigSet;
					val2.Save();
				}
				foreach (KeyValuePair<CustomSyncedValueBase, object> customValue in parsedConfigs.customValues)
				{
					if (!isServer)
					{
						CustomSyncedValueBase key2 = customValue.Key;
						if (key2.LocalBaseValue == null)
						{
							key2.LocalBaseValue = customValue.Key.BoxedValue;
						}
					}
					customValue.Key.BoxedValue = customValue.Value;
				}
				Debug.Log((object)string.Format("Received {0} configs and {1} custom values from {2} for mod {3}", parsedConfigs.configValues.Count, parsedConfigs.customValues.Count, (isServer || clientUpdate) ? $"client {sender}" : "the server", DisplayName ?? Name));
				if (!isServer)
				{
					serverLockedSettingChanged();
				}
				return true;
			}
			finally
			{
				ProcessingServerUpdate = false;
			}
		}

		private ParsedConfigs ReadConfigsFromPackage(ZPackage package)
		{
			ParsedConfigs parsedConfigs = new ParsedConfigs();
			Dictionary<string, OwnConfigEntryBase> dictionary = allConfigs.Where((OwnConfigEntryBase c) => c.SynchronizedConfig).ToDictionary((OwnConfigEntryBase c) => c.BaseConfig.Definition.Section + "_" + c.BaseConfig.Definition.Key, (OwnConfigEntryBase c) => c);
			Dictionary<string, CustomSyncedValueBase> dictionary2 = allCustomValues.ToDictionary((CustomSyncedValueBase c) => c.Identifier, (CustomSyncedValueBase c) => c);
			int num = package.ReadInt();
			for (int num2 = 0; num2 < num; num2++)
			{
				string text = package.ReadString();
				string text2 = package.ReadString();
				string text3 = package.ReadString();
				Type type = Type.GetType(text3);
				if (text3 == "" || type != null)
				{
					object obj;
					try
					{
						obj = ((text3 == "") ? null : ReadValueWithTypeFromZPackage(package, type));
					}
					catch (InvalidDeserializationTypeException ex)
					{
						Debug.LogWarning((object)("Got unexpected struct internal type " + ex.received + " for field " + ex.field + " struct " + text3 + " for " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ", expecting " + ex.expected));
						continue;
					}
					OwnConfigEntryBase value2;
					if (text == "Internal")
					{
						CustomSyncedValueBase value;
						if (text2 == "serverversion")
						{
							if (obj?.ToString() != CurrentVersion)
							{
								Debug.LogWarning((object)("Received server version is not equal: server version = " + (obj?.ToString() ?? "null") + "; local version = " + (CurrentVersion ?? "unknown")));
							}
						}
						else if (text2 == "lockexempt")
						{
							if (obj is bool flag)
							{
								lockExempt = flag;
							}
						}
						else if (dictionary2.TryGetValue(text2, out value))
						{
							if ((text3 == "" && (!value.Type.IsValueType || Nullable.GetUnderlyingType(value.Type) != null)) || GetZPackageTypeString(value.Type) == text3)
							{
								parsedConfigs.customValues[value] = obj;
								continue;
							}
							Debug.LogWarning((object)("Got unexpected type " + text3 + " for internal value " + text2 + " for mod " + (DisplayName ?? Name) + ", expecting " + value.Type.AssemblyQualifiedName));
						}
					}
					else if (dictionary.TryGetValue(text + "_" + text2, out value2))
					{
						Type type2 = configType(value2.BaseConfig);
						if ((text3 == "" && (!type2.IsValueType || Nullable.GetUnderlyingType(type2) != null)) || GetZPackageTypeString(type2) == text3)
						{
							parsedConfigs.configValues[value2] = obj;
							continue;
						}
						Debug.LogWarning((object)("Got unexpected type " + text3 + " for " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ", expecting " + type2.AssemblyQualifiedName));
					}
					else
					{
						Debug.LogWarning((object)("Received unknown config entry " + text2 + " in section " + text + " for mod " + (DisplayName ?? Name) + ". This may happen if client and server versions of the mod do not match."));
					}
					continue;
				}
				Debug.LogWarning((object)("Got invalid type " + text3 + ", abort reading of received configs"));
				return new ParsedConfigs();
			}
			return parsedConfigs;
		}

		private static bool isWritableConfig(OwnConfigEntryBase config)
		{
			ConfigSync configSync = configSyncs.FirstOrDefault((ConfigSync cs) => cs.allConfigs.Contains(config));
			if (configSync == null)
			{
				return true;
			}
			if (!configSync.IsSourceOfTruth && config.SynchronizedConfig && config.LocalBaseValue != null)
			{
				if (!configSync.IsLocked)
				{
					if (config == configSync.lockedConfig)
					{
						return lockExempt;
					}
					return true;
				}
				return false;
			}
			return true;
		}

		private void serverLockedSettingChanged()
		{
			foreach (OwnConfigEntryBase allConfig in allConfigs)
			{
				configAttribute<ConfigurationManagerAttributes>(allConfig.BaseConfig).ReadOnly = !isWritableConfig(allConfig);
			}
		}

		private void resetConfigsFromServer()
		{
			ConfigFile val = null;
			bool saveOnConfigSet = false;
			foreach (OwnConfigEntryBase item in allConfigs.Where((OwnConfigEntryBase config) => config.LocalBaseValue != null))
			{
				if (val == null)
				{
					val = item.BaseConfig.ConfigFile;
					saveOnConfigSet = val.SaveOnConfigSet;
					val.SaveOnConfigSet = false;
				}
				item.BaseConfig.BoxedValue = item.LocalBaseValue;
				item.LocalBaseValue = null;
			}
			if (val != null)
			{
				val.SaveOnConfigSet = saveOnConfigSet;
			}
			foreach (CustomSyncedValueBase item2 in allCustomValues.Where((CustomSyncedValueBase config) => config.LocalBaseValue != null))
			{
				item2.BoxedValue = item2.LocalBaseValue;
				item2.LocalBaseValue = null;
			}
			lockedConfigChanged -= serverLockedSettingChanged;
			serverLockedSettingChanged();
		}

		private IEnumerator<bool> distributeConfigToPeers(ZNetPeer peer, ZPackage package)
		{
			ZRoutedRpc rpc = ZRoutedRpc.instance;
			if (rpc == null)
			{
				yield break;
			}
			byte[] data = package.GetArray();
			if (data != null && data.LongLength > 250000)
			{
				int fragments = (int)(1 + (data.LongLength - 1) / 250000);
				long packageIdentifier = ++packageCounter;
				int fragment = 0;
				while (fragment < fragments)
				{
					foreach (bool item in waitForQueue())
					{
						yield return item;
					}
					if (peer.m_socket.IsConnected())
					{
						ZPackage val = new ZPackage();
						val.Write((byte)2);
						val.Write(packageIdentifier);
						val.Write(fragment);
						val.Write(fragments);
						val.Write(data.Skip(250000 * fragment).Take(250000).ToArray());
						SendPackage(val);
						if (fragment != fragments - 1)
						{
							yield return true;
						}
						int num = fragment + 1;
						fragment = num;
						continue;
					}
					break;
				}
				yield break;
			}
			foreach (bool item2 in waitForQueue())
			{
				yield return item2;
			}
			SendPackage(package);
			void SendPackage(ZPackage pkg)
			{
				string text = Name + " ConfigSync";
				if (isServer)
				{
					peer.m_rpc.Invoke(text, new object[1] { pkg });
				}
				else
				{
					rpc.InvokeRoutedRPC(peer.m_server ? 0 : peer.m_uid, text, new object[1] { pkg });
				}
			}
			IEnumerable<bool> waitForQueue()
			{
				float timeout = Time.time + 30f;
				while (peer.m_socket.GetSendQueueSize() > 20000)
				{
					if (Time.time > timeout)
					{
						Debug.Log((object)$"Disconnecting {peer.m_uid} after 30 seconds config sending timeout");
						peer.m_rpc.Invoke("Error", new object[1] { (object)(ConnectionStatus)5 });
						ZNet.instance.Disconnect(peer);
						break;
					}
					yield return false;
				}
			}
		}

		private IEnumerator sendZPackage(long target, ZPackage package)
		{
			if (!Object.op_Implicit((Object)(object)ZNet.instance))
			{
				return Enumerable.Empty<object>().GetEnumerator();
			}
			List<ZNetPeer> list = (List<ZNetPeer>)AccessTools.DeclaredField(typeof(ZRoutedRpc), "m_peers").GetValue(ZRoutedRpc.instance);
			if (target != ZRoutedRpc.Everybody)
			{
				list = list.Where((ZNetPeer p) => p.m_uid == target).ToList();
			}
			return sendZPackage(list, package);
		}

		private IEnumerator sendZPackage(List<ZNetPeer> peers, ZPackage package)
		{
			if (!Object.op_Implicit((Object)(object)ZNet.instance))
			{
				yield break;
			}
			byte[] array = package.GetArray();
			if (array != null && array.LongLength > 10000)
			{
				ZPackage val = new ZPackage();
				val.Write((byte)4);
				MemoryStream memoryStream = new MemoryStream();
				using (DeflateStream deflateStream = new DeflateStream(memoryStream, CompressionLevel.Optimal))
				{
					deflateStream.Write(array, 0, array.Length);
				}
				val.Write(memoryStream.ToArray());
				package = val;
			}
			List<IEnumerator<bool>> writers = (from p in peers
				where p.IsReady()
				select distributeConfigToPeers(p, package)).ToList();
			writers.RemoveAll((IEnumerator<bool> writer) => !writer.MoveNext());
			while (writers.Count > 0)
			{
				yield return null;
				writers.RemoveAll((IEnumerator<bool> writer) => !writer.MoveNext());
			}
		}

		private void Broadcast(long target, params ConfigEntryBase[] configs)
		{
			if (!IsLocked || isServer)
			{
				ZPackage package = ConfigsToPackage(configs);
				ZNet instance = ZNet.instance;
				if (instance != null)
				{
					((MonoBehaviour)instance).StartCoroutine(sendZPackage(target, package));
				}
			}
		}

		private void Broadcast(long target, params CustomSyncedValueBase[] customValues)
		{
			if (!IsLocked || isServer)
			{
				ZPackage package = ConfigsToPackage(null, customValues);
				ZNet instance = ZNet.instance;
				if (instance != null)
				{
					((MonoBehaviour)instance).StartCoroutine(sendZPackage(target, package));
				}
			}
		}

		private static OwnConfigEntryBase? configData(ConfigEntryBase config)
		{
			return config.Description.Tags?.OfType<OwnConfigEntryBase>().SingleOrDefault();
		}

		public static SyncedConfigEntry<T>? ConfigData<T>(ConfigEntry<T> config)
		{
			return ((ConfigEntryBase)config).Description.Tags?.OfType<SyncedConfigEntry<T>>().SingleOrDefault();
		}

		private static T configAttribute<T>(ConfigEntryBase config)
		{
			return config.Description.Tags.OfType<T>().First();
		}

		private static Type configType(ConfigEntryBase config)
		{
			return configType(config.SettingType);
		}

		private static Type configType(Type type)
		{
			if (!type.IsEnum)
			{
				return type;
			}
			return Enum.GetUnderlyingType(type);
		}

		private static ZPackage ConfigsToPackage(IEnumerable<ConfigEntryBase>? configs = null, IEnumerable<CustomSyncedValueBase>? customValues = null, IEnumerable<PackageEntry>? packageEntries = null, bool partial = true)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			List<ConfigEntryBase> list = configs?.Where((ConfigEntryBase config) => configData(config).SynchronizedConfig).ToList() ?? new List<ConfigEntryBase>();
			List<CustomSyncedValueBase> list2 = customValues?.ToList() ?? new List<CustomSyncedValueBase>();
			ZPackage val = new ZPackage();
			val.Write(partial ? ((byte)1) : ((byte)0));
			val.Write(list.Count + list2.Count + (packageEntries?.Count() ?? 0));
			foreach (PackageEntry item in packageEntries ?? Array.Empty<PackageEntry>())
			{
				AddEntryToPackage(val, item);
			}
			foreach (CustomSyncedValueBase item2 in list2)
			{
				AddEntryToPackage(val, new PackageEntry
				{
					section = "Internal",
					key = item2.Identifier,
					type = item2.Type,
					value = item2.BoxedValue
				});
			}
			foreach (ConfigEntryBase item3 in list)
			{
				AddEntryToPackage(val, new PackageEntry
				{
					section = item3.Definition.Section,
					key = item3.Definition.Key,
					type = configType(item3),
					value = item3.BoxedValue
				});
			}
			return val;
		}

		private static void AddEntryToPackage(ZPackage package, PackageEntry entry)
		{
			package.Write(entry.section);
			package.Write(entry.key);
			package.Write((entry.value == null) ? "" : GetZPackageTypeString(entry.type));
			AddValueToZPackage(package, entry.value);
		}

		private static string GetZPackageTypeString(Type type)
		{
			return type.AssemblyQualifiedName;
		}

		private static void AddValueToZPackage(ZPackage package, object? value)
		{
			Type type = value?.GetType();
			if (value is Enum)
			{
				value = ((IConvertible)value).ToType(Enum.GetUnderlyingType(value.GetType()), CultureInfo.InvariantCulture);
			}
			else
			{
				if (value is ICollection collection)
				{
					package.Write(collection.Count);
					{
						foreach (object item in collection)
						{
							AddValueToZPackage(package, item);
						}
						return;
					}
				}
				if ((object)type != null && type.IsValueType && !type.IsPrimitive)
				{
					FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					package.Write(fields.Length);
					FieldInfo[] array = fields;
					foreach (FieldInfo fieldInfo in array)
					{
						package.Write(GetZPackageTypeString(fieldInfo.FieldType));
						AddValueToZPackage(package, fieldInfo.GetValue(value));
					}
					return;
				}
			}
			ZRpc.Serialize(new object[1] { value }, ref package);
		}

		private static object ReadValueWithTypeFromZPackage(ZPackage package, Type type)
		{
			if ((object)type != null && type.IsValueType && !type.IsPrimitive && !type.IsEnum)
			{
				FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				int num = package.ReadInt();
				if (num != fields.Length)
				{
					throw new InvalidDeserializationTypeException
					{
						received = $"(field count: {num})",
						expected = $"(field count: {fields.Length})"
					};
				}
				object uninitializedObject = FormatterServices.GetUninitializedObject(type);
				FieldInfo[] array = fields;
				foreach (FieldInfo fieldInfo in array)
				{
					string text = package.ReadString();
					if (text != GetZPackageTypeString(fieldInfo.FieldType))
					{
						throw new InvalidDeserializationTypeException
						{
							received = text,
							expected = GetZPackageTypeString(fieldInfo.FieldType),
							field = fieldInfo.Name
						};
					}
					fieldInfo.SetValue(uninitializedObject, ReadValueWithTypeFromZPackage(package, fieldInfo.FieldType));
				}
				return uninitializedObject;
			}
			if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<, >))
			{
				int num2 = package.ReadInt();
				IDictionary dictionary = (IDictionary)Activator.CreateInstance(type);
				Type type2 = typeof(KeyValuePair<, >).MakeGenericType(type.GenericTypeArguments);
				FieldInfo field = type2.GetField("key", BindingFlags.Instance | BindingFlags.NonPublic);
				FieldInfo field2 = type2.GetField("value", BindingFlags.Instance | BindingFlags.NonPublic);
				for (int j = 0; j < num2; j++)
				{
					object obj = ReadValueWithTypeFromZPackage(package, type2);
					dictionary.Add(field.GetValue(obj), field2.GetValue(obj));
				}
				return dictionary;
			}
			if (type != typeof(List<string>) && type.IsGenericType)
			{
				Type type3 = typeof(ICollection<>).MakeGenericType(type.GenericTypeArguments[0]);
				if ((object)type3 != null && type3.IsAssignableFrom(type))
				{
					int num3 = package.ReadInt();
					object obj2 = Activator.CreateInstance(type);
					MethodInfo method = type3.GetMethod("Add");
					for (int k = 0; k < num3; k++)
					{
						method.Invoke(obj2, new object[1] { ReadValueWithTypeFromZPackage(package, type.GenericTypeArguments[0]) });
					}
					return obj2;
				}
			}
			ParameterInfo parameterInfo = (ParameterInfo)FormatterServices.GetUninitializedObject(typeof(ParameterInfo));
			AccessTools.DeclaredField(typeof(ParameterInfo), "ClassImpl").SetValue(parameterInfo, type);
			List<object> source = new List<object>();
			ZRpc.Deserialize(new ParameterInfo[2] { null, parameterInfo }, package, ref source);
			return source.First();
		}
	}
	[PublicAPI]
	[HarmonyPatch]
	public class VersionCheck
	{
		private static readonly HashSet<VersionCheck> versionChecks;

		private static readonly Dictionary<string, string> notProcessedNames;

		public string Name;

		private string? displayName;

		private string? currentVersion;

		private string? minimumRequiredVersion;

		public bool ModRequired = true;

		private string? ReceivedCurrentVersion;

		private string? ReceivedMinimumRequiredVersion;

		private readonly List<ZRpc> ValidatedClients = new List<ZRpc>();

		private ConfigSync? ConfigSync;

		public string DisplayName
		{
			get
			{
				return displayName ?? Name;
			}
			set
			{
				displayName = value;
			}
		}

		public string CurrentVersion
		{
			get
			{
				return currentVersion ?? "0.0.0";
			}
			set
			{
				currentVersion = value;
			}
		}

		public string MinimumRequiredVersion
		{
			get
			{
				string text = minimumRequiredVersion;
				if (text == null)
				{
					if (!ModRequired)
					{
						return "0.0.0";
					}
					text = CurrentVersion;
				}
				return text;
			}
			set
			{
				minimumRequiredVersion = value;
			}
		}

		private static void PatchServerSync()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			Patches patchInfo = PatchProcessor.GetPatchInfo((MethodBase)AccessTools.DeclaredMethod(typeof(ZNet), "Awake", (Type[])null, (Type[])null));
			if (patchInfo != null && patchInfo.Postfixes.Count((Patch p) => p.PatchMethod.DeclaringType == typeof(ConfigSync.RegisterRPCPatch)) > 0)
			{
				return;
			}
			Harmony val = new Harmony("org.bepinex.helpers.ServerSync");
			foreach (Type item in from t in typeof(ConfigSync).GetNestedTypes(BindingFlags.NonPublic).Concat(new Type[1] { typeof(VersionCheck) })
				where t.IsClass
				select t)
			{
				val.PatchAll(item);
			}
		}

		static VersionCheck()
		{
			versionChecks = new HashSet<VersionCheck>();
			notProcessedNames = new Dictionary<string, string>();
			typeof(ThreadingHelper).GetMethod("StartSyncInvoke").Invoke(ThreadingHelper.Instance, new object[1]
			{
				new Action(PatchServerSync)
			});
		}

		public VersionCheck(string name)
		{
			Name = name;
			ModRequired = true;
			versionChecks.Add(this);
		}

		public VersionCheck(ConfigSync configSync)
		{
			ConfigSync = configSync;
			Name = ConfigSync.Name;
			versionChecks.Add(this);
		}

		public void Initialize()
		{
			ReceivedCurrentVersion = null;
			ReceivedMinimumRequiredVersion = null;
			if (ConfigSync != null)
			{
				Name = ConfigSync.Name;
				DisplayName = ConfigSync.DisplayName;
				CurrentVersion = ConfigSync.CurrentVersion;
				MinimumRequiredVersion = ConfigSync.MinimumRequiredVersion;
				ModRequired = ConfigSync.ModRequired;
			}
		}

		private bool IsVersionOk()
		{
			if (ReceivedMinimumRequiredVersion == null || ReceivedCurrentVersion == null)
			{
				return !ModRequired;
			}
			bool num = new Version(CurrentVersion) >= new Version(ReceivedMinimumRequiredVersion);
			bool flag = new Version(ReceivedCurrentVersion) >= new Version(MinimumRequiredVersion);
			return num && flag;
		}

		private string ErrorClient()
		{
			if (ReceivedMinimumRequiredVersion == null)
			{
				return DisplayName + " is not installed on the server.";
			}
			if (!(new Version(CurrentVersion) >= new Version(ReceivedMinimumRequiredVersion)))
			{
				return DisplayName + " needs to be at least version " + ReceivedMinimumRequiredVersion + ". You have version " + CurrentVersion + ".";
			}
			return DisplayName + " may not be higher than version " + ReceivedCurrentVersion + ". You have version " + CurrentVersion + ".";
		}

		private string ErrorServer(ZRpc rpc)
		{
			return "Disconnect: The client (" + rpc.GetSocket().GetHostName() + ") doesn't have the correct " + DisplayName + " version " + MinimumRequiredVersion;
		}

		private string Error(ZRpc? rpc = null)
		{
			if (rpc != null)
			{
				return ErrorServer(rpc);
			}
			return ErrorClient();
		}

		private static VersionCheck[] GetFailedClient()
		{
			return versionChecks.Where((VersionCheck check) => !check.IsVersionOk()).ToArray();
		}

		private static VersionCheck[] GetFailedServer(ZRpc rpc)
		{
			return versionChecks.Where((VersionCheck check) => check.ModRequired && !check.ValidatedClients.Contains(rpc)).ToArray();
		}

		private static void Logout()
		{
			Game.instance.Logout(true, true);
			AccessTools.DeclaredField(typeof(ZNet), "m_connectionStatus").SetValue(null, (object)(ConnectionStatus)3);
		}

		private static void DisconnectClient(ZRpc rpc)
		{
			rpc.Invoke("Error", new object[1] { 3 });
		}

		private static void CheckVersion(ZRpc rpc, ZPackage pkg)
		{
			CheckVersion(rpc, pkg, null);
		}

		private static void CheckVersion(ZRpc rpc, ZPackage pkg, Action<ZRpc, ZPackage>? original)
		{
			string text = pkg.ReadString();
			string text2 = pkg.ReadString();
			string text3 = pkg.ReadString();
			bool flag = false;
			foreach (VersionCheck versionCheck in versionChecks)
			{
				if (!(text != versionCheck.Name))
				{
					Debug.Log((object)("Received " + versionCheck.DisplayName + " version " + text3 + " and minimum version " + text2 + " from the " + (ZNet.instance.IsServer() ? "client" : "server") + "."));
					versionCheck.ReceivedMinimumRequiredVersion = text2;
					versionCheck.ReceivedCurrentVersion = text3;
					if (ZNet.instance.IsServer() && versionCheck.IsVersionOk())
					{
						versionCheck.ValidatedClients.Add(rpc);
					}
					flag = true;
				}
			}
			if (flag)
			{
				return;
			}
			pkg.SetPos(0);
			if (original != null)
			{
				original(rpc, pkg);
				if (pkg.GetPos() == 0)
				{
					notProcessedNames.Add(text, text3);
				}
			}
		}

		[HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")]
		[HarmonyPrefix]
		private static bool RPC_PeerInfo(ZRpc rpc, ZNet __instance)
		{
			VersionCheck[] array = (__instance.IsServer() ? GetFailedServer(rpc) : GetFailedClient());
			if (array.Length == 0)
			{
				return true;
			}
			VersionCheck[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				Debug.LogWarning((object)array2[i].Error(rpc));
			}
			if (__instance.IsServer())
			{
				DisconnectClient(rpc);
			}
			else
			{
				Logout();
			}
			return false;
		}

		[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
		[HarmonyPrefix]
		private static void RegisterAndCheckVersion(ZNetPeer peer, ZNet __instance)
		{
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Expected O, but got Unknown
			notProcessedNames.Clear();
			IDictionary dictionary = (IDictionary)typeof(ZRpc).GetField("m_functions", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(peer.m_rpc);
			if (dictionary.Contains(StringExtensionMethods.GetStableHashCode("ServerSync VersionCheck")))
			{
				object obj = dictionary[StringExtensionMethods.GetStableHashCode("ServerSync VersionCheck")];
				Action<ZRpc, ZPackage> action = (Action<ZRpc, ZPackage>)obj.GetType().GetField("m_action", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(obj);
				peer.m_rpc.Register<ZPackage>("ServerSync VersionCheck", (Action<ZRpc, ZPackage>)delegate(ZRpc rpc, ZPackage pkg)
				{
					CheckVersion(rpc, pkg, action);
				});
			}
			else
			{
				peer.m_rpc.Register<ZPackage>("ServerSync VersionCheck", (Action<ZRpc, ZPackage>)CheckVersion);
			}
			foreach (VersionCheck versionCheck in versionChecks)
			{
				versionCheck.Initialize();
				if (versionCheck.ModRequired || __instance.IsServer())
				{
					Debug.Log((object)("Sending " + versionCheck.DisplayName + " version " + versionCheck.CurrentVersion + " and minimum version " + versionCheck.MinimumRequiredVersion + " to the " + (__instance.IsServer() ? "client" : "server") + "."));
					ZPackage val = new ZPackage();
					val.Write(versionCheck.Name);
					val.Write(versionCheck.MinimumRequiredVersion);
					val.Write(versionCheck.CurrentVersion);
					peer.m_rpc.Invoke("ServerSync VersionCheck", new object[1] { val });
				}
			}
		}

		[HarmonyPatch(typeof(ZNet), "Disconnect")]
		[HarmonyPrefix]
		private static void RemoveDisconnected(ZNetPeer peer, ZNet __instance)
		{
			if (!__instance.IsServer())
			{
				return;
			}
			foreach (VersionCheck versionCheck in versionChecks)
			{
				versionCheck.ValidatedClients.Remove(peer.m_rpc);
			}
		}

		[HarmonyPatch(typeof(FejdStartup), "ShowConnectError")]
		[HarmonyPostfix]
		private static void ShowConnectionError(FejdStartup __instance)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			//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)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.m_connectionFailedPanel.activeSelf || (int)ZNet.GetConnectionStatus() != 3)
			{
				return;
			}
			bool flag = false;
			VersionCheck[] failedClient = GetFailedClient();
			if (failedClient.Length != 0)
			{
				string text = string.Join("\n", failedClient.Select((VersionCheck check) => check.Error()));
				TMP_Text connectionFailedError = __instance.m_connectionFailedError;
				connectionFailedError.text = connectionFailedError.text + "\n" + text;
				flag = true;
			}
			foreach (KeyValuePair<string, string> item in notProcessedNames.OrderBy<KeyValuePair<string, string>, string>((KeyValuePair<string, string> kv) => kv.Key))
			{
				if (!__instance.m_connectionFailedError.text.Contains(item.Key))
				{
					TMP_Text connectionFailedError2 = __instance.m_connectionFailedError;
					connectionFailedError2.text = connectionFailedError2.text + "\nServer expects you to have " + item.Key + " (Version: " + item.Value + ") installed.";
					flag = true;
				}
			}
			if (flag)
			{
				RectTransform component = ((Component)__instance.m_connectionFailedPanel.transform.Find("Image")).GetComponent<RectTransform>();
				Vector2 sizeDelta = component.sizeDelta;
				sizeDelta.x = 675f;
				component.sizeDelta = sizeDelta;
				__instance.m_connectionFailedError.ForceMeshUpdate(false, false);
				float num = __instance.m_connectionFailedError.renderedHeight + 105f;
				RectTransform component2 = ((Component)((Component)component).transform.Find("ButtonOk")).GetComponent<RectTransform>();
				component2.anchoredPosition = new Vector2(component2.anchoredPosition.x, component2.anchoredPosition.y - (num - component.sizeDelta.y) / 2f);
				sizeDelta = component.sizeDelta;
				sizeDelta.y = num;
				component.sizeDelta = sizeDelta;
			}
		}
	}
}
namespace SmoothServer
{
	internal sealed class ConfigWatcher : IDisposable
	{
		private const double DebounceSeconds = 0.5;

		private const double PollIntervalSeconds = 0.5;

		private const double IgnoreAfterReloadSeconds = 1.0;

		private readonly ConfigFile _cfg;

		private readonly ManualLogSource _log;

		private readonly string _fileName;

		private readonly string _logPrefix;

		private FileSystemWatcher _fsw;

		private volatile bool _pending;

		private DateTime _lastEventUtc;

		private DateTime _lastReloadUtc = DateTime.MinValue;

		private DateTime _lastPollUtc = DateTime.MinValue;

		private DateTime _lastKnownWriteUtc = DateTime.MinValue;

		private static readonly List<string> _statReloads = new List<string>();

		internal static List<string> ConsumeReloadSummaries()
		{
			List<string> result = new List<string>(_statReloads);
			_statReloads.Clear();
			return result;
		}

		public ConfigWatcher(ConfigFile cfg, ManualLogSource log, string logPrefix = "[Config]")
		{
			_cfg = cfg;
			_log = log;
			_logPrefix = logPrefix;
			_fileName = Path.GetFileName(cfg.ConfigFilePath);
			_lastKnownWriteUtc = SafeGetLastWriteUtc();
			string directoryName = Path.GetDirectoryName(cfg.ConfigFilePath);
			if (string.IsNullOrEmpty(directoryName))
			{
				_log.LogWarning((object)(_logPrefix + " watcher: could not resolve a directory for " + cfg.ConfigFilePath));
				return;
			}
			try
			{
				_fsw = new FileSystemWatcher(directoryName)
				{
					NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite),
					IncludeSubdirectories = false
				};
				_fsw.Changed += OnFsEvent;
				_fsw.Created += OnFsEvent;
				_fsw.Renamed += OnFsRenamed;
				_fsw.Error += OnFsError;
				_fsw.EnableRaisingEvents = true;
			}
			catch (Exception ex)
			{
				_log.LogWarning((object)(_logPrefix + " could not start FileSystemWatcher, relying on polling: " + ex.Message));
				_fsw = null;
			}
			_log.LogInfo((object)(_logPrefix + " watching " + cfg.ConfigFilePath + " for live edits"));
		}

		private void OnFsEvent(object sender, FileSystemEventArgs e)
		{
			if (string.Equals(e.Name, _fileName, StringComparison.OrdinalIgnoreCase))
			{
				Schedule();
			}
		}

		private void OnFsRenamed(object sender, RenamedEventArgs e)
		{
			if (string.Equals(e.Name, _fileName, StringComparison.OrdinalIgnoreCase))
			{
				Schedule();
			}
		}

		private void OnFsError(object sender, ErrorEventArgs e)
		{
			_log.LogWarning((object)(_logPrefix + " watcher error (falling back to polling): " + e.GetException()));
		}

		private void Schedule()
		{
			if (!((DateTime.UtcNow - _lastReloadUtc).TotalSeconds < 1.0))
			{
				_pending = true;
				_lastEventUtc = DateTime.UtcNow;
			}
		}

		private DateTime SafeGetLastWriteUtc()
		{
			try
			{
				return File.GetLastWriteTimeUtc(_cfg.ConfigFilePath);
			}
			catch
			{
				return DateTime.MinValue;
			}
		}

		public void Pump()
		{
			if ((DateTime.UtcNow - _lastPollUtc).TotalSeconds >= 0.5)
			{
				_lastPollUtc = DateTime.UtcNow;
				DateTime dateTime = SafeGetLastWriteUtc();
				if (dateTime != DateTime.MinValue && dateTime != _lastKnownWriteUtc)
				{
					_lastKnownWriteUtc = dateTime;
					Schedule();
				}
			}
			if (!_pending || (DateTime.UtcNow - _lastEventUtc).TotalSeconds < 0.5)
			{
				return;
			}
			_pending = false;
			try
			{
				DoReload();
			}
			catch (Exception ex)
			{
				_log.LogError((object)(_logPrefix + " reload failed: " + ex));
			}
		}

		private void DoReload()
		{
			Dictionary<ConfigDefinition, string> before = Snapshot();
			bool saveOnConfigSet = _cfg.SaveOnConfigSet;
			_cfg.SaveOnConfigSet = false;
			try
			{
				_cfg.Reload();
			}
			finally
			{
				_cfg.SaveOnConfigSet = saveOnConfigSet;
			}
			_lastReloadUtc = DateTime.UtcNow;
			_lastKnownWriteUtc = SafeGetLastWriteUtc();
			List<string> list = Diff(before);
			string text = ((list.Count == 0) ? "no changes" : string.Join(", ", list.ToArray()));
			_statReloads.Add(text);
			_log.LogInfo((object)((list.Count == 0) ? (_logPrefix + " reloaded: no changes") : (_logPrefix + " reloaded: " + text)));
		}

		private Dictionary<ConfigDefinition, string> Snapshot()
		{
			Dictionary<ConfigDefinition, string> dictionary = new Dictionary<ConfigDefinition, string>();
			foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in _cfg)
			{
				try
				{
					dictionary[item.Key] = item.Value.GetSerializedValue();
				}
				catch
				{
				}
			}
			return dictionary;
		}

		private List<string> Diff(Dictionary<ConfigDefinition, string> before)
		{
			List<string> list = new List<string>();
			foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in _cfg)
			{
				string serializedValue;
				try
				{
					serializedValue = item.Value.GetSerializedValue();
				}
				catch
				{
					continue;
				}
				if (!before.TryGetValue(item.Key, out string value))
				{
					value = "?";
				}
				if (value != serializedValue)
				{
					list.Add("[" + item.Key.Section + "] " + item.Key.Key + " " + value + " -> " + serializedValue);
				}
			}
			return list;
		}

		public void Dispose()
		{
			if (_fsw != null)
			{
				try
				{
					_fsw.EnableRaisingEvents = false;
					_fsw.Changed -= OnFsEvent;
					_fsw.Created -= OnFsEvent;
					_fsw.Renamed -= OnFsRenamed;
					_fsw.Error -= OnFsError;
					_fsw.Dispose();
				}
				catch
				{
				}
				_fsw = null;
			}
		}
	}
	internal sealed class CreateBudgetModule : FeatureModule
	{
		private const int VanillaMax = 10;

		private ConfigEntry<int> _max;

		internal static bool Active;

		internal static int MaxCreatedPerFrame = 10;

		public override string Name => "CreateBudget";

		public override void Configure(ConfigFile cfg)
		{
			EnabledCfg = cfg.Bind<bool>("CreateBudget", "Enabled", true, "Make ZNetScene's per-frame object instantiation budget configurable.");
			_max = cfg.Bind<int>("CreateBudget", "MaxCreatedPerFrame", 10, "Objects ZNetScene may instantiate per frame outside the loading screen. Vanilla 10 - the default is deliberately vanilla, raise it to test.");
			Watch<int>(_max);
		}

		internal static int GetMaxCreatedPerFrame()
		{
			if (!Active || !FeatureModule.ServerActive())
			{
				return 10;
			}
			return MaxCreatedPerFrame;
		}

		protected override void ApplyPatches()
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			MaxCreatedPerFrame = Math.Max(1, _max.Value);
			MethodInfo methodInfo = AccessTools.Method(typeof(ZNetScene), "CreateObjects", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				throw new Exception("SmoothServer CreateBudget: ZNetScene.CreateObjects not found");
			}
			Harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(CreateBudgetModule), "Transpiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			Active = true;
			FeatureModule.Log.LogInfo((object)("[CreateBudget] maxCreatedPerFrame=" + MaxCreatedPerFrame + ((MaxCreatedPerFrame == 10) ? " (vanilla value, no behaviour change)" : "")));
		}

		public override void Disable()
		{
			Active = false;
			base.Disable();
		}

		public override void OnConfigChanged(ConfigEntryBase entry)
		{
			if ((object)entry == _max)
			{
				MaxCreatedPerFrame = Math.Max(1, _max.Value);
				FeatureModule.Log.LogInfo((object)("[CreateBudget] maxCreatedPerFrame=" + MaxCreatedPerFrame + ((MaxCreatedPerFrame == 10) ? " (vanilla value, no behaviour change)" : "")));
			}
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = 0;
			for (int i = 0; i < list.Count; i++)
			{
				if (ILUtil.TryGetI4(list[i], out var value) && value == 10)
				{
					ILUtil.ReplaceWithCall(list[i], typeof(CreateBudgetModule), "GetMaxCreatedPerFrame");
					num++;
				}
			}
			if (num != 1)
			{
				string text = "SmoothServer CreateBudget transpiler: expected exactly 1x " + 10 + " in ZNetScene.CreateObjects, found " + num + " - game IL changed, refusing to patch";
				SmoothServerPlugin.Log.LogError((object)text);
				throw new Exception(text);
			}
			SmoothServerPlugin.Log.LogInfo((object)"[CreateBudget] transpiler OK: 1x maxCreatedPerFrame replaced (assertion 1 passed)");
			return list;
		}
	}
	internal enum ModuleSide
	{
		Server,
		Client,
		Both
	}
	internal abstract class FeatureModule
	{
		public ConfigEntry<bool> EnabledCfg;

		protected Harmony Harmony;

		protected ConfigFile Cfg;

		public string Status = "not-run";

		public bool Applied;

		public abstract string Name { get; }

		public virtual ModuleSide Side => ModuleSide.Server;

		public virtual string Section => Name;

		public virtual bool DefaultEnabled => true;

		protected virtual string EnabledDescription => "Enable the " + Name + " module.";

		public bool Enabled
		{
			get
			{
				if (EnabledCfg != null)
				{
					return EnabledCfg.Value;
				}
				return false;
			}
		}

		public bool IsActive
		{
			get
			{
				if (Applied)
				{
					return Enabled;
				}
				return false;
			}
		}

		protected static ManualLogSource Log => SmoothServerPlugin.Log;

		public virtual void Configure(ConfigFile cfg)
		{
			Cfg = cfg;
			EnabledCfg = BindSynced(Section, "Enabled", DefaultEnabled, EnabledDescription);
			Bind();
		}

		public void TryEnable(string guidPrefix)
		{
			TryEnable(guidPrefix, SmoothServerPlugin.RunningSide);
		}

		public void TryEnable(string guidPrefix, ModuleSide runningSide)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			if (Side != ModuleSide.Both && Side != runningSide)
			{
				Applied = false;
				Status = "disabled(side)";
				return;
			}
			if (EnabledCfg == null || !EnabledCfg.Value)
			{
				Status = "disabled";
				Applied = false;
				return;
			}
			try
			{
				Harmony = new Harmony(guidPrefix + "." + Name);
				ApplyPatches();
				Applied = true;
				Status = "applied";
				Log.LogInfo((object)("[" + Name + "] applied"));
			}
			catch (Exception ex)
			{
				Applied = false;
				string text = ((ex.InnerException != null) ? ex.InnerException.Message : ex.Message);
				Status = "FAILED(" + text + ")";
				Log.LogError((object)("[" + Name + "] FAILED to patch: " + ex));
				Disable();
			}
		}

		protected virtual void Bind()
		{
		}

		protected abstract void ApplyPatches();

		public virtual void OnConfigChanged(ConfigEntryBase entry)
		{
		}

		public virtual string StatusDetail()
		{
			return null;
		}

		protected void Watch<T>(ConfigEntry<T> entry)
		{
			entry.SettingChanged += delegate
			{
				try
				{
					OnConfigChanged((ConfigEntryBase)(object)entry);
				}
				catch (Exception ex)
				{
					Log.LogError((object)("[" + Name + "] OnConfigChanged threw: " + ex));
				}
			};
		}

		public virtual void Disable()
		{
			Applied = false;
			try
			{
				if (Harmony != null)
				{
					Harmony.UnpatchSelf();
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[" + Name + "] unpatch failed: " + ex.Message));
			}
		}

		protected ConfigEntry<T> BindSynced<T>(string section, string key, T defaultValue, string description)
		{
			return SmoothServerPlugin.BindSynced(section, key, defaultValue, description, this);
		}

		protected ConfigEntry<T> BindSynced<T>(string key, T defaultValue, string description)
		{
			return SmoothServerPlugin.BindSynced(Section, key, defaultValue, description, this);
		}

		protected ConfigEntry<T> BindLocal<T>(string section, string key, T defaultValue, string description)
		{
			return SmoothServerPlugin.BindLocal(section, key, defaultValue, description, this);
		}

		protected ConfigEntry<T> BindLocal<T>(string key, T defaultValue, string description)
		{
			return SmoothServerPlugin.BindLocal(Section, key, defaultValue, description, this);
		}

		protected internal static bool ServerActive()
		{
			if ((Object)(object)ZNet.instance != (Object)null)
			{
				return ZNet.instance.IsServer();
			}
			return false;
		}

		protected internal static bool ClientActive()
		{
			if ((Object)(object)ZNet.instance != (Object)null)
			{
				return !ZNet.instance.IsDedicated();
			}
			return false;
		}
	}
	internal sealed class FrameRateModule : FeatureModule
	{
		private ConfigEntry<int> _target;

		internal static bool Active;

		internal static int TargetFrameRate;

		private static float _sinceStart = -1f;

		private static bool _reasserted;

		public override string Name => "FrameRate";

		public override void Configure(ConfigFile cfg)
		{
			EnabledCfg = cfg.Bind<bool>("FrameRate", "Enabled", true, "Allow SmoothServer to set the server's frame cap. Does nothing while TargetFrameRate is 0.");
			_target = cfg.Bind<int>("FrameRate", "TargetFrameRate", 0, "Server frame rate cap. 0 = leave vanilla (Unity's headless default, ~30). Set 60 or 120 to raise it. -1 = uncapped (burns a whole core).");
			Watch<int>(_target);
		}

		protected override void ApplyPatches()
		{
			TargetFrameRate = _target.Value;
			_sinceStart = -1f;
			_reasserted = false;
			Active = true;
		}

		public override void Disable()
		{
			Active = false;
			base.Disable();
		}

		public override void OnConfigChanged(ConfigEntryBase entry)
		{
			if ((object)entry == _target)
			{
				TargetFrameRate = _target.Value;
				Reapply();
			}
		}

		internal static void OnZNetStart()
		{
			if (Active)
			{
				Reapply();
			}
		}

		private static void Reapply()
		{
			if (!Active)
			{
				return;
			}
			if (!FeatureModule.ServerActive())
			{
				SmoothServerPlugin.Log.LogInfo((object)("[FrameRate] config changed to " + TargetFrameRate + " but server not active yet, will apply at ZNet.Start"));
				return;
			}
			int targetFrameRate = Application.targetFrameRate;
			int vSyncCount = QualitySettings.vSyncCount;
			if (TargetFrameRate == 0)
			{
				SmoothServerPlugin.Log.LogInfo((object)("[FrameRate] TargetFrameRate=0, leaving vanilla (Application.targetFrameRate=" + targetFrameRate + ", vSyncCount=" + vSyncCount + ")"));
				return;
			}
			Application.targetFrameRate = TargetFrameRate;
			QualitySettings.vSyncCount = 0;
			_sinceStart = 0f;
			_reasserted = false;
			SmoothServerPlugin.Log.LogInfo((object)("[FrameRate] targetFrameRate " + targetFrameRate + " -> " + Application.targetFrameRate + ", vSyncCount " + vSyncCount + " -> " + QualitySettings.vSyncCount));
		}

		internal static void Tick(float dt)
		{
			if (Active && !_reasserted && !(_sinceStart < 0f))
			{
				_sinceStart += dt;
				if (!(_sinceStart < 5f))
				{
					_reasserted = true;
					int targetFrameRate = Application.targetFrameRate;
					Application.targetFrameRate = TargetFrameRate;
					QualitySettings.vSyncCount = 0;
					SmoothServerPlugin.Log.LogInfo((object)("[FrameRate] re-assert after 5s: was " + targetFrameRate + ", now " + Application.targetFrameRate + ((targetFrameRate == TargetFrameRate) ? " (held)" : " (SOMETHING RESET IT)")));
				}
			}
		}
	}
	internal static class ILUtil
	{
		internal static bool TryGetI4(CodeInstruction ci, out int value)
		{
			value = 0;
			if (ci == null || ci.operand == null)
			{
				return false;
			}
			if (ci.opcode == OpCodes.Ldc_I4 || ci.opcode == OpCodes.Ldc_I4_S)
			{
				try
				{
					value = Convert.ToInt32(ci.operand);
					return true;
				}
				catch
				{
					return false;
				}
			}
			return false;
		}

		internal static void ReplaceWithCall(CodeInstruction ci, Type owner, string method)
		{
			MethodInfo methodInfo = AccessTools.Method(owner, method, (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				throw new Exception("SmoothServer: replacement method " + owner.Name + "." + method + " not found");
			}
			ci.opcode = OpCodes.Call;
			ci.operand = methodInfo;
		}
	}
	internal sealed class AdaptiveBudgetModule : FeatureModule
	{
		private sealed class PeerBudget
		{
			public int Target;

			public bool Congested;

			public int Samples;
		}

		private ConfigEntry<int> _floor;

		private ConfigEntry<int> _ceiling;

		private ConfigEntry<float> _k;

		private ConfigEntry<int> _pendingBackoff;

		private ConfigEntry<float> _smoothing;

		private ConfigEntry<float> _logInterval;

		private ConfigEntry<bool> _callSiteSwap;

		internal static bool Active;

		internal static int FloorBytes = 16384;

		internal static int CeilingBytes = 131072;

		internal static float K = 2f;

		internal static int PendingBackoffBytes = 8192;

		internal static float Smoothing = 0.3f;

		internal static bool UseCallSiteSwap = false;

		private const int PingFloorMs = 5;

		private const int PingCeilMs = 250;

		private static readonly Dictionary<long, PeerBudget> Budgets = new Dictionary<long, PeerBudget>();

		private static float _logAcc;

		private static float LogIntervalSec = 10f;

		private static int _savedHighWater;

		private static bool _swapped;

		private static long _currentPeerUid;

		public override string Name => "AdaptiveBudget";

		public override void Configure(ConfigFile cfg)
		{
			EnabledCfg = cfg.Bind<bool>("AdaptiveBudget", "Enabled", true, "Replace SendBudget's single HighWaterBytes number with a per-peer target derived from that peer's live RTT and throughput, backing off on real congestion.");
			_floor = cfg.Bind<int>("AdaptiveBudget", "FloorBytes", 16384, "Never budget a peer below this many bytes. Vanilla is 10240 for everyone.");
			_ceiling = cfg.Bind<int>("AdaptiveBudget", "CeilingBytes", 131072, "Never budget a peer above this many bytes. Steam's own send queue starts erroring well above this; 128KB is a deliberate safety margin.");
			_k = cfg.Bind<float>("AdaptiveBudget", "K", 2f, "Multiplier on the bandwidth-delay product (outBytesPerSec * RTT). 1.0 exactly fills the pipe; 2.0 leaves headroom for bursts. Clamped to 0.5-8.");
			_pendingBackoff = cfg.Bind<int>("AdaptiveBudget", "PendingBackoffBytes", 8192, "Back off while a peer's Steam-side PENDING bytes (queued, not yet on the wire) exceed this. In-flight/unacked bytes deliberately do NOT trigger a back-off.");
			_smoothing = cfg.Bind<float>("AdaptiveBudget", "Smoothing", 0.3f, "EMA factor for the per-peer target. 1.0 = react instantly, 0.1 = very smooth.");
			_logInterval = cfg.Bind<float>("AdaptiveBudget", "LogIntervalSec", 10f, "Seconds between per-peer budget lines. 0 disables the log line.");
			_callSiteSwap = cfg.Bind<bool>("AdaptiveBudget", "UseCallSiteSwap", false, "Legacy application path, OFF by default. Since 0.3.0 SendBudget's GetHighWaterBytes() calls AdaptiveBudgetModule.HighWaterFor() directly, so the per-peer budget already applies. true additionally swaps SendBudgetModule.HighWaterBytes around each ZDOMan.SendZDOs call - only useful if that hook call is ever removed.");
			Watch<int>(_floor);
			Watch<int>(_ceiling);
			Watch<float>(_k);
			Watch<int>(_pendingBackoff);
			Watch<float>(_smoothing);
			Watch<float>(_logInterval);
			Watch<bool>(_callSiteSwap);
		}

		protected override void ApplyPatches()
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Expected O, but got Unknown
			//IL_00cf: Expected O, but got Unknown
			ReadConfig();
			MethodInfo methodInfo = AccessTools.Method(typeof(ZDOMan), "SendZDOs", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				throw new Exception("SmoothServer AdaptiveBudget: ZDOMan.SendZDOs not found");
			}
			ParameterInfo[] parameters = methodInfo.GetParameters();
			if (parameters.Length != 2 || parameters[0].Name != "peer" || parameters[1].ParameterType != typeof(bool))
			{
				throw new Exception("SmoothServer AdaptiveBudget: ZDOMan.SendZDOs signature changed (expected (ZDOPeer peer, bool flush), got " + parameters.Length + " params) - refusing to patch");
			}
			Harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(AdaptiveBudgetModule), "Prefix", (Type[])null)
			{
				priority = 200
			}, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(AdaptiveBudgetModule), "Finalizer", (Type[])null), (HarmonyMethod)null);
			Budgets.Clear();
			Active = true;
			FeatureModule.Log.LogInfo((object)("[AdaptiveBudget] floor=" + FloorBytes + "B ceiling=" + CeilingBytes + "B K=" + K.ToString("F1") + " pendingBackoff=" + PendingBackoffBytes + "B smoothing=" + Smoothing.ToString("F2") + " apply=" + (UseCallSiteSwap ? "call-site swap of SendBudget.HighWaterBytes" : "HighWaterFor() hook")));
		}

		public override void Disable()
		{
			Active = false;
			Budgets.Clear();
			base.Disable();
		}

		public override void OnConfigChanged(ConfigEntryBase entry)
		{
			ReadConfig();
			FeatureModule.Log.LogInfo((object)("[AdaptiveBudget] floor=" + FloorBytes + "B ceiling=" + CeilingBytes + "B K=" + K.ToString("F1") + " pendingBackoff=" + PendingBackoffBytes + "B"));
		}

		private void ReadConfig()
		{
			FloorBytes = Math.Max(2048, _floor.Value);
			CeilingBytes = Math.Max(FloorBytes, _ceiling.Value);
			K = Mathf.Clamp(_k.Value, 0.5f, 8f);
			PendingBackoffBytes = Math.Max(512, _pendingBackoff.Value);
			Smoothing = Mathf.Clamp(_smoothing.Value, 0.05f, 1f);
			LogIntervalSec = ((_logInterval == null) ? 10f : Mathf.Max(0f, _logInterval.Value));
			UseCallSiteSwap = _callSiteSwap.Value;
		}

		internal static int HighWaterFor(int configured)
		{
			if (!Active || !FeatureModule.ServerActive())
			{
				return configured;
			}
			if (_currentPeerUid == 0L)
			{
				return configured;
			}
			if (!Budgets.TryGetValue(_currentPeerUid, out PeerBudget value) || value.Samples == 0)
			{
				return configured;
			}
			return value.Target;
		}

		internal static bool TryGetBudget(long uid, out int target, out bool congested)
		{
			if (Active && Budgets.TryGetValue(uid, out PeerBudget value) && value.Samples > 0)
			{
				target = value.Target;
				congested = value.Congested;
				return true;
			}
			target = 0;
			congested = false;
			return false;
		}

		private static void Prefix(ZDOPeer peer)
		{
			_currentPeerUid = 0L;
			_swapped = false;
			if (Active && FeatureModule.ServerActive() && peer != null && peer.m_peer != null)
			{
				_currentPeerUid = peer.m_peer.m_uid;
				if (UseCallSiteSwap && Budgets.TryGetValue(_currentPeerUid, out PeerBudget value) && value.Samples != 0)
				{
					_savedHighWater = SendBudgetModule.HighWaterBytes;
					SendBudgetModule.HighWaterBytes = value.Target;
					_swapped = true;
				}
			}
		}

		private static void Finalizer()
		{
			if (_swapped)
			{
				SendBudgetModule.HighWaterBytes = _savedHighWater;
				_swapped = false;
			}
			_currentPeerUid = 0L;
		}

		internal static void Tick(float dt)
		{
			if (!Active || !FeatureModule.ServerActive())
			{
				return;
			}
			PeerTelemetryModule.PeerStat[] array = PeerTelemetryModule.Snapshot();
			if (array.Length == 0)
			{
				if (Budgets.Count > 0)
				{
					Budgets.Clear();
				}
				return;
			}
			int highWaterBytes = SendBudgetModule.HighWaterBytes;
			for (int i = 0; i < array.Length; i++)
			{
				PeerTelemetryModule.PeerStat peerStat = array[i];
				if (!Budgets.TryGetValue(peerStat.Uid, out PeerBudget value))
				{
					value = new PeerBudget
					{
						Target = highWaterBytes
					};
					Budgets[peerStat.Uid] = value;
				}
				if (!peerStat.Valid)
				{
					value.Target = highWaterBytes;
					value.Samples = 0;
					value.Congested = false;
					continue;
				}
				float num = (float)Mathf.Clamp(peerStat.Ping, 5, 250) / 1000f;
				float num2 = peerStat.OutBytesPerSec * num;
				float num3 = K * num2;
				int num4 = peerStat.PendingReliable + peerStat.PendingUnreliable;
				value.Congested = num4 > PendingBackoffBytes;
				if (value.Congested)
				{
					num3 = Mathf.Min(num3, (float)value.Target * 0.5f);
				}
				num3 = Mathf.Clamp(num3, (float)FloorBytes, (float)CeilingBytes);
				value.Target = Mathf.RoundToInt(Mathf.Lerp((float)value.Target, num3, Smoothing));
				value.Target = Mathf.Clamp(value.Target, FloorBytes, CeilingBytes);
				value.Samples++;
			}
			if (Budgets.Count > array.Length)
			{
				HashSet<long> hashSet = new HashSet<long>();
				for (int j = 0; j < array.Length; j++)
				{
					hashSet.Add(array[j].Uid);
				}
				List<long> list = new List<long>();
				foreach (KeyValuePair<long, PeerBudget> budget in Budgets)
				{
					if (!hashSet.Contains(budget.Key))
					{
						list.Add(budget.Key);
					}
				}
				foreach (long item in list)
				{
					Budgets.Remove(item);
				}
			}
			if (LogIntervalSec <= 0f)
			{
				return;
			}
			_logAcc += dt;
			if (_logAcc < LogIntervalSec)
			{
				return;
			}
			_logAcc = 0f;
			foreach (KeyValuePair<long, PeerBudget> budget2 in Budgets)
			{
				PeerBudget value2 = budget2.Value;
				SmoothServerPlugin.Log.LogInfo((object)string.Format("[AdaptiveBudget] uid={0} target={1}B ({2}) samples={3} base={4}B", budget2.Key, value2.Target, value2.Congested ? "backing off" : "steady", value2.Samples, highWaterBytes));
			}
		}
	}
	internal sealed class AsyncSaveModule : FeatureModule
	{
		private ConfigEntry<bool> _preSize;

		private ConfigEntry<bool> _logStalls;

		private ConfigEntry<float> _selfTestSeconds;

		internal static bool Active;

		internal static bool PreSizeClone = true;

		internal static bool LogStalls = true;

		private static readonly Stopwatch MainThreadWatch = new Stopwatch();

		private static readonly Stopwatch ThreadWatch = new Stopwatch();

		private static int _lastZdoCount;

		private static double _lastStallMs = -1.0;

		private static int _statSaveCount;

		private static double _statMaxStallMs;

		private static float _selfTestAt = -1f;

		private static int _selfTestPhase;

		private static float _selfTestTimer;

		private static double _stallVanilla = -1.0;

		private static double _stallOptimised = -1.0;

		private static bool _savedPreSize;

		public override string Name => "AsyncSave";

		public override void Configure(ConfigFile cfg)
		{
			EnabledCfg = cfg.Bind<bool>("AsyncSave", "Enabled", true, "Measure the main-thread world-save stall and shrink it. Vanilla already writes the file on a background thread; the stall is ZDOMan.PrepareSave's ZDO clone.");
			_preSize = cfg.Bind<bool>("AsyncSave", "PreSizeClone", true, "Pre-size ZDOMan.GetSaveClone()'s list from the live ZDO count instead of letting it grow from zero. Same output, no reallocation storm on the main thread.");
			_logStalls = cfg.Bind<bool>("AsyncSave", "LogStalls", true, "Log one line per world save with the main-thread stall and the background-thread time.");
			_selfTestSeconds = cfg.Bind<float>("AsyncSave", "SelfTestSeconds", 0f, "0 = off. Above 0: this many seconds after the world is up AND with 0 peers connected, force two saves - one with PreSizeClone off, one on - and log both stalls and the delta. Headless proof; leave at 0 in production.");
			Watch<bool>(_preSize);
			Watch<bool>(_logStalls);
			Watch<float>(_selfTestSeconds);
		}

		protected override void ApplyPatches()
		{
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Expected O, but got Unknown
			//IL_0174: Expected O, but got Unknown
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Expected O, but got Unknown
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Expected O, but got Unknown
			PreSizeClone = _preSize.Value;
			LogStalls = _logStalls.Value;
			MethodInfo methodInfo = AccessTools.Method(typeof(ZNet), "SaveWorld", new Type[1] { typeof(bool) }, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(ZNet), "SaveWorldThread", (Type[])null, (Type[])null);
			MethodInfo methodInfo3 = AccessTools.Method(typeof(ZDOMan), "GetSaveClone", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				throw new Exception("SmoothServer AsyncSave: ZNet.SaveWorld(bool) not found");
			}
			if (methodInfo2 == null)
			{
				throw new Exception("SmoothServer AsyncSave: ZNet.SaveWorldThread not found - vanilla's background save thread is gone, re-check the design");
			}
			if (methodInfo3 == null || methodInfo3.ReturnType != typeof(List<ZDO>))
			{
				throw new Exception("SmoothServer AsyncSave: ZDOMan.GetSaveClone() -> List<ZDO> not found");
			}
			if (AccessTools.Field(typeof(ZDOMan), "m_objectsBySector") == null || AccessTools.Field(typeof(ZDOMan), "m_objectsByOutsideSector") == null || AccessTools.Field(typeof(ZDOMan), "m_objectsByID") == null)
			{
				throw new Exception("SmoothServer AsyncSave: ZDOMan sector/ID collections not found");
			}
			Harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(AsyncSaveModule), "SaveWorldPrefix", (Type[])null)
			{
				priority = 800
			}, new HarmonyMethod(typeof(AsyncSaveModule), "SaveWorldPostfix", (Type[])null)
			{
				priority = 0
			}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(AsyncSaveModule), "SaveWorldThreadPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(AsyncSaveModule), "GetSaveClonePrefix", (Type[])null)
			{
				priority = 600
			}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			_selfTestAt = _selfTestSeconds.Value;
			_selfTestPhase = ((_selfTestAt > 0f) ? 1 : 0);
			_selfTestTimer = 0f;
			Active = true;
			FeatureModule.Log.LogInfo((object)("[AsyncSave] vanilla already writes the world on ZNet.SaveWorldThread; instrumenting the MAIN-THREAD half (PrepareSave). preSizeClone=" + PreSizeClone + " logStalls=" + LogStalls + ((_selfTestAt > 0f) ? (" selfTest=in " + _selfTestAt.ToString("F0") + "s") : "")));
		}

		public override void Disable()
		{
			Active = false;
			_selfTestPhase = 0;
			base.Disable();
		}

		public override void OnConfigChanged(ConfigEntryBase entry)
		{
			if ((object)entry == _preSize)
			{
				PreSizeClone = _preSize.Value;
				FeatureModule.Log.LogInfo((object)("[AsyncSave] preSizeClone -> " + PreSizeClone));
			}
			else if ((object)entry == _logStalls)
			{
				LogStalls = _logStalls.Value;
			}
		}

		private static void SaveWorldPrefix()
		{
			if (Active)
			{
				_lastZdoCount = ((ZDOMan.instance != null) ? ZDOMan.instance.m_objectsByID.Count : (-1));
				MainThreadWatch.Reset();
				MainThreadWatch.Start();
				ThreadWatch.Reset();
				ThreadWatch.Start();
			}
		}

		private static void SaveWorldPostfix()
		{
			if (Active)
			{
				MainThreadWatch.Stop();
				_lastStallMs = MainThreadWatch.Elapsed.TotalMilliseconds;
				_statSaveCount++;
				if (_lastStallMs > _statMaxStallMs)
				{
					_statMaxStallMs = _lastStallMs;
				}
				if (LogStalls)
				{
					SmoothServerPlugin.Log.LogInfo((object)$"[AsyncSave] world save: main-thread stall {_lastStallMs:F1}ms for {_lastZdoCount} ZDOs (preSizeClone={PreSizeClone}); serialisation + file write continue on ZNet.SaveWorldThread");
				}
			}
		}

		private static void SaveWorldThreadPostfix()
		{
			if (Active)
			{
				ThreadWatch.Stop();
				if (LogStalls)
				{
					SmoothServerPlugin.Log.LogInfo((object)$"[AsyncSave] background save thread finished {ThreadWatch.Elapsed.TotalMilliseconds:F0}ms after SaveWorld started");
				}
			}
		}

		private static bool GetSaveClonePrefix(ZDOMan __instance, ref List<ZDO> __result)
		{
			if (!Active || !PreSizeClone)
			{
				return true;
			}
			List<ZDO> list = new List<ZDO>(__instance.m_objectsByID.Count + 64);
			List<ZDO>[] objectsBySector = __instance.m_objectsBySector;
			foreach (List<ZDO> list2 in objectsBySector)
			{
				if (list2 == null)
				{
					continue;
				}
				for (int j = 0; j < list2.Count; j++)
				{
					ZDO val = list2[j];
					if (val.Persistent)
					{
						list.Add(val.Clone());
					}
				}
			}
			foreach (List<ZDO> value in __instance.m_objectsByOutsideSector.Values)
			{
				for (int k = 0; k < value.Count; k++)
				{
					ZDO val2 = value[k];
					if (val2.Persistent)
					{
						list.Add(val2.Clone());
					}
				}
			}
			__result = list;
			return false;
		}

		internal static void ConsumeSaveStats(out int count, out double maxStallMs)
		{
			count = _statSaveCount;
			maxStallMs = _statMaxStallMs;
			_statSaveCount = 0;
			_statMaxStallMs = 0.0;
		}

		internal static void Tick(float dt)
		{
			if (!Active || _selfTestPhase == 0 || !FeatureModule.ServerActive())
			{
				return;
			}
			ZNet instance = ZNet.instance;
			ZDOMan instance2 = ZDOMan.instance;
			if ((Object)(object)instance == (Object)null || instance2 == null)
			{
				return;
			}
			_selfTestTimer += dt;
			switch (_selfTestPhase)
			{
			case 1:
				if (!(_selfTestTimer < _selfTestAt))
				{
					if (instance2.m_peers.Count > 0)
					{
						SmoothServerPlugin.Log.LogInfo((object)("[AsyncSave] self-test skipped: " + instance2.m_peers.Count + " peer(s) connected"));
						_selfTestPhase = 0;
						break;
					}
					_savedPreSize = PreSizeClone;
					PreSizeClone = false;
					SmoothServerPlugin.Log.LogInfo((object)"[AsyncSave] self-test A: forcing a save with PreSizeClone=false");
					_lastStallMs = -1.0;
					instance.Save(false, false, false);
					_selfTestTimer = 0f;
					_selfTestPhase = 2;
				}
				break;
			case 2:
				if (!(_lastStallMs < 0.0))
				{
					_stallVanilla = _lastStallMs;
					if (!(_selfTestTimer < 5f) && !instance.IsSaving())
					{
						PreSizeClone = true;
						SmoothServerPlugin.Log.LogInfo((object)"[AsyncSave] self-test B: forcing a save with PreSizeClone=true");
						_lastStallMs = -1.0;
						instance.Save(false, false, false);
						_selfTestTimer = 0f;
						_selfTestPhase = 4;
					}
				}
				break;
			case 4:
				if (!(_lastStallMs < 0.0))
				{
					_stallOptimised = _lastStallMs;
					if (!(_selfTestTimer < 5f) && !instance.IsSaving())
					{
						PreSizeClone = _savedPreSize;
						SmoothServerPlugin.Log.LogInfo((object)$"[AsyncSave] SELF-TEST RESULT: {_lastZdoCount} ZDOs, main-thread stall vanilla-clone={_stallVanilla:F1}ms, pre-sized-clone={_stallOptimised:F1}ms, delta={_stallVanilla - _stallOptimised:F1}ms ({((_stallVanilla > 0.0) ? (100.0 * (_stallVanilla - _stallOptimised) / _stallVanilla) : 0.0):F1}%). PreSizeClone restored to {PreSizeClone}.");
						_selfTestPhase = 0;
					}
				}
				break;
			case 3:
				break;
			}
		}
	}
	internal sealed class GcThrottleModule : FeatureModule
	{
		private ConfigEntry<float> _minInterval;

		private ConfigEntry<bool> _offPeak;

		private ConfigEntry<bool> _logSkips;

		internal static bool Active;

		internal static float MinIntervalSec = 3600f;

		internal static bool OffPeak = true;

		internal static bool LogSkips = true;

		private static float _lastRun = -1f;

		private static int _skipped;

		private static bool _deferred;

		private static int _statGcCount;

		public override string Name => "GcThrottle";

		internal static int ConsumeGcEvents()
		{
			int statGcCount = _statGcCount;
			_statGcCount = 0;
			return statGcCount;
		}

		public override void Configure(ConfigFile cfg)
		{
			EnabledCfg = cfg.Bind<bool>("GcThrottle", "Enabled", true, "Throttle Game.CollectResources (Resources.UnloadUnusedAssets) - vanilla's hourly whole-heap sweep, measured at ~200ms of main-thread stall.");
			_minInterval = cfg.Bind<float>("GcThrottle", "MinIntervalSec", 3600f, "Minimum seconds between sweeps we allow through. Vanilla's own periodic check is 3600s but CollectResourcesCheck can fire one after only 1200s.");
			_offPeak = cfg.Bind<bool>("GcThrottle", "OffPeak", true, "Only allow a sweep when the server is idle: 0 peers connected and no world save in flight. A sweep refused this way is retried as soon as the server goes idle.");
			_logSkips = cfg.Bind<bool>("GcThrottle", "LogSkips", true, "Log when a sweep is allowed through or deferred.");
			Watch<float>(_minInterval);
			Watch<bool>(_offPeak);
			Watch<bool>(_logSkips);
		}

		protected override void ApplyPatches()
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			ReadConfig();
			MethodInfo methodInfo = AccessTools.Method(typeof(Game), "CollectResources", new Type[1] { typeof(bool) }, (Type[])null);
			if (methodInfo == null)
			{
				throw new Exception("SmoothServer GcThrottle: Game.CollectResources(bool) not found");
			}
			Harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(GcThrottleModule), "Prefix", (Type[])null)
			{
				priority = 600
			}, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			_lastRun = -1f;
			_skipped = 0;
			_deferred = false;
			Active = true;
			FeatureModule.Log.LogInfo((object)("[GcThrottle] Resources.UnloadUnusedAssets throttled to at most once per " + MinIntervalSec.ToString("F0") + "s" + (OffPeak ? ", idle-server only" : "")));
		}

		public override void Disable()
		{
			Active = false;
			base.Disable();
		}

		public override void OnConfigChanged(ConfigEntryBase entry)
		{
			ReadConfig();
			FeatureModule.Log.LogInfo((object)("[GcThrottle] minInterval=" + MinIntervalSec.ToString("F0") + "s offPeak=" + OffPeak));
		}

		private void ReadConfig()
		{
			MinIntervalSec = Mathf.Max(0f, _minInterval.Value);
			OffPeak = _offPeak.Value;
			LogSkips = _logSkips.Value;
		}

		private static bool Prefix()
		{
			if (!Active || !FeatureModule.ServerActive())
			{
				return true;
			}
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (_lastRun >= 0f && realtimeSinceStartup - _lastRun < MinIntervalSec)
			{
				_skipped++;
				if (LogSkips)
				{
					SmoothServerPlugin.Log.LogInfo((object)("[GcThrottle] skipped UnloadUnusedAssets (" + (realtimeSinceStartup - _lastRun).ToString("F0") + "s since the last one, minimum " + MinIntervalSec.ToString("F0") + "s; " + _skipped + " skipped so far)"));
				}
				return false;
			}
			if (OffPeak && !IsIdle())
			{
				_skipped++;
				if (!_deferred)
				{
					_deferred = true;
					if (LogSkips)
					{
						SmoothServerPlugin.Log.LogInfo((object)"[GcThrottle] deferred UnloadUnusedAssets: players online (OffPeak=true); it will run once the server is idle");
					}
				}
				return false;
			}
			_deferred = false;
			_lastRun = realtimeSinceStartup;
			_statGcCount++;
			if (LogSkips)
			{
				SmoothServerPlugin.Log.LogInfo((object)("[GcThrottle] allowing UnloadUnusedAssets through" + ((_skipped > 0) ? (" (" + _skipped + " skipped since the last one)") : "")));
			}
			_skipped = 0;
			return true;
		}

		private static bool IsIdle()
		{
			ZNet instance = ZNet.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return true;
			}
			if (instance.IsSaving())
			{
				return false;
			}
			List<ZNetPeer> connectedPeers = instance.GetConnectedPeers();
			if (connectedPeers != null)
			{
				return connectedPeers.Count == 0;
			}
			return true;
		}
	}
	internal sealed class OwnershipReleaseModule : FeatureModule
	{
		private const float VanillaIntervalSec = 2f;

		private ConfigEntry<float> _interval;

		internal static bool Active;

		internal static float ReleaseIntervalSec = 0.5f;

		public override string Name => "OwnershipRelease";

		public override void Configure(ConfigFile cfg)
		{
			EnabledCfg = cfg.Bind<bool>("OwnershipRelease", "Enabled", true, "Shorten ZDOMan's ownership-release sweep interval from vanilla's 2 seconds.");
			_interval = cfg.Bind<float>("OwnershipRelease", "ReleaseIntervalSec", 0.5f, "Seconds between ownership-release sweeps. Vanilla 2.0. Lower = mobs are re-claimed faster when their owner leaves a zone, at the cost of more scans per second - enable VPOServer.ReleaseScanSpeedup with this. Clamped to 0.1-10.");
			Watch<float>(_interval);
		}

		internal static float GetReleaseIntervalSec()
		{
			if (!Active || !FeatureModule.ServerActive())
			{
				return 2f;
			}
			return ReleaseIntervalSec;
		}

		protected override void ApplyPatches()
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			ReleaseIntervalSec = Mathf.Clamp(_interval.Value, 0.1f, 10f);
			MethodInfo methodInfo = AccessTools.Method(typeof(ZDOMan), "ReleaseZDOS", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				throw new Exception("SmoothServer OwnershipRelease: ZDOMan.ReleaseZDOS not found");
			}
			Harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(OwnershipReleaseModule), "Transpiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
			Active = true;
			FeatureModule.Log.LogInfo((object)("[OwnershipRelease] releaseIntervalSec=" + ReleaseIntervalSec.ToString("F2") + " (vanilla 2.00)"));
		}

		public override void Disable()
		{
			Active = false;
			base.Disable();
		}

		public override void OnConfigChanged(ConfigEntryBase entry)
		{
			if ((object)entry == _interval)
			{
				ReleaseIntervalSec = Mathf.Clamp(_interval.Value, 0.1f, 10f);
				FeatureModule.Log.LogInfo((object)("[OwnershipRelease] releaseIntervalSec -> " + ReleaseIntervalSec.ToString("F2")));
			}
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = 0;
			for (int i = 0; i < list.Count; i++)
			{
				if (ServerIL.TryGetR4(list[i], out var value) && !(Math.Abs(value - 2f) > 0.0001f))
				{
					ILUtil.ReplaceWithCall(list[i], typeof(OwnershipReleaseModule), "GetReleaseIntervalSec");
					num++;
				}
			}
			if (num != 1)
			{
				string text = "SmoothServer OwnershipRelease transpiler: expected exactly 1x " + 2f + "f in ZDOMan.ReleaseZDOS, found " + num + " - game IL changed, refusing to patch";
				SmoothServerPlugin.Log.LogError((object)text);
				throw new Exception(text);
			}
			SmoothServerPlugin.Log.LogInfo((object)"[OwnershipRelease] transpiler OK: 1x releaseZDOTimer threshold replaced (assertion 1 passed)");
			return list;
		}
	}
	internal static class ServerIL
	{
		internal static bool TryGetR4(CodeInstruction ci, out float value)
		{
			value = 0f;
			if (ci == null || ci.operand == null)
			{
				return false;
			}
			if (ci.opcode != OpCodes.Ldc_R4)
			{
				return false;
			}
			try
			{
				value = Convert.ToSingle(ci.operand);
				return true;
			}
			catch
			{
				return false;
			}
		}
	}
	internal sealed class PeerTelemetryModule : FeatureModule
	{
		internal struct PeerStat
		{
			public long Uid;

			public string PlayerName;

			public bool Valid;

			public int Ping;

			public float QualityLocal;

			public float QualityRemote;

			public float OutBytesPerSec;

			public float InBytesPerSec;

			public int PendingReliable;

			public int PendingUnreliable;

			public int SentUnackedReliable;

			public int SendRateBytesPerSec;

			public int SocketQueueBytes;

			public int ZdoQueue;

			public int ForceSend;

			public int InvalidSector;

			public float SampledAt;
		}

		private ConfigEntry<float> _interval;

		private ConfigEntry<float> _sampleInterval;

		internal static bool Active;

		internal static float IntervalSec = 10f;

		internal static float SampleIntervalSec = 1f;

		private static readonly Dictionary<long, PeerStat> Stats = new Dictionary<long, PeerStat>();

		private static readonly List<long> TempIds = new List<long>();

		private static float _sampleAcc;

		private static float _logAcc;

		private static int _steamIface;

		private static bool _ifaceLogged;

		private static bool _qualityAbsent;

		public override string Name => "PeerTelemetry";

		public override void Configure(ConfigFile cfg)
		{
			EnabledCfg = cfg.Bind<bool>("PeerTelemetry", "Enabled", true, "Log a per-peer network line (ping, pending/in-flight bytes, send rate, ZDO queue). Also feeds AdaptiveBudget.");
			_interval = cfg.Bind<float>("PeerTelemetry", "IntervalSec", 10f, "Seconds between per-peer telemetry lines.");
			_sampleInterval = cfg.Bind<float>("PeerTelemetry", "SampleIntervalSec", 1f, "Seconds between samples of the live Steam connection status. The snapshot other modules read is refreshed at this rate; the log line is printed every IntervalSec.");
			Watch<float>(_interval);
			Watch<float>(_sampleInterval);
		}

		protected override void ApplyPatches()
		{
			IntervalSec = Mathf.Max(1f, _interval.Value);
			SampleIntervalSec = Mathf.Clamp(_sampleInterval.Value, 0.1f, 10f);
			Stats.Clear();
			_sampleAcc = 0f;
			_logAcc = 0f;
			Active = true;
			FeatureModule.Log.LogInfo((object)("[PeerTelemetry] sampling every " + SampleIntervalSec.ToString("F1") + "s, logging every " + IntervalSec.ToString("F1") + "s (no patches)"));
		}

		public override void Disable()
		{
			Active = false;
			Stats.Clear();
			base.Disable();
		}

		public override void OnConfigChanged(ConfigEntryBase entry)
		{
			if ((object)entry == _interval)
			{
				IntervalSec = Mathf.Max(1f, _interval.Value);
			}
			else
			{
				if ((object)entry != _sampleInterval)
				{
					return;
				}
				SampleIntervalSec = Mathf.Clamp(_sampleInterval.Value, 0.1f, 10f);
			}
			_logAcc = 0f;
			FeatureModule.Log.LogInfo((object)("[PeerTelemetry] interval=" + IntervalSec.ToString("F1") + "s sample=" + SampleIntervalSec.ToString("F1") + "s"));
		}

		internal static bool TryGet(long uid, out PeerStat stat)
		{
			return Stats.TryGetValue(uid, out stat);
		}

		internal static PeerStat[] Snapshot()
		{
			PeerStat[] array = new PeerStat[Stats.Count];
			Stats.Values.CopyTo(array, 0);
			return array;
		}

		internal static void Tick(float dt)
		{
			if (Active && FeatureModule.ServerActive())
			{
				_sampleAcc += dt;
				_logAcc += dt;
				if (_sampleAcc >= SampleIntervalSec)
				{
					_sampleAcc = 0f;
					Sample();
				}
				if (_logAcc >= IntervalSec)
				{
					_logAcc = 0f;
					Emit();
				}
			}
		}

		private static void Sample()
		{
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			ZDOMan instance = ZDOMan.instance;
			if (instance == null)
			{
				return;
			}
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			TempIds.Clear();
			float qualityLocal = default(float);
			float qualityRemote = default(float);
			int ping = default(int);
			float outBytesPerSec = default(float);
			float inBytesPerSec = default(float);
			for (int i = 0; i < instance.m_peers.Count; i++)
			{
				ZDOPeer val = instance.m_peers[i];
				if (val == null || val.m_peer == null)
				{
					continue;
				}
				PeerStat value = new PeerStat
				{
					Uid = val.m_peer.m_uid,
					PlayerName = (string.IsNullOrEmpty(val.m_peer.m_playerName) ? "?" : val.m_peer.m_playerName),
					ZdoQueue = val.m_zdos.Count,
					ForceSend = val.m_forceSend.Count,
					InvalidSector = val.m_invalidSector.Count,
					SampledAt = realtimeSinceStartup
				};
				ISocket socket = val.m_peer.m_socket;
				if (socket != null)
				{
					try
					{
						value.SocketQueueBytes = socket.GetSendQueueSize();
					}
					catch
					{
						value.SocketQueueBytes = -1;
					}
				}
				ZSteamSocket val2 = (ZSteamSocket)(object)((socket is ZSteamSocket) ? socket : null);
				if (val2 != null)
				{
					if (!_qualityAbsent)
					{
						try
						{
							val2.GetConnectionQuality(ref qualityLocal, ref qualityRemote, ref ping, ref outBytesPerSec, ref inBytesPerSec);
							value.QualityLocal = qualityLocal;
							value.QualityRemote = qualityRemote;
							value.Ping = ping;
							value.OutBytesPerSec = outBytesPerSec;
							value.InBytesPerSec = inBytesPerSec;
						}
						catch (Exception ex)
						{
							if (ex.Message != null && ex.Message.IndexOf("not initialized", StringComparison.OrdinalIgnoreCase) >= 0)
							{
								_qualityAbsent = true;
								SmoothServerPlugin.Log.LogInfo((object)("[PeerTelemetry] ZSteamSocket.GetConnectionQuality is unusable on this build (" + ex.Message.Trim() + ") - ping/quality come from GetConnectionRealTimeStatus instead"));
							}
						}
					}
					if (TryRealTimeStatus(val2, out var status))
					{
						value.V

System.Buffers.dll

Decompiled 4 hours ago
using System;
using System.Diagnostics;
using System.Diagnostics.Tracing;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using FxResources.System.Buffers;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyTitle("System.Buffers")]
[assembly: AssemblyDescription("System.Buffers")]
[assembly: AssemblyDefaultAlias("System.Buffers")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyFileVersion("4.6.28619.01")]
[assembly: AssemblyInformationalVersion("4.6.28619.01 @BuiltBy: dlab14-DDVSOWINAGE069 @Branch: release/2.1 @SrcCode: https://github.com/dotnet/corefx/tree/7601f4f6225089ffb291dc7d58293c7bbf5c5d4f")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.0.3.0")]
[module: UnverifiableCode]
namespace FxResources.System.Buffers
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class SR
	{
		private static ResourceManager s_resourceManager;

		private static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(ResourceType));

		internal static Type ResourceType { get; } = typeof(SR);


		internal static string ArgumentException_BufferNotFromPool => GetResourceString("ArgumentException_BufferNotFromPool", null);

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static bool UsingResourceKeys()
		{
			return false;
		}

		internal static string GetResourceString(string resourceKey, string defaultString)
		{
			string text = null;
			try
			{
				text = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			if (defaultString != null && resourceKey.Equals(text, StringComparison.Ordinal))
			{
				return defaultString;
			}
			return text;
		}

		internal static string Format(string resourceFormat, params object[] args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + string.Join(", ", args);
				}
				return string.Format(resourceFormat, args);
			}
			return resourceFormat;
		}

		internal static string Format(string resourceFormat, object p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(resourceFormat, p1);
		}

		internal static string Format(string resourceFormat, object p1, object p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(resourceFormat, p1, p2);
		}

		internal static string Format(string resourceFormat, object p1, object p2, object p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(resourceFormat, p1, p2, p3);
		}
	}
}
namespace System.Buffers
{
	public abstract class ArrayPool<T>
	{
		private static ArrayPool<T> s_sharedInstance;

		public static ArrayPool<T> Shared
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				return Volatile.Read(ref s_sharedInstance) ?? EnsureSharedCreated();
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static ArrayPool<T> EnsureSharedCreated()
		{
			Interlocked.CompareExchange(ref s_sharedInstance, Create(), null);
			return s_sharedInstance;
		}

		public static ArrayPool<T> Create()
		{
			return new DefaultArrayPool<T>();
		}

		public static ArrayPool<T> Create(int maxArrayLength, int maxArraysPerBucket)
		{
			return new DefaultArrayPool<T>(maxArrayLength, maxArraysPerBucket);
		}

		public abstract T[] Rent(int minimumLength);

		public abstract void Return(T[] array, bool clearArray = false);
	}
	[EventSource(Name = "System.Buffers.ArrayPoolEventSource")]
	internal sealed class ArrayPoolEventSource : EventSource
	{
		internal enum BufferAllocatedReason
		{
			Pooled,
			OverMaximumSize,
			PoolExhausted
		}

		internal static readonly System.Buffers.ArrayPoolEventSource Log = new System.Buffers.ArrayPoolEventSource();

		[Event(1, Level = EventLevel.Verbose)]
		internal unsafe void BufferRented(int bufferId, int bufferSize, int poolId, int bucketId)
		{
			EventData* ptr = stackalloc EventData[4];
			*ptr = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferId)
			};
			ptr[1] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferSize)
			};
			ptr[2] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&poolId)
			};
			ptr[3] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bucketId)
			};
			WriteEventCore(1, 4, ptr);
		}

		[Event(2, Level = EventLevel.Informational)]
		internal unsafe void BufferAllocated(int bufferId, int bufferSize, int poolId, int bucketId, BufferAllocatedReason reason)
		{
			EventData* ptr = stackalloc EventData[5];
			*ptr = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferId)
			};
			ptr[1] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bufferSize)
			};
			ptr[2] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&poolId)
			};
			ptr[3] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&bucketId)
			};
			ptr[4] = new EventData
			{
				Size = 4,
				DataPointer = (IntPtr)(&reason)
			};
			WriteEventCore(2, 5, ptr);
		}

		[Event(3, Level = EventLevel.Verbose)]
		internal void BufferReturned(int bufferId, int bufferSize, int poolId)
		{
			WriteEvent(3, bufferId, bufferSize, poolId);
		}
	}
	internal sealed class DefaultArrayPool<T> : ArrayPool<T>
	{
		private sealed class Bucket
		{
			internal readonly int _bufferLength;

			private readonly T[][] _buffers;

			private readonly int _poolId;

			private SpinLock _lock;

			private int _index;

			internal int Id => GetHashCode();

			internal Bucket(int bufferLength, int numberOfBuffers, int poolId)
			{
				_lock = new SpinLock(Debugger.IsAttached);
				_buffers = new T[numberOfBuffers][];
				_bufferLength = bufferLength;
				_poolId = poolId;
			}

			internal T[] Rent()
			{
				T[][] buffers = _buffers;
				T[] array = null;
				bool lockTaken = false;
				bool flag = false;
				try
				{
					_lock.Enter(ref lockTaken);
					if (_index < buffers.Length)
					{
						array = buffers[_index];
						buffers[_index++] = null;
						flag = array == null;
					}
				}
				finally
				{
					if (lockTaken)
					{
						_lock.Exit(useMemoryBarrier: false);
					}
				}
				if (flag)
				{
					array = new T[_bufferLength];
					System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log;
					if (log.IsEnabled())
					{
						log.BufferAllocated(array.GetHashCode(), _bufferLength, _poolId, Id, System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.Pooled);
					}
				}
				return array;
			}

			internal void Return(T[] array)
			{
				if (array.Length != _bufferLength)
				{
					throw new ArgumentException(System.SR.ArgumentException_BufferNotFromPool, "array");
				}
				bool lockTaken = false;
				try
				{
					_lock.Enter(ref lockTaken);
					if (_index != 0)
					{
						_buffers[--_index] = array;
					}
				}
				finally
				{
					if (lockTaken)
					{
						_lock.Exit(useMemoryBarrier: false);
					}
				}
			}
		}

		private const int DefaultMaxArrayLength = 1048576;

		private const int DefaultMaxNumberOfArraysPerBucket = 50;

		private static T[] s_emptyArray;

		private readonly Bucket[] _buckets;

		private int Id => GetHashCode();

		internal DefaultArrayPool()
			: this(1048576, 50)
		{
		}

		internal DefaultArrayPool(int maxArrayLength, int maxArraysPerBucket)
		{
			if (maxArrayLength <= 0)
			{
				throw new ArgumentOutOfRangeException("maxArrayLength");
			}
			if (maxArraysPerBucket <= 0)
			{
				throw new ArgumentOutOfRangeException("maxArraysPerBucket");
			}
			if (maxArrayLength > 1073741824)
			{
				maxArrayLength = 1073741824;
			}
			else if (maxArrayLength < 16)
			{
				maxArrayLength = 16;
			}
			int id = Id;
			int num = System.Buffers.Utilities.SelectBucketIndex(maxArrayLength);
			Bucket[] array = new Bucket[num + 1];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new Bucket(System.Buffers.Utilities.GetMaxSizeForBucket(i), maxArraysPerBucket, id);
			}
			_buckets = array;
		}

		public override T[] Rent(int minimumLength)
		{
			if (minimumLength < 0)
			{
				throw new ArgumentOutOfRangeException("minimumLength");
			}
			if (minimumLength == 0)
			{
				return s_emptyArray ?? (s_emptyArray = new T[0]);
			}
			System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log;
			T[] array = null;
			int num = System.Buffers.Utilities.SelectBucketIndex(minimumLength);
			if (num < _buckets.Length)
			{
				int num2 = num;
				do
				{
					array = _buckets[num2].Rent();
					if (array != null)
					{
						if (log.IsEnabled())
						{
							log.BufferRented(array.GetHashCode(), array.Length, Id, _buckets[num2].Id);
						}
						return array;
					}
				}
				while (++num2 < _buckets.Length && num2 != num + 2);
				array = new T[_buckets[num]._bufferLength];
			}
			else
			{
				array = new T[minimumLength];
			}
			if (log.IsEnabled())
			{
				int hashCode = array.GetHashCode();
				int bucketId = -1;
				log.BufferRented(hashCode, array.Length, Id, bucketId);
				log.BufferAllocated(hashCode, array.Length, Id, bucketId, (num >= _buckets.Length) ? System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.OverMaximumSize : System.Buffers.ArrayPoolEventSource.BufferAllocatedReason.PoolExhausted);
			}
			return array;
		}

		public override void Return(T[] array, bool clearArray = false)
		{
			if (array == null)
			{
				throw new ArgumentNullException("array");
			}
			if (array.Length == 0)
			{
				return;
			}
			int num = System.Buffers.Utilities.SelectBucketIndex(array.Length);
			if (num < _buckets.Length)
			{
				if (clearArray)
				{
					Array.Clear(array, 0, array.Length);
				}
				_buckets[num].Return(array);
			}
			System.Buffers.ArrayPoolEventSource log = System.Buffers.ArrayPoolEventSource.Log;
			if (log.IsEnabled())
			{
				log.BufferReturned(array.GetHashCode(), array.Length, Id);
			}
		}
	}
	internal static class Utilities
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static int SelectBucketIndex(int bufferSize)
		{
			uint num = (uint)(bufferSize - 1) >> 4;
			int num2 = 0;
			if (num > 65535)
			{
				num >>= 16;
				num2 = 16;
			}
			if (num > 255)
			{
				num >>= 8;
				num2 += 8;
			}
			if (num > 15)
			{
				num >>= 4;
				num2 += 4;
			}
			if (num > 3)
			{
				num >>= 2;
				num2 += 2;
			}
			if (num > 1)
			{
				num >>= 1;
				num2++;
			}
			return num2 + (int)num;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static int GetMaxSizeForBucket(int binIndex)
		{
			return 16 << binIndex;
		}
	}
}

System.Memory.dll

Decompiled 4 hours ago
using System;
using System.Buffers;
using System.Buffers.Binary;
using System.Buffers.Text;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Numerics;
using System.Numerics.Hashing;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using FxResources.System.Memory;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyTitle("System.Memory")]
[assembly: AssemblyDescription("System.Memory")]
[assembly: AssemblyDefaultAlias("System.Memory")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")]
[assembly: AssemblyFileVersion("4.6.31308.01")]
[assembly: AssemblyInformationalVersion("4.6.31308.01 @BuiltBy: cloudtest-841353dfc000000 @Branch: release/2.1-MSRC @SrcCode: https://github.com/dotnet/corefx/tree/32b491939fbd125f304031c35038b1e14b4e3958")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32 | DllImportSearchPath.AssemblyDirectory)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.0.1.2")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsByRefLikeAttribute : Attribute
	{
	}
}
namespace FxResources.System.Memory
{
	internal static class SR
	{
	}
}
namespace System
{
	public readonly struct SequencePosition : IEquatable<SequencePosition>
	{
		private readonly object _object;

		private readonly int _integer;

		public SequencePosition(object @object, int integer)
		{
			_object = @object;
			_integer = integer;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public object GetObject()
		{
			return _object;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public int GetInteger()
		{
			return _integer;
		}

		public bool Equals(SequencePosition other)
		{
			if (_integer == other._integer)
			{
				return object.Equals(_object, other._object);
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			if (obj is SequencePosition other)
			{
				return Equals(other);
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			return HashHelpers.Combine(_object?.GetHashCode() ?? 0, _integer);
		}
	}
	internal static class ThrowHelper
	{
		internal static void ThrowArgumentNullException(System.ExceptionArgument argument)
		{
			throw CreateArgumentNullException(argument);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentNullException(System.ExceptionArgument argument)
		{
			return new ArgumentNullException(argument.ToString());
		}

		internal static void ThrowArrayTypeMismatchException()
		{
			throw CreateArrayTypeMismatchException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArrayTypeMismatchException()
		{
			return new ArrayTypeMismatchException();
		}

		internal static void ThrowArgumentException_InvalidTypeWithPointersNotSupported(Type type)
		{
			throw CreateArgumentException_InvalidTypeWithPointersNotSupported(type);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentException_InvalidTypeWithPointersNotSupported(Type type)
		{
			return new ArgumentException(System.SR.Format(System.SR.Argument_InvalidTypeWithPointersNotSupported, type));
		}

		internal static void ThrowArgumentException_DestinationTooShort()
		{
			throw CreateArgumentException_DestinationTooShort();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentException_DestinationTooShort()
		{
			return new ArgumentException(System.SR.Argument_DestinationTooShort);
		}

		internal static void ThrowIndexOutOfRangeException()
		{
			throw CreateIndexOutOfRangeException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateIndexOutOfRangeException()
		{
			return new IndexOutOfRangeException();
		}

		internal static void ThrowArgumentOutOfRangeException()
		{
			throw CreateArgumentOutOfRangeException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException()
		{
			return new ArgumentOutOfRangeException();
		}

		internal static void ThrowArgumentOutOfRangeException(System.ExceptionArgument argument)
		{
			throw CreateArgumentOutOfRangeException(argument);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException(System.ExceptionArgument argument)
		{
			return new ArgumentOutOfRangeException(argument.ToString());
		}

		internal static void ThrowArgumentOutOfRangeException_PrecisionTooLarge()
		{
			throw CreateArgumentOutOfRangeException_PrecisionTooLarge();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException_PrecisionTooLarge()
		{
			return new ArgumentOutOfRangeException("precision", System.SR.Format(System.SR.Argument_PrecisionTooLarge, (byte)99));
		}

		internal static void ThrowArgumentOutOfRangeException_SymbolDoesNotFit()
		{
			throw CreateArgumentOutOfRangeException_SymbolDoesNotFit();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException_SymbolDoesNotFit()
		{
			return new ArgumentOutOfRangeException("symbol", System.SR.Argument_BadFormatSpecifier);
		}

		internal static void ThrowInvalidOperationException()
		{
			throw CreateInvalidOperationException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateInvalidOperationException()
		{
			return new InvalidOperationException();
		}

		internal static void ThrowInvalidOperationException_OutstandingReferences()
		{
			throw CreateInvalidOperationException_OutstandingReferences();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateInvalidOperationException_OutstandingReferences()
		{
			return new InvalidOperationException(System.SR.OutstandingReferences);
		}

		internal static void ThrowInvalidOperationException_UnexpectedSegmentType()
		{
			throw CreateInvalidOperationException_UnexpectedSegmentType();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateInvalidOperationException_UnexpectedSegmentType()
		{
			return new InvalidOperationException(System.SR.UnexpectedSegmentType);
		}

		internal static void ThrowInvalidOperationException_EndPositionNotReached()
		{
			throw CreateInvalidOperationException_EndPositionNotReached();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateInvalidOperationException_EndPositionNotReached()
		{
			return new InvalidOperationException(System.SR.EndPositionNotReached);
		}

		internal static void ThrowArgumentOutOfRangeException_PositionOutOfRange()
		{
			throw CreateArgumentOutOfRangeException_PositionOutOfRange();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException_PositionOutOfRange()
		{
			return new ArgumentOutOfRangeException("position");
		}

		internal static void ThrowArgumentOutOfRangeException_OffsetOutOfRange()
		{
			throw CreateArgumentOutOfRangeException_OffsetOutOfRange();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentOutOfRangeException_OffsetOutOfRange()
		{
			return new ArgumentOutOfRangeException("offset");
		}

		internal static void ThrowObjectDisposedException_ArrayMemoryPoolBuffer()
		{
			throw CreateObjectDisposedException_ArrayMemoryPoolBuffer();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateObjectDisposedException_ArrayMemoryPoolBuffer()
		{
			return new ObjectDisposedException("ArrayMemoryPoolBuffer");
		}

		internal static void ThrowFormatException_BadFormatSpecifier()
		{
			throw CreateFormatException_BadFormatSpecifier();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateFormatException_BadFormatSpecifier()
		{
			return new FormatException(System.SR.Argument_BadFormatSpecifier);
		}

		internal static void ThrowArgumentException_OverlapAlignmentMismatch()
		{
			throw CreateArgumentException_OverlapAlignmentMismatch();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateArgumentException_OverlapAlignmentMismatch()
		{
			return new ArgumentException(System.SR.Argument_OverlapAlignmentMismatch);
		}

		internal static void ThrowNotSupportedException()
		{
			throw CreateThrowNotSupportedException();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static Exception CreateThrowNotSupportedException()
		{
			return new NotSupportedException();
		}

		public static bool TryFormatThrowFormatException(out int bytesWritten)
		{
			bytesWritten = 0;
			ThrowFormatException_BadFormatSpecifier();
			return false;
		}

		public static bool TryParseThrowFormatException<T>(out T value, out int bytesConsumed)
		{
			value = default(T);
			bytesConsumed = 0;
			ThrowFormatException_BadFormatSpecifier();
			return false;
		}

		public static void ThrowArgumentValidationException<T>(ReadOnlySequenceSegment<T> startSegment, int startIndex, ReadOnlySequenceSegment<T> endSegment)
		{
			throw CreateArgumentValidationException(startSegment, startIndex, endSegment);
		}

		private static Exception CreateArgumentValidationException<T>(ReadOnlySequenceSegment<T> startSegment, int startIndex, ReadOnlySequenceSegment<T> endSegment)
		{
			if (startSegment == null)
			{
				return CreateArgumentNullException(System.ExceptionArgument.startSegment);
			}
			if (endSegment == null)
			{
				return CreateArgumentNullException(System.ExceptionArgument.endSegment);
			}
			if (startSegment != endSegment && startSegment.RunningIndex > endSegment.RunningIndex)
			{
				return CreateArgumentOutOfRangeException(System.ExceptionArgument.endSegment);
			}
			if ((uint)startSegment.Memory.Length < (uint)startIndex)
			{
				return CreateArgumentOutOfRangeException(System.ExceptionArgument.startIndex);
			}
			return CreateArgumentOutOfRangeException(System.ExceptionArgument.endIndex);
		}

		public static void ThrowArgumentValidationException(Array array, int start)
		{
			throw CreateArgumentValidationException(array, start);
		}

		private static Exception CreateArgumentValidationException(Array array, int start)
		{
			if (array == null)
			{
				return CreateArgumentNullException(System.ExceptionArgument.array);
			}
			if ((uint)start > (uint)array.Length)
			{
				return CreateArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return CreateArgumentOutOfRangeException(System.ExceptionArgument.length);
		}

		public static void ThrowStartOrEndArgumentValidationException(long start)
		{
			throw CreateStartOrEndArgumentValidationException(start);
		}

		private static Exception CreateStartOrEndArgumentValidationException(long start)
		{
			if (start < 0)
			{
				return CreateArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return CreateArgumentOutOfRangeException(System.ExceptionArgument.length);
		}
	}
	internal enum ExceptionArgument
	{
		length,
		start,
		minimumBufferSize,
		elementIndex,
		comparable,
		comparer,
		destination,
		offset,
		startSegment,
		endSegment,
		startIndex,
		endIndex,
		array,
		culture,
		manager
	}
	internal static class DecimalDecCalc
	{
		private static uint D32DivMod1E9(uint hi32, ref uint lo32)
		{
			ulong num = ((ulong)hi32 << 32) | lo32;
			lo32 = (uint)(num / 1000000000);
			return (uint)(num % 1000000000);
		}

		internal static uint DecDivMod1E9(ref MutableDecimal value)
		{
			return D32DivMod1E9(D32DivMod1E9(D32DivMod1E9(0u, ref value.High), ref value.Mid), ref value.Low);
		}

		internal static void DecAddInt32(ref MutableDecimal value, uint i)
		{
			if (D32AddCarry(ref value.Low, i) && D32AddCarry(ref value.Mid, 1u))
			{
				D32AddCarry(ref value.High, 1u);
			}
		}

		private static bool D32AddCarry(ref uint value, uint i)
		{
			uint num = value;
			uint num2 = (value = num + i);
			if (num2 >= num)
			{
				return num2 < i;
			}
			return true;
		}

		internal static void DecMul10(ref MutableDecimal value)
		{
			MutableDecimal d = value;
			DecShiftLeft(ref value);
			DecShiftLeft(ref value);
			DecAdd(ref value, d);
			DecShiftLeft(ref value);
		}

		private static void DecShiftLeft(ref MutableDecimal value)
		{
			uint num = (((value.Low & 0x80000000u) != 0) ? 1u : 0u);
			uint num2 = (((value.Mid & 0x80000000u) != 0) ? 1u : 0u);
			value.Low <<= 1;
			value.Mid = (value.Mid << 1) | num;
			value.High = (value.High << 1) | num2;
		}

		private static void DecAdd(ref MutableDecimal value, MutableDecimal d)
		{
			if (D32AddCarry(ref value.Low, d.Low) && D32AddCarry(ref value.Mid, 1u))
			{
				D32AddCarry(ref value.High, 1u);
			}
			if (D32AddCarry(ref value.Mid, d.Mid))
			{
				D32AddCarry(ref value.High, 1u);
			}
			D32AddCarry(ref value.High, d.High);
		}
	}
	internal static class Number
	{
		private static class DoubleHelper
		{
			public unsafe static uint Exponent(double d)
			{
				return (*(uint*)((byte*)(&d) + 4) >> 20) & 0x7FFu;
			}

			public unsafe static ulong Mantissa(double d)
			{
				return *(uint*)(&d) | ((ulong)(uint)(*(int*)((byte*)(&d) + 4) & 0xFFFFF) << 32);
			}

			public unsafe static bool Sign(double d)
			{
				return *(uint*)((byte*)(&d) + 4) >> 31 != 0;
			}
		}

		internal const int DECIMAL_PRECISION = 29;

		private static readonly ulong[] s_rgval64Power10 = new ulong[30]
		{
			11529215046068469760uL, 14411518807585587200uL, 18014398509481984000uL, 11258999068426240000uL, 14073748835532800000uL, 17592186044416000000uL, 10995116277760000000uL, 13743895347200000000uL, 17179869184000000000uL, 10737418240000000000uL,
			13421772800000000000uL, 16777216000000000000uL, 10485760000000000000uL, 13107200000000000000uL, 16384000000000000000uL, 14757395258967641293uL, 11805916207174113035uL, 9444732965739290428uL, 15111572745182864686uL, 12089258196146291749uL,
			9671406556917033399uL, 15474250491067253438uL, 12379400392853802751uL, 9903520314283042201uL, 15845632502852867522uL, 12676506002282294018uL, 10141204801825835215uL, 16225927682921336344uL, 12980742146337069075uL, 10384593717069655260uL
		};

		private static readonly sbyte[] s_rgexp64Power10 = new sbyte[15]
		{
			4, 7, 10, 14, 17, 20, 24, 27, 30, 34,
			37, 40, 44, 47, 50
		};

		private static readonly ulong[] s_rgval64Power10By16 = new ulong[42]
		{
			10240000000000000000uL, 11368683772161602974uL, 12621774483536188886uL, 14012984643248170708uL, 15557538194652854266uL, 17272337110188889248uL, 9588073174409622172uL, 10644899600020376798uL, 11818212630765741798uL, 13120851772591970216uL,
			14567071740625403792uL, 16172698447808779622uL, 17955302187076837696uL, 9967194951097567532uL, 11065809325636130658uL, 12285516299433008778uL, 13639663065038175358uL, 15143067982934716296uL, 16812182738118149112uL, 9332636185032188787uL,
			10361307573072618722uL, 16615349947311448416uL, 14965776766268445891uL, 13479973333575319909uL, 12141680576410806707uL, 10936253623915059637uL, 9850501549098619819uL, 17745086042373215136uL, 15983352577617880260uL, 14396524142538228461uL,
			12967236152753103031uL, 11679847981112819795uL, 10520271803096747049uL, 9475818434452569218uL, 17070116948172427008uL, 15375394465392026135uL, 13848924157002783096uL, 12474001934591998882uL, 11235582092889474480uL, 10120112665365530972uL,
			18230774251475056952uL, 16420821625123739930uL
		};

		private static readonly short[] s_rgexp64Power10By16 = new short[21]
		{
			54, 107, 160, 213, 266, 319, 373, 426, 479, 532,
			585, 638, 691, 745, 798, 851, 904, 957, 1010, 1064,
			1117
		};

		public static void RoundNumber(ref NumberBuffer number, int pos)
		{
			Span<byte> digits = number.Digits;
			int i;
			for (i = 0; i < pos && digits[i] != 0; i++)
			{
			}
			if (i == pos && digits[i] >= 53)
			{
				while (i > 0 && digits[i - 1] == 57)
				{
					i--;
				}
				if (i > 0)
				{
					digits[i - 1]++;
				}
				else
				{
					number.Scale++;
					digits[0] = 49;
					i = 1;
				}
			}
			else
			{
				while (i > 0 && digits[i - 1] == 48)
				{
					i--;
				}
			}
			if (i == 0)
			{
				number.Scale = 0;
				number.IsNegative = false;
			}
			digits[i] = 0;
		}

		internal static bool NumberBufferToDouble(ref NumberBuffer number, out double value)
		{
			double num = NumberToDouble(ref number);
			uint num2 = DoubleHelper.Exponent(num);
			ulong num3 = DoubleHelper.Mantissa(num);
			switch (num2)
			{
			case 2047u:
				value = 0.0;
				return false;
			case 0u:
				if (num3 == 0L)
				{
					num = 0.0;
				}
				break;
			}
			value = num;
			return true;
		}

		public unsafe static bool NumberBufferToDecimal(ref NumberBuffer number, ref decimal value)
		{
			MutableDecimal value2 = default(MutableDecimal);
			byte* ptr = number.UnsafeDigits;
			int num = number.Scale;
			if (*ptr == 0)
			{
				if (num > 0)
				{
					num = 0;
				}
			}
			else
			{
				if (num > 29)
				{
					return false;
				}
				while ((num > 0 || (*ptr != 0 && num > -28)) && (value2.High < 429496729 || (value2.High == 429496729 && (value2.Mid < 2576980377u || (value2.Mid == 2576980377u && (value2.Low < 2576980377u || (value2.Low == 2576980377u && *ptr <= 53)))))))
				{
					DecimalDecCalc.DecMul10(ref value2);
					if (*ptr != 0)
					{
						DecimalDecCalc.DecAddInt32(ref value2, (uint)(*(ptr++) - 48));
					}
					num--;
				}
				if (*(ptr++) >= 53)
				{
					bool flag = true;
					if (*(ptr - 1) == 53 && *(ptr - 2) % 2 == 0)
					{
						int num2 = 20;
						while (*ptr == 48 && num2 != 0)
						{
							ptr++;
							num2--;
						}
						if (*ptr == 0 || num2 == 0)
						{
							flag = false;
						}
					}
					if (flag)
					{
						DecimalDecCalc.DecAddInt32(ref value2, 1u);
						if ((value2.High | value2.Mid | value2.Low) == 0)
						{
							value2.High = 429496729u;
							value2.Mid = 2576980377u;
							value2.Low = 2576980378u;
							num++;
						}
					}
				}
			}
			if (num > 0)
			{
				return false;
			}
			if (num <= -29)
			{
				value2.High = 0u;
				value2.Low = 0u;
				value2.Mid = 0u;
				value2.Scale = 28;
			}
			else
			{
				value2.Scale = -num;
			}
			value2.IsNegative = number.IsNegative;
			value = System.Runtime.CompilerServices.Unsafe.As<MutableDecimal, decimal>(ref value2);
			return true;
		}

		public static void DecimalToNumber(decimal value, ref NumberBuffer number)
		{
			ref MutableDecimal reference = ref System.Runtime.CompilerServices.Unsafe.As<decimal, MutableDecimal>(ref value);
			Span<byte> digits = number.Digits;
			number.IsNegative = reference.IsNegative;
			int num = 29;
			while ((reference.Mid != 0) | (reference.High != 0))
			{
				uint num2 = DecimalDecCalc.DecDivMod1E9(ref reference);
				for (int i = 0; i < 9; i++)
				{
					digits[--num] = (byte)(num2 % 10 + 48);
					num2 /= 10;
				}
			}
			for (uint num3 = reference.Low; num3 != 0; num3 /= 10)
			{
				digits[--num] = (byte)(num3 % 10 + 48);
			}
			int num4 = 29 - num;
			number.Scale = num4 - reference.Scale;
			Span<byte> digits2 = number.Digits;
			int index = 0;
			while (--num4 >= 0)
			{
				digits2[index++] = digits[num++];
			}
			digits2[index] = 0;
		}

		private static uint DigitsToInt(ReadOnlySpan<byte> digits, int count)
		{
			uint value;
			int bytesConsumed;
			bool flag = Utf8Parser.TryParse(digits.Slice(0, count), out value, out bytesConsumed, 'D');
			return value;
		}

		private static ulong Mul32x32To64(uint a, uint b)
		{
			return (ulong)a * (ulong)b;
		}

		private static ulong Mul64Lossy(ulong a, ulong b, ref int pexp)
		{
			ulong num = Mul32x32To64((uint)(a >> 32), (uint)(b >> 32)) + (Mul32x32To64((uint)(a >> 32), (uint)b) >> 32) + (Mul32x32To64((uint)a, (uint)(b >> 32)) >> 32);
			if ((num & 0x8000000000000000uL) == 0L)
			{
				num <<= 1;
				pexp--;
			}
			return num;
		}

		private static int abs(int value)
		{
			if (value < 0)
			{
				return -value;
			}
			return value;
		}

		private unsafe static double NumberToDouble(ref NumberBuffer number)
		{
			ReadOnlySpan<byte> digits = number.Digits;
			int i = 0;
			int numDigits = number.NumDigits;
			int num = numDigits;
			for (; digits[i] == 48; i++)
			{
				num--;
			}
			if (num == 0)
			{
				return 0.0;
			}
			int num2 = Math.Min(num, 9);
			num -= num2;
			ulong num3 = DigitsToInt(digits, num2);
			if (num > 0)
			{
				num2 = Math.Min(num, 9);
				num -= num2;
				uint b = (uint)(s_rgval64Power10[num2 - 1] >> 64 - s_rgexp64Power10[num2 - 1]);
				num3 = Mul32x32To64((uint)num3, b) + DigitsToInt(digits.Slice(9), num2);
			}
			int num4 = number.Scale - (numDigits - num);
			int num5 = abs(num4);
			if (num5 >= 352)
			{
				ulong num6 = ((num4 > 0) ? 9218868437227405312uL : 0);
				if (number.IsNegative)
				{
					num6 |= 0x8000000000000000uL;
				}
				return *(double*)(&num6);
			}
			int pexp = 64;
			if ((num3 & 0xFFFFFFFF00000000uL) == 0L)
			{
				num3 <<= 32;
				pexp -= 32;
			}
			if ((num3 & 0xFFFF000000000000uL) == 0L)
			{
				num3 <<= 16;
				pexp -= 16;
			}
			if ((num3 & 0xFF00000000000000uL) == 0L)
			{
				num3 <<= 8;
				pexp -= 8;
			}
			if ((num3 & 0xF000000000000000uL) == 0L)
			{
				num3 <<= 4;
				pexp -= 4;
			}
			if ((num3 & 0xC000000000000000uL) == 0L)
			{
				num3 <<= 2;
				pexp -= 2;
			}
			if ((num3 & 0x8000000000000000uL) == 0L)
			{
				num3 <<= 1;
				pexp--;
			}
			int num7 = num5 & 0xF;
			if (num7 != 0)
			{
				int num8 = s_rgexp64Power10[num7 - 1];
				pexp += ((num4 < 0) ? (-num8 + 1) : num8);
				ulong b2 = s_rgval64Power10[num7 + ((num4 < 0) ? 15 : 0) - 1];
				num3 = Mul64Lossy(num3, b2, ref pexp);
			}
			num7 = num5 >> 4;
			if (num7 != 0)
			{
				int num9 = s_rgexp64Power10By16[num7 - 1];
				pexp += ((num4 < 0) ? (-num9 + 1) : num9);
				ulong b3 = s_rgval64Power10By16[num7 + ((num4 < 0) ? 21 : 0) - 1];
				num3 = Mul64Lossy(num3, b3, ref pexp);
			}
			if (((uint)(int)num3 & 0x400u) != 0)
			{
				ulong num10 = num3 + 1023 + (ulong)(((int)num3 >> 11) & 1);
				if (num10 < num3)
				{
					num10 = (num10 >> 1) | 0x8000000000000000uL;
					pexp++;
				}
				num3 = num10;
			}
			pexp += 1022;
			num3 = ((pexp <= 0) ? ((pexp == -52 && num3 >= 9223372036854775896uL) ? 1 : ((pexp > -52) ? (num3 >> -pexp + 11 + 1) : 0)) : ((pexp < 2047) ? ((ulong)((long)pexp << 52) + ((num3 >> 11) & 0xFFFFFFFFFFFFFL)) : 9218868437227405312uL));
			if (number.IsNegative)
			{
				num3 |= 0x8000000000000000uL;
			}
			return *(double*)(&num3);
		}
	}
	internal ref struct NumberBuffer
	{
		public int Scale;

		public bool IsNegative;

		public const int BufferSize = 51;

		private byte _b0;

		private byte _b1;

		private byte _b2;

		private byte _b3;

		private byte _b4;

		private byte _b5;

		private byte _b6;

		private byte _b7;

		private byte _b8;

		private byte _b9;

		private byte _b10;

		private byte _b11;

		private byte _b12;

		private byte _b13;

		private byte _b14;

		private byte _b15;

		private byte _b16;

		private byte _b17;

		private byte _b18;

		private byte _b19;

		private byte _b20;

		private byte _b21;

		private byte _b22;

		private byte _b23;

		private byte _b24;

		private byte _b25;

		private byte _b26;

		private byte _b27;

		private byte _b28;

		private byte _b29;

		private byte _b30;

		private byte _b31;

		private byte _b32;

		private byte _b33;

		private byte _b34;

		private byte _b35;

		private byte _b36;

		private byte _b37;

		private byte _b38;

		private byte _b39;

		private byte _b40;

		private byte _b41;

		private byte _b42;

		private byte _b43;

		private byte _b44;

		private byte _b45;

		private byte _b46;

		private byte _b47;

		private byte _b48;

		private byte _b49;

		private byte _b50;

		public unsafe Span<byte> Digits => new Span<byte>(System.Runtime.CompilerServices.Unsafe.AsPointer<byte>(ref _b0), 51);

		public unsafe byte* UnsafeDigits => (byte*)System.Runtime.CompilerServices.Unsafe.AsPointer<byte>(ref _b0);

		public int NumDigits => Digits.IndexOf<byte>(0);

		[Conditional("DEBUG")]
		public void CheckConsistency()
		{
		}

		public override string ToString()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append('[');
			stringBuilder.Append('"');
			Span<byte> digits = Digits;
			for (int i = 0; i < 51; i++)
			{
				byte b = digits[i];
				if (b == 0)
				{
					break;
				}
				stringBuilder.Append((char)b);
			}
			stringBuilder.Append('"');
			stringBuilder.Append(", Scale = " + Scale);
			stringBuilder.Append(", IsNegative   = " + IsNegative);
			stringBuilder.Append(']');
			return stringBuilder.ToString();
		}
	}
	[DebuggerTypeProxy(typeof(System.MemoryDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly struct Memory<T>
	{
		private readonly object _object;

		private readonly int _index;

		private readonly int _length;

		private const int RemoveFlagsBitMask = int.MaxValue;

		public static Memory<T> Empty => default(Memory<T>);

		public int Length => _length & 0x7FFFFFFF;

		public bool IsEmpty => (_length & 0x7FFFFFFF) == 0;

		public Span<T> Span
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				Span<T> result;
				if (_index < 0)
				{
					result = ((MemoryManager<T>)_object).GetSpan();
					return result.Slice(_index & 0x7FFFFFFF, _length);
				}
				if (typeof(T) == typeof(char) && _object is string text)
				{
					result = new Span<T>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)text), MemoryExtensions.StringAdjustment, text.Length);
					return result.Slice(_index, _length);
				}
				if (_object != null)
				{
					return new Span<T>((T[])_object, _index, _length & 0x7FFFFFFF);
				}
				result = default(Span<T>);
				return result;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory(T[] array)
		{
			if (array == null)
			{
				this = default(Memory<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			_object = array;
			_index = 0;
			_length = array.Length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(T[] array, int start)
		{
			if (array == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException();
				}
				this = default(Memory<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = array;
			_index = start;
			_length = array.Length - start;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException();
				}
				this = default(Memory<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = array;
			_index = start;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(MemoryManager<T> manager, int length)
		{
			if (length < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = manager;
			_index = int.MinValue;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(MemoryManager<T> manager, int start, int length)
		{
			if (length < 0 || start < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = manager;
			_index = start | int.MinValue;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Memory(object obj, int start, int length)
		{
			_object = obj;
			_index = start;
			_length = length;
		}

		public static implicit operator Memory<T>(T[] array)
		{
			return new Memory<T>(array);
		}

		public static implicit operator Memory<T>(ArraySegment<T> segment)
		{
			return new Memory<T>(segment.Array, segment.Offset, segment.Count);
		}

		public static implicit operator ReadOnlyMemory<T>(Memory<T> memory)
		{
			return System.Runtime.CompilerServices.Unsafe.As<Memory<T>, ReadOnlyMemory<T>>(ref memory);
		}

		public override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				if (!(_object is string text))
				{
					return Span.ToString();
				}
				return text.Substring(_index, _length & 0x7FFFFFFF);
			}
			return $"System.Memory<{typeof(T).Name}>[{_length & 0x7FFFFFFF}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory<T> Slice(int start)
		{
			int length = _length;
			int num = length & 0x7FFFFFFF;
			if ((uint)start > (uint)num)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new Memory<T>(_object, _index + start, length - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Memory<T> Slice(int start, int length)
		{
			int length2 = _length;
			int num = length2 & 0x7FFFFFFF;
			if ((uint)start > (uint)num || (uint)length > (uint)(num - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			return new Memory<T>(_object, _index + start, length | (length2 & int.MinValue));
		}

		public void CopyTo(Memory<T> destination)
		{
			Span.CopyTo(destination.Span);
		}

		public bool TryCopyTo(Memory<T> destination)
		{
			return Span.TryCopyTo(destination.Span);
		}

		public unsafe MemoryHandle Pin()
		{
			if (_index < 0)
			{
				return ((MemoryManager<T>)_object).Pin(_index & 0x7FFFFFFF);
			}
			if (typeof(T) == typeof(char) && _object is string value)
			{
				GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned);
				void* pointer = System.Runtime.CompilerServices.Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer, handle);
			}
			if (_object is T[] array)
			{
				if (_length < 0)
				{
					void* pointer2 = System.Runtime.CompilerServices.Unsafe.Add<T>(System.Runtime.CompilerServices.Unsafe.AsPointer<T>(ref MemoryMarshal.GetReference<T>(array)), _index);
					return new MemoryHandle(pointer2);
				}
				GCHandle handle2 = GCHandle.Alloc(array, GCHandleType.Pinned);
				void* pointer3 = System.Runtime.CompilerServices.Unsafe.Add<T>((void*)handle2.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer3, handle2);
			}
			return default(MemoryHandle);
		}

		public T[] ToArray()
		{
			return Span.ToArray();
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			if (obj is ReadOnlyMemory<T> readOnlyMemory)
			{
				return readOnlyMemory.Equals(this);
			}
			if (obj is Memory<T> other)
			{
				return Equals(other);
			}
			return false;
		}

		public bool Equals(Memory<T> other)
		{
			if (_object == other._object && _index == other._index)
			{
				return _length == other._length;
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			if (_object == null)
			{
				return 0;
			}
			int hashCode = _object.GetHashCode();
			int index = _index;
			int hashCode2 = index.GetHashCode();
			index = _length;
			return CombineHashCodes(hashCode, hashCode2, index.GetHashCode());
		}

		private static int CombineHashCodes(int left, int right)
		{
			return ((left << 5) + left) ^ right;
		}

		private static int CombineHashCodes(int h1, int h2, int h3)
		{
			return CombineHashCodes(CombineHashCodes(h1, h2), h3);
		}
	}
	internal sealed class MemoryDebugView<T>
	{
		private readonly ReadOnlyMemory<T> _memory;

		[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
		public T[] Items => _memory.ToArray();

		public MemoryDebugView(Memory<T> memory)
		{
			_memory = memory;
		}

		public MemoryDebugView(ReadOnlyMemory<T> memory)
		{
			_memory = memory;
		}
	}
	public static class MemoryExtensions
	{
		internal static readonly IntPtr StringAdjustment = MeasureStringAdjustment();

		public static ReadOnlySpan<char> Trim(this ReadOnlySpan<char> span)
		{
			return span.TrimStart().TrimEnd();
		}

		public static ReadOnlySpan<char> TrimStart(this ReadOnlySpan<char> span)
		{
			int i;
			for (i = 0; i < span.Length && char.IsWhiteSpace(span[i]); i++)
			{
			}
			return span.Slice(i);
		}

		public static ReadOnlySpan<char> TrimEnd(this ReadOnlySpan<char> span)
		{
			int num = span.Length - 1;
			while (num >= 0 && char.IsWhiteSpace(span[num]))
			{
				num--;
			}
			return span.Slice(0, num + 1);
		}

		public static ReadOnlySpan<char> Trim(this ReadOnlySpan<char> span, char trimChar)
		{
			return span.TrimStart(trimChar).TrimEnd(trimChar);
		}

		public static ReadOnlySpan<char> TrimStart(this ReadOnlySpan<char> span, char trimChar)
		{
			int i;
			for (i = 0; i < span.Length && span[i] == trimChar; i++)
			{
			}
			return span.Slice(i);
		}

		public static ReadOnlySpan<char> TrimEnd(this ReadOnlySpan<char> span, char trimChar)
		{
			int num = span.Length - 1;
			while (num >= 0 && span[num] == trimChar)
			{
				num--;
			}
			return span.Slice(0, num + 1);
		}

		public static ReadOnlySpan<char> Trim(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars)
		{
			return span.TrimStart(trimChars).TrimEnd(trimChars);
		}

		public static ReadOnlySpan<char> TrimStart(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars)
		{
			if (trimChars.IsEmpty)
			{
				return span.TrimStart();
			}
			int i;
			for (i = 0; i < span.Length; i++)
			{
				int num = 0;
				while (num < trimChars.Length)
				{
					if (span[i] != trimChars[num])
					{
						num++;
						continue;
					}
					goto IL_003c;
				}
				break;
				IL_003c:;
			}
			return span.Slice(i);
		}

		public static ReadOnlySpan<char> TrimEnd(this ReadOnlySpan<char> span, ReadOnlySpan<char> trimChars)
		{
			if (trimChars.IsEmpty)
			{
				return span.TrimEnd();
			}
			int num;
			for (num = span.Length - 1; num >= 0; num--)
			{
				int num2 = 0;
				while (num2 < trimChars.Length)
				{
					if (span[num] != trimChars[num2])
					{
						num2++;
						continue;
					}
					goto IL_0044;
				}
				break;
				IL_0044:;
			}
			return span.Slice(0, num + 1);
		}

		public static bool IsWhiteSpace(this ReadOnlySpan<char> span)
		{
			for (int i = 0; i < span.Length; i++)
			{
				if (!char.IsWhiteSpace(span[i]))
				{
					return false;
				}
			}
			return true;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this Span<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.IndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this Span<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.LastIndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool SequenceEqual<T>(this Span<T> span, ReadOnlySpan<T> other) where T : IEquatable<T>
		{
			int length = span.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length == other.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), (NUInt)length * size);
				}
				return false;
			}
			if (length == other.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other), length);
			}
			return false;
		}

		public static int SequenceCompareTo<T>(this Span<T> span, ReadOnlySpan<T> other) where T : IComparable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.SequenceCompareTo(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.SequenceCompareTo(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			return System.SpanHelpers.SequenceCompareTo(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(other), other.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this ReadOnlySpan<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.IndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOf<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.IndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this ReadOnlySpan<T> span, T value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value), span.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.LastIndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, char>(ref value), span.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), value, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOf<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOf(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), value.Length);
			}
			return System.SpanHelpers.LastIndexOf(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(value), value.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this Span<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this Span<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this Span<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int IndexOfAny<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.IndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.IndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this Span<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this Span<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this Span<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, T value0, T value1, T value2) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value0), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value1), System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value2), span.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), value0, value1, value2, span.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int LastIndexOfAny<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> values) where T : IEquatable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.LastIndexOfAny(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)), values.Length);
			}
			return System.SpanHelpers.LastIndexOfAny(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(values), values.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool SequenceEqual<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other) where T : IEquatable<T>
		{
			int length = span.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length == other.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), (NUInt)length * size);
				}
				return false;
			}
			if (length == other.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other), length);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int SequenceCompareTo<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other) where T : IComparable<T>
		{
			if (typeof(T) == typeof(byte))
			{
				return System.SpanHelpers.SequenceCompareTo(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			if (typeof(T) == typeof(char))
			{
				return System.SpanHelpers.SequenceCompareTo(ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(span)), span.Length, ref System.Runtime.CompilerServices.Unsafe.As<T, char>(ref MemoryMarshal.GetReference(other)), other.Length);
			}
			return System.SpanHelpers.SequenceCompareTo(ref MemoryMarshal.GetReference(span), span.Length, ref MemoryMarshal.GetReference(other), other.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool StartsWith<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length <= span.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length * size);
				}
				return false;
			}
			if (length <= span.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(value), length);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool StartsWith<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length <= span.Length)
				{
					return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(span)), ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length * size);
				}
				return false;
			}
			if (length <= span.Length)
			{
				return System.SpanHelpers.SequenceEqual(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(value), length);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool EndsWith<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = span.Length;
			int length2 = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length2 <= length)
				{
					return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref MemoryMarshal.GetReference(span), length - length2)), ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length2 * size);
				}
				return false;
			}
			if (length2 <= length)
			{
				return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref MemoryMarshal.GetReference(span), length - length2), ref MemoryMarshal.GetReference(value), length2);
			}
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool EndsWith<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T>
		{
			int length = span.Length;
			int length2 = value.Length;
			if (default(T) != null && IsTypeComparableAsBytes<T>(out var size))
			{
				if (length2 <= length)
				{
					return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref MemoryMarshal.GetReference(span), length - length2)), ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(value)), (NUInt)length2 * size);
				}
				return false;
			}
			if (length2 <= length)
			{
				return System.SpanHelpers.SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref MemoryMarshal.GetReference(span), length - length2), ref MemoryMarshal.GetReference(value), length2);
			}
			return false;
		}

		public static void Reverse<T>(this Span<T> span)
		{
			ref T reference = ref MemoryMarshal.GetReference(span);
			int num = 0;
			int num2 = span.Length - 1;
			while (num < num2)
			{
				T val = System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, num);
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, num) = System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, num2);
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, num2) = val;
				num++;
				num2--;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this T[] array)
		{
			return new Span<T>(array);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this T[] array, int start, int length)
		{
			return new Span<T>(array, start, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this ArraySegment<T> segment)
		{
			return new Span<T>(segment.Array, segment.Offset, segment.Count);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this ArraySegment<T> segment, int start)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new Span<T>(segment.Array, segment.Offset + start, segment.Count - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Span<T> AsSpan<T>(this ArraySegment<T> segment, int start, int length)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			if ((uint)length > segment.Count - start)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length);
			}
			return new Span<T>(segment.Array, segment.Offset + start, length);
		}

		public static Memory<T> AsMemory<T>(this T[] array)
		{
			return new Memory<T>(array);
		}

		public static Memory<T> AsMemory<T>(this T[] array, int start)
		{
			return new Memory<T>(array, start);
		}

		public static Memory<T> AsMemory<T>(this T[] array, int start, int length)
		{
			return new Memory<T>(array, start, length);
		}

		public static Memory<T> AsMemory<T>(this ArraySegment<T> segment)
		{
			return new Memory<T>(segment.Array, segment.Offset, segment.Count);
		}

		public static Memory<T> AsMemory<T>(this ArraySegment<T> segment, int start)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new Memory<T>(segment.Array, segment.Offset + start, segment.Count - start);
		}

		public static Memory<T> AsMemory<T>(this ArraySegment<T> segment, int start, int length)
		{
			if ((uint)start > segment.Count)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			if ((uint)length > segment.Count - start)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length);
			}
			return new Memory<T>(segment.Array, segment.Offset + start, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void CopyTo<T>(this T[] source, Span<T> destination)
		{
			new ReadOnlySpan<T>(source).CopyTo(destination);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static void CopyTo<T>(this T[] source, Memory<T> destination)
		{
			source.CopyTo(destination.Span);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Overlaps<T>(this Span<T> span, ReadOnlySpan<T> other)
		{
			return ((ReadOnlySpan<T>)span).Overlaps(other);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool Overlaps<T>(this Span<T> span, ReadOnlySpan<T> other, out int elementOffset)
		{
			return ((ReadOnlySpan<T>)span).Overlaps(other, out elementOffset);
		}

		public static bool Overlaps<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other)
		{
			if (span.IsEmpty || other.IsEmpty)
			{
				return false;
			}
			IntPtr intPtr = System.Runtime.CompilerServices.Unsafe.ByteOffset<T>(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other));
			if (System.Runtime.CompilerServices.Unsafe.SizeOf<IntPtr>() == 4)
			{
				if ((uint)(int)intPtr >= (uint)(span.Length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>()))
				{
					return (uint)(int)intPtr > (uint)(-(other.Length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>()));
				}
				return true;
			}
			if ((ulong)(long)intPtr >= (ulong)((long)span.Length * (long)System.Runtime.CompilerServices.Unsafe.SizeOf<T>()))
			{
				return (ulong)(long)intPtr > (ulong)(-((long)other.Length * (long)System.Runtime.CompilerServices.Unsafe.SizeOf<T>()));
			}
			return true;
		}

		public static bool Overlaps<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> other, out int elementOffset)
		{
			if (span.IsEmpty || other.IsEmpty)
			{
				elementOffset = 0;
				return false;
			}
			IntPtr intPtr = System.Runtime.CompilerServices.Unsafe.ByteOffset<T>(ref MemoryMarshal.GetReference(span), ref MemoryMarshal.GetReference(other));
			if (System.Runtime.CompilerServices.Unsafe.SizeOf<IntPtr>() == 4)
			{
				if ((uint)(int)intPtr < (uint)(span.Length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>()) || (uint)(int)intPtr > (uint)(-(other.Length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>())))
				{
					if ((int)intPtr % System.Runtime.CompilerServices.Unsafe.SizeOf<T>() != 0)
					{
						System.ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch();
					}
					elementOffset = (int)intPtr / System.Runtime.CompilerServices.Unsafe.SizeOf<T>();
					return true;
				}
				elementOffset = 0;
				return false;
			}
			if ((ulong)(long)intPtr < (ulong)((long)span.Length * (long)System.Runtime.CompilerServices.Unsafe.SizeOf<T>()) || (ulong)(long)intPtr > (ulong)(-((long)other.Length * (long)System.Runtime.CompilerServices.Unsafe.SizeOf<T>())))
			{
				if ((long)intPtr % System.Runtime.CompilerServices.Unsafe.SizeOf<T>() != 0L)
				{
					System.ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch();
				}
				elementOffset = (int)((long)intPtr / System.Runtime.CompilerServices.Unsafe.SizeOf<T>());
				return true;
			}
			elementOffset = 0;
			return false;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T>(this Span<T> span, IComparable<T> comparable)
		{
			return span.BinarySearch<T, IComparable<T>>(comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparable>(this Span<T> span, TComparable comparable) where TComparable : IComparable<T>
		{
			return BinarySearch((ReadOnlySpan<T>)span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparer>(this Span<T> span, T value, TComparer comparer) where TComparer : IComparer<T>
		{
			return ((ReadOnlySpan<T>)span).BinarySearch(value, comparer);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T>(this ReadOnlySpan<T> span, IComparable<T> comparable)
		{
			return MemoryExtensions.BinarySearch<T, IComparable<T>>(span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparable>(this ReadOnlySpan<T> span, TComparable comparable) where TComparable : IComparable<T>
		{
			return System.SpanHelpers.BinarySearch(span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparer>(this ReadOnlySpan<T> span, T value, TComparer comparer) where TComparer : IComparer<T>
		{
			if (comparer == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.comparer);
			}
			System.SpanHelpers.ComparerComparable<T, TComparer> comparable = new System.SpanHelpers.ComparerComparable<T, TComparer>(value, comparer);
			return BinarySearch(span, comparable);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static bool IsTypeComparableAsBytes<T>(out NUInt size)
		{
			if (typeof(T) == typeof(byte) || typeof(T) == typeof(sbyte))
			{
				size = (NUInt)1;
				return true;
			}
			if (typeof(T) == typeof(char) || typeof(T) == typeof(short) || typeof(T) == typeof(ushort))
			{
				size = (NUInt)2;
				return true;
			}
			if (typeof(T) == typeof(int) || typeof(T) == typeof(uint))
			{
				size = (NUInt)4;
				return true;
			}
			if (typeof(T) == typeof(long) || typeof(T) == typeof(ulong))
			{
				size = (NUInt)8;
				return true;
			}
			size = default(NUInt);
			return false;
		}

		public static Span<T> AsSpan<T>(this T[] array, int start)
		{
			return Span<T>.Create(array, start);
		}

		public static bool Contains(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			return span.IndexOf(value, comparisonType) >= 0;
		}

		public static bool Equals(this ReadOnlySpan<char> span, ReadOnlySpan<char> other, StringComparison comparisonType)
		{
			switch (comparisonType)
			{
			case StringComparison.Ordinal:
				return span.SequenceEqual(other);
			case StringComparison.OrdinalIgnoreCase:
				if (span.Length != other.Length)
				{
					return false;
				}
				return EqualsOrdinalIgnoreCase(span, other);
			default:
				return span.ToString().Equals(other.ToString(), comparisonType);
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private static bool EqualsOrdinalIgnoreCase(ReadOnlySpan<char> span, ReadOnlySpan<char> other)
		{
			if (other.Length == 0)
			{
				return true;
			}
			return CompareToOrdinalIgnoreCase(span, other) == 0;
		}

		public static int CompareTo(this ReadOnlySpan<char> span, ReadOnlySpan<char> other, StringComparison comparisonType)
		{
			return comparisonType switch
			{
				StringComparison.Ordinal => span.SequenceCompareTo(other), 
				StringComparison.OrdinalIgnoreCase => CompareToOrdinalIgnoreCase(span, other), 
				_ => string.Compare(span.ToString(), other.ToString(), comparisonType), 
			};
		}

		private unsafe static int CompareToOrdinalIgnoreCase(ReadOnlySpan<char> strA, ReadOnlySpan<char> strB)
		{
			int num = Math.Min(strA.Length, strB.Length);
			int num2 = num;
			fixed (char* ptr = &MemoryMarshal.GetReference(strA))
			{
				fixed (char* ptr3 = &MemoryMarshal.GetReference(strB))
				{
					char* ptr2 = ptr;
					char* ptr4 = ptr3;
					while (num != 0 && *ptr2 <= '\u007f' && *ptr4 <= '\u007f')
					{
						int num3 = *ptr2;
						int num4 = *ptr4;
						if (num3 == num4)
						{
							ptr2++;
							ptr4++;
							num--;
							continue;
						}
						if ((uint)(num3 - 97) <= 25u)
						{
							num3 -= 32;
						}
						if ((uint)(num4 - 97) <= 25u)
						{
							num4 -= 32;
						}
						if (num3 != num4)
						{
							return num3 - num4;
						}
						ptr2++;
						ptr4++;
						num--;
					}
					if (num == 0)
					{
						return strA.Length - strB.Length;
					}
					num2 -= num;
					return string.Compare(strA.Slice(num2).ToString(), strB.Slice(num2).ToString(), StringComparison.OrdinalIgnoreCase);
				}
			}
		}

		public static int IndexOf(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			if (comparisonType == StringComparison.Ordinal)
			{
				return span.IndexOf(value);
			}
			return span.ToString().IndexOf(value.ToString(), comparisonType);
		}

		public static int ToLower(this ReadOnlySpan<char> source, Span<char> destination, CultureInfo culture)
		{
			if (culture == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.culture);
			}
			if (destination.Length < source.Length)
			{
				return -1;
			}
			string text = source.ToString();
			string text2 = text.ToLower(culture);
			AsSpan(text2).CopyTo(destination);
			return source.Length;
		}

		public static int ToLowerInvariant(this ReadOnlySpan<char> source, Span<char> destination)
		{
			return source.ToLower(destination, CultureInfo.InvariantCulture);
		}

		public static int ToUpper(this ReadOnlySpan<char> source, Span<char> destination, CultureInfo culture)
		{
			if (culture == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.culture);
			}
			if (destination.Length < source.Length)
			{
				return -1;
			}
			string text = source.ToString();
			string text2 = text.ToUpper(culture);
			AsSpan(text2).CopyTo(destination);
			return source.Length;
		}

		public static int ToUpperInvariant(this ReadOnlySpan<char> source, Span<char> destination)
		{
			return source.ToUpper(destination, CultureInfo.InvariantCulture);
		}

		public static bool EndsWith(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			switch (comparisonType)
			{
			case StringComparison.Ordinal:
				return span.EndsWith(value);
			case StringComparison.OrdinalIgnoreCase:
				if (value.Length <= span.Length)
				{
					return EqualsOrdinalIgnoreCase(span.Slice(span.Length - value.Length), value);
				}
				return false;
			default:
			{
				string text = span.ToString();
				string value2 = value.ToString();
				return text.EndsWith(value2, comparisonType);
			}
			}
		}

		public static bool StartsWith(this ReadOnlySpan<char> span, ReadOnlySpan<char> value, StringComparison comparisonType)
		{
			switch (comparisonType)
			{
			case StringComparison.Ordinal:
				return span.StartsWith(value);
			case StringComparison.OrdinalIgnoreCase:
				if (value.Length <= span.Length)
				{
					return EqualsOrdinalIgnoreCase(span.Slice(0, value.Length), value);
				}
				return false;
			default:
			{
				string text = span.ToString();
				string value2 = value.ToString();
				return text.StartsWith(value2, comparisonType);
			}
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ReadOnlySpan<char> AsSpan(this string text)
		{
			if (text == null)
			{
				return default(ReadOnlySpan<char>);
			}
			return new ReadOnlySpan<char>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<char>>((object)text), StringAdjustment, text.Length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ReadOnlySpan<char> AsSpan(this string text, int start)
		{
			if (text == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlySpan<char>);
			}
			if ((uint)start > (uint)text.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlySpan<char>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<char>>((object)text), StringAdjustment + start * 2, text.Length - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ReadOnlySpan<char> AsSpan(this string text, int start, int length)
		{
			if (text == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlySpan<char>);
			}
			if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlySpan<char>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<char>>((object)text), StringAdjustment + start * 2, length);
		}

		public static ReadOnlyMemory<char> AsMemory(this string text)
		{
			if (text == null)
			{
				return default(ReadOnlyMemory<char>);
			}
			return new ReadOnlyMemory<char>(text, 0, text.Length);
		}

		public static ReadOnlyMemory<char> AsMemory(this string text, int start)
		{
			if (text == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlyMemory<char>);
			}
			if ((uint)start > (uint)text.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<char>(text, start, text.Length - start);
		}

		public static ReadOnlyMemory<char> AsMemory(this string text, int start, int length)
		{
			if (text == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(ReadOnlyMemory<char>);
			}
			if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<char>(text, start, length);
		}

		private unsafe static IntPtr MeasureStringAdjustment()
		{
			string text = "a";
			fixed (char* ptr = text)
			{
				return System.Runtime.CompilerServices.Unsafe.ByteOffset<char>(ref System.Runtime.CompilerServices.Unsafe.As<Pinnable<char>>((object)text).Data, ref System.Runtime.CompilerServices.Unsafe.AsRef<char>((void*)ptr));
			}
		}
	}
	[DebuggerTypeProxy(typeof(System.MemoryDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly struct ReadOnlyMemory<T>
	{
		private readonly object _object;

		private readonly int _index;

		private readonly int _length;

		internal const int RemoveFlagsBitMask = int.MaxValue;

		public static ReadOnlyMemory<T> Empty => default(ReadOnlyMemory<T>);

		public int Length => _length & 0x7FFFFFFF;

		public bool IsEmpty => (_length & 0x7FFFFFFF) == 0;

		public ReadOnlySpan<T> Span
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				if (_index < 0)
				{
					return ((MemoryManager<T>)_object).GetSpan().Slice(_index & 0x7FFFFFFF, _length);
				}
				ReadOnlySpan<T> result;
				if (typeof(T) == typeof(char) && _object is string text)
				{
					result = new ReadOnlySpan<T>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)text), MemoryExtensions.StringAdjustment, text.Length);
					return result.Slice(_index, _length);
				}
				if (_object != null)
				{
					return new ReadOnlySpan<T>((T[])_object, _index, _length & 0x7FFFFFFF);
				}
				result = default(ReadOnlySpan<T>);
				return result;
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory(T[] array)
		{
			if (array == null)
			{
				this = default(ReadOnlyMemory<T>);
				return;
			}
			_object = array;
			_index = 0;
			_length = array.Length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException();
				}
				this = default(ReadOnlyMemory<T>);
				return;
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException();
			}
			_object = array;
			_index = start;
			_length = length;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal ReadOnlyMemory(object obj, int start, int length)
		{
			_object = obj;
			_index = start;
			_length = length;
		}

		public static implicit operator ReadOnlyMemory<T>(T[] array)
		{
			return new ReadOnlyMemory<T>(array);
		}

		public static implicit operator ReadOnlyMemory<T>(ArraySegment<T> segment)
		{
			return new ReadOnlyMemory<T>(segment.Array, segment.Offset, segment.Count);
		}

		public override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				if (!(_object is string text))
				{
					return Span.ToString();
				}
				return text.Substring(_index, _length & 0x7FFFFFFF);
			}
			return $"System.ReadOnlyMemory<{typeof(T).Name}>[{_length & 0x7FFFFFFF}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory<T> Slice(int start)
		{
			int length = _length;
			int num = length & 0x7FFFFFFF;
			if ((uint)start > (uint)num)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<T>(_object, _index + start, length - start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlyMemory<T> Slice(int start, int length)
		{
			int length2 = _length;
			int num = _length & 0x7FFFFFFF;
			if ((uint)start > (uint)num || (uint)length > (uint)(num - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			return new ReadOnlyMemory<T>(_object, _index + start, length | (length2 & int.MinValue));
		}

		public void CopyTo(Memory<T> destination)
		{
			Span.CopyTo(destination.Span);
		}

		public bool TryCopyTo(Memory<T> destination)
		{
			return Span.TryCopyTo(destination.Span);
		}

		public unsafe MemoryHandle Pin()
		{
			if (_index < 0)
			{
				return ((MemoryManager<T>)_object).Pin(_index & 0x7FFFFFFF);
			}
			if (typeof(T) == typeof(char) && _object is string value)
			{
				GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned);
				void* pointer = System.Runtime.CompilerServices.Unsafe.Add<T>((void*)handle.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer, handle);
			}
			if (_object is T[] array)
			{
				if (_length < 0)
				{
					void* pointer2 = System.Runtime.CompilerServices.Unsafe.Add<T>(System.Runtime.CompilerServices.Unsafe.AsPointer<T>(ref MemoryMarshal.GetReference<T>(array)), _index);
					return new MemoryHandle(pointer2);
				}
				GCHandle handle2 = GCHandle.Alloc(array, GCHandleType.Pinned);
				void* pointer3 = System.Runtime.CompilerServices.Unsafe.Add<T>((void*)handle2.AddrOfPinnedObject(), _index);
				return new MemoryHandle(pointer3, handle2);
			}
			return default(MemoryHandle);
		}

		public T[] ToArray()
		{
			return Span.ToArray();
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			if (obj is ReadOnlyMemory<T> other)
			{
				return Equals(other);
			}
			if (obj is Memory<T> memory)
			{
				return Equals(memory);
			}
			return false;
		}

		public bool Equals(ReadOnlyMemory<T> other)
		{
			if (_object == other._object && _index == other._index)
			{
				return _length == other._length;
			}
			return false;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			if (_object == null)
			{
				return 0;
			}
			int hashCode = _object.GetHashCode();
			int index = _index;
			int hashCode2 = index.GetHashCode();
			index = _length;
			return CombineHashCodes(hashCode, hashCode2, index.GetHashCode());
		}

		private static int CombineHashCodes(int left, int right)
		{
			return ((left << 5) + left) ^ right;
		}

		private static int CombineHashCodes(int h1, int h2, int h3)
		{
			return CombineHashCodes(CombineHashCodes(h1, h2), h3);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal object GetObjectStartLength(out int start, out int length)
		{
			start = _index;
			length = _length;
			return _object;
		}
	}
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly ref struct ReadOnlySpan<T>
	{
		public ref struct Enumerator
		{
			private readonly ReadOnlySpan<T> _span;

			private int _index;

			public ref readonly T Current
			{
				[MethodImpl(MethodImplOptions.AggressiveInlining)]
				get
				{
					return ref _span[_index];
				}
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			internal Enumerator(ReadOnlySpan<T> span)
			{
				_span = span;
				_index = -1;
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public bool MoveNext()
			{
				int num = _index + 1;
				if (num < _span.Length)
				{
					_index = num;
					return true;
				}
				return false;
			}
		}

		private readonly Pinnable<T> _pinnable;

		private readonly IntPtr _byteOffset;

		private readonly int _length;

		public int Length => _length;

		public bool IsEmpty => _length == 0;

		public static ReadOnlySpan<T> Empty => default(ReadOnlySpan<T>);

		public unsafe ref readonly T this[int index]
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				if ((uint)index >= (uint)_length)
				{
					System.ThrowHelper.ThrowIndexOutOfRangeException();
				}
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer()), index);
				}
				return ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset), index);
			}
		}

		internal Pinnable<T> Pinnable => _pinnable;

		internal IntPtr ByteOffset => _byteOffset;

		public static bool operator !=(ReadOnlySpan<T> left, ReadOnlySpan<T> right)
		{
			return !(left == right);
		}

		[Obsolete("Equals() on ReadOnlySpan will always throw an exception. Use == instead.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallEqualsOnSpan);
		}

		[Obsolete("GetHashCode() on ReadOnlySpan will always throw an exception.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallGetHashCodeOnSpan);
		}

		public static implicit operator ReadOnlySpan<T>(T[] array)
		{
			return new ReadOnlySpan<T>(array);
		}

		public static implicit operator ReadOnlySpan<T>(ArraySegment<T> segment)
		{
			return new ReadOnlySpan<T>(segment.Array, segment.Offset, segment.Count);
		}

		public Enumerator GetEnumerator()
		{
			return new Enumerator(this);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan(T[] array)
		{
			if (array == null)
			{
				this = default(ReadOnlySpan<T>);
				return;
			}
			_length = array.Length;
			_pinnable = System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				this = default(ReadOnlySpan<T>);
				return;
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[CLSCompliant(false)]
		public unsafe ReadOnlySpan(void* pointer, int length)
		{
			if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
			{
				System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
			}
			if (length < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = null;
			_byteOffset = new IntPtr(pointer);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal ReadOnlySpan(Pinnable<T> pinnable, IntPtr byteOffset, int length)
		{
			_length = length;
			_pinnable = pinnable;
			_byteOffset = byteOffset;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public unsafe ref readonly T GetPinnableReference()
		{
			if (_length != 0)
			{
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer());
				}
				return ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset);
			}
			return ref System.Runtime.CompilerServices.Unsafe.AsRef<T>((void*)null);
		}

		public void CopyTo(Span<T> destination)
		{
			if (!TryCopyTo(destination))
			{
				System.ThrowHelper.ThrowArgumentException_DestinationTooShort();
			}
		}

		public bool TryCopyTo(Span<T> destination)
		{
			int length = _length;
			int length2 = destination.Length;
			if (length == 0)
			{
				return true;
			}
			if ((uint)length > (uint)length2)
			{
				return false;
			}
			ref T src = ref DangerousGetPinnableReference();
			System.SpanHelpers.CopyTo(ref destination.DangerousGetPinnableReference(), length2, ref src, length);
			return true;
		}

		public static bool operator ==(ReadOnlySpan<T> left, ReadOnlySpan<T> right)
		{
			if (left._length == right._length)
			{
				return System.Runtime.CompilerServices.Unsafe.AreSame<T>(ref left.DangerousGetPinnableReference(), ref right.DangerousGetPinnableReference());
			}
			return false;
		}

		public unsafe override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				if (_byteOffset == MemoryExtensions.StringAdjustment)
				{
					object obj = System.Runtime.CompilerServices.Unsafe.As<object>((object)_pinnable);
					if (obj is string text && _length == text.Length)
					{
						return text;
					}
				}
				fixed (char* value = &System.Runtime.CompilerServices.Unsafe.As<T, char>(ref DangerousGetPinnableReference()))
				{
					return new string(value, 0, _length);
				}
			}
			return $"System.ReadOnlySpan<{typeof(T).Name}>[{_length}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan<T> Slice(int start)
		{
			if ((uint)start > (uint)_length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			int length = _length - start;
			return new ReadOnlySpan<T>(_pinnable, byteOffset, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public ReadOnlySpan<T> Slice(int start, int length)
		{
			if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			return new ReadOnlySpan<T>(_pinnable, byteOffset, length);
		}

		public T[] ToArray()
		{
			if (_length == 0)
			{
				return System.SpanHelpers.PerTypeValues<T>.EmptyArray;
			}
			T[] array = new T[_length];
			CopyTo(array);
			return array;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[EditorBrowsable(EditorBrowsableState.Never)]
		internal unsafe ref T DangerousGetPinnableReference()
		{
			if (_pinnable == null)
			{
				IntPtr byteOffset = _byteOffset;
				return ref System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer());
			}
			return ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset);
		}
	}
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	[DebuggerTypeProxy(typeof(System.SpanDebugView<>))]
	[DebuggerDisplay("{ToString(),raw}")]
	public readonly ref struct Span<T>
	{
		public ref struct Enumerator
		{
			private readonly Span<T> _span;

			private int _index;

			public ref T Current
			{
				[MethodImpl(MethodImplOptions.AggressiveInlining)]
				get
				{
					return ref _span[_index];
				}
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			internal Enumerator(Span<T> span)
			{
				_span = span;
				_index = -1;
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public bool MoveNext()
			{
				int num = _index + 1;
				if (num < _span.Length)
				{
					_index = num;
					return true;
				}
				return false;
			}
		}

		private readonly Pinnable<T> _pinnable;

		private readonly IntPtr _byteOffset;

		private readonly int _length;

		public int Length => _length;

		public bool IsEmpty => _length == 0;

		public static Span<T> Empty => default(Span<T>);

		public unsafe ref T this[int index]
		{
			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			get
			{
				if ((uint)index >= (uint)_length)
				{
					System.ThrowHelper.ThrowIndexOutOfRangeException();
				}
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer()), index);
				}
				return ref System.Runtime.CompilerServices.Unsafe.Add<T>(ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset), index);
			}
		}

		internal Pinnable<T> Pinnable => _pinnable;

		internal IntPtr ByteOffset => _byteOffset;

		public static bool operator !=(Span<T> left, Span<T> right)
		{
			return !(left == right);
		}

		[Obsolete("Equals() on Span will always throw an exception. Use == instead.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override bool Equals(object obj)
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallEqualsOnSpan);
		}

		[Obsolete("GetHashCode() on Span will always throw an exception.")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public override int GetHashCode()
		{
			throw new NotSupportedException(System.SR.NotSupported_CannotCallGetHashCodeOnSpan);
		}

		public static implicit operator Span<T>(T[] array)
		{
			return new Span<T>(array);
		}

		public static implicit operator Span<T>(ArraySegment<T> segment)
		{
			return new Span<T>(segment.Array, segment.Offset, segment.Count);
		}

		public Enumerator GetEnumerator()
		{
			return new Enumerator(this);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span(T[] array)
		{
			if (array == null)
			{
				this = default(Span<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			_length = array.Length;
			_pinnable = System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static Span<T> Create(T[] array, int start)
		{
			if (array == null)
			{
				if (start != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				return default(Span<T>);
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start);
			int length = array.Length - start;
			return new Span<T>(System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)array), byteOffset, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span(T[] array, int start, int length)
		{
			if (array == null)
			{
				if (start != 0 || length != 0)
				{
					System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
				}
				this = default(Span<T>);
				return;
			}
			if (default(T) == null && array.GetType() != typeof(T[]))
			{
				System.ThrowHelper.ThrowArrayTypeMismatchException();
			}
			if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)array);
			_byteOffset = System.SpanHelpers.PerTypeValues<T>.ArrayAdjustment.Add<T>(start);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[CLSCompliant(false)]
		public unsafe Span(void* pointer, int length)
		{
			if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
			{
				System.ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
			}
			if (length < 0)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			_length = length;
			_pinnable = null;
			_byteOffset = new IntPtr(pointer);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal Span(Pinnable<T> pinnable, IntPtr byteOffset, int length)
		{
			_length = length;
			_pinnable = pinnable;
			_byteOffset = byteOffset;
		}

		[EditorBrowsable(EditorBrowsableState.Never)]
		public unsafe ref T GetPinnableReference()
		{
			if (_length != 0)
			{
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					return ref System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer());
				}
				return ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset);
			}
			return ref System.Runtime.CompilerServices.Unsafe.AsRef<T>((void*)null);
		}

		public unsafe void Clear()
		{
			int length = _length;
			if (length == 0)
			{
				return;
			}
			UIntPtr byteLength = (UIntPtr)(ulong)((uint)length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>());
			if ((System.Runtime.CompilerServices.Unsafe.SizeOf<T>() & (sizeof(IntPtr) - 1)) != 0)
			{
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					byte* ptr = (byte*)byteOffset.ToPointer();
					System.SpanHelpers.ClearLessThanPointerSized(ptr, byteLength);
				}
				else
				{
					System.SpanHelpers.ClearLessThanPointerSized(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset)), byteLength);
				}
			}
			else if (System.SpanHelpers.IsReferenceOrContainsReferences<T>())
			{
				UIntPtr pointerSizeLength = (UIntPtr)(ulong)(length * System.Runtime.CompilerServices.Unsafe.SizeOf<T>() / sizeof(IntPtr));
				System.SpanHelpers.ClearPointerSizedWithReferences(ref System.Runtime.CompilerServices.Unsafe.As<T, IntPtr>(ref DangerousGetPinnableReference()), pointerSizeLength);
			}
			else
			{
				System.SpanHelpers.ClearPointerSizedWithoutReferences(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref DangerousGetPinnableReference()), byteLength);
			}
		}

		public unsafe void Fill(T value)
		{
			int length = _length;
			if (length == 0)
			{
				return;
			}
			if (System.Runtime.CompilerServices.Unsafe.SizeOf<T>() == 1)
			{
				byte b = System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref value);
				if (_pinnable == null)
				{
					IntPtr byteOffset = _byteOffset;
					System.Runtime.CompilerServices.Unsafe.InitBlockUnaligned(byteOffset.ToPointer(), b, (uint)length);
				}
				else
				{
					System.Runtime.CompilerServices.Unsafe.InitBlockUnaligned(ref System.Runtime.CompilerServices.Unsafe.As<T, byte>(ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset)), b, (uint)length);
				}
				return;
			}
			ref T reference = ref DangerousGetPinnableReference();
			int i;
			for (i = 0; i < (length & -8); i += 8)
			{
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 1) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 2) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 3) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 4) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 5) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 6) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 7) = value;
			}
			if (i < (length & -4))
			{
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 1) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 2) = value;
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i + 3) = value;
				i += 4;
			}
			for (; i < length; i++)
			{
				System.Runtime.CompilerServices.Unsafe.Add<T>(ref reference, i) = value;
			}
		}

		public void CopyTo(Span<T> destination)
		{
			if (!TryCopyTo(destination))
			{
				System.ThrowHelper.ThrowArgumentException_DestinationTooShort();
			}
		}

		public bool TryCopyTo(Span<T> destination)
		{
			int length = _length;
			int length2 = destination._length;
			if (length == 0)
			{
				return true;
			}
			if ((uint)length > (uint)length2)
			{
				return false;
			}
			ref T src = ref DangerousGetPinnableReference();
			System.SpanHelpers.CopyTo(ref destination.DangerousGetPinnableReference(), length2, ref src, length);
			return true;
		}

		public static bool operator ==(Span<T> left, Span<T> right)
		{
			if (left._length == right._length)
			{
				return System.Runtime.CompilerServices.Unsafe.AreSame<T>(ref left.DangerousGetPinnableReference(), ref right.DangerousGetPinnableReference());
			}
			return false;
		}

		public static implicit operator ReadOnlySpan<T>(Span<T> span)
		{
			return new ReadOnlySpan<T>(span._pinnable, span._byteOffset, span._length);
		}

		public unsafe override string ToString()
		{
			if (typeof(T) == typeof(char))
			{
				fixed (char* value = &System.Runtime.CompilerServices.Unsafe.As<T, char>(ref DangerousGetPinnableReference()))
				{
					return new string(value, 0, _length);
				}
			}
			return $"System.Span<{typeof(T).Name}>[{_length}]";
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span<T> Slice(int start)
		{
			if ((uint)start > (uint)_length)
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			int length = _length - start;
			return new Span<T>(_pinnable, byteOffset, length);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public Span<T> Slice(int start, int length)
		{
			if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start))
			{
				System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.start);
			}
			IntPtr byteOffset = _byteOffset.Add<T>(start);
			return new Span<T>(_pinnable, byteOffset, length);
		}

		public T[] ToArray()
		{
			if (_length == 0)
			{
				return System.SpanHelpers.PerTypeValues<T>.EmptyArray;
			}
			T[] array = new T[_length];
			CopyTo(array);
			return array;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[EditorBrowsable(EditorBrowsableState.Never)]
		internal unsafe ref T DangerousGetPinnableReference()
		{
			if (_pinnable == null)
			{
				IntPtr byteOffset = _byteOffset;
				return ref System.Runtime.CompilerServices.Unsafe.AsRef<T>(byteOffset.ToPointer());
			}
			return ref System.Runtime.CompilerServices.Unsafe.AddByteOffset<T>(ref _pinnable.Data, _byteOffset);
		}
	}
	internal sealed class SpanDebugView<T>
	{
		private readonly T[] _array;

		[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
		public T[] Items => _array;

		public SpanDebugView(Span<T> span)
		{
			_array = span.ToArray();
		}

		public SpanDebugView(ReadOnlySpan<T> span)
		{
			_array = span.ToArray();
		}
	}
	internal static class SpanHelpers
	{
		internal struct ComparerComparable<T, TComparer> : IComparable<T> where TComparer : IComparer<T>
		{
			private readonly T _value;

			private readonly TComparer _comparer;

			public ComparerComparable(T value, TComparer comparer)
			{
				_value = value;
				_comparer = comparer;
			}

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public int CompareTo(T other)
			{
				return _comparer.Compare(_value, other);
			}
		}

		[StructLayout(LayoutKind.Sequential, Size = 64)]
		private struct Reg64
		{
		}

		[StructLayout(LayoutKind.Sequential, Size = 32)]
		private struct Reg32
		{
		}

		[StructLayout(LayoutKind.Sequential, Size = 16)]
		private struct Reg16
		{
		}

		public static class PerTypeValues<T>
		{
			public static readonly bool IsReferenceOrContainsReferences = IsReferenceOrContainsReferencesCore(typeof(T));

			public static readonly T[] EmptyArray = new T[0];

			public static readonly IntPtr ArrayAdjustment = MeasureArrayAdjustment();

			private static IntPtr MeasureArrayAdjustment()
			{
				T[] array = new T[1];
				return System.Runtime.CompilerServices.Unsafe.ByteOffset<T>(ref System.Runtime.CompilerServices.Unsafe.As<Pinnable<T>>((object)array).Data, ref array[0]);
			}
		}

		private const ulong XorPowerOfTwoToHighByte = 283686952306184uL;

		private const ulong XorPowerOfTwoToHighChar = 4295098372uL;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int BinarySearch<T, TComparable>(this ReadOnlySpan<T> span, TComparable comparable) where TComparable : IComparable<T>
		{
			if (comparable == null)
			{
				System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.comparable);
			}
			return BinarySearch(ref MemoryMarshal.GetReference(span), span.Length, comparable);
		}

		public static int BinarySearch<T, TComparable>(ref T spanStart, int length, TComparable comparable) where TComparable : IComparable<T>
		{
			int num = 0;
			int num2 = length - 1;
			while (num <= num2)
			{
				int num3 = num2 + num >>> 1;
				int num4 = comparable.CompareTo(System.Runtime.CompilerServices.Unsafe.Add<T>(ref spanStart, num3));
				if (num4 == 0)
				{
					return num3;
				}
				if (num4 > 0)
				{
					num = num3 + 1;
				}
				else
				{
					num2 = num3 - 1;
				}
			}
			return ~num;
		}

		public static int IndexOf(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength)
		{
			if (valueLength == 0)
			{
				return 0;
			}
			byte value2 = value;
			ref byte second = ref System.Runtime.CompilerServices.Unsafe.Add<byte>(ref value, 1);
			int num = valueLength - 1;
			int num2 = 0;
			while (true)
			{
				int num3 = searchSpaceLength - num2 - num;
				if (num3 <= 0)
				{
					break;
				}
				int num4 = IndexOf(ref System.Runtime.CompilerServices.Unsafe.Add<byte>(ref searchSpace, num2), value2, num3);
				if (num4 == -1)
				{
					break;
				}
				num2 += num4;
				if (SequenceEqual(ref System.Runtime.CompilerServices.Unsafe.Add<byte>(ref searchSpace, num2 + 1), ref second, num))
				{
					return num2;
				}
				num2++;
			}
			return -1;
		}

		public static int IndexOfAny(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength)
		{
			if (valueLength == 0)
			{
				return 0;
			}
			int num = -1;
			for (int i = 0; i < valueLength; i++)
			{
				int num2 = IndexOf(ref searchSpace, System.Runtime.CompilerServices.Unsafe.Add<byte>(ref value, i), searchSpaceLength);
				if ((uint)num2 < (uint)num)
				{
					num = num2;
					searchSpaceLength = num2;
					if (num == 0)
					{
						break;
			

System.Numerics.Vectors.dll

Decompiled 4 hours ago
using System;
using System.Diagnostics;
using System.Globalization;
using System.Numerics;
using System.Numerics.Hashing;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using FxResources.System.Numerics.Vectors;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyTitle("System.Numerics.Vectors")]
[assembly: AssemblyDescription("System.Numerics.Vectors")]
[assembly: AssemblyDefaultAlias("System.Numerics.Vectors")]
[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: AssemblyCopyright("© Microsoft Corporation.  All rights reserved.")]
[assembly: AssemblyFileVersion("4.6.26515.06")]
[assembly: AssemblyInformationalVersion("4.6.26515.06 @BuiltBy: dlab-DDVSOWINAGE059 @Branch: release/2.1 @SrcCode: https://github.com/dotnet/corefx/tree/30ab651fcb4354552bd4891619a0bdd81e0ebdbf")]
[assembly: CLSCompliant(true)]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyMetadata("PreferInbox", "True")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.1.4.0")]
[assembly: TypeForwardedTo(typeof(Matrix3x2))]
[assembly: TypeForwardedTo(typeof(Matrix4x4))]
[assembly: TypeForwardedTo(typeof(Plane))]
[assembly: TypeForwardedTo(typeof(Quaternion))]
[assembly: TypeForwardedTo(typeof(Vector2))]
[assembly: TypeForwardedTo(typeof(Vector3))]
[assembly: TypeForwardedTo(typeof(Vector4))]
[module: UnverifiableCode]
namespace FxResources.System.Numerics.Vectors
{
	internal static class SR
	{
	}
}
namespace System
{
	internal static class MathF
	{
		public const float PI = 3.1415927f;

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Abs(float x)
		{
			return Math.Abs(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Acos(float x)
		{
			return (float)Math.Acos(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Cos(float x)
		{
			return (float)Math.Cos(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float IEEERemainder(float x, float y)
		{
			return (float)Math.IEEERemainder(x, y);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Pow(float x, float y)
		{
			return (float)Math.Pow(x, y);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Sin(float x)
		{
			return (float)Math.Sin(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Sqrt(float x)
		{
			return (float)Math.Sqrt(x);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static float Tan(float x)
		{
			return (float)Math.Tan(x);
		}
	}
	internal static class SR
	{
		private static ResourceManager s_resourceManager;

		private static ResourceManager ResourceManager => s_resourceManager ?? (s_resourceManager = new ResourceManager(ResourceType));

		internal static Type ResourceType { get; } = typeof(SR);


		internal static string Arg_ArgumentOutOfRangeException => GetResourceString("Arg_ArgumentOutOfRangeException", null);

		internal static string Arg_ElementsInSourceIsGreaterThanDestination => GetResourceString("Arg_ElementsInSourceIsGreaterThanDestination", null);

		internal static string Arg_NullArgumentNullRef => GetResourceString("Arg_NullArgumentNullRef", null);

		internal static string Arg_TypeNotSupported => GetResourceString("Arg_TypeNotSupported", null);

		internal static string Arg_InsufficientNumberOfElements => GetResourceString("Arg_InsufficientNumberOfElements", null);

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static bool UsingResourceKeys()
		{
			return false;
		}

		internal static string GetResourceString(string resourceKey, string defaultString)
		{
			string text = null;
			try
			{
				text = ResourceManager.GetString(resourceKey);
			}
			catch (MissingManifestResourceException)
			{
			}
			if (defaultString != null && resourceKey.Equals(text, StringComparison.Ordinal))
			{
				return defaultString;
			}
			return text;
		}

		internal static string Format(string resourceFormat, params object[] args)
		{
			if (args != null)
			{
				if (UsingResourceKeys())
				{
					return resourceFormat + string.Join(", ", args);
				}
				return string.Format(resourceFormat, args);
			}
			return resourceFormat;
		}

		internal static string Format(string resourceFormat, object p1)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1);
			}
			return string.Format(resourceFormat, p1);
		}

		internal static string Format(string resourceFormat, object p1, object p2)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2);
			}
			return string.Format(resourceFormat, p1, p2);
		}

		internal static string Format(string resourceFormat, object p1, object p2, object p3)
		{
			if (UsingResourceKeys())
			{
				return string.Join(", ", resourceFormat, p1, p2, p3);
			}
			return string.Format(resourceFormat, p1, p2, p3);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Field, Inherited = false)]
	internal sealed class IntrinsicAttribute : Attribute
	{
	}
}
namespace System.Numerics
{
	internal class ConstantHelper
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static byte GetByteWithAllBitsSet()
		{
			byte result = 0;
			result = byte.MaxValue;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static sbyte GetSByteWithAllBitsSet()
		{
			sbyte result = 0;
			result = -1;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ushort GetUInt16WithAllBitsSet()
		{
			ushort result = 0;
			result = ushort.MaxValue;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static short GetInt16WithAllBitsSet()
		{
			short result = 0;
			result = -1;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static uint GetUInt32WithAllBitsSet()
		{
			uint result = 0u;
			result = uint.MaxValue;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int GetInt32WithAllBitsSet()
		{
			int result = 0;
			result = -1;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static ulong GetUInt64WithAllBitsSet()
		{
			ulong result = 0uL;
			result = ulong.MaxValue;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static long GetInt64WithAllBitsSet()
		{
			long result = 0L;
			result = -1L;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static float GetSingleWithAllBitsSet()
		{
			float result = 0f;
			*(int*)(&result) = -1;
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public unsafe static double GetDoubleWithAllBitsSet()
		{
			double result = 0.0;
			*(long*)(&result) = -1L;
			return result;
		}
	}
	[StructLayout(LayoutKind.Explicit)]
	internal struct Register
	{
		[FieldOffset(0)]
		internal byte byte_0;

		[FieldOffset(1)]
		internal byte byte_1;

		[FieldOffset(2)]
		internal byte byte_2;

		[FieldOffset(3)]
		internal byte byte_3;

		[FieldOffset(4)]
		internal byte byte_4;

		[FieldOffset(5)]
		internal byte byte_5;

		[FieldOffset(6)]
		internal byte byte_6;

		[FieldOffset(7)]
		internal byte byte_7;

		[FieldOffset(8)]
		internal byte byte_8;

		[FieldOffset(9)]
		internal byte byte_9;

		[FieldOffset(10)]
		internal byte byte_10;

		[FieldOffset(11)]
		internal byte byte_11;

		[FieldOffset(12)]
		internal byte byte_12;

		[FieldOffset(13)]
		internal byte byte_13;

		[FieldOffset(14)]
		internal byte byte_14;

		[FieldOffset(15)]
		internal byte byte_15;

		[FieldOffset(0)]
		internal sbyte sbyte_0;

		[FieldOffset(1)]
		internal sbyte sbyte_1;

		[FieldOffset(2)]
		internal sbyte sbyte_2;

		[FieldOffset(3)]
		internal sbyte sbyte_3;

		[FieldOffset(4)]
		internal sbyte sbyte_4;

		[FieldOffset(5)]
		internal sbyte sbyte_5;

		[FieldOffset(6)]
		internal sbyte sbyte_6;

		[FieldOffset(7)]
		internal sbyte sbyte_7;

		[FieldOffset(8)]
		internal sbyte sbyte_8;

		[FieldOffset(9)]
		internal sbyte sbyte_9;

		[FieldOffset(10)]
		internal sbyte sbyte_10;

		[FieldOffset(11)]
		internal sbyte sbyte_11;

		[FieldOffset(12)]
		internal sbyte sbyte_12;

		[FieldOffset(13)]
		internal sbyte sbyte_13;

		[FieldOffset(14)]
		internal sbyte sbyte_14;

		[FieldOffset(15)]
		internal sbyte sbyte_15;

		[FieldOffset(0)]
		internal ushort uint16_0;

		[FieldOffset(2)]
		internal ushort uint16_1;

		[FieldOffset(4)]
		internal ushort uint16_2;

		[FieldOffset(6)]
		internal ushort uint16_3;

		[FieldOffset(8)]
		internal ushort uint16_4;

		[FieldOffset(10)]
		internal ushort uint16_5;

		[FieldOffset(12)]
		internal ushort uint16_6;

		[FieldOffset(14)]
		internal ushort uint16_7;

		[FieldOffset(0)]
		internal short int16_0;

		[FieldOffset(2)]
		internal short int16_1;

		[FieldOffset(4)]
		internal short int16_2;

		[FieldOffset(6)]
		internal short int16_3;

		[FieldOffset(8)]
		internal short int16_4;

		[FieldOffset(10)]
		internal short int16_5;

		[FieldOffset(12)]
		internal short int16_6;

		[FieldOffset(14)]
		internal short int16_7;

		[FieldOffset(0)]
		internal uint uint32_0;

		[FieldOffset(4)]
		internal uint uint32_1;

		[FieldOffset(8)]
		internal uint uint32_2;

		[FieldOffset(12)]
		internal uint uint32_3;

		[FieldOffset(0)]
		internal int int32_0;

		[FieldOffset(4)]
		internal int int32_1;

		[FieldOffset(8)]
		internal int int32_2;

		[FieldOffset(12)]
		internal int int32_3;

		[FieldOffset(0)]
		internal ulong uint64_0;

		[FieldOffset(8)]
		internal ulong uint64_1;

		[FieldOffset(0)]
		internal long int64_0;

		[FieldOffset(8)]
		internal long int64_1;

		[FieldOffset(0)]
		internal float single_0;

		[FieldOffset(4)]
		internal float single_1;

		[FieldOffset(8)]
		internal float single_2;

		[FieldOffset(12)]
		internal float single_3;

		[FieldOffset(0)]
		internal double double_0;

		[FieldOffset(8)]
		internal double double_1;
	}
	[System.Runtime.CompilerServices.Intrinsic]
	public struct Vector<T> : IEquatable<Vector<T>>, IFormattable where T : struct
	{
		private struct VectorSizeHelper
		{
			internal Vector<T> _placeholder;

			internal byte _byte;
		}

		private System.Numerics.Register register;

		private static readonly int s_count = InitializeCount();

		private static readonly Vector<T> s_zero = default(Vector<T>);

		private static readonly Vector<T> s_one = new Vector<T>(GetOneValue());

		private static readonly Vector<T> s_allOnes = new Vector<T>(GetAllBitsSetValue());

		public static int Count
		{
			[System.Runtime.CompilerServices.Intrinsic]
			get
			{
				return s_count;
			}
		}

		public static Vector<T> Zero
		{
			[System.Runtime.CompilerServices.Intrinsic]
			get
			{
				return s_zero;
			}
		}

		public static Vector<T> One
		{
			[System.Runtime.CompilerServices.Intrinsic]
			get
			{
				return s_one;
			}
		}

		internal static Vector<T> AllOnes => s_allOnes;

		public unsafe T this[int index]
		{
			[System.Runtime.CompilerServices.Intrinsic]
			get
			{
				if (index >= Count || index < 0)
				{
					throw new IndexOutOfRangeException(System.SR.Format(System.SR.Arg_ArgumentOutOfRangeException, index));
				}
				if (typeof(T) == typeof(byte))
				{
					fixed (byte* ptr = &register.byte_0)
					{
						return (T)(object)ptr[index];
					}
				}
				if (typeof(T) == typeof(sbyte))
				{
					fixed (sbyte* ptr2 = &register.sbyte_0)
					{
						return (T)(object)ptr2[index];
					}
				}
				if (typeof(T) == typeof(ushort))
				{
					fixed (ushort* ptr3 = &register.uint16_0)
					{
						return (T)(object)ptr3[index];
					}
				}
				if (typeof(T) == typeof(short))
				{
					fixed (short* ptr4 = &register.int16_0)
					{
						return (T)(object)ptr4[index];
					}
				}
				if (typeof(T) == typeof(uint))
				{
					fixed (uint* ptr5 = &register.uint32_0)
					{
						return (T)(object)ptr5[index];
					}
				}
				if (typeof(T) == typeof(int))
				{
					fixed (int* ptr6 = &register.int32_0)
					{
						return (T)(object)ptr6[index];
					}
				}
				if (typeof(T) == typeof(ulong))
				{
					fixed (ulong* ptr7 = &register.uint64_0)
					{
						return (T)(object)ptr7[index];
					}
				}
				if (typeof(T) == typeof(long))
				{
					fixed (long* ptr8 = &register.int64_0)
					{
						return (T)(object)ptr8[index];
					}
				}
				if (typeof(T) == typeof(float))
				{
					fixed (float* ptr9 = &register.single_0)
					{
						return (T)(object)ptr9[index];
					}
				}
				if (typeof(T) == typeof(double))
				{
					fixed (double* ptr10 = &register.double_0)
					{
						return (T)(object)ptr10[index];
					}
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
		}

		private unsafe static int InitializeCount()
		{
			VectorSizeHelper vectorSizeHelper = default(VectorSizeHelper);
			byte* ptr = &vectorSizeHelper._placeholder.register.byte_0;
			byte* ptr2 = &vectorSizeHelper._byte;
			int num = (int)(ptr2 - ptr);
			int num2 = -1;
			if (typeof(T) == typeof(byte))
			{
				num2 = 1;
			}
			else if (typeof(T) == typeof(sbyte))
			{
				num2 = 1;
			}
			else if (typeof(T) == typeof(ushort))
			{
				num2 = 2;
			}
			else if (typeof(T) == typeof(short))
			{
				num2 = 2;
			}
			else if (typeof(T) == typeof(uint))
			{
				num2 = 4;
			}
			else if (typeof(T) == typeof(int))
			{
				num2 = 4;
			}
			else if (typeof(T) == typeof(ulong))
			{
				num2 = 8;
			}
			else if (typeof(T) == typeof(long))
			{
				num2 = 8;
			}
			else if (typeof(T) == typeof(float))
			{
				num2 = 4;
			}
			else
			{
				if (!(typeof(T) == typeof(double)))
				{
					throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
				}
				num2 = 8;
			}
			return num / num2;
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public unsafe Vector(T value)
		{
			this = default(Vector<T>);
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					fixed (byte* ptr = &register.byte_0)
					{
						for (int i = 0; i < Count; i++)
						{
							ptr[i] = (byte)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(sbyte))
				{
					fixed (sbyte* ptr2 = &register.sbyte_0)
					{
						for (int j = 0; j < Count; j++)
						{
							ptr2[j] = (sbyte)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(ushort))
				{
					fixed (ushort* ptr3 = &register.uint16_0)
					{
						for (int k = 0; k < Count; k++)
						{
							ptr3[k] = (ushort)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(short))
				{
					fixed (short* ptr4 = &register.int16_0)
					{
						for (int l = 0; l < Count; l++)
						{
							ptr4[l] = (short)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(uint))
				{
					fixed (uint* ptr5 = &register.uint32_0)
					{
						for (int m = 0; m < Count; m++)
						{
							ptr5[m] = (uint)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(int))
				{
					fixed (int* ptr6 = &register.int32_0)
					{
						for (int n = 0; n < Count; n++)
						{
							ptr6[n] = (int)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(ulong))
				{
					fixed (ulong* ptr7 = &register.uint64_0)
					{
						for (int num = 0; num < Count; num++)
						{
							ptr7[num] = (ulong)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(long))
				{
					fixed (long* ptr8 = &register.int64_0)
					{
						for (int num2 = 0; num2 < Count; num2++)
						{
							ptr8[num2] = (long)(object)value;
						}
					}
				}
				else if (typeof(T) == typeof(float))
				{
					fixed (float* ptr9 = &register.single_0)
					{
						for (int num3 = 0; num3 < Count; num3++)
						{
							ptr9[num3] = (float)(object)value;
						}
					}
				}
				else
				{
					if (!(typeof(T) == typeof(double)))
					{
						return;
					}
					fixed (double* ptr10 = &register.double_0)
					{
						for (int num4 = 0; num4 < Count; num4++)
						{
							ptr10[num4] = (double)(object)value;
						}
					}
				}
			}
			else if (typeof(T) == typeof(byte))
			{
				register.byte_0 = (byte)(object)value;
				register.byte_1 = (byte)(object)value;
				register.byte_2 = (byte)(object)value;
				register.byte_3 = (byte)(object)value;
				register.byte_4 = (byte)(object)value;
				register.byte_5 = (byte)(object)value;
				register.byte_6 = (byte)(object)value;
				register.byte_7 = (byte)(object)value;
				register.byte_8 = (byte)(object)value;
				register.byte_9 = (byte)(object)value;
				register.byte_10 = (byte)(object)value;
				register.byte_11 = (byte)(object)value;
				register.byte_12 = (byte)(object)value;
				register.byte_13 = (byte)(object)value;
				register.byte_14 = (byte)(object)value;
				register.byte_15 = (byte)(object)value;
			}
			else if (typeof(T) == typeof(sbyte))
			{
				register.sbyte_0 = (sbyte)(object)value;
				register.sbyte_1 = (sbyte)(object)value;
				register.sbyte_2 = (sbyte)(object)value;
				register.sbyte_3 = (sbyte)(object)value;
				register.sbyte_4 = (sbyte)(object)value;
				register.sbyte_5 = (sbyte)(object)value;
				register.sbyte_6 = (sbyte)(object)value;
				register.sbyte_7 = (sbyte)(object)value;
				register.sbyte_8 = (sbyte)(object)value;
				register.sbyte_9 = (sbyte)(object)value;
				register.sbyte_10 = (sbyte)(object)value;
				register.sbyte_11 = (sbyte)(object)value;
				register.sbyte_12 = (sbyte)(object)value;
				register.sbyte_13 = (sbyte)(object)value;
				register.sbyte_14 = (sbyte)(object)value;
				register.sbyte_15 = (sbyte)(object)value;
			}
			else if (typeof(T) == typeof(ushort))
			{
				register.uint16_0 = (ushort)(object)value;
				register.uint16_1 = (ushort)(object)value;
				register.uint16_2 = (ushort)(object)value;
				register.uint16_3 = (ushort)(object)value;
				register.uint16_4 = (ushort)(object)value;
				register.uint16_5 = (ushort)(object)value;
				register.uint16_6 = (ushort)(object)value;
				register.uint16_7 = (ushort)(object)value;
			}
			else if (typeof(T) == typeof(short))
			{
				register.int16_0 = (short)(object)value;
				register.int16_1 = (short)(object)value;
				register.int16_2 = (short)(object)value;
				register.int16_3 = (short)(object)value;
				register.int16_4 = (short)(object)value;
				register.int16_5 = (short)(object)value;
				register.int16_6 = (short)(object)value;
				register.int16_7 = (short)(object)value;
			}
			else if (typeof(T) == typeof(uint))
			{
				register.uint32_0 = (uint)(object)value;
				register.uint32_1 = (uint)(object)value;
				register.uint32_2 = (uint)(object)value;
				register.uint32_3 = (uint)(object)value;
			}
			else if (typeof(T) == typeof(int))
			{
				register.int32_0 = (int)(object)value;
				register.int32_1 = (int)(object)value;
				register.int32_2 = (int)(object)value;
				register.int32_3 = (int)(object)value;
			}
			else if (typeof(T) == typeof(ulong))
			{
				register.uint64_0 = (ulong)(object)value;
				register.uint64_1 = (ulong)(object)value;
			}
			else if (typeof(T) == typeof(long))
			{
				register.int64_0 = (long)(object)value;
				register.int64_1 = (long)(object)value;
			}
			else if (typeof(T) == typeof(float))
			{
				register.single_0 = (float)(object)value;
				register.single_1 = (float)(object)value;
				register.single_2 = (float)(object)value;
				register.single_3 = (float)(object)value;
			}
			else if (typeof(T) == typeof(double))
			{
				register.double_0 = (double)(object)value;
				register.double_1 = (double)(object)value;
			}
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public Vector(T[] values)
			: this(values, 0)
		{
		}

		public unsafe Vector(T[] values, int index)
		{
			this = default(Vector<T>);
			if (values == null)
			{
				throw new NullReferenceException(System.SR.Arg_NullArgumentNullRef);
			}
			if (index < 0 || values.Length - index < Count)
			{
				throw new IndexOutOfRangeException(System.SR.Format(System.SR.Arg_InsufficientNumberOfElements, Count, "values"));
			}
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					fixed (byte* ptr = &register.byte_0)
					{
						for (int i = 0; i < Count; i++)
						{
							ptr[i] = (byte)(object)values[i + index];
						}
					}
				}
				else if (typeof(T) == typeof(sbyte))
				{
					fixed (sbyte* ptr2 = &register.sbyte_0)
					{
						for (int j = 0; j < Count; j++)
						{
							ptr2[j] = (sbyte)(object)values[j + index];
						}
					}
				}
				else if (typeof(T) == typeof(ushort))
				{
					fixed (ushort* ptr3 = &register.uint16_0)
					{
						for (int k = 0; k < Count; k++)
						{
							ptr3[k] = (ushort)(object)values[k + index];
						}
					}
				}
				else if (typeof(T) == typeof(short))
				{
					fixed (short* ptr4 = &register.int16_0)
					{
						for (int l = 0; l < Count; l++)
						{
							ptr4[l] = (short)(object)values[l + index];
						}
					}
				}
				else if (typeof(T) == typeof(uint))
				{
					fixed (uint* ptr5 = &register.uint32_0)
					{
						for (int m = 0; m < Count; m++)
						{
							ptr5[m] = (uint)(object)values[m + index];
						}
					}
				}
				else if (typeof(T) == typeof(int))
				{
					fixed (int* ptr6 = &register.int32_0)
					{
						for (int n = 0; n < Count; n++)
						{
							ptr6[n] = (int)(object)values[n + index];
						}
					}
				}
				else if (typeof(T) == typeof(ulong))
				{
					fixed (ulong* ptr7 = &register.uint64_0)
					{
						for (int num = 0; num < Count; num++)
						{
							ptr7[num] = (ulong)(object)values[num + index];
						}
					}
				}
				else if (typeof(T) == typeof(long))
				{
					fixed (long* ptr8 = &register.int64_0)
					{
						for (int num2 = 0; num2 < Count; num2++)
						{
							ptr8[num2] = (long)(object)values[num2 + index];
						}
					}
				}
				else if (typeof(T) == typeof(float))
				{
					fixed (float* ptr9 = &register.single_0)
					{
						for (int num3 = 0; num3 < Count; num3++)
						{
							ptr9[num3] = (float)(object)values[num3 + index];
						}
					}
				}
				else
				{
					if (!(typeof(T) == typeof(double)))
					{
						return;
					}
					fixed (double* ptr10 = &register.double_0)
					{
						for (int num4 = 0; num4 < Count; num4++)
						{
							ptr10[num4] = (double)(object)values[num4 + index];
						}
					}
				}
			}
			else if (typeof(T) == typeof(byte))
			{
				fixed (byte* ptr11 = &register.byte_0)
				{
					*ptr11 = (byte)(object)values[index];
					ptr11[1] = (byte)(object)values[1 + index];
					ptr11[2] = (byte)(object)values[2 + index];
					ptr11[3] = (byte)(object)values[3 + index];
					ptr11[4] = (byte)(object)values[4 + index];
					ptr11[5] = (byte)(object)values[5 + index];
					ptr11[6] = (byte)(object)values[6 + index];
					ptr11[7] = (byte)(object)values[7 + index];
					ptr11[8] = (byte)(object)values[8 + index];
					ptr11[9] = (byte)(object)values[9 + index];
					ptr11[10] = (byte)(object)values[10 + index];
					ptr11[11] = (byte)(object)values[11 + index];
					ptr11[12] = (byte)(object)values[12 + index];
					ptr11[13] = (byte)(object)values[13 + index];
					ptr11[14] = (byte)(object)values[14 + index];
					ptr11[15] = (byte)(object)values[15 + index];
				}
			}
			else if (typeof(T) == typeof(sbyte))
			{
				fixed (sbyte* ptr12 = &register.sbyte_0)
				{
					*ptr12 = (sbyte)(object)values[index];
					ptr12[1] = (sbyte)(object)values[1 + index];
					ptr12[2] = (sbyte)(object)values[2 + index];
					ptr12[3] = (sbyte)(object)values[3 + index];
					ptr12[4] = (sbyte)(object)values[4 + index];
					ptr12[5] = (sbyte)(object)values[5 + index];
					ptr12[6] = (sbyte)(object)values[6 + index];
					ptr12[7] = (sbyte)(object)values[7 + index];
					ptr12[8] = (sbyte)(object)values[8 + index];
					ptr12[9] = (sbyte)(object)values[9 + index];
					ptr12[10] = (sbyte)(object)values[10 + index];
					ptr12[11] = (sbyte)(object)values[11 + index];
					ptr12[12] = (sbyte)(object)values[12 + index];
					ptr12[13] = (sbyte)(object)values[13 + index];
					ptr12[14] = (sbyte)(object)values[14 + index];
					ptr12[15] = (sbyte)(object)values[15 + index];
				}
			}
			else if (typeof(T) == typeof(ushort))
			{
				fixed (ushort* ptr13 = &register.uint16_0)
				{
					*ptr13 = (ushort)(object)values[index];
					ptr13[1] = (ushort)(object)values[1 + index];
					ptr13[2] = (ushort)(object)values[2 + index];
					ptr13[3] = (ushort)(object)values[3 + index];
					ptr13[4] = (ushort)(object)values[4 + index];
					ptr13[5] = (ushort)(object)values[5 + index];
					ptr13[6] = (ushort)(object)values[6 + index];
					ptr13[7] = (ushort)(object)values[7 + index];
				}
			}
			else if (typeof(T) == typeof(short))
			{
				fixed (short* ptr14 = &register.int16_0)
				{
					*ptr14 = (short)(object)values[index];
					ptr14[1] = (short)(object)values[1 + index];
					ptr14[2] = (short)(object)values[2 + index];
					ptr14[3] = (short)(object)values[3 + index];
					ptr14[4] = (short)(object)values[4 + index];
					ptr14[5] = (short)(object)values[5 + index];
					ptr14[6] = (short)(object)values[6 + index];
					ptr14[7] = (short)(object)values[7 + index];
				}
			}
			else if (typeof(T) == typeof(uint))
			{
				fixed (uint* ptr15 = &register.uint32_0)
				{
					*ptr15 = (uint)(object)values[index];
					ptr15[1] = (uint)(object)values[1 + index];
					ptr15[2] = (uint)(object)values[2 + index];
					ptr15[3] = (uint)(object)values[3 + index];
				}
			}
			else if (typeof(T) == typeof(int))
			{
				fixed (int* ptr16 = &register.int32_0)
				{
					*ptr16 = (int)(object)values[index];
					ptr16[1] = (int)(object)values[1 + index];
					ptr16[2] = (int)(object)values[2 + index];
					ptr16[3] = (int)(object)values[3 + index];
				}
			}
			else if (typeof(T) == typeof(ulong))
			{
				fixed (ulong* ptr17 = &register.uint64_0)
				{
					*ptr17 = (ulong)(object)values[index];
					ptr17[1] = (ulong)(object)values[1 + index];
				}
			}
			else if (typeof(T) == typeof(long))
			{
				fixed (long* ptr18 = &register.int64_0)
				{
					*ptr18 = (long)(object)values[index];
					ptr18[1] = (long)(object)values[1 + index];
				}
			}
			else if (typeof(T) == typeof(float))
			{
				fixed (float* ptr19 = &register.single_0)
				{
					*ptr19 = (float)(object)values[index];
					ptr19[1] = (float)(object)values[1 + index];
					ptr19[2] = (float)(object)values[2 + index];
					ptr19[3] = (float)(object)values[3 + index];
				}
			}
			else if (typeof(T) == typeof(double))
			{
				fixed (double* ptr20 = &register.double_0)
				{
					*ptr20 = (double)(object)values[index];
					ptr20[1] = (double)(object)values[1 + index];
				}
			}
		}

		internal unsafe Vector(void* dataPointer)
			: this(dataPointer, 0)
		{
		}

		internal unsafe Vector(void* dataPointer, int offset)
		{
			this = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				byte* ptr = (byte*)dataPointer;
				ptr += offset;
				fixed (byte* ptr2 = &register.byte_0)
				{
					for (int i = 0; i < Count; i++)
					{
						ptr2[i] = ptr[i];
					}
				}
				return;
			}
			if (typeof(T) == typeof(sbyte))
			{
				sbyte* ptr3 = (sbyte*)dataPointer;
				ptr3 += offset;
				fixed (sbyte* ptr4 = &register.sbyte_0)
				{
					for (int j = 0; j < Count; j++)
					{
						ptr4[j] = ptr3[j];
					}
				}
				return;
			}
			if (typeof(T) == typeof(ushort))
			{
				ushort* ptr5 = (ushort*)dataPointer;
				ptr5 += offset;
				fixed (ushort* ptr6 = &register.uint16_0)
				{
					for (int k = 0; k < Count; k++)
					{
						ptr6[k] = ptr5[k];
					}
				}
				return;
			}
			if (typeof(T) == typeof(short))
			{
				short* ptr7 = (short*)dataPointer;
				ptr7 += offset;
				fixed (short* ptr8 = &register.int16_0)
				{
					for (int l = 0; l < Count; l++)
					{
						ptr8[l] = ptr7[l];
					}
				}
				return;
			}
			if (typeof(T) == typeof(uint))
			{
				uint* ptr9 = (uint*)dataPointer;
				ptr9 += offset;
				fixed (uint* ptr10 = &register.uint32_0)
				{
					for (int m = 0; m < Count; m++)
					{
						ptr10[m] = ptr9[m];
					}
				}
				return;
			}
			if (typeof(T) == typeof(int))
			{
				int* ptr11 = (int*)dataPointer;
				ptr11 += offset;
				fixed (int* ptr12 = &register.int32_0)
				{
					for (int n = 0; n < Count; n++)
					{
						ptr12[n] = ptr11[n];
					}
				}
				return;
			}
			if (typeof(T) == typeof(ulong))
			{
				ulong* ptr13 = (ulong*)dataPointer;
				ptr13 += offset;
				fixed (ulong* ptr14 = &register.uint64_0)
				{
					for (int num = 0; num < Count; num++)
					{
						ptr14[num] = ptr13[num];
					}
				}
				return;
			}
			if (typeof(T) == typeof(long))
			{
				long* ptr15 = (long*)dataPointer;
				ptr15 += offset;
				fixed (long* ptr16 = &register.int64_0)
				{
					for (int num2 = 0; num2 < Count; num2++)
					{
						ptr16[num2] = ptr15[num2];
					}
				}
				return;
			}
			if (typeof(T) == typeof(float))
			{
				float* ptr17 = (float*)dataPointer;
				ptr17 += offset;
				fixed (float* ptr18 = &register.single_0)
				{
					for (int num3 = 0; num3 < Count; num3++)
					{
						ptr18[num3] = ptr17[num3];
					}
				}
				return;
			}
			if (typeof(T) == typeof(double))
			{
				double* ptr19 = (double*)dataPointer;
				ptr19 += offset;
				fixed (double* ptr20 = &register.double_0)
				{
					for (int num4 = 0; num4 < Count; num4++)
					{
						ptr20[num4] = ptr19[num4];
					}
				}
				return;
			}
			throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
		}

		private Vector(ref System.Numerics.Register existingRegister)
		{
			register = existingRegister;
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public void CopyTo(T[] destination)
		{
			CopyTo(destination, 0);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public unsafe void CopyTo(T[] destination, int startIndex)
		{
			if (destination == null)
			{
				throw new NullReferenceException(System.SR.Arg_NullArgumentNullRef);
			}
			if (startIndex < 0 || startIndex >= destination.Length)
			{
				throw new ArgumentOutOfRangeException("startIndex", System.SR.Format(System.SR.Arg_ArgumentOutOfRangeException, startIndex));
			}
			if (destination.Length - startIndex < Count)
			{
				throw new ArgumentException(System.SR.Format(System.SR.Arg_ElementsInSourceIsGreaterThanDestination, startIndex));
			}
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					fixed (byte* ptr = (byte[])(object)destination)
					{
						for (int i = 0; i < Count; i++)
						{
							ptr[startIndex + i] = (byte)(object)this[i];
						}
					}
				}
				else if (typeof(T) == typeof(sbyte))
				{
					fixed (sbyte* ptr2 = (sbyte[])(object)destination)
					{
						for (int j = 0; j < Count; j++)
						{
							ptr2[startIndex + j] = (sbyte)(object)this[j];
						}
					}
				}
				else if (typeof(T) == typeof(ushort))
				{
					fixed (ushort* ptr3 = (ushort[])(object)destination)
					{
						for (int k = 0; k < Count; k++)
						{
							ptr3[startIndex + k] = (ushort)(object)this[k];
						}
					}
				}
				else if (typeof(T) == typeof(short))
				{
					fixed (short* ptr4 = (short[])(object)destination)
					{
						for (int l = 0; l < Count; l++)
						{
							ptr4[startIndex + l] = (short)(object)this[l];
						}
					}
				}
				else if (typeof(T) == typeof(uint))
				{
					fixed (uint* ptr5 = (uint[])(object)destination)
					{
						for (int m = 0; m < Count; m++)
						{
							ptr5[startIndex + m] = (uint)(object)this[m];
						}
					}
				}
				else if (typeof(T) == typeof(int))
				{
					fixed (int* ptr6 = (int[])(object)destination)
					{
						for (int n = 0; n < Count; n++)
						{
							ptr6[startIndex + n] = (int)(object)this[n];
						}
					}
				}
				else if (typeof(T) == typeof(ulong))
				{
					fixed (ulong* ptr7 = (ulong[])(object)destination)
					{
						for (int num = 0; num < Count; num++)
						{
							ptr7[startIndex + num] = (ulong)(object)this[num];
						}
					}
				}
				else if (typeof(T) == typeof(long))
				{
					fixed (long* ptr8 = (long[])(object)destination)
					{
						for (int num2 = 0; num2 < Count; num2++)
						{
							ptr8[startIndex + num2] = (long)(object)this[num2];
						}
					}
				}
				else if (typeof(T) == typeof(float))
				{
					fixed (float* ptr9 = (float[])(object)destination)
					{
						for (int num3 = 0; num3 < Count; num3++)
						{
							ptr9[startIndex + num3] = (float)(object)this[num3];
						}
					}
				}
				else
				{
					if (!(typeof(T) == typeof(double)))
					{
						return;
					}
					fixed (double* ptr10 = (double[])(object)destination)
					{
						for (int num4 = 0; num4 < Count; num4++)
						{
							ptr10[startIndex + num4] = (double)(object)this[num4];
						}
					}
				}
			}
			else if (typeof(T) == typeof(byte))
			{
				fixed (byte* ptr11 = (byte[])(object)destination)
				{
					ptr11[startIndex] = register.byte_0;
					ptr11[startIndex + 1] = register.byte_1;
					ptr11[startIndex + 2] = register.byte_2;
					ptr11[startIndex + 3] = register.byte_3;
					ptr11[startIndex + 4] = register.byte_4;
					ptr11[startIndex + 5] = register.byte_5;
					ptr11[startIndex + 6] = register.byte_6;
					ptr11[startIndex + 7] = register.byte_7;
					ptr11[startIndex + 8] = register.byte_8;
					ptr11[startIndex + 9] = register.byte_9;
					ptr11[startIndex + 10] = register.byte_10;
					ptr11[startIndex + 11] = register.byte_11;
					ptr11[startIndex + 12] = register.byte_12;
					ptr11[startIndex + 13] = register.byte_13;
					ptr11[startIndex + 14] = register.byte_14;
					ptr11[startIndex + 15] = register.byte_15;
				}
			}
			else if (typeof(T) == typeof(sbyte))
			{
				fixed (sbyte* ptr12 = (sbyte[])(object)destination)
				{
					ptr12[startIndex] = register.sbyte_0;
					ptr12[startIndex + 1] = register.sbyte_1;
					ptr12[startIndex + 2] = register.sbyte_2;
					ptr12[startIndex + 3] = register.sbyte_3;
					ptr12[startIndex + 4] = register.sbyte_4;
					ptr12[startIndex + 5] = register.sbyte_5;
					ptr12[startIndex + 6] = register.sbyte_6;
					ptr12[startIndex + 7] = register.sbyte_7;
					ptr12[startIndex + 8] = register.sbyte_8;
					ptr12[startIndex + 9] = register.sbyte_9;
					ptr12[startIndex + 10] = register.sbyte_10;
					ptr12[startIndex + 11] = register.sbyte_11;
					ptr12[startIndex + 12] = register.sbyte_12;
					ptr12[startIndex + 13] = register.sbyte_13;
					ptr12[startIndex + 14] = register.sbyte_14;
					ptr12[startIndex + 15] = register.sbyte_15;
				}
			}
			else if (typeof(T) == typeof(ushort))
			{
				fixed (ushort* ptr13 = (ushort[])(object)destination)
				{
					ptr13[startIndex] = register.uint16_0;
					ptr13[startIndex + 1] = register.uint16_1;
					ptr13[startIndex + 2] = register.uint16_2;
					ptr13[startIndex + 3] = register.uint16_3;
					ptr13[startIndex + 4] = register.uint16_4;
					ptr13[startIndex + 5] = register.uint16_5;
					ptr13[startIndex + 6] = register.uint16_6;
					ptr13[startIndex + 7] = register.uint16_7;
				}
			}
			else if (typeof(T) == typeof(short))
			{
				fixed (short* ptr14 = (short[])(object)destination)
				{
					ptr14[startIndex] = register.int16_0;
					ptr14[startIndex + 1] = register.int16_1;
					ptr14[startIndex + 2] = register.int16_2;
					ptr14[startIndex + 3] = register.int16_3;
					ptr14[startIndex + 4] = register.int16_4;
					ptr14[startIndex + 5] = register.int16_5;
					ptr14[startIndex + 6] = register.int16_6;
					ptr14[startIndex + 7] = register.int16_7;
				}
			}
			else if (typeof(T) == typeof(uint))
			{
				fixed (uint* ptr15 = (uint[])(object)destination)
				{
					ptr15[startIndex] = register.uint32_0;
					ptr15[startIndex + 1] = register.uint32_1;
					ptr15[startIndex + 2] = register.uint32_2;
					ptr15[startIndex + 3] = register.uint32_3;
				}
			}
			else if (typeof(T) == typeof(int))
			{
				fixed (int* ptr16 = (int[])(object)destination)
				{
					ptr16[startIndex] = register.int32_0;
					ptr16[startIndex + 1] = register.int32_1;
					ptr16[startIndex + 2] = register.int32_2;
					ptr16[startIndex + 3] = register.int32_3;
				}
			}
			else if (typeof(T) == typeof(ulong))
			{
				fixed (ulong* ptr17 = (ulong[])(object)destination)
				{
					ptr17[startIndex] = register.uint64_0;
					ptr17[startIndex + 1] = register.uint64_1;
				}
			}
			else if (typeof(T) == typeof(long))
			{
				fixed (long* ptr18 = (long[])(object)destination)
				{
					ptr18[startIndex] = register.int64_0;
					ptr18[startIndex + 1] = register.int64_1;
				}
			}
			else if (typeof(T) == typeof(float))
			{
				fixed (float* ptr19 = (float[])(object)destination)
				{
					ptr19[startIndex] = register.single_0;
					ptr19[startIndex + 1] = register.single_1;
					ptr19[startIndex + 2] = register.single_2;
					ptr19[startIndex + 3] = register.single_3;
				}
			}
			else if (typeof(T) == typeof(double))
			{
				fixed (double* ptr20 = (double[])(object)destination)
				{
					ptr20[startIndex] = register.double_0;
					ptr20[startIndex + 1] = register.double_1;
				}
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public override bool Equals(object obj)
		{
			if (!(obj is Vector<T>))
			{
				return false;
			}
			return Equals((Vector<T>)obj);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public bool Equals(Vector<T> other)
		{
			if (Vector.IsHardwareAccelerated)
			{
				for (int i = 0; i < Count; i++)
				{
					if (!ScalarEquals(this[i], other[i]))
					{
						return false;
					}
				}
				return true;
			}
			if (typeof(T) == typeof(byte))
			{
				if (register.byte_0 == other.register.byte_0 && register.byte_1 == other.register.byte_1 && register.byte_2 == other.register.byte_2 && register.byte_3 == other.register.byte_3 && register.byte_4 == other.register.byte_4 && register.byte_5 == other.register.byte_5 && register.byte_6 == other.register.byte_6 && register.byte_7 == other.register.byte_7 && register.byte_8 == other.register.byte_8 && register.byte_9 == other.register.byte_9 && register.byte_10 == other.register.byte_10 && register.byte_11 == other.register.byte_11 && register.byte_12 == other.register.byte_12 && register.byte_13 == other.register.byte_13 && register.byte_14 == other.register.byte_14)
				{
					return register.byte_15 == other.register.byte_15;
				}
				return false;
			}
			if (typeof(T) == typeof(sbyte))
			{
				if (register.sbyte_0 == other.register.sbyte_0 && register.sbyte_1 == other.register.sbyte_1 && register.sbyte_2 == other.register.sbyte_2 && register.sbyte_3 == other.register.sbyte_3 && register.sbyte_4 == other.register.sbyte_4 && register.sbyte_5 == other.register.sbyte_5 && register.sbyte_6 == other.register.sbyte_6 && register.sbyte_7 == other.register.sbyte_7 && register.sbyte_8 == other.register.sbyte_8 && register.sbyte_9 == other.register.sbyte_9 && register.sbyte_10 == other.register.sbyte_10 && register.sbyte_11 == other.register.sbyte_11 && register.sbyte_12 == other.register.sbyte_12 && register.sbyte_13 == other.register.sbyte_13 && register.sbyte_14 == other.register.sbyte_14)
				{
					return register.sbyte_15 == other.register.sbyte_15;
				}
				return false;
			}
			if (typeof(T) == typeof(ushort))
			{
				if (register.uint16_0 == other.register.uint16_0 && register.uint16_1 == other.register.uint16_1 && register.uint16_2 == other.register.uint16_2 && register.uint16_3 == other.register.uint16_3 && register.uint16_4 == other.register.uint16_4 && register.uint16_5 == other.register.uint16_5 && register.uint16_6 == other.register.uint16_6)
				{
					return register.uint16_7 == other.register.uint16_7;
				}
				return false;
			}
			if (typeof(T) == typeof(short))
			{
				if (register.int16_0 == other.register.int16_0 && register.int16_1 == other.register.int16_1 && register.int16_2 == other.register.int16_2 && register.int16_3 == other.register.int16_3 && register.int16_4 == other.register.int16_4 && register.int16_5 == other.register.int16_5 && register.int16_6 == other.register.int16_6)
				{
					return register.int16_7 == other.register.int16_7;
				}
				return false;
			}
			if (typeof(T) == typeof(uint))
			{
				if (register.uint32_0 == other.register.uint32_0 && register.uint32_1 == other.register.uint32_1 && register.uint32_2 == other.register.uint32_2)
				{
					return register.uint32_3 == other.register.uint32_3;
				}
				return false;
			}
			if (typeof(T) == typeof(int))
			{
				if (register.int32_0 == other.register.int32_0 && register.int32_1 == other.register.int32_1 && register.int32_2 == other.register.int32_2)
				{
					return register.int32_3 == other.register.int32_3;
				}
				return false;
			}
			if (typeof(T) == typeof(ulong))
			{
				if (register.uint64_0 == other.register.uint64_0)
				{
					return register.uint64_1 == other.register.uint64_1;
				}
				return false;
			}
			if (typeof(T) == typeof(long))
			{
				if (register.int64_0 == other.register.int64_0)
				{
					return register.int64_1 == other.register.int64_1;
				}
				return false;
			}
			if (typeof(T) == typeof(float))
			{
				if (register.single_0 == other.register.single_0 && register.single_1 == other.register.single_1 && register.single_2 == other.register.single_2)
				{
					return register.single_3 == other.register.single_3;
				}
				return false;
			}
			if (typeof(T) == typeof(double))
			{
				if (register.double_0 == other.register.double_0)
				{
					return register.double_1 == other.register.double_1;
				}
				return false;
			}
			throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
		}

		public override int GetHashCode()
		{
			int num = 0;
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					for (int i = 0; i < Count; i++)
					{
						num = HashHelpers.Combine(num, ((byte)(object)this[i]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(sbyte))
				{
					for (int j = 0; j < Count; j++)
					{
						num = HashHelpers.Combine(num, ((sbyte)(object)this[j]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(ushort))
				{
					for (int k = 0; k < Count; k++)
					{
						num = HashHelpers.Combine(num, ((ushort)(object)this[k]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(short))
				{
					for (int l = 0; l < Count; l++)
					{
						num = HashHelpers.Combine(num, ((short)(object)this[l]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(uint))
				{
					for (int m = 0; m < Count; m++)
					{
						num = HashHelpers.Combine(num, ((uint)(object)this[m]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(int))
				{
					for (int n = 0; n < Count; n++)
					{
						num = HashHelpers.Combine(num, ((int)(object)this[n]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(ulong))
				{
					for (int num2 = 0; num2 < Count; num2++)
					{
						num = HashHelpers.Combine(num, ((ulong)(object)this[num2]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(long))
				{
					for (int num3 = 0; num3 < Count; num3++)
					{
						num = HashHelpers.Combine(num, ((long)(object)this[num3]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(float))
				{
					for (int num4 = 0; num4 < Count; num4++)
					{
						num = HashHelpers.Combine(num, ((float)(object)this[num4]).GetHashCode());
					}
					return num;
				}
				if (typeof(T) == typeof(double))
				{
					for (int num5 = 0; num5 < Count; num5++)
					{
						num = HashHelpers.Combine(num, ((double)(object)this[num5]).GetHashCode());
					}
					return num;
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
			if (typeof(T) == typeof(byte))
			{
				num = HashHelpers.Combine(num, register.byte_0.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_1.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_2.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_3.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_4.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_5.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_6.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_7.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_8.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_9.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_10.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_11.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_12.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_13.GetHashCode());
				num = HashHelpers.Combine(num, register.byte_14.GetHashCode());
				return HashHelpers.Combine(num, register.byte_15.GetHashCode());
			}
			if (typeof(T) == typeof(sbyte))
			{
				num = HashHelpers.Combine(num, register.sbyte_0.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_1.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_2.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_3.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_4.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_5.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_6.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_7.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_8.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_9.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_10.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_11.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_12.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_13.GetHashCode());
				num = HashHelpers.Combine(num, register.sbyte_14.GetHashCode());
				return HashHelpers.Combine(num, register.sbyte_15.GetHashCode());
			}
			if (typeof(T) == typeof(ushort))
			{
				num = HashHelpers.Combine(num, register.uint16_0.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_1.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_2.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_3.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_4.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_5.GetHashCode());
				num = HashHelpers.Combine(num, register.uint16_6.GetHashCode());
				return HashHelpers.Combine(num, register.uint16_7.GetHashCode());
			}
			if (typeof(T) == typeof(short))
			{
				num = HashHelpers.Combine(num, register.int16_0.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_1.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_2.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_3.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_4.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_5.GetHashCode());
				num = HashHelpers.Combine(num, register.int16_6.GetHashCode());
				return HashHelpers.Combine(num, register.int16_7.GetHashCode());
			}
			if (typeof(T) == typeof(uint))
			{
				num = HashHelpers.Combine(num, register.uint32_0.GetHashCode());
				num = HashHelpers.Combine(num, register.uint32_1.GetHashCode());
				num = HashHelpers.Combine(num, register.uint32_2.GetHashCode());
				return HashHelpers.Combine(num, register.uint32_3.GetHashCode());
			}
			if (typeof(T) == typeof(int))
			{
				num = HashHelpers.Combine(num, register.int32_0.GetHashCode());
				num = HashHelpers.Combine(num, register.int32_1.GetHashCode());
				num = HashHelpers.Combine(num, register.int32_2.GetHashCode());
				return HashHelpers.Combine(num, register.int32_3.GetHashCode());
			}
			if (typeof(T) == typeof(ulong))
			{
				num = HashHelpers.Combine(num, register.uint64_0.GetHashCode());
				return HashHelpers.Combine(num, register.uint64_1.GetHashCode());
			}
			if (typeof(T) == typeof(long))
			{
				num = HashHelpers.Combine(num, register.int64_0.GetHashCode());
				return HashHelpers.Combine(num, register.int64_1.GetHashCode());
			}
			if (typeof(T) == typeof(float))
			{
				num = HashHelpers.Combine(num, register.single_0.GetHashCode());
				num = HashHelpers.Combine(num, register.single_1.GetHashCode());
				num = HashHelpers.Combine(num, register.single_2.GetHashCode());
				return HashHelpers.Combine(num, register.single_3.GetHashCode());
			}
			if (typeof(T) == typeof(double))
			{
				num = HashHelpers.Combine(num, register.double_0.GetHashCode());
				return HashHelpers.Combine(num, register.double_1.GetHashCode());
			}
			throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
		}

		public override string ToString()
		{
			return ToString("G", CultureInfo.CurrentCulture);
		}

		public string ToString(string format)
		{
			return ToString(format, CultureInfo.CurrentCulture);
		}

		public string ToString(string format, IFormatProvider formatProvider)
		{
			StringBuilder stringBuilder = new StringBuilder();
			string numberGroupSeparator = NumberFormatInfo.GetInstance(formatProvider).NumberGroupSeparator;
			stringBuilder.Append('<');
			for (int i = 0; i < Count - 1; i++)
			{
				stringBuilder.Append(((IFormattable)(object)this[i]).ToString(format, formatProvider));
				stringBuilder.Append(numberGroupSeparator);
				stringBuilder.Append(' ');
			}
			stringBuilder.Append(((IFormattable)(object)this[Count - 1]).ToString(format, formatProvider));
			stringBuilder.Append('>');
			return stringBuilder.ToString();
		}

		public unsafe static Vector<T>operator +(Vector<T> left, Vector<T> right)
		{
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					byte* ptr = stackalloc byte[(int)(uint)Count];
					for (int i = 0; i < Count; i++)
					{
						ptr[i] = (byte)(object)ScalarAdd(left[i], right[i]);
					}
					return new Vector<T>(ptr);
				}
				if (typeof(T) == typeof(sbyte))
				{
					sbyte* ptr2 = stackalloc sbyte[(int)(uint)Count];
					for (int j = 0; j < Count; j++)
					{
						ptr2[j] = (sbyte)(object)ScalarAdd(left[j], right[j]);
					}
					return new Vector<T>(ptr2);
				}
				if (typeof(T) == typeof(ushort))
				{
					ushort* ptr3 = stackalloc ushort[Count];
					for (int k = 0; k < Count; k++)
					{
						ptr3[k] = (ushort)(object)ScalarAdd(left[k], right[k]);
					}
					return new Vector<T>(ptr3);
				}
				if (typeof(T) == typeof(short))
				{
					short* ptr4 = stackalloc short[Count];
					for (int l = 0; l < Count; l++)
					{
						ptr4[l] = (short)(object)ScalarAdd(left[l], right[l]);
					}
					return new Vector<T>(ptr4);
				}
				if (typeof(T) == typeof(uint))
				{
					uint* ptr5 = stackalloc uint[Count];
					for (int m = 0; m < Count; m++)
					{
						ptr5[m] = (uint)(object)ScalarAdd(left[m], right[m]);
					}
					return new Vector<T>(ptr5);
				}
				if (typeof(T) == typeof(int))
				{
					int* ptr6 = stackalloc int[Count];
					for (int n = 0; n < Count; n++)
					{
						ptr6[n] = (int)(object)ScalarAdd(left[n], right[n]);
					}
					return new Vector<T>(ptr6);
				}
				if (typeof(T) == typeof(ulong))
				{
					ulong* ptr7 = stackalloc ulong[Count];
					for (int num = 0; num < Count; num++)
					{
						ptr7[num] = (ulong)(object)ScalarAdd(left[num], right[num]);
					}
					return new Vector<T>(ptr7);
				}
				if (typeof(T) == typeof(long))
				{
					long* ptr8 = stackalloc long[Count];
					for (int num2 = 0; num2 < Count; num2++)
					{
						ptr8[num2] = (long)(object)ScalarAdd(left[num2], right[num2]);
					}
					return new Vector<T>(ptr8);
				}
				if (typeof(T) == typeof(float))
				{
					float* ptr9 = stackalloc float[Count];
					for (int num3 = 0; num3 < Count; num3++)
					{
						ptr9[num3] = (float)(object)ScalarAdd(left[num3], right[num3]);
					}
					return new Vector<T>(ptr9);
				}
				if (typeof(T) == typeof(double))
				{
					double* ptr10 = stackalloc double[Count];
					for (int num4 = 0; num4 < Count; num4++)
					{
						ptr10[num4] = (double)(object)ScalarAdd(left[num4], right[num4]);
					}
					return new Vector<T>(ptr10);
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(left.register.byte_0 + right.register.byte_0);
				result.register.byte_1 = (byte)(left.register.byte_1 + right.register.byte_1);
				result.register.byte_2 = (byte)(left.register.byte_2 + right.register.byte_2);
				result.register.byte_3 = (byte)(left.register.byte_3 + right.register.byte_3);
				result.register.byte_4 = (byte)(left.register.byte_4 + right.register.byte_4);
				result.register.byte_5 = (byte)(left.register.byte_5 + right.register.byte_5);
				result.register.byte_6 = (byte)(left.register.byte_6 + right.register.byte_6);
				result.register.byte_7 = (byte)(left.register.byte_7 + right.register.byte_7);
				result.register.byte_8 = (byte)(left.register.byte_8 + right.register.byte_8);
				result.register.byte_9 = (byte)(left.register.byte_9 + right.register.byte_9);
				result.register.byte_10 = (byte)(left.register.byte_10 + right.register.byte_10);
				result.register.byte_11 = (byte)(left.register.byte_11 + right.register.byte_11);
				result.register.byte_12 = (byte)(left.register.byte_12 + right.register.byte_12);
				result.register.byte_13 = (byte)(left.register.byte_13 + right.register.byte_13);
				result.register.byte_14 = (byte)(left.register.byte_14 + right.register.byte_14);
				result.register.byte_15 = (byte)(left.register.byte_15 + right.register.byte_15);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(left.register.sbyte_0 + right.register.sbyte_0);
				result.register.sbyte_1 = (sbyte)(left.register.sbyte_1 + right.register.sbyte_1);
				result.register.sbyte_2 = (sbyte)(left.register.sbyte_2 + right.register.sbyte_2);
				result.register.sbyte_3 = (sbyte)(left.register.sbyte_3 + right.register.sbyte_3);
				result.register.sbyte_4 = (sbyte)(left.register.sbyte_4 + right.register.sbyte_4);
				result.register.sbyte_5 = (sbyte)(left.register.sbyte_5 + right.register.sbyte_5);
				result.register.sbyte_6 = (sbyte)(left.register.sbyte_6 + right.register.sbyte_6);
				result.register.sbyte_7 = (sbyte)(left.register.sbyte_7 + right.register.sbyte_7);
				result.register.sbyte_8 = (sbyte)(left.register.sbyte_8 + right.register.sbyte_8);
				result.register.sbyte_9 = (sbyte)(left.register.sbyte_9 + right.register.sbyte_9);
				result.register.sbyte_10 = (sbyte)(left.register.sbyte_10 + right.register.sbyte_10);
				result.register.sbyte_11 = (sbyte)(left.register.sbyte_11 + right.register.sbyte_11);
				result.register.sbyte_12 = (sbyte)(left.register.sbyte_12 + right.register.sbyte_12);
				result.register.sbyte_13 = (sbyte)(left.register.sbyte_13 + right.register.sbyte_13);
				result.register.sbyte_14 = (sbyte)(left.register.sbyte_14 + right.register.sbyte_14);
				result.register.sbyte_15 = (sbyte)(left.register.sbyte_15 + right.register.sbyte_15);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(left.register.uint16_0 + right.register.uint16_0);
				result.register.uint16_1 = (ushort)(left.register.uint16_1 + right.register.uint16_1);
				result.register.uint16_2 = (ushort)(left.register.uint16_2 + right.register.uint16_2);
				result.register.uint16_3 = (ushort)(left.register.uint16_3 + right.register.uint16_3);
				result.register.uint16_4 = (ushort)(left.register.uint16_4 + right.register.uint16_4);
				result.register.uint16_5 = (ushort)(left.register.uint16_5 + right.register.uint16_5);
				result.register.uint16_6 = (ushort)(left.register.uint16_6 + right.register.uint16_6);
				result.register.uint16_7 = (ushort)(left.register.uint16_7 + right.register.uint16_7);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(left.register.int16_0 + right.register.int16_0);
				result.register.int16_1 = (short)(left.register.int16_1 + right.register.int16_1);
				result.register.int16_2 = (short)(left.register.int16_2 + right.register.int16_2);
				result.register.int16_3 = (short)(left.register.int16_3 + right.register.int16_3);
				result.register.int16_4 = (short)(left.register.int16_4 + right.register.int16_4);
				result.register.int16_5 = (short)(left.register.int16_5 + right.register.int16_5);
				result.register.int16_6 = (short)(left.register.int16_6 + right.register.int16_6);
				result.register.int16_7 = (short)(left.register.int16_7 + right.register.int16_7);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = left.register.uint32_0 + right.register.uint32_0;
				result.register.uint32_1 = left.register.uint32_1 + right.register.uint32_1;
				result.register.uint32_2 = left.register.uint32_2 + right.register.uint32_2;
				result.register.uint32_3 = left.register.uint32_3 + right.register.uint32_3;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = left.register.int32_0 + right.register.int32_0;
				result.register.int32_1 = left.register.int32_1 + right.register.int32_1;
				result.register.int32_2 = left.register.int32_2 + right.register.int32_2;
				result.register.int32_3 = left.register.int32_3 + right.register.int32_3;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = left.register.uint64_0 + right.register.uint64_0;
				result.register.uint64_1 = left.register.uint64_1 + right.register.uint64_1;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = left.register.int64_0 + right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 + right.register.int64_1;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = left.register.single_0 + right.register.single_0;
				result.register.single_1 = left.register.single_1 + right.register.single_1;
				result.register.single_2 = left.register.single_2 + right.register.single_2;
				result.register.single_3 = left.register.single_3 + right.register.single_3;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = left.register.double_0 + right.register.double_0;
				result.register.double_1 = left.register.double_1 + right.register.double_1;
			}
			return result;
		}

		public unsafe static Vector<T>operator -(Vector<T> left, Vector<T> right)
		{
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					byte* ptr = stackalloc byte[(int)(uint)Count];
					for (int i = 0; i < Count; i++)
					{
						ptr[i] = (byte)(object)ScalarSubtract(left[i], right[i]);
					}
					return new Vector<T>(ptr);
				}
				if (typeof(T) == typeof(sbyte))
				{
					sbyte* ptr2 = stackalloc sbyte[(int)(uint)Count];
					for (int j = 0; j < Count; j++)
					{
						ptr2[j] = (sbyte)(object)ScalarSubtract(left[j], right[j]);
					}
					return new Vector<T>(ptr2);
				}
				if (typeof(T) == typeof(ushort))
				{
					ushort* ptr3 = stackalloc ushort[Count];
					for (int k = 0; k < Count; k++)
					{
						ptr3[k] = (ushort)(object)ScalarSubtract(left[k], right[k]);
					}
					return new Vector<T>(ptr3);
				}
				if (typeof(T) == typeof(short))
				{
					short* ptr4 = stackalloc short[Count];
					for (int l = 0; l < Count; l++)
					{
						ptr4[l] = (short)(object)ScalarSubtract(left[l], right[l]);
					}
					return new Vector<T>(ptr4);
				}
				if (typeof(T) == typeof(uint))
				{
					uint* ptr5 = stackalloc uint[Count];
					for (int m = 0; m < Count; m++)
					{
						ptr5[m] = (uint)(object)ScalarSubtract(left[m], right[m]);
					}
					return new Vector<T>(ptr5);
				}
				if (typeof(T) == typeof(int))
				{
					int* ptr6 = stackalloc int[Count];
					for (int n = 0; n < Count; n++)
					{
						ptr6[n] = (int)(object)ScalarSubtract(left[n], right[n]);
					}
					return new Vector<T>(ptr6);
				}
				if (typeof(T) == typeof(ulong))
				{
					ulong* ptr7 = stackalloc ulong[Count];
					for (int num = 0; num < Count; num++)
					{
						ptr7[num] = (ulong)(object)ScalarSubtract(left[num], right[num]);
					}
					return new Vector<T>(ptr7);
				}
				if (typeof(T) == typeof(long))
				{
					long* ptr8 = stackalloc long[Count];
					for (int num2 = 0; num2 < Count; num2++)
					{
						ptr8[num2] = (long)(object)ScalarSubtract(left[num2], right[num2]);
					}
					return new Vector<T>(ptr8);
				}
				if (typeof(T) == typeof(float))
				{
					float* ptr9 = stackalloc float[Count];
					for (int num3 = 0; num3 < Count; num3++)
					{
						ptr9[num3] = (float)(object)ScalarSubtract(left[num3], right[num3]);
					}
					return new Vector<T>(ptr9);
				}
				if (typeof(T) == typeof(double))
				{
					double* ptr10 = stackalloc double[Count];
					for (int num4 = 0; num4 < Count; num4++)
					{
						ptr10[num4] = (double)(object)ScalarSubtract(left[num4], right[num4]);
					}
					return new Vector<T>(ptr10);
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(left.register.byte_0 - right.register.byte_0);
				result.register.byte_1 = (byte)(left.register.byte_1 - right.register.byte_1);
				result.register.byte_2 = (byte)(left.register.byte_2 - right.register.byte_2);
				result.register.byte_3 = (byte)(left.register.byte_3 - right.register.byte_3);
				result.register.byte_4 = (byte)(left.register.byte_4 - right.register.byte_4);
				result.register.byte_5 = (byte)(left.register.byte_5 - right.register.byte_5);
				result.register.byte_6 = (byte)(left.register.byte_6 - right.register.byte_6);
				result.register.byte_7 = (byte)(left.register.byte_7 - right.register.byte_7);
				result.register.byte_8 = (byte)(left.register.byte_8 - right.register.byte_8);
				result.register.byte_9 = (byte)(left.register.byte_9 - right.register.byte_9);
				result.register.byte_10 = (byte)(left.register.byte_10 - right.register.byte_10);
				result.register.byte_11 = (byte)(left.register.byte_11 - right.register.byte_11);
				result.register.byte_12 = (byte)(left.register.byte_12 - right.register.byte_12);
				result.register.byte_13 = (byte)(left.register.byte_13 - right.register.byte_13);
				result.register.byte_14 = (byte)(left.register.byte_14 - right.register.byte_14);
				result.register.byte_15 = (byte)(left.register.byte_15 - right.register.byte_15);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(left.register.sbyte_0 - right.register.sbyte_0);
				result.register.sbyte_1 = (sbyte)(left.register.sbyte_1 - right.register.sbyte_1);
				result.register.sbyte_2 = (sbyte)(left.register.sbyte_2 - right.register.sbyte_2);
				result.register.sbyte_3 = (sbyte)(left.register.sbyte_3 - right.register.sbyte_3);
				result.register.sbyte_4 = (sbyte)(left.register.sbyte_4 - right.register.sbyte_4);
				result.register.sbyte_5 = (sbyte)(left.register.sbyte_5 - right.register.sbyte_5);
				result.register.sbyte_6 = (sbyte)(left.register.sbyte_6 - right.register.sbyte_6);
				result.register.sbyte_7 = (sbyte)(left.register.sbyte_7 - right.register.sbyte_7);
				result.register.sbyte_8 = (sbyte)(left.register.sbyte_8 - right.register.sbyte_8);
				result.register.sbyte_9 = (sbyte)(left.register.sbyte_9 - right.register.sbyte_9);
				result.register.sbyte_10 = (sbyte)(left.register.sbyte_10 - right.register.sbyte_10);
				result.register.sbyte_11 = (sbyte)(left.register.sbyte_11 - right.register.sbyte_11);
				result.register.sbyte_12 = (sbyte)(left.register.sbyte_12 - right.register.sbyte_12);
				result.register.sbyte_13 = (sbyte)(left.register.sbyte_13 - right.register.sbyte_13);
				result.register.sbyte_14 = (sbyte)(left.register.sbyte_14 - right.register.sbyte_14);
				result.register.sbyte_15 = (sbyte)(left.register.sbyte_15 - right.register.sbyte_15);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(left.register.uint16_0 - right.register.uint16_0);
				result.register.uint16_1 = (ushort)(left.register.uint16_1 - right.register.uint16_1);
				result.register.uint16_2 = (ushort)(left.register.uint16_2 - right.register.uint16_2);
				result.register.uint16_3 = (ushort)(left.register.uint16_3 - right.register.uint16_3);
				result.register.uint16_4 = (ushort)(left.register.uint16_4 - right.register.uint16_4);
				result.register.uint16_5 = (ushort)(left.register.uint16_5 - right.register.uint16_5);
				result.register.uint16_6 = (ushort)(left.register.uint16_6 - right.register.uint16_6);
				result.register.uint16_7 = (ushort)(left.register.uint16_7 - right.register.uint16_7);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(left.register.int16_0 - right.register.int16_0);
				result.register.int16_1 = (short)(left.register.int16_1 - right.register.int16_1);
				result.register.int16_2 = (short)(left.register.int16_2 - right.register.int16_2);
				result.register.int16_3 = (short)(left.register.int16_3 - right.register.int16_3);
				result.register.int16_4 = (short)(left.register.int16_4 - right.register.int16_4);
				result.register.int16_5 = (short)(left.register.int16_5 - right.register.int16_5);
				result.register.int16_6 = (short)(left.register.int16_6 - right.register.int16_6);
				result.register.int16_7 = (short)(left.register.int16_7 - right.register.int16_7);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = left.register.uint32_0 - right.register.uint32_0;
				result.register.uint32_1 = left.register.uint32_1 - right.register.uint32_1;
				result.register.uint32_2 = left.register.uint32_2 - right.register.uint32_2;
				result.register.uint32_3 = left.register.uint32_3 - right.register.uint32_3;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = left.register.int32_0 - right.register.int32_0;
				result.register.int32_1 = left.register.int32_1 - right.register.int32_1;
				result.register.int32_2 = left.register.int32_2 - right.register.int32_2;
				result.register.int32_3 = left.register.int32_3 - right.register.int32_3;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = left.register.uint64_0 - right.register.uint64_0;
				result.register.uint64_1 = left.register.uint64_1 - right.register.uint64_1;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = left.register.int64_0 - right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 - right.register.int64_1;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = left.register.single_0 - right.register.single_0;
				result.register.single_1 = left.register.single_1 - right.register.single_1;
				result.register.single_2 = left.register.single_2 - right.register.single_2;
				result.register.single_3 = left.register.single_3 - right.register.single_3;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = left.register.double_0 - right.register.double_0;
				result.register.double_1 = left.register.double_1 - right.register.double_1;
			}
			return result;
		}

		public unsafe static Vector<T>operator *(Vector<T> left, Vector<T> right)
		{
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					byte* ptr = stackalloc byte[(int)(uint)Count];
					for (int i = 0; i < Count; i++)
					{
						ptr[i] = (byte)(object)ScalarMultiply(left[i], right[i]);
					}
					return new Vector<T>(ptr);
				}
				if (typeof(T) == typeof(sbyte))
				{
					sbyte* ptr2 = stackalloc sbyte[(int)(uint)Count];
					for (int j = 0; j < Count; j++)
					{
						ptr2[j] = (sbyte)(object)ScalarMultiply(left[j], right[j]);
					}
					return new Vector<T>(ptr2);
				}
				if (typeof(T) == typeof(ushort))
				{
					ushort* ptr3 = stackalloc ushort[Count];
					for (int k = 0; k < Count; k++)
					{
						ptr3[k] = (ushort)(object)ScalarMultiply(left[k], right[k]);
					}
					return new Vector<T>(ptr3);
				}
				if (typeof(T) == typeof(short))
				{
					short* ptr4 = stackalloc short[Count];
					for (int l = 0; l < Count; l++)
					{
						ptr4[l] = (short)(object)ScalarMultiply(left[l], right[l]);
					}
					return new Vector<T>(ptr4);
				}
				if (typeof(T) == typeof(uint))
				{
					uint* ptr5 = stackalloc uint[Count];
					for (int m = 0; m < Count; m++)
					{
						ptr5[m] = (uint)(object)ScalarMultiply(left[m], right[m]);
					}
					return new Vector<T>(ptr5);
				}
				if (typeof(T) == typeof(int))
				{
					int* ptr6 = stackalloc int[Count];
					for (int n = 0; n < Count; n++)
					{
						ptr6[n] = (int)(object)ScalarMultiply(left[n], right[n]);
					}
					return new Vector<T>(ptr6);
				}
				if (typeof(T) == typeof(ulong))
				{
					ulong* ptr7 = stackalloc ulong[Count];
					for (int num = 0; num < Count; num++)
					{
						ptr7[num] = (ulong)(object)ScalarMultiply(left[num], right[num]);
					}
					return new Vector<T>(ptr7);
				}
				if (typeof(T) == typeof(long))
				{
					long* ptr8 = stackalloc long[Count];
					for (int num2 = 0; num2 < Count; num2++)
					{
						ptr8[num2] = (long)(object)ScalarMultiply(left[num2], right[num2]);
					}
					return new Vector<T>(ptr8);
				}
				if (typeof(T) == typeof(float))
				{
					float* ptr9 = stackalloc float[Count];
					for (int num3 = 0; num3 < Count; num3++)
					{
						ptr9[num3] = (float)(object)ScalarMultiply(left[num3], right[num3]);
					}
					return new Vector<T>(ptr9);
				}
				if (typeof(T) == typeof(double))
				{
					double* ptr10 = stackalloc double[Count];
					for (int num4 = 0; num4 < Count; num4++)
					{
						ptr10[num4] = (double)(object)ScalarMultiply(left[num4], right[num4]);
					}
					return new Vector<T>(ptr10);
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(left.register.byte_0 * right.register.byte_0);
				result.register.byte_1 = (byte)(left.register.byte_1 * right.register.byte_1);
				result.register.byte_2 = (byte)(left.register.byte_2 * right.register.byte_2);
				result.register.byte_3 = (byte)(left.register.byte_3 * right.register.byte_3);
				result.register.byte_4 = (byte)(left.register.byte_4 * right.register.byte_4);
				result.register.byte_5 = (byte)(left.register.byte_5 * right.register.byte_5);
				result.register.byte_6 = (byte)(left.register.byte_6 * right.register.byte_6);
				result.register.byte_7 = (byte)(left.register.byte_7 * right.register.byte_7);
				result.register.byte_8 = (byte)(left.register.byte_8 * right.register.byte_8);
				result.register.byte_9 = (byte)(left.register.byte_9 * right.register.byte_9);
				result.register.byte_10 = (byte)(left.register.byte_10 * right.register.byte_10);
				result.register.byte_11 = (byte)(left.register.byte_11 * right.register.byte_11);
				result.register.byte_12 = (byte)(left.register.byte_12 * right.register.byte_12);
				result.register.byte_13 = (byte)(left.register.byte_13 * right.register.byte_13);
				result.register.byte_14 = (byte)(left.register.byte_14 * right.register.byte_14);
				result.register.byte_15 = (byte)(left.register.byte_15 * right.register.byte_15);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(left.register.sbyte_0 * right.register.sbyte_0);
				result.register.sbyte_1 = (sbyte)(left.register.sbyte_1 * right.register.sbyte_1);
				result.register.sbyte_2 = (sbyte)(left.register.sbyte_2 * right.register.sbyte_2);
				result.register.sbyte_3 = (sbyte)(left.register.sbyte_3 * right.register.sbyte_3);
				result.register.sbyte_4 = (sbyte)(left.register.sbyte_4 * right.register.sbyte_4);
				result.register.sbyte_5 = (sbyte)(left.register.sbyte_5 * right.register.sbyte_5);
				result.register.sbyte_6 = (sbyte)(left.register.sbyte_6 * right.register.sbyte_6);
				result.register.sbyte_7 = (sbyte)(left.register.sbyte_7 * right.register.sbyte_7);
				result.register.sbyte_8 = (sbyte)(left.register.sbyte_8 * right.register.sbyte_8);
				result.register.sbyte_9 = (sbyte)(left.register.sbyte_9 * right.register.sbyte_9);
				result.register.sbyte_10 = (sbyte)(left.register.sbyte_10 * right.register.sbyte_10);
				result.register.sbyte_11 = (sbyte)(left.register.sbyte_11 * right.register.sbyte_11);
				result.register.sbyte_12 = (sbyte)(left.register.sbyte_12 * right.register.sbyte_12);
				result.register.sbyte_13 = (sbyte)(left.register.sbyte_13 * right.register.sbyte_13);
				result.register.sbyte_14 = (sbyte)(left.register.sbyte_14 * right.register.sbyte_14);
				result.register.sbyte_15 = (sbyte)(left.register.sbyte_15 * right.register.sbyte_15);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(left.register.uint16_0 * right.register.uint16_0);
				result.register.uint16_1 = (ushort)(left.register.uint16_1 * right.register.uint16_1);
				result.register.uint16_2 = (ushort)(left.register.uint16_2 * right.register.uint16_2);
				result.register.uint16_3 = (ushort)(left.register.uint16_3 * right.register.uint16_3);
				result.register.uint16_4 = (ushort)(left.register.uint16_4 * right.register.uint16_4);
				result.register.uint16_5 = (ushort)(left.register.uint16_5 * right.register.uint16_5);
				result.register.uint16_6 = (ushort)(left.register.uint16_6 * right.register.uint16_6);
				result.register.uint16_7 = (ushort)(left.register.uint16_7 * right.register.uint16_7);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(left.register.int16_0 * right.register.int16_0);
				result.register.int16_1 = (short)(left.register.int16_1 * right.register.int16_1);
				result.register.int16_2 = (short)(left.register.int16_2 * right.register.int16_2);
				result.register.int16_3 = (short)(left.register.int16_3 * right.register.int16_3);
				result.register.int16_4 = (short)(left.register.int16_4 * right.register.int16_4);
				result.register.int16_5 = (short)(left.register.int16_5 * right.register.int16_5);
				result.register.int16_6 = (short)(left.register.int16_6 * right.register.int16_6);
				result.register.int16_7 = (short)(left.register.int16_7 * right.register.int16_7);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = left.register.uint32_0 * right.register.uint32_0;
				result.register.uint32_1 = left.register.uint32_1 * right.register.uint32_1;
				result.register.uint32_2 = left.register.uint32_2 * right.register.uint32_2;
				result.register.uint32_3 = left.register.uint32_3 * right.register.uint32_3;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = left.register.int32_0 * right.register.int32_0;
				result.register.int32_1 = left.register.int32_1 * right.register.int32_1;
				result.register.int32_2 = left.register.int32_2 * right.register.int32_2;
				result.register.int32_3 = left.register.int32_3 * right.register.int32_3;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = left.register.uint64_0 * right.register.uint64_0;
				result.register.uint64_1 = left.register.uint64_1 * right.register.uint64_1;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = left.register.int64_0 * right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 * right.register.int64_1;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = left.register.single_0 * right.register.single_0;
				result.register.single_1 = left.register.single_1 * right.register.single_1;
				result.register.single_2 = left.register.single_2 * right.register.single_2;
				result.register.single_3 = left.register.single_3 * right.register.single_3;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = left.register.double_0 * right.register.double_0;
				result.register.double_1 = left.register.double_1 * right.register.double_1;
			}
			return result;
		}

		public static Vector<T>operator *(Vector<T> value, T factor)
		{
			if (Vector.IsHardwareAccelerated)
			{
				return new Vector<T>(factor) * value;
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(value.register.byte_0 * (byte)(object)factor);
				result.register.byte_1 = (byte)(value.register.byte_1 * (byte)(object)factor);
				result.register.byte_2 = (byte)(value.register.byte_2 * (byte)(object)factor);
				result.register.byte_3 = (byte)(value.register.byte_3 * (byte)(object)factor);
				result.register.byte_4 = (byte)(value.register.byte_4 * (byte)(object)factor);
				result.register.byte_5 = (byte)(value.register.byte_5 * (byte)(object)factor);
				result.register.byte_6 = (byte)(value.register.byte_6 * (byte)(object)factor);
				result.register.byte_7 = (byte)(value.register.byte_7 * (byte)(object)factor);
				result.register.byte_8 = (byte)(value.register.byte_8 * (byte)(object)factor);
				result.register.byte_9 = (byte)(value.register.byte_9 * (byte)(object)factor);
				result.register.byte_10 = (byte)(value.register.byte_10 * (byte)(object)factor);
				result.register.byte_11 = (byte)(value.register.byte_11 * (byte)(object)factor);
				result.register.byte_12 = (byte)(value.register.byte_12 * (byte)(object)factor);
				result.register.byte_13 = (byte)(value.register.byte_13 * (byte)(object)factor);
				result.register.byte_14 = (byte)(value.register.byte_14 * (byte)(object)factor);
				result.register.byte_15 = (byte)(value.register.byte_15 * (byte)(object)factor);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(value.register.sbyte_0 * (sbyte)(object)factor);
				result.register.sbyte_1 = (sbyte)(value.register.sbyte_1 * (sbyte)(object)factor);
				result.register.sbyte_2 = (sbyte)(value.register.sbyte_2 * (sbyte)(object)factor);
				result.register.sbyte_3 = (sbyte)(value.register.sbyte_3 * (sbyte)(object)factor);
				result.register.sbyte_4 = (sbyte)(value.register.sbyte_4 * (sbyte)(object)factor);
				result.register.sbyte_5 = (sbyte)(value.register.sbyte_5 * (sbyte)(object)factor);
				result.register.sbyte_6 = (sbyte)(value.register.sbyte_6 * (sbyte)(object)factor);
				result.register.sbyte_7 = (sbyte)(value.register.sbyte_7 * (sbyte)(object)factor);
				result.register.sbyte_8 = (sbyte)(value.register.sbyte_8 * (sbyte)(object)factor);
				result.register.sbyte_9 = (sbyte)(value.register.sbyte_9 * (sbyte)(object)factor);
				result.register.sbyte_10 = (sbyte)(value.register.sbyte_10 * (sbyte)(object)factor);
				result.register.sbyte_11 = (sbyte)(value.register.sbyte_11 * (sbyte)(object)factor);
				result.register.sbyte_12 = (sbyte)(value.register.sbyte_12 * (sbyte)(object)factor);
				result.register.sbyte_13 = (sbyte)(value.register.sbyte_13 * (sbyte)(object)factor);
				result.register.sbyte_14 = (sbyte)(value.register.sbyte_14 * (sbyte)(object)factor);
				result.register.sbyte_15 = (sbyte)(value.register.sbyte_15 * (sbyte)(object)factor);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(value.register.uint16_0 * (ushort)(object)factor);
				result.register.uint16_1 = (ushort)(value.register.uint16_1 * (ushort)(object)factor);
				result.register.uint16_2 = (ushort)(value.register.uint16_2 * (ushort)(object)factor);
				result.register.uint16_3 = (ushort)(value.register.uint16_3 * (ushort)(object)factor);
				result.register.uint16_4 = (ushort)(value.register.uint16_4 * (ushort)(object)factor);
				result.register.uint16_5 = (ushort)(value.register.uint16_5 * (ushort)(object)factor);
				result.register.uint16_6 = (ushort)(value.register.uint16_6 * (ushort)(object)factor);
				result.register.uint16_7 = (ushort)(value.register.uint16_7 * (ushort)(object)factor);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(value.register.int16_0 * (short)(object)factor);
				result.register.int16_1 = (short)(value.register.int16_1 * (short)(object)factor);
				result.register.int16_2 = (short)(value.register.int16_2 * (short)(object)factor);
				result.register.int16_3 = (short)(value.register.int16_3 * (short)(object)factor);
				result.register.int16_4 = (short)(value.register.int16_4 * (short)(object)factor);
				result.register.int16_5 = (short)(value.register.int16_5 * (short)(object)factor);
				result.register.int16_6 = (short)(value.register.int16_6 * (short)(object)factor);
				result.register.int16_7 = (short)(value.register.int16_7 * (short)(object)factor);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = value.register.uint32_0 * (uint)(object)factor;
				result.register.uint32_1 = value.register.uint32_1 * (uint)(object)factor;
				result.register.uint32_2 = value.register.uint32_2 * (uint)(object)factor;
				result.register.uint32_3 = value.register.uint32_3 * (uint)(object)factor;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = value.register.int32_0 * (int)(object)factor;
				result.register.int32_1 = value.register.int32_1 * (int)(object)factor;
				result.register.int32_2 = value.register.int32_2 * (int)(object)factor;
				result.register.int32_3 = value.register.int32_3 * (int)(object)factor;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = value.register.uint64_0 * (ulong)(object)factor;
				result.register.uint64_1 = value.register.uint64_1 * (ulong)(object)factor;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = value.register.int64_0 * (long)(object)factor;
				result.register.int64_1 = value.register.int64_1 * (long)(object)factor;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = value.register.single_0 * (float)(object)factor;
				result.register.single_1 = value.register.single_1 * (float)(object)factor;
				result.register.single_2 = value.register.single_2 * (float)(object)factor;
				result.register.single_3 = value.register.single_3 * (float)(object)factor;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = value.register.double_0 * (double)(object)factor;
				result.register.double_1 = value.register.double_1 * (double)(object)factor;
			}
			return result;
		}

		public static Vector<T>operator *(T factor, Vector<T> value)
		{
			if (Vector.IsHardwareAccelerated)
			{
				return new Vector<T>(factor) * value;
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(value.register.byte_0 * (byte)(object)factor);
				result.register.byte_1 = (byte)(value.register.byte_1 * (byte)(object)factor);
				result.register.byte_2 = (byte)(value.register.byte_2 * (byte)(object)factor);
				result.register.byte_3 = (byte)(value.register.byte_3 * (byte)(object)factor);
				result.register.byte_4 = (byte)(value.register.byte_4 * (byte)(object)factor);
				result.register.byte_5 = (byte)(value.register.byte_5 * (byte)(object)factor);
				result.register.byte_6 = (byte)(value.register.byte_6 * (byte)(object)factor);
				result.register.byte_7 = (byte)(value.register.byte_7 * (byte)(object)factor);
				result.register.byte_8 = (byte)(value.register.byte_8 * (byte)(object)factor);
				result.register.byte_9 = (byte)(value.register.byte_9 * (byte)(object)factor);
				result.register.byte_10 = (byte)(value.register.byte_10 * (byte)(object)factor);
				result.register.byte_11 = (byte)(value.register.byte_11 * (byte)(object)factor);
				result.register.byte_12 = (byte)(value.register.byte_12 * (byte)(object)factor);
				result.register.byte_13 = (byte)(value.register.byte_13 * (byte)(object)factor);
				result.register.byte_14 = (byte)(value.register.byte_14 * (byte)(object)factor);
				result.register.byte_15 = (byte)(value.register.byte_15 * (byte)(object)factor);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(value.register.sbyte_0 * (sbyte)(object)factor);
				result.register.sbyte_1 = (sbyte)(value.register.sbyte_1 * (sbyte)(object)factor);
				result.register.sbyte_2 = (sbyte)(value.register.sbyte_2 * (sbyte)(object)factor);
				result.register.sbyte_3 = (sbyte)(value.register.sbyte_3 * (sbyte)(object)factor);
				result.register.sbyte_4 = (sbyte)(value.register.sbyte_4 * (sbyte)(object)factor);
				result.register.sbyte_5 = (sbyte)(value.register.sbyte_5 * (sbyte)(object)factor);
				result.register.sbyte_6 = (sbyte)(value.register.sbyte_6 * (sbyte)(object)factor);
				result.register.sbyte_7 = (sbyte)(value.register.sbyte_7 * (sbyte)(object)factor);
				result.register.sbyte_8 = (sbyte)(value.register.sbyte_8 * (sbyte)(object)factor);
				result.register.sbyte_9 = (sbyte)(value.register.sbyte_9 * (sbyte)(object)factor);
				result.register.sbyte_10 = (sbyte)(value.register.sbyte_10 * (sbyte)(object)factor);
				result.register.sbyte_11 = (sbyte)(value.register.sbyte_11 * (sbyte)(object)factor);
				result.register.sbyte_12 = (sbyte)(value.register.sbyte_12 * (sbyte)(object)factor);
				result.register.sbyte_13 = (sbyte)(value.register.sbyte_13 * (sbyte)(object)factor);
				result.register.sbyte_14 = (sbyte)(value.register.sbyte_14 * (sbyte)(object)factor);
				result.register.sbyte_15 = (sbyte)(value.register.sbyte_15 * (sbyte)(object)factor);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(value.register.uint16_0 * (ushort)(object)factor);
				result.register.uint16_1 = (ushort)(value.register.uint16_1 * (ushort)(object)factor);
				result.register.uint16_2 = (ushort)(value.register.uint16_2 * (ushort)(object)factor);
				result.register.uint16_3 = (ushort)(value.register.uint16_3 * (ushort)(object)factor);
				result.register.uint16_4 = (ushort)(value.register.uint16_4 * (ushort)(object)factor);
				result.register.uint16_5 = (ushort)(value.register.uint16_5 * (ushort)(object)factor);
				result.register.uint16_6 = (ushort)(value.register.uint16_6 * (ushort)(object)factor);
				result.register.uint16_7 = (ushort)(value.register.uint16_7 * (ushort)(object)factor);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(value.register.int16_0 * (short)(object)factor);
				result.register.int16_1 = (short)(value.register.int16_1 * (short)(object)factor);
				result.register.int16_2 = (short)(value.register.int16_2 * (short)(object)factor);
				result.register.int16_3 = (short)(value.register.int16_3 * (short)(object)factor);
				result.register.int16_4 = (short)(value.register.int16_4 * (short)(object)factor);
				result.register.int16_5 = (short)(value.register.int16_5 * (short)(object)factor);
				result.register.int16_6 = (short)(value.register.int16_6 * (short)(object)factor);
				result.register.int16_7 = (short)(value.register.int16_7 * (short)(object)factor);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = value.register.uint32_0 * (uint)(object)factor;
				result.register.uint32_1 = value.register.uint32_1 * (uint)(object)factor;
				result.register.uint32_2 = value.register.uint32_2 * (uint)(object)factor;
				result.register.uint32_3 = value.register.uint32_3 * (uint)(object)factor;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = value.register.int32_0 * (int)(object)factor;
				result.register.int32_1 = value.register.int32_1 * (int)(object)factor;
				result.register.int32_2 = value.register.int32_2 * (int)(object)factor;
				result.register.int32_3 = value.register.int32_3 * (int)(object)factor;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = value.register.uint64_0 * (ulong)(object)factor;
				result.register.uint64_1 = value.register.uint64_1 * (ulong)(object)factor;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = value.register.int64_0 * (long)(object)factor;
				result.register.int64_1 = value.register.int64_1 * (long)(object)factor;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = value.register.single_0 * (float)(object)factor;
				result.register.single_1 = value.register.single_1 * (float)(object)factor;
				result.register.single_2 = value.register.single_2 * (float)(object)factor;
				result.register.single_3 = value.register.single_3 * (float)(object)factor;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = value.register.double_0 * (double)(object)factor;
				result.register.double_1 = value.register.double_1 * (double)(object)factor;
			}
			return result;
		}

		public unsafe static Vector<T>operator /(Vector<T> left, Vector<T> right)
		{
			if (Vector.IsHardwareAccelerated)
			{
				if (typeof(T) == typeof(byte))
				{
					byte* ptr = stackalloc byte[(int)(uint)Count];
					for (int i = 0; i < Count; i++)
					{
						ptr[i] = (byte)(object)ScalarDivide(left[i], right[i]);
					}
					return new Vector<T>(ptr);
				}
				if (typeof(T) == typeof(sbyte))
				{
					sbyte* ptr2 = stackalloc sbyte[(int)(uint)Count];
					for (int j = 0; j < Count; j++)
					{
						ptr2[j] = (sbyte)(object)ScalarDivide(left[j], right[j]);
					}
					return new Vector<T>(ptr2);
				}
				if (typeof(T) == typeof(ushort))
				{
					ushort* ptr3 = stackalloc ushort[Count];
					for (int k = 0; k < Count; k++)
					{
						ptr3[k] = (ushort)(object)ScalarDivide(left[k], right[k]);
					}
					return new Vector<T>(ptr3);
				}
				if (typeof(T) == typeof(short))
				{
					short* ptr4 = stackalloc short[Count];
					for (int l = 0; l < Count; l++)
					{
						ptr4[l] = (short)(object)ScalarDivide(left[l], right[l]);
					}
					return new Vector<T>(ptr4);
				}
				if (typeof(T) == typeof(uint))
				{
					uint* ptr5 = stackalloc uint[Count];
					for (int m = 0; m < Count; m++)
					{
						ptr5[m] = (uint)(object)ScalarDivide(left[m], right[m]);
					}
					return new Vector<T>(ptr5);
				}
				if (typeof(T) == typeof(int))
				{
					int* ptr6 = stackalloc int[Count];
					for (int n = 0; n < Count; n++)
					{
						ptr6[n] = (int)(object)ScalarDivide(left[n], right[n]);
					}
					return new Vector<T>(ptr6);
				}
				if (typeof(T) == typeof(ulong))
				{
					ulong* ptr7 = stackalloc ulong[Count];
					for (int num = 0; num < Count; num++)
					{
						ptr7[num] = (ulong)(object)ScalarDivide(left[num], right[num]);
					}
					return new Vector<T>(ptr7);
				}
				if (typeof(T) == typeof(long))
				{
					long* ptr8 = stackalloc long[Count];
					for (int num2 = 0; num2 < Count; num2++)
					{
						ptr8[num2] = (long)(object)ScalarDivide(left[num2], right[num2]);
					}
					return new Vector<T>(ptr8);
				}
				if (typeof(T) == typeof(float))
				{
					float* ptr9 = stackalloc float[Count];
					for (int num3 = 0; num3 < Count; num3++)
					{
						ptr9[num3] = (float)(object)ScalarDivide(left[num3], right[num3]);
					}
					return new Vector<T>(ptr9);
				}
				if (typeof(T) == typeof(double))
				{
					double* ptr10 = stackalloc double[Count];
					for (int num4 = 0; num4 < Count; num4++)
					{
						ptr10[num4] = (double)(object)ScalarDivide(left[num4], right[num4]);
					}
					return new Vector<T>(ptr10);
				}
				throw new NotSupportedException(System.SR.Arg_TypeNotSupported);
			}
			Vector<T> result = default(Vector<T>);
			if (typeof(T) == typeof(byte))
			{
				result.register.byte_0 = (byte)(left.register.byte_0 / right.register.byte_0);
				result.register.byte_1 = (byte)(left.register.byte_1 / right.register.byte_1);
				result.register.byte_2 = (byte)(left.register.byte_2 / right.register.byte_2);
				result.register.byte_3 = (byte)(left.register.byte_3 / right.register.byte_3);
				result.register.byte_4 = (byte)(left.register.byte_4 / right.register.byte_4);
				result.register.byte_5 = (byte)(left.register.byte_5 / right.register.byte_5);
				result.register.byte_6 = (byte)(left.register.byte_6 / right.register.byte_6);
				result.register.byte_7 = (byte)(left.register.byte_7 / right.register.byte_7);
				result.register.byte_8 = (byte)(left.register.byte_8 / right.register.byte_8);
				result.register.byte_9 = (byte)(left.register.byte_9 / right.register.byte_9);
				result.register.byte_10 = (byte)(left.register.byte_10 / right.register.byte_10);
				result.register.byte_11 = (byte)(left.register.byte_11 / right.register.byte_11);
				result.register.byte_12 = (byte)(left.register.byte_12 / right.register.byte_12);
				result.register.byte_13 = (byte)(left.register.byte_13 / right.register.byte_13);
				result.register.byte_14 = (byte)(left.register.byte_14 / right.register.byte_14);
				result.register.byte_15 = (byte)(left.register.byte_15 / right.register.byte_15);
			}
			else if (typeof(T) == typeof(sbyte))
			{
				result.register.sbyte_0 = (sbyte)(left.register.sbyte_0 / right.register.sbyte_0);
				result.register.sbyte_1 = (sbyte)(left.register.sbyte_1 / right.register.sbyte_1);
				result.register.sbyte_2 = (sbyte)(left.register.sbyte_2 / right.register.sbyte_2);
				result.register.sbyte_3 = (sbyte)(left.register.sbyte_3 / right.register.sbyte_3);
				result.register.sbyte_4 = (sbyte)(left.register.sbyte_4 / right.register.sbyte_4);
				result.register.sbyte_5 = (sbyte)(left.register.sbyte_5 / right.register.sbyte_5);
				result.register.sbyte_6 = (sbyte)(left.register.sbyte_6 / right.register.sbyte_6);
				result.register.sbyte_7 = (sbyte)(left.register.sbyte_7 / right.register.sbyte_7);
				result.register.sbyte_8 = (sbyte)(left.register.sbyte_8 / right.register.sbyte_8);
				result.register.sbyte_9 = (sbyte)(left.register.sbyte_9 / right.register.sbyte_9);
				result.register.sbyte_10 = (sbyte)(left.register.sbyte_10 / right.register.sbyte_10);
				result.register.sbyte_11 = (sbyte)(left.register.sbyte_11 / right.register.sbyte_11);
				result.register.sbyte_12 = (sbyte)(left.register.sbyte_12 / right.register.sbyte_12);
				result.register.sbyte_13 = (sbyte)(left.register.sbyte_13 / right.register.sbyte_13);
				result.register.sbyte_14 = (sbyte)(left.register.sbyte_14 / right.register.sbyte_14);
				result.register.sbyte_15 = (sbyte)(left.register.sbyte_15 / right.register.sbyte_15);
			}
			else if (typeof(T) == typeof(ushort))
			{
				result.register.uint16_0 = (ushort)(left.register.uint16_0 / right.register.uint16_0);
				result.register.uint16_1 = (ushort)(left.register.uint16_1 / right.register.uint16_1);
				result.register.uint16_2 = (ushort)(left.register.uint16_2 / right.register.uint16_2);
				result.register.uint16_3 = (ushort)(left.register.uint16_3 / right.register.uint16_3);
				result.register.uint16_4 = (ushort)(left.register.uint16_4 / right.register.uint16_4);
				result.register.uint16_5 = (ushort)(left.register.uint16_5 / right.register.uint16_5);
				result.register.uint16_6 = (ushort)(left.register.uint16_6 / right.register.uint16_6);
				result.register.uint16_7 = (ushort)(left.register.uint16_7 / right.register.uint16_7);
			}
			else if (typeof(T) == typeof(short))
			{
				result.register.int16_0 = (short)(left.register.int16_0 / right.register.int16_0);
				result.register.int16_1 = (short)(left.register.int16_1 / right.register.int16_1);
				result.register.int16_2 = (short)(left.register.int16_2 / right.register.int16_2);
				result.register.int16_3 = (short)(left.register.int16_3 / right.register.int16_3);
				result.register.int16_4 = (short)(left.register.int16_4 / right.register.int16_4);
				result.register.int16_5 = (short)(left.register.int16_5 / right.register.int16_5);
				result.register.int16_6 = (short)(left.register.int16_6 / right.register.int16_6);
				result.register.int16_7 = (short)(left.register.int16_7 / right.register.int16_7);
			}
			else if (typeof(T) == typeof(uint))
			{
				result.register.uint32_0 = left.register.uint32_0 / right.register.uint32_0;
				result.register.uint32_1 = left.register.uint32_1 / right.register.uint32_1;
				result.register.uint32_2 = left.register.uint32_2 / right.register.uint32_2;
				result.register.uint32_3 = left.register.uint32_3 / right.register.uint32_3;
			}
			else if (typeof(T) == typeof(int))
			{
				result.register.int32_0 = left.register.int32_0 / right.register.int32_0;
				result.register.int32_1 = left.register.int32_1 / right.register.int32_1;
				result.register.int32_2 = left.register.int32_2 / right.register.int32_2;
				result.register.int32_3 = left.register.int32_3 / right.register.int32_3;
			}
			else if (typeof(T) == typeof(ulong))
			{
				result.register.uint64_0 = left.register.uint64_0 / right.register.uint64_0;
				result.register.uint64_1 = left.register.uint64_1 / right.register.uint64_1;
			}
			else if (typeof(T) == typeof(long))
			{
				result.register.int64_0 = left.register.int64_0 / right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 / right.register.int64_1;
			}
			else if (typeof(T) == typeof(float))
			{
				result.register.single_0 = left.register.single_0 / right.register.single_0;
				result.register.single_1 = left.register.single_1 / right.register.single_1;
				result.register.single_2 = left.register.single_2 / right.register.single_2;
				result.register.single_3 = left.register.single_3 / right.register.single_3;
			}
			else if (typeof(T) == typeof(double))
			{
				result.register.double_0 = left.register.double_0 / right.register.double_0;
				result.register.double_1 = left.register.double_1 / right.register.double_1;
			}
			return result;
		}

		public static Vector<T>operator -(Vector<T> value)
		{
			return Zero - value;
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public unsafe static Vector<T>operator &(Vector<T> left, Vector<T> right)
		{
			Vector<T> result = default(Vector<T>);
			if (Vector.IsHardwareAccelerated)
			{
				long* ptr = &result.register.int64_0;
				long* ptr2 = &left.register.int64_0;
				long* ptr3 = &right.register.int64_0;
				for (int i = 0; i < Vector<long>.Count; i++)
				{
					ptr[i] = ptr2[i] & ptr3[i];
				}
			}
			else
			{
				result.register.int64_0 = left.register.int64_0 & right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 & right.register.int64_1;
			}
			return result;
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public unsafe static Vector<T>operator |(Vector<T> left, Vector<T> right)
		{
			Vector<T> result = default(Vector<T>);
			if (Vector.IsHardwareAccelerated)
			{
				long* ptr = &result.register.int64_0;
				long* ptr2 = &left.register.int64_0;
				long* ptr3 = &right.register.int64_0;
				for (int i = 0; i < Vector<long>.Count; i++)
				{
					ptr[i] = ptr2[i] | ptr3[i];
				}
			}
			else
			{
				result.register.int64_0 = left.register.int64_0 | right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 | right.register.int64_1;
			}
			return result;
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public unsafe static Vector<T>operator ^(Vector<T> left, Vector<T> right)
		{
			Vector<T> result = default(Vector<T>);
			if (Vector.IsHardwareAccelerated)
			{
				long* ptr = &result.register.int64_0;
				long* ptr2 = &left.register.int64_0;
				long* ptr3 = &right.register.int64_0;
				for (int i = 0; i < Vector<long>.Count; i++)
				{
					ptr[i] = ptr2[i] ^ ptr3[i];
				}
			}
			else
			{
				result.register.int64_0 = left.register.int64_0 ^ right.register.int64_0;
				result.register.int64_1 = left.register.int64_1 ^ right.register.int64_1;
			}
			return result;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static Vector<T>operator ~(Vector<T> value)
		{
			return s_allOnes ^ value;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool operator ==(Vector<T> left, Vector<T> right)
		{
			return left.Equals(right);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static bool operator !=(Vector<T> left, Vector<T> right)
		{
			return !(left == right);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<byte>(Vector<T> value)
		{
			return new Vector<byte>(ref value.register);
		}

		[CLSCompliant(false)]
		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<sbyte>(Vector<T> value)
		{
			return new Vector<sbyte>(ref value.register);
		}

		[CLSCompliant(false)]
		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<ushort>(Vector<T> value)
		{
			return new Vector<ushort>(ref value.register);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<short>(Vector<T> value)
		{
			return new Vector<short>(ref value.register);
		}

		[CLSCompliant(false)]
		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<uint>(Vector<T> value)
		{
			return new Vector<uint>(ref value.register);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<int>(Vector<T> value)
		{
			return new Vector<int>(ref value.register);
		}

		[CLSCompliant(false)]
		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<ulong>(Vector<T> value)
		{
			return new Vector<ulong>(ref value.register);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<long>(Vector<T> value)
		{
			return new Vector<long>(ref value.register);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<float>(Vector<T> value)
		{
			return new Vector<float>(ref value.register);
		}

		[System.Runtime.CompilerServices.Intrinsic]
		public static explicit operator Vector<double>(Vector<T> value)
		{
			return new Vector<double>(ref value.register);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Compile

System.Runtime.CompilerServices.Unsafe.dll

Decompiled 4 hours ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;

[assembly: AssemblyCompany("Microsoft Corporation")]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyFileVersion("4.0.0.0")]
[assembly: AssemblyInformationalVersion("4.0.0.0")]
[assembly: AssemblyTitle("System.Runtime.CompilerServices.Unsafe")]
[assembly: AssemblyDescription("System.Runtime.CompilerServices.Unsafe")]
[assembly: AssemblyMetadata(".NETFrameworkAssembly", "")]
[assembly: AssemblyMetadata("Serviceable", "True")]
[assembly: AssemblyCopyright("© Microsoft Corporation.  All rights reserved.")]
[assembly: AssemblyProduct("Microsoft® .NET Framework")]
[assembly: CLSCompliant(false)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("4.0.4.1")]
namespace System.Runtime.CompilerServices
{
	public static class Unsafe
	{
		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static T Read<T>(void* source)
		{
			return Unsafe.Read<T>(source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static T ReadUnaligned<T>(void* source)
		{
			return Unsafe.ReadUnaligned<T>(source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static T ReadUnaligned<T>(ref byte source)
		{
			return Unsafe.ReadUnaligned<T>(ref source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void Write<T>(void* destination, T value)
		{
			Unsafe.Write(destination, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void WriteUnaligned<T>(void* destination, T value)
		{
			Unsafe.WriteUnaligned(destination, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void WriteUnaligned<T>(ref byte destination, T value)
		{
			Unsafe.WriteUnaligned(ref destination, value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void Copy<T>(void* destination, ref T source)
		{
			Unsafe.Write(destination, source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void Copy<T>(ref T destination, void* source)
		{
			destination = Unsafe.Read<T>(source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void* AsPointer<T>(ref T value)
		{
			return Unsafe.AsPointer(ref value);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static int SizeOf<T>()
		{
			return Unsafe.SizeOf<T>();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void CopyBlock(void* destination, void* source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlock(destination, source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void CopyBlock(ref byte destination, ref byte source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlock(ref destination, ref source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void CopyBlockUnaligned(void* destination, void* source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlockUnaligned(destination, source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void CopyBlockUnaligned(ref byte destination, ref byte source, uint byteCount)
		{
			// IL cpblk instruction
			Unsafe.CopyBlockUnaligned(ref destination, ref source, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void InitBlock(void* startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlock(startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void InitBlock(ref byte startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlock(ref startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void InitBlockUnaligned(void* startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlockUnaligned(startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount)
		{
			// IL initblk instruction
			Unsafe.InitBlockUnaligned(ref startAddress, value, byteCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static T As<T>(object o) where T : class
		{
			return (T)o;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static ref T AsRef<T>(void* source)
		{
			return ref *(T*)source;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T AsRef<T>(in T source)
		{
			return ref source;
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref TTo As<TFrom, TTo>(ref TFrom source)
		{
			return ref Unsafe.As<TFrom, TTo>(ref source);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Add<T>(ref T source, int elementOffset)
		{
			return ref Unsafe.Add(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void* Add<T>(void* source, int elementOffset)
		{
			return (byte*)source + (nint)elementOffset * (nint)Unsafe.SizeOf<T>();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Add<T>(ref T source, IntPtr elementOffset)
		{
			return ref Unsafe.Add(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T AddByteOffset<T>(ref T source, IntPtr byteOffset)
		{
			return ref Unsafe.AddByteOffset(ref source, byteOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Subtract<T>(ref T source, int elementOffset)
		{
			return ref Unsafe.Subtract(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public unsafe static void* Subtract<T>(void* source, int elementOffset)
		{
			return (byte*)source - (nint)elementOffset * (nint)Unsafe.SizeOf<T>();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T Subtract<T>(ref T source, IntPtr elementOffset)
		{
			return ref Unsafe.Subtract(ref source, elementOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static ref T SubtractByteOffset<T>(ref T source, IntPtr byteOffset)
		{
			return ref Unsafe.SubtractByteOffset(ref source, byteOffset);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static IntPtr ByteOffset<T>(ref T origin, ref T target)
		{
			return Unsafe.ByteOffset(target: ref target, origin: ref origin);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static bool AreSame<T>(ref T left, ref T right)
		{
			return Unsafe.AreSame(ref left, ref right);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static bool IsAddressGreaterThan<T>(ref T left, ref T right)
		{
			return Unsafe.IsAddressGreaterThan(ref left, ref right);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[System.Runtime.Versioning.NonVersionable]
		public static bool IsAddressLessThan<T>(ref T left, ref T right)
		{
			return Unsafe.IsAddressLessThan(ref left, ref right);
		}
	}
}
namespace System.Runtime.Versioning
{
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
	internal sealed class NonVersionableAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
}