Decompiled source of Slides Bot Control v1.2.3

PrioritySet.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("PrioritySet")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Indexed set with optional per-slot priority, conflict resolution, and queue-style operations.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+978d443a8b6a1f288913a375cd36f7569deece8b")]
[assembly: AssemblyProduct("PrioritySet")]
[assembly: AssemblyTitle("PrioritySet")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace PrioritySet
{
	[Flags]
	public enum CleanFlags
	{
		None = 0,
		NullValues = 1,
		NullPriorities = 2,
		NullValuesAndPriorities = 3
	}
	public enum ConflictResolution
	{
		KeepIndex,
		KeepPriority,
		ThrowOnConflict
	}
	public enum DuplicateValuePolicy
	{
		ThrowOnDuplicate,
		Reject,
		ReplaceExisting
	}
	public enum PlacementIndexBias
	{
		HighestValidIndex,
		LowestValidIndex
	}
	[Flags]
	public enum PrioritySetChangeKind
	{
		None = 0,
		Add = 1,
		Remove = 2,
		Reorder = 4,
		PriorityChange = 8,
		Clear = 0x10,
		Clean = 0x20,
		Sort = 0x40,
		BulkSetOperation = 0x80,
		Update = 0x100
	}
	public sealed class PrioritySetChangedEventArgs : EventArgs
	{
		public PrioritySetChangeKind ChangeKind { get; }

		public int? Index { get; }

		public object? Value { get; }

		public int? Priority { get; }

		public PrioritySetChangedEventArgs(PrioritySetChangeKind changeKind, int? index = null, object? value = null, int? priority = null)
		{
			ChangeKind = changeKind;
			Index = index;
			Value = value;
			Priority = priority;
		}
	}
	public class PrioritySet<T> : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IReadOnlyList<T>, IReadOnlyCollection<T>, ISet<T>
	{
		private sealed class ChangedScope : IDisposable
		{
			private readonly PrioritySet<T> _owner;

			public ChangedScope(PrioritySet<T> owner)
			{
				_owner = owner;
			}

			public void Dispose()
			{
				_owner._changedScopeDepth--;
				if (_owner._changedScopeDepth == 0)
				{
					_owner.FlushPendingChanged();
				}
			}
		}

		private sealed record FilteredChangedSubscription(PrioritySetChangeKind ChangeKinds, EventHandler<PrioritySetChangedEventArgs> Handler);

		private sealed class FilteredChangedSubscriptionToken : IDisposable
		{
			private PrioritySet<T>? _owner;

			private readonly FilteredChangedSubscription _subscription;

			public FilteredChangedSubscriptionToken(PrioritySet<T> owner, FilteredChangedSubscription subscription)
			{
				_owner = owner;
				_subscription = subscription;
			}

			public void Dispose()
			{
				if (_owner != null)
				{
					_owner.RemoveFilteredSubscription(_subscription);
					_owner = null;
				}
			}
		}

		private sealed class EntriesReadOnlyView : IReadOnlyList<PrioritySetEntry<T>>, IEnumerable<PrioritySetEntry<T>>, IEnumerable, IReadOnlyCollection<PrioritySetEntry<T>>
		{
			private readonly PrioritySet<T> _owner;

			public PrioritySetEntry<T> this[int index]
			{
				get
				{
					_owner.ValidateIndex(index);
					Entry<T> entry = _owner._entries[index];
					return new PrioritySetEntry<T>(entry.Value, entry.Priority, index);
				}
			}

			public int Count => _owner.Count;

			public EntriesReadOnlyView(PrioritySet<T> owner)
			{
				_owner = owner;
			}

			public IEnumerator<PrioritySetEntry<T>> GetEnumerator()
			{
				for (int i = 0; i < _owner.Count; i++)
				{
					yield return this[i];
				}
			}

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

		private sealed class ItemsReadOnlyView : IReadOnlyList<T>, IEnumerable<T>, IEnumerable, IReadOnlyCollection<T>
		{
			private readonly PrioritySet<T> _owner;

			public T this[int index] => _owner[index];

			public int Count => _owner.Count;

			public ItemsReadOnlyView(PrioritySet<T> owner)
			{
				_owner = owner;
			}

			public IEnumerator<T> GetEnumerator()
			{
				return _owner.GetEnumerator();
			}

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

		private readonly List<FilteredChangedSubscription> _filteredChangedSubscriptions = new List<FilteredChangedSubscription>();

		private int _changedScopeDepth;

		private PrioritySetChangeKind _pendingChangeKind;

		private int? _pendingIndex;

		private object? _pendingValue;

		private int? _pendingPriority;

		private readonly List<Entry<T>> _entries = new List<Entry<T>>();

		private readonly Dictionary<T, int> _indexByValue;

		private readonly Dictionary<int, T> _priorityToValue = new Dictionary<int, T>();

		private readonly IEqualityComparer<T> _comparer;

		private readonly EntriesReadOnlyView _entriesView;

		private readonly ItemsReadOnlyView _itemsView;

		public ConflictResolution DefaultConflictResolution { get; set; }

		public DuplicateValuePolicy DefaultDuplicateValuePolicy { get; set; } = DuplicateValuePolicy.Reject;

		public PlacementIndexBias DefaultPlacementIndexBias { get; set; }

		public int Count => _entries.Count;

		public bool IsReadOnly => false;

		public IReadOnlyList<PrioritySetEntry<T>> Entries => _entriesView;

		public IReadOnlyList<T> Items => _itemsView;

		public T this[int index]
		{
			get
			{
				ValidateIndex(index);
				return _entries[index].Value;
			}
			set
			{
				ValidateIndex(index);
				T value2 = _entries[index].Value;
				if (!_comparer.Equals(value2, value))
				{
					TrySetValueAt(index, value);
				}
			}
		}

		public event EventHandler<PrioritySetChangedEventArgs>? Changed;

		private void NotifyChanged(PrioritySetChangeKind changeKind, int? index = null, object? value = null, int? priority = null)
		{
			if (changeKind != PrioritySetChangeKind.None)
			{
				if (_changedScopeDepth > 0)
				{
					_pendingChangeKind |= changeKind;
					_pendingIndex = index;
					_pendingValue = value;
					_pendingPriority = priority;
				}
				else
				{
					RaiseChanged(new PrioritySetChangedEventArgs(changeKind, index, value, priority));
				}
			}
		}

		private IDisposable BeginChangedScope()
		{
			_changedScopeDepth++;
			return new ChangedScope(this);
		}

		private void FlushPendingChanged()
		{
			if (_pendingChangeKind != PrioritySetChangeKind.None)
			{
				RaiseChanged(new PrioritySetChangedEventArgs(_pendingChangeKind, _pendingIndex, _pendingValue, _pendingPriority));
				_pendingChangeKind = PrioritySetChangeKind.None;
				_pendingIndex = null;
				_pendingValue = null;
				_pendingPriority = null;
			}
		}

		public IDisposable Subscribe(PrioritySetChangeKind changeKinds, EventHandler<PrioritySetChangedEventArgs> handler)
		{
			ArgumentNullException.ThrowIfNull(handler, "handler");
			if (changeKinds == PrioritySetChangeKind.None)
			{
				throw new ArgumentException("At least one change kind must be specified.", "changeKinds");
			}
			FilteredChangedSubscription filteredChangedSubscription = new FilteredChangedSubscription(changeKinds, handler);
			_filteredChangedSubscriptions.Add(filteredChangedSubscription);
			return new FilteredChangedSubscriptionToken(this, filteredChangedSubscription);
		}

		private void RaiseChanged(PrioritySetChangedEventArgs args)
		{
			this.Changed?.Invoke(this, args);
			if (_filteredChangedSubscriptions.Count == 0)
			{
				return;
			}
			FilteredChangedSubscription[] array = _filteredChangedSubscriptions.ToArray();
			foreach (FilteredChangedSubscription filteredChangedSubscription in array)
			{
				if ((args.ChangeKind & filteredChangedSubscription.ChangeKinds) != PrioritySetChangeKind.None)
				{
					filteredChangedSubscription.Handler(this, args);
				}
			}
		}

		private void RemoveFilteredSubscription(FilteredChangedSubscription subscription)
		{
			_filteredChangedSubscriptions.Remove(subscription);
		}

		public int Clean(CleanFlags flags = CleanFlags.NullValues)
		{
			if (flags == CleanFlags.None)
			{
				return 0;
			}
			bool flag = flags.HasFlag(CleanFlags.NullValues);
			bool flag2 = flags.HasFlag(CleanFlags.NullPriorities);
			int num = 0;
			for (int num2 = _entries.Count - 1; num2 >= 0; num2--)
			{
				Entry<T> entry = _entries[num2];
				bool num3 = flag && entry.Value == null;
				bool flag3 = flag2 && !entry.Priority.HasValue;
				if (num3 || flag3)
				{
					int? priority = entry.Priority;
					if (priority.HasValue)
					{
						int valueOrDefault = priority.GetValueOrDefault();
						UnregisterPriority(valueOrDefault, entry.Value);
					}
					RemoveIndexForValue(entry.Value);
					_entries.RemoveAt(num2);
					num++;
				}
			}
			if (num > 0)
			{
				RebuildIndexMap();
				RebuildPriorityMapFromEntries();
				EnsurePriorityOrdering();
				NotifyChanged(PrioritySetChangeKind.Clean);
			}
			return num;
		}

		public PrioritySet()
			: this((IEqualityComparer<T>?)null)
		{
		}

		public PrioritySet(IEnumerable<T> collection)
			: this(collection, (IEqualityComparer<T>?)null, DuplicateValuePolicy.Reject)
		{
		}

		public PrioritySet(IEnumerable<T> collection, IEqualityComparer<T>? comparer, DuplicateValuePolicy duplicateValuePolicy = DuplicateValuePolicy.Reject)
			: this(comparer)
		{
			ArgumentNullException.ThrowIfNull(collection, "collection");
			DefaultDuplicateValuePolicy = duplicateValuePolicy;
			foreach (T item in collection)
			{
				if (item != null && _indexByValue.ContainsKey(item))
				{
					switch (duplicateValuePolicy)
					{
					case DuplicateValuePolicy.ThrowOnDuplicate:
						throw new InvalidOperationException("Duplicate non-null value in collection.");
					case DuplicateValuePolicy.ReplaceExisting:
						Remove(item);
						break;
					case DuplicateValuePolicy.Reject:
						continue;
					}
				}
				Add(item);
			}
		}

		public PrioritySet(IEqualityComparer<T>? comparer)
		{
			_comparer = comparer ?? EqualityComparer<T>.Default;
			_indexByValue = new Dictionary<T, int>(_comparer);
			_entriesView = new EntriesReadOnlyView(this);
			_itemsView = new ItemsReadOnlyView(this);
		}

		public void Clear()
		{
			_entries.Clear();
			_indexByValue.Clear();
			_priorityToValue.Clear();
			NotifyChanged(PrioritySetChangeKind.Clear);
		}

		public bool Contains([AllowNull] T value)
		{
			if (value == null)
			{
				return IndexOfNullReference() >= 0;
			}
			return _indexByValue.ContainsKey(value);
		}

		public void CopyTo(T[] array, int arrayIndex)
		{
			ArgumentNullException.ThrowIfNull(array, "array");
			if (arrayIndex < 0)
			{
				throw new ArgumentOutOfRangeException("arrayIndex");
			}
			if (array.Length - arrayIndex < Count)
			{
				throw new ArgumentException("Destination array is not long enough.");
			}
			for (int i = 0; i < Count; i++)
			{
				array[arrayIndex + i] = _entries[i].Value;
			}
		}

		public IEnumerator<T> GetEnumerator()
		{
			for (int i = 0; i < _entries.Count; i++)
			{
				yield return _entries[i].Value;
			}
		}

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

		public int IndexOf([AllowNull] T value)
		{
			if (value == null)
			{
				return IndexOfNullReference();
			}
			if (!_indexByValue.TryGetValue(value, out var value2))
			{
				return -1;
			}
			return value2;
		}

		public int? GetPriority([AllowNull] T value)
		{
			if (!TryGetIndexForLookup(value, out var index))
			{
				return null;
			}
			return _entries[index].Priority;
		}

		public PrioritySetEntry<T>? GetEntryByValue([AllowNull] T value)
		{
			if (!TryGetIndexForLookup(value, out var index))
			{
				return null;
			}
			Entry<T> entry = _entries[index];
			return new PrioritySetEntry<T>(entry.Value, entry.Priority, index);
		}

		public T? GetByPriority(int priority)
		{
			if (!_priorityToValue.TryGetValue(priority, out var value))
			{
				return default(T);
			}
			return value;
		}

		public bool TryGetByPriority(int priority, out T? value)
		{
			if (_priorityToValue.TryGetValue(priority, out var value2))
			{
				value = value2;
				return true;
			}
			value = default(T);
			return false;
		}

		public PrioritySetEntry<T>? GetEntryByPriority(int priority)
		{
			if (!_priorityToValue.TryGetValue(priority, out var value))
			{
				return null;
			}
			if (value != null && _indexByValue.TryGetValue(value, out var value2))
			{
				return new PrioritySetEntry<T>(_entries[value2].Value, priority, value2);
			}
			for (int i = 0; i < _entries.Count; i++)
			{
				int? priority2 = _entries[i].Priority;
				if (priority2.HasValue)
				{
					int valueOrDefault = priority2.GetValueOrDefault();
					if (valueOrDefault == priority)
					{
						return new PrioritySetEntry<T>(_entries[i].Value, priority, i);
					}
				}
			}
			return null;
		}

		public IEnumerable<T> ByPriority()
		{
			for (int i = 0; i < _entries.Count; i++)
			{
				if (_entries[i].Priority.HasValue)
				{
					yield return _entries[i].Value;
				}
			}
		}

		public void Validate()
		{
			int num = 0;
			for (int i = 0; i < _entries.Count; i++)
			{
				if (_entries[i].Value != null)
				{
					num++;
				}
			}
			if (num != _indexByValue.Count)
			{
				throw new InvalidOperationException("Non-null entry count does not match value map.");
			}
			_priorityToValue.Clear();
			RebuildPriorityMapFromEntries();
			for (int j = 0; j < _entries.Count; j++)
			{
				T value = _entries[j].Value;
				if (value != null)
				{
					if (!_indexByValue.TryGetValue(value, out var value2) || value2 != j)
					{
						throw new InvalidOperationException("Value map index mismatch.");
					}
					int? priority = _entries[j].Priority;
					if (priority.HasValue && PrioritySetInvariant.HasConflict(_entries, j, priority))
					{
						throw new InvalidOperationException($"Ordering conflict at index {j}.");
					}
				}
			}
		}

		private ConflictResolution ResolvePolicy(ConflictResolution? resolution)
		{
			return resolution ?? DefaultConflictResolution;
		}

		private DuplicateValuePolicy ResolveDuplicatePolicy(DuplicateValuePolicy? policy)
		{
			return policy ?? DefaultDuplicateValuePolicy;
		}

		private PlacementIndexBias ResolvePlacementIndexBias(PlacementIndexBias? placementIndexBias)
		{
			return placementIndexBias ?? DefaultPlacementIndexBias;
		}

		private PlacementIndexBias ResolveEnqueuePlacementIndexBias(PlacementIndexBias? placementIndexBias)
		{
			return placementIndexBias ?? PlacementIndexBias.LowestValidIndex;
		}

		private void ValidateIndex(int index)
		{
			if ((uint)index >= (uint)_entries.Count)
			{
				throw new ArgumentOutOfRangeException("index");
			}
		}

		private void RebuildIndexMap()
		{
			_indexByValue.Clear();
			for (int i = 0; i < _entries.Count; i++)
			{
				T value = _entries[i].Value;
				if (value != null)
				{
					_indexByValue[value] = i;
				}
			}
		}

		private int IndexOfNullReference()
		{
			for (int i = 0; i < _entries.Count; i++)
			{
				if (_entries[i].Value == null)
				{
					return i;
				}
			}
			return -1;
		}

		private bool TryGetIndexForLookup([AllowNull] T value, out int index)
		{
			if (value == null)
			{
				index = IndexOfNullReference();
				return index >= 0;
			}
			return _indexByValue.TryGetValue(value, out index);
		}

		private bool TryGetIndexForPriority(int priority, out int index)
		{
			index = -1;
			if (!_priorityToValue.TryGetValue(priority, out var value))
			{
				return false;
			}
			if (value != null && _indexByValue.TryGetValue(value, out var value2))
			{
				index = value2;
				return true;
			}
			for (int i = 0; i < _entries.Count; i++)
			{
				int? priority2 = _entries[i].Priority;
				if (priority2.HasValue)
				{
					int valueOrDefault = priority2.GetValueOrDefault();
					if (valueOrDefault == priority)
					{
						index = i;
						return true;
					}
				}
			}
			return false;
		}

		private bool TryResolveSlotIndex(int? index, int? priority, [AllowNull] T value, bool byValue, out int resolvedIndex)
		{
			resolvedIndex = -1;
			if (byValue)
			{
				if (index.HasValue || priority.HasValue)
				{
					throw new ArgumentException("Specify only one slot locator (value).");
				}
				return TryGetIndexForLookup(value, out resolvedIndex);
			}
			if (index.HasValue)
			{
				int valueOrDefault = index.GetValueOrDefault();
				if (priority.HasValue)
				{
					throw new ArgumentException("Specify only one slot locator (index or priority).");
				}
				if ((uint)valueOrDefault >= (uint)_entries.Count)
				{
					return false;
				}
				resolvedIndex = valueOrDefault;
				return true;
			}
			if (priority.HasValue)
			{
				int valueOrDefault2 = priority.GetValueOrDefault();
				return TryGetIndexForPriority(valueOrDefault2, out resolvedIndex);
			}
			throw new ArgumentException("Specify one slot locator: index, priority, or value.");
		}

		private static int ComputeRelativeInsertIndex(int anchorIndex, bool insertAfter)
		{
			if (!insertAfter)
			{
				return anchorIndex;
			}
			return anchorIndex + 1;
		}

		private bool IsAlreadyInSet([AllowNull] T value)
		{
			if (value != null)
			{
				return _indexByValue.ContainsKey(value);
			}
			return false;
		}

		private void SetIndexForValue([AllowNull] T value, int index)
		{
			if (value != null)
			{
				_indexByValue[value] = index;
			}
		}

		private void RemoveIndexForValue([AllowNull] T value)
		{
			if (value != null)
			{
				_indexByValue.Remove(value);
			}
		}

		private bool ContainsValueIn(IEnumerable<T> values, [AllowNull] T value)
		{
			foreach (T value2 in values)
			{
				if (_comparer.Equals(value2, value))
				{
					return true;
				}
			}
			return false;
		}

		private void RebuildPriorityMapFromEntries()
		{
			_priorityToValue.Clear();
			for (int i = 0; i < _entries.Count; i++)
			{
				int? priority = _entries[i].Priority;
				if (priority.HasValue)
				{
					int valueOrDefault = priority.GetValueOrDefault();
					_priorityToValue[valueOrDefault] = _entries[i].Value;
				}
			}
		}

		private void RegisterPriority(int priority, [AllowNull] T value)
		{
			if (_priorityToValue.TryGetValue(priority, out var value2) && !_comparer.Equals(value2, value))
			{
				throw new InvalidOperationException($"Duplicate priority {priority}.");
			}
			_priorityToValue[priority] = value;
		}

		private void UnregisterPriority(int? priority, [AllowNull] T value)
		{
			if (priority.HasValue)
			{
				int valueOrDefault = priority.GetValueOrDefault();
				if (_priorityToValue.TryGetValue(valueOrDefault, out var value2) && _comparer.Equals(value2, value))
				{
					_priorityToValue.Remove(valueOrDefault);
				}
			}
		}

		private void UpdateEntryPriority(Entry<T> entry, int? newPriority)
		{
			UnregisterPriority(entry.Priority, entry.Value);
			entry.Priority = newPriority;
			if (newPriority.HasValue)
			{
				int valueOrDefault = newPriority.GetValueOrDefault();
				RegisterPriority(valueOrDefault, entry.Value);
			}
		}

		public T[] ToArray()
		{
			T[] array = new T[_entries.Count];
			for (int i = 0; i < _entries.Count; i++)
			{
				array[i] = _entries[i].Value;
			}
			return array;
		}

		public List<T> ToList()
		{
			List<T> list = new List<T>(_entries.Count);
			for (int i = 0; i < _entries.Count; i++)
			{
				list.Add(_entries[i].Value);
			}
			return list;
		}

		public HashSet<T> ToHashSet()
		{
			HashSet<T> hashSet = new HashSet<T>(_comparer);
			for (int i = 0; i < _entries.Count; i++)
			{
				T value = _entries[i].Value;
				if (value != null)
				{
					hashSet.Add(value);
				}
			}
			return hashSet;
		}

		public ISet<T> ToSet()
		{
			return ToHashSet();
		}

		public static implicit operator T[](PrioritySet<T> set)
		{
			return set.ToArray();
		}

		public static implicit operator List<T>(PrioritySet<T> set)
		{
			return set.ToList();
		}

		public static explicit operator HashSet<T>(PrioritySet<T> set)
		{
			return set.ToHashSet();
		}

		public bool TryAdd([AllowNull] T value, int? index = null, int? priority = null, ConflictResolution? resolution = null, DuplicateValuePolicy? duplicateValuePolicy = null, PlacementIndexBias? placementIndexBias = null)
		{
			bool hasValue = index.HasValue;
			bool hasValue2 = priority.HasValue;
			if (IsAlreadyInSet(value))
			{
				if (!hasValue && !hasValue2)
				{
					return HandleDuplicateAdd(value, duplicateValuePolicy);
				}
				ApplyAddToExistingSlot(value, index, priority, resolution);
				int? index2 = null;
				int value2;
				if (value == null)
				{
					int num = IndexOfNullReference();
					if (num >= 0)
					{
						index2 = num;
					}
				}
				else if (_indexByValue.TryGetValue(value, out value2))
				{
					index2 = value2;
				}
				int? obj;
				if (index2.HasValue)
				{
					int valueOrDefault = index2.GetValueOrDefault();
					obj = _entries[valueOrDefault].Priority;
				}
				else
				{
					obj = null;
				}
				int? priority2 = obj;
				PrioritySetChangeKind prioritySetChangeKind = PrioritySetChangeKind.None;
				if (hasValue)
				{
					prioritySetChangeKind |= PrioritySetChangeKind.Reorder;
				}
				if (hasValue2)
				{
					prioritySetChangeKind |= PrioritySetChangeKind.PriorityChange;
				}
				NotifyChanged(prioritySetChangeKind, index2, value, priority2);
				return true;
			}
			PrioritySetChangeKind prioritySetChangeKind2 = PrioritySetChangeKind.None;
			prioritySetChangeKind2 |= PrioritySetChangeKind.Add;
			if (hasValue)
			{
				prioritySetChangeKind2 |= PrioritySetChangeKind.Reorder;
			}
			if (hasValue2)
			{
				prioritySetChangeKind2 |= PrioritySetChangeKind.PriorityChange;
			}
			if (!hasValue && !hasValue2)
			{
				InsertCore(_entries.Count, value, null);
				int value3;
				int? index3 = ((value == null) ? new int?(IndexOfNullReference()) : (_indexByValue.TryGetValue(value, out value3) ? new int?(value3) : ((int?)null)));
				int? obj2;
				if (index3.HasValue)
				{
					int valueOrDefault2 = index3.GetValueOrDefault();
					obj2 = _entries[valueOrDefault2].Priority;
				}
				else
				{
					obj2 = null;
				}
				int? priority3 = obj2;
				NotifyChanged(prioritySetChangeKind2, index3, value, priority3);
				return true;
			}
			InsertWithPlacement(value, index, priority, resolution, ResolvePlacementIndexBias(placementIndexBias));
			int? index4 = null;
			int value4;
			if (value == null)
			{
				int num2 = IndexOfNullReference();
				if (num2 >= 0)
				{
					index4 = num2;
				}
			}
			else if (_indexByValue.TryGetValue(value, out value4))
			{
				index4 = value4;
			}
			int? obj3;
			if (index4.HasValue)
			{
				int valueOrDefault3 = index4.GetValueOrDefault();
				obj3 = _entries[valueOrDefault3].Priority;
			}
			else
			{
				obj3 = null;
			}
			int? priority4 = obj3;
			NotifyChanged(prioritySetChangeKind2, index4, value, priority4);
			return true;
		}

		public bool Add([AllowNull] T value, int? priority = null, ConflictResolution? resolution = null, DuplicateValuePolicy? duplicateValuePolicy = null, PlacementIndexBias? placementIndexBias = null)
		{
			return TryAdd(value, null, priority, resolution, duplicateValuePolicy, placementIndexBias);
		}

		public bool AddAt([AllowNull] T value, int index, ConflictResolution? resolution = null, DuplicateValuePolicy? duplicateValuePolicy = null)
		{
			return TryAdd(value, index, null, resolution, duplicateValuePolicy);
		}

		public bool AddAt([AllowNull] T value, int index, int priority, ConflictResolution? resolution = null, DuplicateValuePolicy? duplicateValuePolicy = null)
		{
			return TryAdd(value, index, priority, resolution, duplicateValuePolicy);
		}

		void ICollection<T>.Add(T value)
		{
			Add(value);
		}

		bool ISet<T>.Add(T value)
		{
			return Add(value);
		}

		public void Insert(int index, [AllowNull] T value)
		{
			TryInsert(index, value);
		}

		public void Insert(int index, [AllowNull] T value, int? priority, ConflictResolution? resolution = null, DuplicateValuePolicy? duplicateValuePolicy = null)
		{
			TryInsert(index, value, priority, resolution, duplicateValuePolicy);
		}

		public bool TryInsert(int index, [AllowNull] T value)
		{
			return TryInsert(index, value, null);
		}

		public bool TryInsert(int index, [AllowNull] T value, int? priority, ConflictResolution? resolution = null, DuplicateValuePolicy? duplicateValuePolicy = null)
		{
			if (IsAlreadyInSet(value) && !TryPrepareDuplicateForInsert(value, duplicateValuePolicy))
			{
				return false;
			}
			if (!priority.HasValue)
			{
				InsertCore(index, value, null);
				int value2;
				int? index2 = ((value == null) ? new int?(IndexOfNullReference()) : (_indexByValue.TryGetValue(value, out value2) ? new int?(value2) : ((int?)null)));
				int? obj;
				if (index2.HasValue)
				{
					int valueOrDefault = index2.GetValueOrDefault();
					obj = _entries[valueOrDefault].Priority;
				}
				else
				{
					obj = null;
				}
				int? priority2 = obj;
				NotifyChanged(PrioritySetChangeKind.Add, index2, value, priority2);
				return true;
			}
			InsertWithPlacement(value, index, priority, resolution, ResolvePlacementIndexBias(null));
			SyncPriorityMap();
			int? index3 = null;
			int value3;
			if (value == null)
			{
				int num = IndexOfNullReference();
				if (num >= 0)
				{
					index3 = num;
				}
			}
			else if (_indexByValue.TryGetValue(value, out value3))
			{
				index3 = value3;
			}
			int? obj2;
			if (index3.HasValue)
			{
				int valueOrDefault2 = index3.GetValueOrDefault();
				obj2 = _entries[valueOrDefault2].Priority;
			}
			else
			{
				obj2 = null;
			}
			int? priority3 = obj2;
			PrioritySetChangeKind prioritySetChangeKind = PrioritySetChangeKind.Add;
			if (priority.HasValue)
			{
				prioritySetChangeKind |= PrioritySetChangeKind.PriorityChange;
			}
			NotifyChanged(prioritySetChangeKind, index3, value, priority3);
			return true;
		}

		void IList<T>.Insert(int index, T item)
		{
			Insert(index, item);
		}

		public void InsertRelativeAt([AllowNull] T value, int anchorIndex, bool insertAfter = true, int? priority = null, ConflictResolution? resolution = null, DuplicateValuePolicy? duplicateValuePolicy = null)
		{
			TryInsertRelativeAt(value, anchorIndex, insertAfter, priority, resolution, duplicateValuePolicy);
		}

		public void InsertRelativeByPriority([AllowNull] T value, int anchorPriority, bool insertAfter = true, int? priority = null, ConflictResolution? resolution = null, DuplicateValuePolicy? duplicateValuePolicy = null)
		{
			TryInsertRelativeByPriority(value, anchorPriority, insertAfter, priority, resolution, duplicateValuePolicy);
		}

		public void InsertRelative([AllowNull] T value, [AllowNull] T anchorValue, bool insertAfter = true, int? priority = null, ConflictResolution? resolution = null, DuplicateValuePolicy? duplicateValuePolicy = null)
		{
			TryInsertRelative(value, anchorValue, insertAfter, priority, resolution, duplicateValuePolicy);
		}

		public bool TryInsertRelativeAt([AllowNull] T value, int anchorIndex, bool insertAfter = true, int? priority = null, ConflictResolution? resolution = null, DuplicateValuePolicy? duplicateValuePolicy = null)
		{
			if (!TryResolveSlotIndex(anchorIndex, null, default(T), byValue: false, out var resolvedIndex))
			{
				return false;
			}
			int index = ComputeRelativeInsertIndex(resolvedIndex, insertAfter);
			return TryInsert(index, value, priority, resolution, duplicateValuePolicy);
		}

		public bool TryInsertRelativeByPriority([AllowNull] T value, int anchorPriority, bool insertAfter = true, int? priority = null, ConflictResolution? resolution = null, DuplicateValuePolicy? duplicateValuePolicy = null)
		{
			if (!TryResolveSlotIndex(null, anchorPriority, default(T), byValue: false, out var resolvedIndex))
			{
				return false;
			}
			int index = ComputeRelativeInsertIndex(resolvedIndex, insertAfter);
			return TryInsert(index, value, priority, resolution, duplicateValuePolicy);
		}

		public bool TryInsertRelative([AllowNull] T value, [AllowNull] T anchorValue, bool insertAfter = true, int? priority = null, ConflictResolution? resolution = null, DuplicateValuePolicy? duplicateValuePolicy = null)
		{
			if (!TryResolveSlotIndex(null, null, anchorValue, byValue: true, out var resolvedIndex))
			{
				return false;
			}
			int index = ComputeRelativeInsertIndex(resolvedIndex, insertAfter);
			return TryInsert(index, value, priority, resolution, duplicateValuePolicy);
		}

		public bool Remove([AllowNull] T value)
		{
			if (!TryGetIndexForLookup(value, out var index))
			{
				return false;
			}
			RemoveAt(index);
			return true;
		}

		public bool TryRemoveAt(int index)
		{
			if (index < 0 || index >= _entries.Count)
			{
				return false;
			}
			Entry<T> entry = _entries[index];
			UnregisterPriority(entry.Priority, entry.Value);
			_entries.RemoveAt(index);
			RemoveIndexForValue(entry.Value);
			RebuildIndexMap();
			EnsurePriorityOrdering();
			NotifyChanged(PrioritySetChangeKind.Remove, index, entry.Value, entry.Priority);
			return true;
		}

		public void RemoveAt(int index)
		{
			if (!TryRemoveAt(index))
			{
				throw new ArgumentOutOfRangeException("index");
			}
		}

		public bool RemoveByPriority(int priority)
		{
			return TryRemoveByPriority(priority);
		}

		public bool TryRemoveByPriority(int priority)
		{
			if (!TryResolveSlotIndex(null, priority, default(T), byValue: false, out var resolvedIndex))
			{
				return false;
			}
			return TryRemoveAt(resolvedIndex);
		}

		public void SetPriority([AllowNull] T value, int newPriority, ConflictResolution? resolution = null)
		{
			TrySetPriority(value, newPriority, resolution);
		}

		public bool TrySetPriority([AllowNull] T value, int newPriority, ConflictResolution? resolution = null)
		{
			if (!TryGetIndexForLookup(value, out var index))
			{
				return false;
			}
			return TrySetPriorityAt(index, newPriority, resolution);
		}

		public void SetPriorityAt(int index, int newPriority, ConflictResolution? resolution = null)
		{
			if (!TrySetPriorityAt(index, newPriority, resolution))
			{
				throw new ArgumentOutOfRangeException("index");
			}
		}

		public bool TrySetPriorityAt(int index, int newPriority, ConflictResolution? resolution = null)
		{
			if ((uint)index >= (uint)_entries.Count)
			{
				return false;
			}
			T value = _entries[index].Value;
			SetPriorityAtCore(index, newPriority, resolution);
			int? index2 = null;
			int value2;
			if (value == null)
			{
				int num = IndexOfNullReference();
				if (num >= 0)
				{
					index2 = num;
				}
			}
			else if (_indexByValue.TryGetValue(value, out value2))
			{
				index2 = value2;
			}
			int? num2;
			if (index2.HasValue)
			{
				int valueOrDefault = index2.GetValueOrDefault();
				num2 = _entries[valueOrDefault].Priority;
			}
			else
			{
				num2 = newPriority;
			}
			int? priority = num2;
			NotifyChanged(PrioritySetChangeKind.PriorityChange, index2, value, priority);
			return true;
		}

		public void SetPriorityByPriority(int currentPriority, int newPriority, ConflictResolution? resolution = null)
		{
			TrySetPriorityByPriority(currentPriority, newPriority, resolution);
		}

		public bool TrySetPriorityByPriority(int currentPriority, int newPriority, ConflictResolution? resolution = null)
		{
			if (!_priorityToValue.TryGetValue(currentPriority, out var value))
			{
				return false;
			}
			return TrySetPriority(value, newPriority, resolution);
		}

		public void ClearPriority([AllowNull] T value)
		{
			TryClearPriority(value);
		}

		public bool TryClearPriority([AllowNull] T value)
		{
			if (!TryGetIndexForLookup(value, out var index))
			{
				return false;
			}
			return TryClearPriorityAt(index);
		}

		public void ClearPriorityAt(int index)
		{
			ValidateIndex(index);
			TryClearPriorityAt(index);
		}

		public bool TryClearPriorityAt(int index)
		{
			if ((uint)index >= (uint)_entries.Count)
			{
				return false;
			}
			Entry<T> entry = _entries[index];
			if (!entry.Priority.HasValue)
			{
				return false;
			}
			UpdateEntryPriority(entry, null);
			NotifyChanged(PrioritySetChangeKind.PriorityChange, index, entry.Value);
			return true;
		}

		public void ClearPriorityByPriority(int priority)
		{
			TryClearPriorityByPriority(priority);
		}

		public bool TryClearPriorityByPriority(int priority)
		{
			if (!TryResolveSlotIndex(null, priority, default(T), byValue: false, out var resolvedIndex))
			{
				return false;
			}
			return TryClearPriorityAt(resolvedIndex);
		}

		public int ReplaceValuesWhere(Func<T, bool> shouldReplace, [AllowNull] T replacement, DuplicateValuePolicy? duplicateValuePolicy = null)
		{
			ArgumentNullException.ThrowIfNull(shouldReplace, "shouldReplace");
			int num = 0;
			for (int i = 0; i < _entries.Count; i++)
			{
				T value = _entries[i].Value;
				if (shouldReplace(value) && !_comparer.Equals(value, replacement) && TryAssignValueAt(i, replacement, null, duplicateValuePolicy))
				{
					num++;
				}
			}
			if (num > 0)
			{
				NotifyChanged(PrioritySetChangeKind.BulkSetOperation);
			}
			return num;
		}

		public void SetValueAt(int index, [AllowNull] T value, DuplicateValuePolicy? duplicateValuePolicy = null, ConflictResolution? resolution = null)
		{
			TrySetValueAt(index, value, duplicateValuePolicy, resolution);
		}

		public bool TrySetValueAt(int index, [AllowNull] T value, DuplicateValuePolicy? duplicateValuePolicy = null, ConflictResolution? resolution = null)
		{
			ValidateIndex(index);
			T value2 = _entries[index].Value;
			if (_comparer.Equals(value2, value))
			{
				return true;
			}
			if (!TryAssignValueAt(index, value, resolution, duplicateValuePolicy))
			{
				return false;
			}
			int? index2;
			if (value != null)
			{
				index2 = ((!_indexByValue.TryGetValue(value, out var value3)) ? ((int?)null) : new int?(value3));
			}
			else
			{
				int num = IndexOfNullReference();
				index2 = ((num >= 0) ? new int?(num) : ((int?)null));
			}
			int? obj;
			if (index2.HasValue)
			{
				int valueOrDefault = index2.GetValueOrDefault();
				obj = _entries[valueOrDefault].Priority;
			}
			else
			{
				obj = null;
			}
			int? priority = obj;
			NotifyChanged(PrioritySetChangeKind.Update, index2, value, priority);
			return true;
		}

		public void SetValueByPriority(int priority, [AllowNull] T value, DuplicateValuePolicy? duplicateValuePolicy = null, ConflictResolution? resolution = null)
		{
			TrySetValueByPriority(priority, value, duplicateValuePolicy, resolution);
		}

		public bool TrySetValueByPriority(int priority, [AllowNull] T value, DuplicateValuePolicy? duplicateValuePolicy = null, ConflictResolution? resolution = null)
		{
			if (!TryGetIndexForPriority(priority, out var index))
			{
				return false;
			}
			return TrySetValueAt(index, value, duplicateValuePolicy, resolution);
		}

		private void ReplaceEntryValueAt(int index, [AllowNull] T newValue)
		{
			ValidateIndex(index);
			Entry<T> entry = _entries[index];
			T value = entry.Value;
			if (!_comparer.Equals(value, newValue))
			{
				RemoveIndexForValue(value);
				int? priority = entry.Priority;
				if (priority.HasValue)
				{
					int valueOrDefault = priority.GetValueOrDefault();
					UnregisterPriority(valueOrDefault, value);
				}
				entry.Value = newValue;
				SetIndexForValue(newValue, index);
				priority = entry.Priority;
				if (priority.HasValue)
				{
					int valueOrDefault2 = priority.GetValueOrDefault();
					RegisterPriority(valueOrDefault2, newValue);
				}
			}
		}

		private bool TryAssignValueAt(int index, [AllowNull] T value, ConflictResolution? resolution = null, DuplicateValuePolicy? duplicateValuePolicy = null)
		{
			ValidateIndex(index);
			if (value != null && _indexByValue.TryGetValue(value, out var value2) && value2 != index)
			{
				switch (ResolveDuplicatePolicy(duplicateValuePolicy))
				{
				case DuplicateValuePolicy.ThrowOnDuplicate:
					throw new InvalidOperationException("Value already exists at another index.");
				case DuplicateValuePolicy.Reject:
					return false;
				case DuplicateValuePolicy.ReplaceExisting:
				{
					int? priority = _entries[value2].Priority;
					RemoveAt(value2);
					if (value2 < index)
					{
						index--;
					}
					if (priority.HasValue)
					{
						int valueOrDefault = priority.GetValueOrDefault();
						PlaceAt(index, value, valueOrDefault, ResolvePolicy(resolution));
					}
					else
					{
						InsertCore(index, value, null);
						ResolvePlacement(index, indexSpecified: true, prioritySpecified: false, ResolvePolicy(resolution));
					}
					SyncPriorityMap();
					return true;
				}
				}
			}
			if (_comparer.Equals(_entries[index].Value, value))
			{
				return true;
			}
			ReplaceEntryValueAt(index, value);
			if (_entries[index].Priority.HasValue)
			{
				ResolvePlacement(index, indexSpecified: true, prioritySpecified: true, ResolvePolicy(resolution));
			}
			SyncPriorityMap();
			return true;
		}

		private bool HandleDuplicateAdd([AllowNull] T value, DuplicateValuePolicy? duplicateValuePolicy)
		{
			switch (ResolveDuplicatePolicy(duplicateValuePolicy))
			{
			case DuplicateValuePolicy.ThrowOnDuplicate:
				throw new InvalidOperationException("Value already exists in the set.");
			case DuplicateValuePolicy.Reject:
				return false;
			case DuplicateValuePolicy.ReplaceExisting:
			{
				Remove(value);
				InsertCore(_entries.Count, value, null);
				int value2;
				int? index = ((value == null) ? new int?(IndexOfNullReference()) : (_indexByValue.TryGetValue(value, out value2) ? new int?(value2) : ((int?)null)));
				int? obj;
				if (index.HasValue)
				{
					int valueOrDefault = index.GetValueOrDefault();
					obj = _entries[valueOrDefault].Priority;
				}
				else
				{
					obj = null;
				}
				int? priority = obj;
				NotifyChanged(PrioritySetChangeKind.Add, index, value, priority);
				return true;
			}
			default:
				return false;
			}
		}

		private bool TryPrepareDuplicateForInsert([AllowNull] T value, DuplicateValuePolicy? duplicateValuePolicy)
		{
			switch (ResolveDuplicatePolicy(duplicateValuePolicy))
			{
			case DuplicateValuePolicy.ThrowOnDuplicate:
				throw new InvalidOperationException("Value already exists in the set.");
			case DuplicateValuePolicy.Reject:
				return false;
			case DuplicateValuePolicy.ReplaceExisting:
				Remove(value);
				return true;
			default:
				return false;
			}
		}

		private void SetPriorityAtCore(int index, int newPriority, ConflictResolution? resolution)
		{
			Entry<T> entry = _entries[index];
			if (entry.Priority == newPriority && !PrioritySetInvariant.HasConflict(_entries, index, newPriority))
			{
				return;
			}
			int? priority = entry.Priority;
			UnregisterPriority(entry.Priority, entry.Value);
			entry.Priority = newPriority;
			if (!PrioritySetInvariant.HasConflict(_entries, index, newPriority))
			{
				RegisterPriority(newPriority, entry.Value);
				return;
			}
			ConflictResolution conflictResolution = ResolvePolicy(resolution);
			if (conflictResolution == ConflictResolution.ThrowOnConflict)
			{
				entry.Priority = priority;
				if (priority.HasValue)
				{
					int valueOrDefault = priority.GetValueOrDefault();
					RegisterPriority(valueOrDefault, entry.Value);
				}
				throw new InvalidOperationException("Priority conflict.");
			}
			ResolvePlacement(index, indexSpecified: false, prioritySpecified: true, conflictResolution);
			SyncPriorityMap();
		}

		private void InsertWithPlacement([AllowNull] T value, int? index, int? priority, ConflictResolution? resolution, PlacementIndexBias placementIndexBias)
		{
			ConflictResolution policy = ResolvePolicy(resolution);
			bool hasValue = index.HasValue;
			bool hasValue2 = priority.HasValue;
			if (!hasValue && hasValue2)
			{
				int value2 = priority.Value;
				int index2 = ResolveTargetIndexForPriorityOnly(value, value2, null, placementIndexBias);
				InsertCore(index2, value, value2, syncPriorityMap: false);
				ResolvePlacement(index2, indexSpecified: false, prioritySpecified: true, policy);
				SyncPriorityMap();
			}
			else if (hasValue && !hasValue2)
			{
				int value3 = index.Value;
				value3 = Math.Clamp(value3, 0, _entries.Count);
				InsertCore(value3, value, null);
				ResolvePlacement(value3, indexSpecified: true, prioritySpecified: false, policy);
				SyncPriorityMap();
			}
			else if (hasValue && hasValue2)
			{
				int index3 = Math.Clamp(index.Value, 0, _entries.Count);
				int value4 = priority.Value;
				if (!PrioritySetInvariant.TryFindHighestValidIndex(_entries, value4, value, out var _))
				{
					ShiftPrioritiesAtOrAbove(value4);
				}
				PlaceAt(index3, value, value4, policy);
			}
			else
			{
				InsertCore(_entries.Count, value, null);
			}
		}

		private void PlaceAt(int index, [AllowNull] T value, int priority, ConflictResolution policy)
		{
			if (IsAlreadyInSet(value))
			{
				throw new InvalidOperationException("Value already exists in the set.");
			}
			InsertCore(index, value, priority, syncPriorityMap: false);
			if (policy == ConflictResolution.ThrowOnConflict && PrioritySetInvariant.HasConflict(_entries, index, priority))
			{
				RemoveAt(index);
				throw new InvalidOperationException("Index and priority conflict.");
			}
			ResolvePlacement(index, indexSpecified: true, prioritySpecified: true, policy);
			SyncPriorityMap();
		}

		private void ResolvePlacement(int index, bool indexSpecified, bool prioritySpecified, ConflictResolution policy)
		{
			ValidateIndex(index);
			Entry<T> entry = _entries[index];
			T value = entry.Value;
			int? priority = entry.Priority;
			if (!priority.HasValue || !PrioritySetInvariant.HasConflict(_entries, index, priority))
			{
				return;
			}
			if (indexSpecified && prioritySpecified)
			{
				switch (policy)
				{
				case ConflictResolution.ThrowOnConflict:
					throw new InvalidOperationException("Index and priority conflict.");
				case ConflictResolution.KeepIndex:
					ApplyPriorityAtIndex(index, priority, value, allowMoveFallback: true);
					return;
				case ConflictResolution.KeepPriority:
					if (!TryMoveToClosestValidIndex(index, priority.Value, value, policy))
					{
						ApplyPriorityAtIndex(index, priority, value, allowMoveFallback: false);
					}
					return;
				}
			}
			if (indexSpecified)
			{
				ApplyPriorityAtIndex(index, priority, value, allowMoveFallback: true);
			}
			else if (prioritySpecified && !TryMoveToClosestValidIndex(index, priority.Value, value, policy))
			{
				ApplyPriorityAtIndex(index, priority, value, allowMoveFallback: false);
			}
		}

		private void ApplyPriorityAtIndex(int index, int? priority, T value, bool allowMoveFallback)
		{
			try
			{
				_entries[index].Priority = PrioritySetInvariant.FindPriorityForIndex(_entries, index, priority);
			}
			catch (InvalidOperationException) when (allowMoveFallback)
			{
				int? num = priority ?? _entries[index].Priority;
				if (num.HasValue)
				{
					int valueOrDefault = num.GetValueOrDefault();
					if (TryMoveToClosestValidIndex(index, valueOrDefault, value, ConflictResolution.KeepPriority))
					{
						return;
					}
				}
				UpdateEntryPriority(_entries[index], null);
			}
		}

		private bool TryMoveToClosestValidIndex(int index, int priority, T value, ConflictResolution policy)
		{
			if (policy == ConflictResolution.KeepIndex)
			{
				return false;
			}
			try
			{
				int num = PrioritySetInvariant.FindClosestValidIndex(_entries, index, priority, value, index);
				if (num != index)
				{
					MoveEntry(index, num);
				}
				return true;
			}
			catch (InvalidOperationException)
			{
				return false;
			}
		}

		private Entry<T> InsertCore(int index, [AllowNull] T value, int? priority, bool syncPriorityMap = true)
		{
			index = Math.Clamp(index, 0, _entries.Count);
			Entry<T> entry = new Entry<T>(value, priority);
			_entries.Insert(index, entry);
			RebuildIndexMap();
			if (syncPriorityMap && priority.HasValue)
			{
				int valueOrDefault = priority.GetValueOrDefault();
				RegisterPriority(valueOrDefault, value);
			}
			return entry;
		}

		private void SyncPriorityMap()
		{
			RebuildPriorityMapFromEntries();
		}

		private int ResolveTargetIndexForPriorityOnly([AllowNull] T value, int priority, int? requestedIndex, PlacementIndexBias placementIndexBias)
		{
			if (requestedIndex.HasValue)
			{
				int valueOrDefault = requestedIndex.GetValueOrDefault();
				valueOrDefault = Math.Clamp(valueOrDefault, 0, _entries.Count);
				if (!PrioritySetInvariant.TryFindHighestValidIndex(_entries, priority, value, out var _))
				{
					ShiftPrioritiesAtOrAbove(priority);
				}
				return valueOrDefault;
			}
			if (placementIndexBias == PlacementIndexBias.LowestValidIndex)
			{
				if (PrioritySetInvariant.TryFindLowestValidIndex(_entries, priority, value, out var index2))
				{
					return index2;
				}
				ShiftPrioritiesAtOrAbove(priority);
				if (PrioritySetInvariant.TryFindLowestValidIndex(_entries, priority, value, out index2))
				{
					return index2;
				}
				return _entries.Count;
			}
			if (PrioritySetInvariant.TryFindHighestValidIndex(_entries, priority, value, out var index3))
			{
				return index3;
			}
			ShiftPrioritiesAtOrAbove(priority);
			if (PrioritySetInvariant.TryFindHighestValidIndex(_entries, priority, value, out index3))
			{
				return index3;
			}
			return _entries.Count;
		}

		private void ShiftPrioritiesAtOrAbove(int threshold)
		{
			List<Entry<T>> list = new List<Entry<T>>();
			foreach (Entry<T> entry in _entries)
			{
				int? priority = entry.Priority;
				if (priority.HasValue)
				{
					int valueOrDefault = priority.GetValueOrDefault();
					if (valueOrDefault >= threshold)
					{
						list.Add(entry);
					}
				}
			}
			list.Sort((Entry<T> a, Entry<T> b) => b.Priority.Value.CompareTo(a.Priority.Value));
			foreach (Entry<T> item in list)
			{
				int value = item.Priority.Value;
				if (value == int.MaxValue)
				{
					throw new InvalidOperationException("Cannot shift priority at int.MaxValue.");
				}
				UnregisterPriority(value, item.Value);
				int num = value + 1;
				item.Priority = num;
				RegisterPriority(num, item.Value);
			}
		}

		private void ApplyAddToExistingSlot([AllowNull] T value, int? index, int? priority, ConflictResolution? resolution)
		{
			if (!TryGetIndexForLookup(value, out var index2))
			{
				return;
			}
			if (index.HasValue)
			{
				int valueOrDefault = index.GetValueOrDefault();
				valueOrDefault = Math.Clamp(valueOrDefault, 0, _entries.Count - 1);
				if (valueOrDefault != index2)
				{
					MoveEntry(index2, valueOrDefault);
					index2 = valueOrDefault;
				}
			}
			if (priority.HasValue)
			{
				int valueOrDefault2 = priority.GetValueOrDefault();
				if (_priorityToValue.TryGetValue(valueOrDefault2, out var value2) && !_comparer.Equals(value2, value))
				{
					ShiftPrioritiesAtOrAbove(valueOrDefault2);
				}
				SetPriorityAtCore(index2, valueOrDefault2, resolution);
			}
			RepairOrderingAfterIndexChange(resolution);
		}

		public void Enqueue([AllowNull] T value)
		{
			TryEnqueue(value);
		}

		public void Enqueue([AllowNull] T value, int priority, ConflictResolution? resolution = null, DuplicateValuePolicy? duplicateValuePolicy = null, PlacementIndexBias? placementIndexBias = null)
		{
			TryEnqueue(value, priority, resolution, duplicateValuePolicy, placementIndexBias);
		}

		public bool TryEnqueue([AllowNull] T value)
		{
			return Add(value);
		}

		public bool TryEnqueue([AllowNull] T value, int priority, ConflictResolution? resolution = null, DuplicateValuePolicy? duplicateValuePolicy = null, PlacementIndexBias? placementIndexBias = null)
		{
			try
			{
				return Add(value, priority, resolution, duplicateValuePolicy, ResolveEnqueuePlacementIndexBias(placementIndexBias));
			}
			catch (InvalidOperationException)
			{
				return false;
			}
		}

		public T Dequeue()
		{
			if (!TryDequeue(out var result))
			{
				throw new InvalidOperationException("The set is empty.");
			}
			return result;
		}

		public bool TryDequeue(out T result)
		{
			if (_entries.Count == 0)
			{
				result = default(T);
				return false;
			}
			T value = _entries[0].Value;
			RemoveAt(0);
			result = value;
			return true;
		}

		public T Peek()
		{
			if (!TryPeek(out var result))
			{
				throw new InvalidOperationException("The set is empty.");
			}
			return result;
		}

		public bool TryPeek(out T result)
		{
			if (_entries.Count == 0)
			{
				result = default(T);
				return false;
			}
			result = _entries[0].Value;
			return true;
		}

		public IEnumerable<T> ByPriorityRange(int minInclusive, int maxInclusive)
		{
			for (int i = 0; i < _entries.Count; i++)
			{
				int? priority = _entries[i].Priority;
				if (priority.HasValue)
				{
					int valueOrDefault = priority.GetValueOrDefault();
					if (valueOrDefault >= minInclusive && valueOrDefault <= maxInclusive)
					{
						yield return _entries[i].Value;
					}
				}
			}
		}

		public IEnumerable<PrioritySetEntry<T>> EntriesByPriorityRange(int minInclusive, int maxInclusive)
		{
			for (int i = 0; i < _entries.Count; i++)
			{
				int? priority = _entries[i].Priority;
				if (priority.HasValue)
				{
					int valueOrDefault = priority.GetValueOrDefault();
					if (valueOrDefault >= minInclusive && valueOrDefault <= maxInclusive)
					{
						yield return new PrioritySetEntry<T>(_entries[i].Value, valueOrDefault, i);
					}
				}
			}
		}

		internal void ApplyIndexPermutation(ReadOnlySpan<int> newOrder)
		{
			if (newOrder.Length != _entries.Count)
			{
				throw new ArgumentException("Permutation length must match Count.", "newOrder");
			}
			bool[] array = new bool[_entries.Count];
			ReadOnlySpan<int> readOnlySpan = newOrder;
			for (int i = 0; i < readOnlySpan.Length; i++)
			{
				int num = readOnlySpan[i];
				if ((uint)num >= (uint)_entries.Count)
				{
					throw new ArgumentOutOfRangeException("newOrder");
				}
				if (array[num])
				{
					throw new ArgumentException("Permutation must be unique.", "newOrder");
				}
				array[num] = true;
			}
			Entry<T>[] array2 = new Entry<T>[_entries.Count];
			for (int j = 0; j < newOrder.Length; j++)
			{
				array2[j] = _entries[newOrder[j]];
			}
			for (int k = 0; k < array2.Length; k++)
			{
				_entries[k] = array2[k];
			}
			RebuildIndexMap();
			RebuildPriorityMapFromEntries();
		}

		internal void RepairOrderingAfterIndexChange(ConflictResolution? resolution = null)
		{
			ConflictResolution conflictResolution = ResolvePolicy(resolution);
			if (conflictResolution == ConflictResolution.ThrowOnConflict)
			{
				conflictResolution = ConflictResolution.KeepIndex;
			}
			int num = Math.Max(_entries.Count * 2, 1);
			for (int i = 0; i < num; i++)
			{
				bool flag = false;
				for (int j = 0; j < _entries.Count; j++)
				{
					Entry<T> entry = _entries[j];
					if (!entry.Priority.HasValue || !PrioritySetInvariant.HasConflict(_entries, j, entry.Priority))
					{
						continue;
					}
					if (conflictResolution == ConflictResolution.KeepPriority)
					{
						try
						{
							int num2 = PrioritySetInvariant.FindClosestValidIndex(_entries, j, entry.Priority.Value, entry.Value, j);
							if (num2 != j)
							{
								MoveEntry(j, num2);
								flag = true;
								break;
							}
						}
						catch (InvalidOperationException)
						{
						}
					}
					try
					{
						int num3 = PrioritySetInvariant.FindPriorityForIndex(_entries, j, entry.Priority);
						if (num3 != entry.Priority)
						{
							UpdateEntryPriority(entry, num3);
							flag = true;
							continue;
						}
					}
					catch (InvalidOperationException)
					{
						RepairPrioritiesAfterSort();
						return;
					}
					if (PrioritySetInvariant.HasConflict(_entries, j, entry.Priority) && conflictResolution != ConflictResolution.KeepIndex && TryMoveToClosestValidIndex(j, entry.Priority.Value, entry.Value, conflictResolution))
					{
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					break;
				}
			}
			for (int k = 0; k < _entries.Count; k++)
			{
				Entry<T> entry2 = _entries[k];
				if (entry2.Priority.HasValue && PrioritySetInvariant.HasConflict(_entries, k, entry2.Priority))
				{
					RepairPrioritiesAfterSort();
					break;
				}
			}
			SyncPriorityMap();
		}

		internal void EnsurePriorityOrdering()
		{
			for (int i = 0; i < _entries.Count; i++)
			{
				Entry<T> entry = _entries[i];
				if (entry.Priority.HasValue && PrioritySetInvariant.HasConflict(_entries, i, entry.Priority))
				{
					RepairPrioritiesAfterSort();
					break;
				}
			}
		}

		internal void RepairPrioritiesAfterSort()
		{
			if (!HasAnyPriorityOrderingConflict())
			{
				return;
			}
			List<(Entry<T>, int)> list = new List<(Entry<T>, int)>();
			for (int i = 0; i < _entries.Count; i++)
			{
				Entry<T> entry = _entries[i];
				int? priority = entry.Priority;
				if (priority.HasValue)
				{
					int valueOrDefault = priority.GetValueOrDefault();
					list.Add((entry, valueOrDefault));
					UnregisterPriority(entry.Priority, entry.Value);
					entry.Priority = null;
				}
			}
			HashSet<int> hashSet = new HashSet<int>();
			int? num = null;
			foreach (var item in list)
			{
				var (entry2, num2) = item;
				if (num.HasValue)
				{
					int valueOrDefault2 = num.GetValueOrDefault();
					if (num2 > valueOrDefault2)
					{
						num2 = valueOrDefault2;
					}
				}
				while (hashSet.Contains(num2))
				{
					if (num2 == int.MinValue)
					{
						throw new InvalidOperationException("Cannot assign unique priorities after sort.");
					}
					num2--;
				}
				UpdateEntryPriority(entry2, num2);
				hashSet.Add(num2);
				num = num2;
			}
			SyncPriorityMap();
		}

		private bool HasAnyPriorityOrderingConflict()
		{
			for (int i = 0; i < _entries.Count; i++)
			{
				Entry<T> entry = _entries[i];
				if (entry.Priority.HasValue && PrioritySetInvariant.HasConflict(_entries, i, entry.Priority))
				{
					return true;
				}
			}
			return false;
		}

		private void MoveEntry(int fromIndex, int toIndex)
		{
			if (fromIndex != toIndex)
			{
				Entry<T> item = _entries[fromIndex];
				_entries.RemoveAt(fromIndex);
				toIndex = Math.Clamp(toIndex, 0, _entries.Count);
				_entries.Insert(toIndex, item);
				RebuildIndexMap();
				SyncPriorityMap();
			}
		}

		public void UnionWith(IEnumerable<T> other)
		{
			ArgumentNullException.ThrowIfNull(other, "other");
			if (other == this)
			{
				return;
			}
			using (BeginChangedScope())
			{
				if (other is PrioritySet<T> prioritySet)
				{
					foreach (Entry<T> entry in prioritySet._entries)
					{
						if (entry.Value == null || !Contains(entry.Value))
						{
							int? priority = entry.Priority;
							if (priority.HasValue)
							{
								int valueOrDefault = priority.GetValueOrDefault();
								Add(entry.Value, valueOrDefault);
							}
							else
							{
								TryAdd(entry.Value);
							}
						}
					}
					NotifyChanged(PrioritySetChangeKind.BulkSetOperation);
					return;
				}
				foreach (T item in other)
				{
					if (item == null || !Contains(item))
					{
						TryAdd(item);
					}
				}
				NotifyChanged(PrioritySetChangeKind.BulkSetOperation);
			}
		}

		public void UnionWith(IEnumerable<T> other, ConflictResolution? resolution)
		{
			ArgumentNullException.ThrowIfNull(other, "other");
			if (other == this)
			{
				return;
			}
			using (BeginChangedScope())
			{
				if (other is PrioritySet<T> prioritySet)
				{
					foreach (Entry<T> entry in prioritySet._entries)
					{
						if (entry.Value == null || !Contains(entry.Value))
						{
							int? priority = entry.Priority;
							if (priority.HasValue)
							{
								int valueOrDefault = priority.GetValueOrDefault();
								Add(entry.Value, valueOrDefault, resolution);
							}
							else
							{
								TryAdd(entry.Value);
							}
						}
					}
					NotifyChanged(PrioritySetChangeKind.BulkSetOperation);
					return;
				}
				foreach (T item in other)
				{
					if (item == null || !Contains(item))
					{
						TryAdd(item);
					}
				}
				NotifyChanged(PrioritySetChangeKind.BulkSetOperation);
			}
		}

		public void IntersectWith(IEnumerable<T> other)
		{
			ArgumentNullException.ThrowIfNull(other, "other");
			using (BeginChangedScope())
			{
				CollectUniqueMembers(other, out HashSet<T> nonNullMembers, out bool hasNull);
				for (int num = Count - 1; num >= 0; num--)
				{
					T value = _entries[num].Value;
					if (value == null)
					{
						if (!hasNull)
						{
							RemoveAt(num);
						}
					}
					else if (!nonNullMembers.Contains(value))
					{
						RemoveAt(num);
					}
				}
				NotifyChanged(PrioritySetChangeKind.BulkSetOperation);
			}
		}

		public void ExceptWith(IEnumerable<T> other)
		{
			ArgumentNullException.ThrowIfNull(other, "other");
			using (BeginChangedScope())
			{
				if (other == this)
				{
					Clear();
					NotifyChanged(PrioritySetChangeKind.BulkSetOperation);
					return;
				}
				foreach (T item in other)
				{
					Remove(item);
				}
				NotifyChanged(PrioritySetChangeKind.BulkSetOperation);
			}
		}

		public void SymmetricExceptWith(IEnumerable<T> other, ConflictResolution? resolution)
		{
			ArgumentNullException.ThrowIfNull(other, "other");
			using (BeginChangedScope())
			{
				CollectUniqueMembers(other, out HashSet<T> nonNullMembers, out bool hasNull);
				if (other is PrioritySet<T> prioritySet)
				{
					bool flag = false;
					foreach (Entry<T> entry in prioritySet._entries)
					{
						if (entry.Value == null)
						{
							flag = true;
						}
						else if (!Remove(entry.Value))
						{
							int? priority = entry.Priority;
							if (priority.HasValue)
							{
								int valueOrDefault = priority.GetValueOrDefault();
								Add(entry.Value, valueOrDefault, resolution);
							}
							else
							{
								TryAdd(entry.Value);
							}
						}
					}
					if (flag)
					{
						if (IndexOfNullReference() >= 0)
						{
							while (Remove(default(T)))
							{
							}
						}
						else
						{
							TryAdd(default(T));
						}
					}
					NotifyChanged(PrioritySetChangeKind.BulkSetOperation);
					return;
				}
				foreach (T item in nonNullMembers)
				{
					if (!Remove(item))
					{
						TryAdd(item);
					}
				}
				if (hasNull)
				{
					if (IndexOfNullReference() >= 0)
					{
						while (Remove(default(T)))
						{
						}
					}
					else
					{
						TryAdd(default(T));
					}
				}
				NotifyChanged(PrioritySetChangeKind.BulkSetOperation);
			}
		}

		public void SymmetricExceptWith(IEnumerable<T> other)
		{
			ArgumentNullException.ThrowIfNull(other, "other");
			using (BeginChangedScope())
			{
				CollectUniqueMembers(other, out HashSet<T> nonNullMembers, out bool hasNull);
				foreach (T item in nonNullMembers)
				{
					if (!Remove(item))
					{
						TryAdd(item);
					}
				}
				if (hasNull)
				{
					if (IndexOfNullReference() >= 0)
					{
						while (Remove(default(T)))
						{
						}
					}
					else
					{
						TryAdd(default(T));
					}
				}
				NotifyChanged(PrioritySetChangeKind.BulkSetOperation);
			}
		}

		public bool IsSubsetOf(IEnumerable<T> other)
		{
			ArgumentNullException.ThrowIfNull(other, "other");
			CollectUniqueMembers(this, out HashSet<T> nonNullMembers, out bool hasNull);
			CollectUniqueMembers(other, out HashSet<T> nonNullMembers2, out bool hasNull2);
			foreach (T item in nonNullMembers)
			{
				if (!nonNullMembers2.Contains(item))
				{
					return false;
				}
			}
			if (hasNull && !hasNull2)
			{
				return false;
			}
			return true;
		}

		public bool IsProperSubsetOf(IEnumerable<T> other)
		{
			ArgumentNullException.ThrowIfNull(other, "other");
			CollectUniqueMembers(this, out HashSet<T> nonNullMembers, out bool hasNull);
			CollectUniqueMembers(other, out HashSet<T> nonNullMembers2, out bool hasNull2);
			int num = nonNullMembers.Count + (hasNull ? 1 : 0);
			int num2 = nonNullMembers2.Count + (hasNull2 ? 1 : 0);
			if (IsSubsetOf(other))
			{
				return num < num2;
			}
			return false;
		}

		public bool IsSupersetOf(IEnumerable<T> other)
		{
			ArgumentNullException.ThrowIfNull(other, "other");
			CollectUniqueMembers(other, out HashSet<T> nonNullMembers, out bool hasNull);
			foreach (T item in nonNullMembers)
			{
				if (!Contains(item))
				{
					return false;
				}
			}
			if (hasNull && IndexOfNullReference() < 0)
			{
				return false;
			}
			return true;
		}

		public bool IsProperSupersetOf(IEnumerable<T> other)
		{
			ArgumentNullException.ThrowIfNull(other, "other");
			CollectUniqueMembers(other, out HashSet<T> nonNullMembers, out bool hasNull);
			int num = nonNullMembers.Count + (hasNull ? 1 : 0);
			int uniqueMemberCount = GetUniqueMemberCount();
			if (IsSupersetOf(other))
			{
				return uniqueMemberCount > num;
			}
			return false;
		}

		public bool Overlaps(IEnumerable<T> other)
		{
			ArgumentNullException.ThrowIfNull(other, "other");
			CollectUniqueMembers(this, out HashSet<T> nonNullMembers, out bool hasNull);
			CollectUniqueMembers(other, out HashSet<T> nonNullMembers2, out bool hasNull2);
			if (hasNull && hasNull2)
			{
				return true;
			}
			foreach (T item in nonNullMembers)
			{
				if (nonNullMembers2.Contains(item))
				{
					return true;
				}
			}
			return false;
		}

		public bool SetEquals(IEnumerable<T> other)
		{
			ArgumentNullException.ThrowIfNull(other, "other");
			CollectUniqueMembers(this, out HashSet<T> nonNullMembers, out bool hasNull);
			CollectUniqueMembers(other, out HashSet<T> nonNullMembers2, out bool hasNull2);
			if (hasNull != hasNull2)
			{
				return false;
			}
			return nonNullMembers.SetEquals(nonNullMembers2);
		}

		private int GetUniqueMemberCount()
		{
			CollectUniqueMembers(this, out HashSet<T> nonNullMembers, out bool hasNull);
			return nonNullMembers.Count + (hasNull ? 1 : 0);
		}

		private void CollectUniqueMembers(IEnumerable<T> source, out HashSet<T> nonNullMembers, out bool hasNull)
		{
			nonNullMembers = new HashSet<T>(_comparer);
			hasNull = false;
			foreach (T item in source)
			{
				if (item == null)
				{
					hasNull = true;
				}
				else
				{
					nonNullMembers.Add(item);
				}
			}
		}

		public PrioritySet(PrioritySet<T> source)
			: this(source?._comparer)
		{
			ArgumentNullException.ThrowIfNull(source, "source");
			DefaultConflictResolution = source.DefaultConflictResolution;
			DefaultDuplicateValuePolicy = source.DefaultDuplicateValuePolicy;
			DefaultPlacementIndexBias = source.DefaultPlacementIndexBias;
			_entries.Clear();
			for (int i = 0; i < source._entries.Count; i++)
			{
				Entry<T> entry = source._entries[i];
				_entries.Add(new Entry<T>(entry.Value, entry.Priority));
			}
			RebuildIndexMap();
			SyncPriorityMap();
		}

		public PrioritySetSnapshot<T> CreateSnapshot()
		{
			PrioritySetEntry<T>[] array = new PrioritySetEntry<T>[_entries.Count];
			for (int i = 0; i < _entries.Count; i++)
			{
				array[i] = new PrioritySetEntry<T>(_entries[i].Value, _entries[i].Priority, i);
			}
			return new PrioritySetSnapshot<T>(array);
		}

		public PrioritySet<T> Clone()
		{
			return new PrioritySet<T>(this);
		}

		public void Sort(Comparison<T> comparison)
		{
			ArgumentNullException.ThrowIfNull(comparison, "comparison");
			if (_entries.Count > 1)
			{
				int[] array = (from x in (from i in Enumerable.Range(0, _entries.Count)
						select (Index: i, Value: _entries[i].Value)).OrderBy(((int Index, T Value) x) => x.Value, Comparer<T>.Create(comparison)).ThenBy(((int Index, T Value) x) => x.Index)
					select x.Index).ToArray();
				ApplyIndexPermutation(array);
				RepairPrioritiesAfterSort();
				NotifyChanged(PrioritySetChangeKind.Sort);
			}
		}

		public void Sort<TKey>(Func<T, TKey> keySelector, IComparer<TKey>? comparer = null)
		{
			ArgumentNullException.ThrowIfNull(keySelector, "keySelector");
			if (comparer == null)
			{
				comparer = Comparer<TKey>.Default;
			}
			Sort((T a, T b) => comparer.Compare(keySelector(a), keySelector(b)));
		}

		public void SetIndexAt(int index, int newIndex, ConflictResolution? resolution = null)
		{
			TrySetIndexAt(index, newIndex, resolution);
		}

		public bool TrySetIndexAt(int index, int newIndex, ConflictResolution? resolution = null)
		{
			if ((uint)index >= (uint)_entries.Count)
			{
				return false;
			}
			int num = Math.Clamp(newIndex, 0, _entries.Count - 1);
			if (num == index)
			{
				return true;
			}
			T value = _entries[index].Value;
			int? priority = _entries[index].Priority;
			MoveEntry(index, num);
			RepairOrderingAfterIndexChange(resolution);
			int? index2 = num;
			if (value != null && _indexByValue.TryGetValue(value, out var value2))
			{
				index2 = value2;
			}
			else if (value == null)
			{
				int num2 = IndexOfNullReference();
				if (num2 >= 0)
				{
					index2 = num2;
				}
			}
			int? num3;
			if (index2.HasValue)
			{
				int valueOrDefault = index2.GetValueOrDefault();
				num3 = _entries[valueOrDefault].Priority;
			}
			else
			{
				num3 = priority;
			}
			int? priority2 = num3;
			NotifyChanged(PrioritySetChangeKind.Reorder, index2, value, priority2);
			return true;
		}

		public void SetIndexByValue([AllowNull] T value, int newIndex, ConflictResolution? resolution = null)
		{
			TrySetIndexByValue(value, newIndex, resolution);
		}

		public bool TrySetIndexByValue([AllowNull] T value, int newIndex, ConflictResolution? resolution = null)
		{
			if (!TryResolveSlotIndex(null, null, value, byValue: true, out var resolvedIndex))
			{
				return false;
			}
			return TrySetIndexAt(resolvedIndex, newIndex, resolution);
		}

		public void SetIndexByPriority(int currentPriority, int newIndex, ConflictResolution? resolution = null)
		{
			TrySetIndexByPriority(currentPriority, newIndex, resolution);
		}

		public bool TrySetIndexByPriority(int currentPriority, int newIndex, ConflictResolution? resolution = null)
		{
			if (!TryResolveSlotIndex(null, currentPriority, default(T), byValue: false, out var resolvedIndex))
			{
				return false;
			}
			return TrySetIndexAt(resolvedIndex, newIndex, resolution);
		}

		public void SetSlotAt(int index, int newIndex, int newPriority, ConflictResolution? resolution = null)
		{
			TrySetSlotAt(index, newIndex, newPriority, resolution);
		}

		public bool TrySetSlotAt(int index, int newIndex, int newPriority, ConflictResolution? resolution = null)
		{
			return TrySetSlotAtCore(index, updateValue: false, default(T), newIndex, newPriority, resolution);
		}

		public void SetSlotAt(int index, [AllowNull] T newValue, int? newIndex = null, int? newPriority = null, ConflictResolution? resolution = null, DuplicateValuePolicy? duplicateValuePolicy = null)
		{
			TrySetSlotAt(index, newValue, newIndex, newPriority, resolution, duplicateValuePolicy);
		}

		public bool TrySetSlotAt(int index, [AllowNull] T newValue, int? newIndex = null, int? newPriority = null, ConflictResolution? resolution = null, DuplicateValuePolicy? duplicateValuePolicy = null)
		{
			if (1 + (newIndex.HasValue ? 1 : 0) + (newPriority.HasValue ? 1 : 0) < 2)
			{
				throw new ArgumentException("Changing only the value requires SetValueAt/TrySetValueAt. Changing only index or priority requires TrySetIndexAt or SetPriorityAt.", "newValue");
			}
			return TrySetSlotAtCore(index, updateValue: true, newValue, newIndex, newPriority, resolution, duplicateValuePolicy);
		}

		public bool TrySetSlotByValue([AllowNull] T currentValue, int? newIndex = null, int? newPriority = null, ConflictResolution? resolution = null)
		{
			if (!TryGetIndexForLookup(currentValue, out var index))
			{
				return false;
			}
			if (!newIndex.HasValue && !newPriority.HasValue)
			{
				return true;
			}
			if (newIndex.HasValue)
			{
				int valueOrDefault = newIndex.GetValueOrDefault();
				if (newPriority.HasValue)
				{
					int valueOrDefault2 = newPriority.GetValueOrDefault();
					return TrySetSlotAt(index, valueOrDefault, valueOrDefault2, resolution);
				}
			}
			if (newIndex.HasValue)
			{
				int valueOrDefault3 = newIndex.GetValueOrDefault();
				return TrySetIndexAt(index, valueOrDefault3, resolution);
			}
			return TrySetPriorityAt(index, newPriority.Value, resolution);
		}

		public bool TrySetSlotByValue([AllowNull] T currentValue, [AllowNull] T newValue, int? newIndex = null, int? newPriority = null, ConflictResolution? resolution = null, DuplicateValuePolicy? duplicateValuePolicy = null)
		{
			if (!TryGetIndexForLookup(currentValue, out var index))
			{
				return false;
			}
			if (!newIndex.HasValue && !newPriority.HasValue)
			{
				return TrySetValueAt(index, newValue, duplicateValuePolicy, resolution);
			}
			return TrySetSlotAt(index, newValue, newIndex, newPriority, resolution, duplicateValuePolicy);
		}

		public bool TrySetSlotByPriority(int currentPriority, int? newIndex = null, int? newPriority = null, ConflictResolution? resolution = null)
		{
			if (!TryGetIndexForPriority(currentPriority, out var index))
			{
				return false;
			}
			if (!newIndex.HasValue && !newPriority.HasValue)
			{
				return true;
			}
			if (newIndex.HasValue)
			{
				int valueOrDefault = newIndex.GetValueOrDefault();
				if (newPriority.HasValue)
				{
					int valueOrDefault2 = newPriority.GetValueOrDefault();
					return TrySetSlotAt(index, valueOrDefault, valueOrDefault2, resolution);
				}
			}
			if (newIndex.HasValue)
			{
				int valueOrDefault3 = newIndex.GetValueOrDefault();
				return TrySetIndexAt(index, valueOrDefault3, resolution);
			}
			return TrySetPriorityAt(index, newPriority.Value, resolution);
		}

		public bool TrySetSlotByPriority(int currentPriority, [AllowNull] T newValue, int? newIndex = null, int? newPriority = null, ConflictResolution? resolution = null, DuplicateValuePolicy? duplicateValuePolicy = null)
		{
			if (!TryGetIndexForPriority(currentPriority, out var index))
			{
				return false;
			}
			if (!newIndex.HasValue && !newPriority.HasValue)
			{
				return TrySetValueAt(index, newValue, duplicateValuePolicy, resolution);
			}
			return TrySetSlotAt(index, newValue, newIndex, newPriority, resolution, duplicateValuePolicy);
		}

		private bool TrySetSlotAtCore(int index, bool updateValue, [AllowNull] T newValue, int? newIndex, int? newPriority, ConflictResolution? resolution, DuplicateValuePolicy? duplicateValuePolicy = null)
		{
			if ((uint)index >= (uint)_entries.Count)
			{
				return false;
			}
			if (!updateValue)
			{
				if (newIndex.HasValue)
				{
					newIndex.GetValueOrDefault();
					if (newPriority.HasValue)
					{
						newPriority.GetValueOrDefault();
						goto IL_009c;
					}
				}
				if (newIndex.HasValue)
				{
					int valueOrDefault = newIndex.GetValueOrDefault();
					return TrySetIndexAt(index, valueOrDefault, resolution);
				}
				if (newPriority.HasValue)
				{
					int valueOrDefault2 = newPriority.GetValueOrDefault();
					return TrySetPriorityAt(index, valueOrDefault2, resolution);
				}
				return false;
			}
			if (1 + (newIndex.HasValue ? 1 : 0) + (newPriority.HasValue ? 1 : 0) < 2)
			{
				return TrySetValueAt(index, newValue, duplicateValuePolicy, resolution);
			}
			goto IL_009c;
			IL_009c:
			T value = _entries[index].Value;
			T val = (T)(updateValue ? ((object)newValue) : ((object)value));
			PrioritySetChangeKind prioritySetChangeKind = PrioritySetChangeKind.None;
			if (newIndex.HasValue)
			{
				int valueOrDefault3 = newIndex.GetValueOrDefault();
				int num = Math.Clamp(valueOrDefault3, 0, _entries.Count - 1);
				if (num != index)
				{
					MoveEntry(index, num);
					index = num;
					prioritySetChangeKind |= PrioritySetChangeKind.Reorder;
				}
			}
			if (updateValue && !_comparer.Equals(_entries[index].Value, newValue))
			{
				if (!TryAssignValueAt(index, newValue, resolution, duplicateValuePolicy))
				{
					return false;
				}
				prioritySetChangeKind |= PrioritySetChangeKind.Update;
			}
			if (newPriority.HasValue)
			{
				int valueOrDefault4 = newPriority.GetValueOrDefault();
				SetPriorityAtCore(index, valueOrDefault4, resolution);
				prioritySetChangeKind |= PrioritySetChangeKind.PriorityChange;
			}
			RepairOrderingAfterIndexChange(resolution);
			if (prioritySetChangeKind == PrioritySetChangeKind.None)
			{
				prioritySetChangeKind = PrioritySetChangeKind.Update;
			}
			int? index2 = null;
			if (val != null && _indexByValue.TryGetValue(val, out var value2))
			{
				index2 = value2;
			}
			else if (val == null)
			{
				int num2 = IndexOfNullReference();
				if (num2 >= 0)
				{
					index2 = num2;
				}
			}
			int? obj;
			if (index2.HasValue)
			{
				int valueOrDefault5 = index2.GetValueOrDefault();
				obj = _entries[valueOrDefault5].Priority;
			}
			else
			{
				obj = null;
			}
			int? priority = obj;
			NotifyChanged(prioritySetChangeKind, index2, val, priority);
			return true;
		}
	}
	public sealed class PrioritySetSnapshot<T> : IReadOnlyList<PrioritySetEntry<T>>, IEnumerable<PrioritySetEntry<T>>, IEnumerable, IReadOnlyCollection<PrioritySetEntry<T>>
	{
		private readonly PrioritySetEntry<T>[] _entries;

		public PrioritySetEntry<T> this[int index] => _entries[index];

		public int Count => _entries.Length;

		internal PrioritySetSnapshot(PrioritySetEntry<T>[] entries)
		{
			_entries = entries;
		}

		public IEnumerator<PrioritySetEntry<T>> GetEnumerator()
		{
			return ((IEnumerable<PrioritySetEntry<T>>)_entries).GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return GetEnumerator();
		}
	}
	public readonly struct PrioritySetEntry<T>
	{
		public T Value { get; }

		public int? Priority { get; }

		public int Index { get; }

		public PrioritySetEntry([AllowNull] T value, int? priority, int index)
		{
			Value = value;
			Priority = priority;
			Index = index;
		}
	}
	internal static class PrioritySetInvariant
	{
		public static int FindPreviousPrioritizedIndex<T>(IReadOnlyList<Entry<T>> entries, int index)
		{
			for (int num = index - 1; num >= 0; num--)
			{
				if (entries[num].Priority.HasValue)
				{
					return num;
				}
			}
			return -1;
		}

		public static int FindNextPrioritizedIndex<T>(IReadOnlyList<Entry<T>> entries, int index)
		{
			for (int i = index + 1; i < entries.Count; i++)
			{
				if (entries[i].Priority.HasValue)
				{
					return i;
				}
			}
			return -1;
		}

		public static bool HasDuplicatePriority<T>(IReadOnlyList<Entry<T>> entries, int index, int priority)
		{
			for (int i = 0; i < entries.Count; i++)
			{
				if (i != index && entries[i].Priority == priority)
				{
					return true;
				}
			}
			return false;
		}

		public static bool HasConflict<T>(IReadOnlyList<Entry<T>> entries, int index, int? priority)
		{
			if (!priority.HasValue)
			{
				return false;
			}
			int value = priority.Value;
			if (HasDuplicatePriority(entries, index, value))
			{
				return true;
			}
			int num = FindPreviousPrioritizedIndex(entries, index);
			if (num >= 0 && entries[num].Priority.Value < value)
			{
				return true;
			}
			int num2 = FindNextPrioritizedIndex(entries, index);
			if (num2 >= 0 && value < entries[num2].Priority.Value)
			{
				return true;
			}
			return false;
		}

		public static bool IsValidPlacement<T>(IReadOnlyList<Entry<T>> entries, int index, int? priority)
		{
			return !HasConflict(entries, index, priority);
		}

		public static (int Min, int Max)? GetAllowedPriorityRange<T>(IReadOnlyList<Entry<T>> entries, int index)
		{
			int num = FindPreviousPrioritizedIndex(entries, index);
			int num2 = FindNextPrioritizedIndex(entries, index);
			if (num < 0 && num2 < 0)
			{
				return null;
			}
			int num3 = ((num >= 0) ? entries[num].Priority.Value : int.MaxValue);
			int num4 = ((num2 >= 0) ? entries[num2].Priority.Value : int.MinValue);
			if (num4 > num3)
			{
				return null;
			}
			return (num4, num3);
		}

		public static int FindPriorityForIndex<T>(IReadOnlyList<Entry<T>> entries, int index, int? requestedPriority)
		{
			if (requestedPriority.HasValue)
			{
				int valueOrDefault = requestedPriority.GetValueOrDefault();
				if (IsValidPlacement(entries, index, valueOrDefault))
				{
					return valueOrDefault;
				}
			}
			(int, int)? allowedPriorityRange = GetAllowedPriorityRange(entries, index);
			if (!allowedPriorityRange.HasValue)
			{
				if (requestedPriority.HasValue)
				{
					int valueOrDefault2 = requestedPriority.GetValueOrDefault();
					if (!HasDuplicatePriority(entries, index, valueOrDefault2))
					{
						return valueOrDefault2;
					}
				}
				for (int num = int.MaxValue; num >= int.MinValue; num--)
				{
					if (!HasDuplicatePriority(entries, index, num))
					{
						return num;
					}
				}
				throw new InvalidOperationException("No valid priority exists for the requested index.");
			}
			var (num2, num3) = allowedPriorityRange.Value;
			if (requestedPriority.HasValue)
			{
				int valueOrDefault3 = requestedPriority.GetValueOrDefault();
				int num4 = Math.Clamp(valueOrDefault3, num2, num3);
				if (!HasDuplicatePriority(entries, index, num4))
				{
					return num4;
				}
			}
			for (int num5 = num3; num5 >= num2; num5--)
			{
				if (!HasDuplicatePriority(entries, index, num5))
				{
					return num5;
				}
			}
			throw new InvalidOperationException("No valid priority exists for the requested index.");
		}

		public static int FindClosestValidIndex<T>(IReadOnlyList<Entry<T>> entries, int desiredIndex, int priority, T value, int sourceIndex = -1)
		{
			desiredIndex = Math.Clamp(desiredIndex, 0, entries.Count);
			int num = -1;
			int num2 = int.MaxValue;
			if (sourceIndex >= 0)
			{
				for (int i = 0; i < entries.Count; i++)
				{
					if (TrySimulateMove(entries, sourceIndex, i, priority))
					{
						int num3 = Math.Abs(i - desiredIndex);
						if (num3 < num2 || (num3 == num2 && i < num))
						{
							num2 = num3;
							num = i;
						}
					}
				}
			}
			else
			{
				for (int j = 0; j <= entries.Count; j++)
				{
					if (TrySimulatePlacement(entries, j, priority, value))
					{
						int num4 = Math.Abs(j - desiredIndex);
						if (num4 < num2 || (num4 == num2 && j < num))
						{
							num2 = num4;
							num = j;
						}
					}
				}
			}
			if (num < 0)
			{
				throw new InvalidOperationException("No valid index exists for the requested priority.");
			}
			return num;
		}

		public static bool TryFindHighestValidIndex<T>(IReadOnlyList<Entry<T>> entries, int priority, T value, out int index)
		{
			for (int num = entries.Count; num >= 0; num--)
			{
				if (TrySimulatePlacement(entries, num, priority, value))
				{
					index = num;
					return true;
				}
			}
			index = 0;
			return false;
		}

		public static bool TryFindLowestValidIndex<T>(IReadOnlyList<Entry<T>> entries, int priority, T value, out int index)
		{
			for (int i = 0; i <= entries.Count; i++)
			{
				if (TrySimulatePlacement(entries, i, priority, value))
				{
					index = i;
					return true;
				}
			}
			index = 0;
			return false;
		}

		private static bool TrySimulatePlacement<T>(IReadOnlyList<Entry<T>> entries, int index, int priority, T value)
		{
			List<Entry<T>> list = new List<Entry<T>>(entries);
			if (index > list.Count)
			{
				return false;
			}
			if (index == list.Count)
			{
				list.Add(new Entry<T>(value, priority));
			}
			else
			{
				list.Insert(index, new Entry<T>(value, priority));
			}
			return IsValidPlacement(list, index, priority);
		}

		private static bool TrySimulateMove<T>(IReadOnlyList<Entry<T>> entries, int fromIndex, int toIndex, int priority)
		{
			if ((uint)fromIndex >= (uint)entries.Count)
			{
				return false;
			}
			T value = entries[fromIndex].Value;
			List<Entry<T>> list = new List<Entry<T>>();
			for (int i = 0; i < entries.Count; i++)
			{
				if (i != fromIndex)
				{
					list.Add(entries[i]);
				}
			}
			int index = Math.Clamp(toIndex, 0, list.Count);
			list.Insert(index, new Entry<T>(value, priority));
			return IsValidPlacement(list, index, priority);
		}
	}
	internal sealed class Entry<T>
	{
		public T Value
		{
			get; [param: AllowNull]
			set;
		}

		public int? Priority { get; set; }

		public Entry([AllowNull] T value, int? priority)
		{
			Value = value;
			Priority = priority;
		}
	}
}

Patchers/Il2CppInteropFix.Patcher.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Preloader.Core.Patching;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Runtime;
using Il2CppInterop.Runtime.Runtime.VersionSpecific.Class;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Il2CppInteropFix.Patcher")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+2f15411dcb5b83d69331116c439ca50c214c1902")]
[assembly: AssemblyProduct("Il2CppInteropFix.Patcher")]
[assembly: AssemblyTitle("Il2CppInteropFix.Patcher")]
[assembly: TargetPlatform("Windows7.0")]
[assembly: SupportedOSPlatform("Windows7.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 Il2CppInteropFix
{
	internal static class FixLogger
	{
		internal static ManualLogSource Log { get; private set; }

		internal static bool Verbose => Environment.GetEnvironmentVariable("IL2CPP_INTEROP_FIX_VERBOSE") == "1";

		internal static void Initialize(ManualLogSource log)
		{
			Log = log;
		}

		internal static void Info(string message)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)message);
			}
		}

		internal static void Warning(string message)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogWarning((object)message);
			}
		}

		internal static void Debug(string message)
		{
			if (Verbose)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogDebug((object)message);
				}
			}
		}

		internal static void Error(string message)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogError((object)message);
			}
		}
	}
	[PatcherPluginInfo("com.slide.il2cppinteropfix.bootstrap", "Il2CppInterop Fix Bootstrap", "1.0.0")]
	internal sealed class Il2CppInteropFixBootstrap : BasePatcher
	{
		private static readonly object ApplyLock = new object();

		private static Harmony _harmony;

		private static bool _chainloaderPatched;

		private static ManualLogSource _log;

		public override void Initialize()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			_log = ((BasePatcher)this).Log;
			FixLogger.Initialize(_log);
			_harmony = new Harmony("com.slide.il2cppinteropfix.bootstrap");
			AppDomain.CurrentDomain.AssemblyLoad += OnAssemblyLoad;
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; i < assemblies.Length; i++)
			{
				OnAssemblyLoaded(assemblies[i]);
			}
		}

		public override void Finalizer()
		{
			TryPatchChainloader();
			TryApplyLookupPatch("preloader Finalizer");
		}

		private static void OnAssemblyLoad(object sender, AssemblyLoadEventArgs args)
		{
			OnAssemblyLoaded(args.LoadedAssembly);
		}

		private static void OnAssemblyLoaded(Assembly assembly)
		{
			string name = assembly.GetName().Name;
			if ((name == "Il2CppInterop.Runtime" || name == "BepInEx.Unity.IL2CPP") ? true : false)
			{
				TryApplyLookupPatch("after " + name + " load");
				TryPatchChainloader();
			}
		}

		private static void TryApplyLookupPatch(string stage)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			lock (ApplyLock)
			{
				if (NestedTypeLookupFix.IsLookupPatchInstalled || !AppDomain.CurrentDomain.GetAssemblies().Any((Assembly assembly) => assembly.GetName().Name == "Il2CppInterop.Runtime"))
				{
					return;
				}
				if (NestedTypeLookupFix.TryInstallLookupPatch(_harmony))
				{
					ManualLogSource log = _log;
					if (log != null)
					{
						bool flag = default(bool);
						BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(51, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Il2CppInterop nested-type injection fix applied (");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(stage);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(").");
						}
						log.LogInfo(val);
					}
				}
				else
				{
					ManualLogSource log2 = _log;
					if (log2 != null)
					{
						log2.LogWarning((object)("Il2CppInterop nested-type injection fix was NOT applied (" + stage + "). Ensure Il2CppInteropFix.Patcher.dll is in BepInEx/patchers."));
					}
				}
			}
		}

		private static void TryPatchChainloader()
		{
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Expected O, but got Unknown
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Expected O, but got Unknown
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Expected O, but got Unknown
			//IL_020f: Expected O, but got Unknown
			lock (ApplyLock)
			{
				if (_chainloaderPatched)
				{
					return;
				}
				Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly assembly2) => assembly2.GetName().Name == "BepInEx.Unity.IL2CPP");
				if (assembly == null)
				{
					return;
				}
				Type type = assembly.GetType("BepInEx.Unity.IL2CPP.Il2CppInteropManager", throwOnError: false);
				Type type2 = assembly.GetType("BepInEx.Unity.IL2CPP.IL2CPPChainloader", throwOnError: false);
				MethodInfo methodInfo = type?.GetMethod("Initialize", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				MethodInfo methodInfo2 = type?.GetMethod("PreloadInteropAssemblies", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				MethodInfo methodInfo3 = type2?.GetMethod("LoadPlugin", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2]
				{
					typeof(PluginInfo),
					typeof(Assembly)
				}, null);
				if (methodInfo == null && methodInfo2 == null && methodInfo3 == null)
				{
					ManualLogSource log = _log;
					if (log != null)
					{
						log.LogDebug((object)("Il2CppInterop fix bootstrap: chainloader methods not ready yet " + $"(managerType={type != null}, chainloaderType={type2 != null})."));
					}
					return;
				}
				if (methodInfo != null)
				{
					_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(Il2CppInteropFixBootstrap), "BeforeInteropInitialize", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				if (methodInfo2 != null)
				{
					_harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(Il2CppInteropFixBootstrap), "AfterPreloadInteropAssemblies", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				if (methodInfo3 != null)
				{
					_harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(Il2CppInteropFixBootstrap), "BeforePluginLoad", (Type[])null), new HarmonyMethod(typeof(Il2CppInteropFixBootstrap), "AfterPluginLoad", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				_chainloaderPatched = true;
				ManualLogSource log2 = _log;
				if (log2 != null)
				{
					log2.LogInfo((object)"Il2CppInterop fix bootstrap installed (pre-plugin).");
				}
			}
		}

		public static void BeforeInteropInitialize()
		{
			TryApplyLookupPatch("before Il2CppInteropManager.Initialize");
		}

		public static void AfterPreloadInteropAssemblies()
		{
			TryApplyLookupPatch("after PreloadInteropAssemblies");
		}

		public static void BeforePluginLoad()
		{
			TryPatchChainloader();
			TryApplyLookupPatch("before plugin Load");
		}

		public static void AfterPluginLoad(PluginInfo pluginInfo, Assembly pluginAssembly)
		{
			string text = pluginAssembly?.GetName().Name ?? string.Empty;
			DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(18, 2);
			defaultInterpolatedStringHandler.AppendLiteral("Plugin loaded: ");
			object value;
			if (pluginInfo == null)
			{
				value = null;
			}
			else
			{
				BepInPlugin metadata = pluginInfo.Metadata;
				value = ((metadata != null) ? metadata.Name : null);
			}
			defaultInterpolatedStringHandler.AppendFormatted((string?)value);
			defaultInterpolatedStringHandler.AppendLiteral(" (");
			defaultInterpolatedStringHandler.AppendFormatted(text);
			defaultInterpolatedStringHandler.AppendLiteral(")");
			FixLogger.Debug(defaultInterpolatedStringHandler.ToStringAndClear());
			if (string.Equals(text, "BotControl", StringComparison.Ordinal))
			{
				NestedTypeLookupFix.LogBotControlSummary();
			}
		}
	}
	internal sealed class NestedTypeDiagnostics
	{
		private readonly List<string> _events = new List<string>();

		private readonly Dictionary<string, string> _shortNameOwners = new Dictionary<string, string>(StringComparer.Ordinal);

		private readonly Dictionary<string, List<string>> _computedFullNames = new Dictionary<string, List<string>>(StringComparer.Ordinal);

		internal int LookupQualifiedAdded;

		internal int LookupShortAdded;

		internal int LookupShortSkipped;

		internal int DeclaringLinkOk;

		internal int DeclaringLinkFailed;

		internal void RecordEvent(string line)
		{
			_events.Add(line);
			FixLogger.Debug(line);
		}

		internal void RecordShortNameOwner(string namespaze, string shortName, string ownerType, IntPtr image)
		{
			string key = $"{namespaze}|{shortName}|{image.ToInt64():X}";
			_shortNameOwners[key] = ownerType;
		}

		internal bool TryGetShortNameOwner(string namespaze, string shortName, IntPtr image, out string ownerType)
		{
			string key = $"{namespaze}|{shortName}|{image.ToInt64():X}";
			return _shortNameOwners.TryGetValue(key, out ownerType);
		}

		internal void RecordComputedFullName(string fullName, string managedType)
		{
			if (!_computedFullNames.TryGetValue(fullName, out var value))
			{
				value = new List<string>();
				_computedFullNames[fullName] = value;
			}
			value.Add(managedType);
		}

		internal string BuildSummary()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("--- Il2CppInteropFix BotControl nested-type summary ---");
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder3 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(46, 3, stringBuilder2);
			handler.AppendLiteral("Lookup: qualified=");
			handler.AppendFormatted(LookupQualifiedAdded);
			handler.AppendLiteral(", shortAdded=");
			handler.AppendFormatted(LookupShortAdded);
			handler.AppendLiteral(", shortSkipped=");
			handler.AppendFormatted(LookupShortSkipped);
			stringBuilder3.AppendLine(ref handler);
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder4 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(32, 2, stringBuilder2);
			handler.AppendLiteral("DeclaringType link: ok=");
			handler.AppendFormatted(DeclaringLinkOk);
			handler.AppendLiteral(", failed=");
			handler.AppendFormatted(DeclaringLinkFailed);
			stringBuilder4.AppendLine(ref handler);
			foreach (KeyValuePair<string, List<string>> computedFullName in _computedFullNames)
			{
				if (computedFullName.Value.Count > 1)
				{
					stringBuilder2 = stringBuilder;
					StringBuilder stringBuilder5 = stringBuilder2;
					handler = new StringBuilder.AppendInterpolatedStringHandler(26, 2, stringBuilder2);
					handler.AppendLiteral("DUPLICATE full name '");
					handler.AppendFormatted(computedFullName.Key);
					handler.AppendLiteral("' -> ");
					handler.AppendFormatted(string.Join(", ", computedFullName.Value));
					stringBuilder5.AppendLine(ref handler);
				}
			}
			if (_events.Count > 0 && FixLogger.Verbose)
			{
				stringBuilder.AppendLine("Per-type trace:");
				foreach (string @event in _events)
				{
					stringBuilder.AppendLine("  " + @event);
				}
			}
			stringBuilder.Append("--- end summary ---");
			return stringBuilder.ToString();
		}
	}
	internal static class NestedTypeLookupFix
	{
		private const Il2CppClassAttributes VisibilityMask = (Il2CppClassAttributes)7u;

		private const Il2CppClassAttributes NestedPublic = (Il2CppClassAttributes)2u;

		private const Il2CppClassAttributes NestedPrivate = (Il2CppClassAttributes)3u;

		private const string TargetAssemblyName = "BotControl";

		private static readonly object InstallLock = new object();

		private static bool _lookupPatchInstalled;

		private static bool _registerPatchInstalled;

		private static FieldInfo _injectedTypesField;

		private static NestedTypeDiagnostics _botControlDiagnostics;

		internal static bool IsLookupPatchInstalled => _lookupPatchInstalled;

		internal static void LogBotControlSummary()
		{
			NestedTypeDiagnostics botControlDiagnostics = _botControlDiagnostics;
			if (botControlDiagnostics == null)
			{
				FixLogger.Info("BotControl finished loading; no nested BotControl types were intercepted by Il2CppInteropFix.");
			}
			else
			{
				FixLogger.Info(botControlDiagnostics.BuildSummary());
			}
		}

		internal static bool ShouldPassThroughToStock(Type type)
		{
			if (type == null || type.DeclaringType == null)
			{
				return true;
			}
			Assembly assembly = type.Assembly;
			string text = assembly.GetName().Name ?? string.Empty;
			if (text.StartsWith("Il2CppInterop.", StringComparison.Ordinal))
			{
				return true;
			}
			string location = assembly.Location;
			if (!string.IsNullOrEmpty(location))
			{
				string text2 = location.Replace('/', '\\');
				if (text2.Contains("\\interop\\", StringComparison.OrdinalIgnoreCase) || text2.Contains("\\patchers\\", StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
			}
			if (!string.Equals(text, "BotControl", StringComparison.Ordinal))
			{
				return true;
			}
			return !IsInjectedType(type);
		}

		internal static bool TryInstallLookupPatch(Harmony harmony)
		{
			lock (InstallLock)
			{
				if (_lookupPatchInstalled)
				{
					return true;
				}
				if (!TryPatchAddTypeToLookup(harmony))
				{
					FixLogger.Error("Failed to patch InjectorHelpers.AddTypeToLookup.");
					return false;
				}
				if (!TryPatchRegisterTypeInIl2Cpp(harmony))
				{
					FixLogger.Warning("AddTypeToLookup patched, but RegisterTypeInIl2Cpp postfix was not installed.");
				}
				_lookupPatchInstalled = true;
				FixLogger.Info("Patches installed: AddTypeToLookup=yes, RegisterTypeInIl2Cpp=" + (_registerPatchInstalled ? "yes" : "no") + ". Set env IL2CPP_INTEROP_FIX_VERBOSE=1 for per-type trace.");
				return true;
			}
		}

		private static bool TryPatchRegisterTypeInIl2Cpp(Harmony harmony)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			if (_registerPatchInstalled)
			{
				return true;
			}
			Type type = FindLoadedType("Il2CppInterop.Runtime.Injection.ClassInjector");
			Type type2 = FindLoadedType("Il2CppInterop.Runtime.Injection.RegisterTypeOptions");
			if (type == null || type2 == null)
			{
				FixLogger.Warning("RegisterTypeInIl2Cpp patch skipped: ClassInjector types not found.");
				return false;
			}
			MethodInfo methodInfo = AccessTools.Method(type, "RegisterTypeInIl2Cpp", new Type[2]
			{
				typeof(Type),
				type2
			}, (Type[])null);
			if (methodInfo == null)
			{
				FixLogger.Warning("RegisterTypeInIl2Cpp patch skipped: target method not found.");
				return false;
			}
			harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(NestedTypeLookupFix), "RegisterTypeInIl2CppPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			_registerPatchInstalled = true;
			return true;
		}

		internal static void RegisterTypeInIl2CppPostfix(Type type)
		{
			if (!ShouldPassThroughToStock(type))
			{
				NestedTypeDiagnostics botControlDiagnostics = GetBotControlDiagnostics();
				string computedFullName;
				string text = TryLinkNestedDeclaringType(type, out computedFullName);
				if (text == "ok")
				{
					botControlDiagnostics.DeclaringLinkOk++;
				}
				else
				{
					botControlDiagnostics.DeclaringLinkFailed++;
				}
				botControlDiagnostics.RecordComputedFullName(computedFullName, type.FullName ?? type.Name);
				botControlDiagnostics.RecordEvent($"Register {type.FullName}: DeclaringType={text}, il2cppFullName='{computedFullName}'");
				FixLogger.Info($"Nested register {type.Name} on {type.DeclaringType?.Name}: DeclaringType {text}, fullName='{computedFullName}'");
			}
		}

		private unsafe static string TryLinkNestedDeclaringType(Type type, out string computedFullName)
		{
			computedFullName = string.Empty;
			try
			{
				Type declaringType = type.DeclaringType;
				if (declaringType == null)
				{
					return "no-managed-declaring-type";
				}
				IntPtr nativeClassPointer = Il2CppClassPointerStore.GetNativeClassPointer(type);
				IntPtr nativeClassPointer2 = Il2CppClassPointerStore.GetNativeClassPointer(declaringType);
				if (nativeClassPointer == IntPtr.Zero)
				{
					return "native-class-missing";
				}
				if (nativeClassPointer2 == IntPtr.Zero)
				{
					return "parent-not-registered-yet (" + declaringType.FullName + ")";
				}
				INativeClassStruct val = UnityVersionHandler.Wrap((Il2CppClass*)(void*)nativeClassPointer);
				computedFullName = BuildIl2CppFullName((Il2CppClass*)(void*)nativeClassPointer);
				val.DeclaringType = (Il2CppClass*)(void*)nativeClassPointer2;
				if (val.DeclaringType == null)
				{
					return "declaring-type-set-null";
				}
				ref Il2CppClassAttributes flags = ref val.Flags;
				flags = (Il2CppClassAttributes)((uint)flags & 0xFFFFFFF8u);
				ref Il2CppClassAttributes flags2 = ref val.Flags;
				flags2 = (Il2CppClassAttributes)((uint)flags2 | (uint)(type.IsNestedPublic ? 2 : 3));
				computedFullName = BuildIl2CppFullName((Il2CppClass*)(void*)nativeClassPointer);
				return "ok";
			}
			catch (Exception ex)
			{
				FixLogger.Warning($"DeclaringType link failed for {type.FullName}: {ex.GetType().Name}: {ex.Message}");
				return "exception:" + ex.GetType().Name;
			}
		}

		private unsafe static string BuildIl2CppFullName(Il2CppClass* classPointer)
		{
			try
			{
				Stack<string> stack = new Stack<string>();
				INativeClassStruct val = UnityVersionHandler.Wrap(classPointer);
				INativeClassStruct val2 = val;
				do
				{
					stack.Push(Marshal.PtrToStringUTF8(val.Name) ?? string.Empty);
					val2 = val;
				}
				while ((val = UnityVersionHandler.Wrap(val.DeclaringType)) != null);
				string text = ((val2.Namespace != IntPtr.Zero) ? (Marshal.PtrToStringUTF8(val2.Namespace) ?? string.Empty) : string.Empty);
				StringBuilder stringBuilder = new StringBuilder();
				if (text.Length > 0)
				{
					stringBuilder.Append(text).Append('.');
				}
				stringBuilder.Append(string.Join("+", stack));
				return stringBuilder.ToString();
			}
			catch (Exception ex)
			{
				return "<full-name-error:" + ex.GetType().Name + ">";
			}
		}

		private static Type FindLoadedType(string fullName)
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; i < assemblies.Length; i++)
			{
				Type type = assemblies[i].GetType(fullName, throwOnError: false);
				if (type != null)
				{
					return type;
				}
			}
			return AccessTools.TypeByName(fullName);
		}

		private static bool TryPatchAddTypeToLookup(Harmony harmony)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(FindLoadedType("Il2CppInterop.Runtime.Injection.InjectorHelpers"), "AddTypeToLookup", new Type[2]
			{
				typeof(Type),
				typeof(IntPtr)
			}, (Type[])null);
			if (methodInfo == null)
			{
				return false;
			}
			harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(NestedTypeLookupFix), "AddTypeToLookupPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			return true;
		}

		internal static bool AddTypeToLookupPrefix(Type type, IntPtr typePointer)
		{
			if (ShouldPassThroughToStock(type))
			{
				return true;
			}
			AddTypeToLookupImpl(type, typePointer);
			return false;
		}

		internal static void AddTypeToLookupImpl(Type type, IntPtr typePointer)
		{
			if (!TryBuildLookupNames(type, out var namespaze, out var klass))
			{
				FixLogger.Warning("Lookup skipped for " + type?.FullName + ": could not build names.");
				return;
			}
			FieldInfo fieldInfo = AccessTools.Field(FindLoadedType("Il2CppInterop.Runtime.Injection.InjectorHelpers"), "s_ClassNameLookup");
			if (fieldInfo == null)
			{
				FixLogger.Warning("s_ClassNameLookup field not found.");
				return;
			}
			Dictionary<(string, string, IntPtr), IntPtr> dict = (Dictionary<(string, string, IntPtr), IntPtr>)fieldInfo.GetValue(null);
			string name = type.Name;
			NestedTypeDiagnostics botControlDiagnostics = GetBotControlDiagnostics();
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			string text = null;
			lock (InstallLock)
			{
				foreach (IntPtr targetImage in GetTargetImages(type))
				{
					if (TryAddLookupEntry(dict, namespaze, klass, targetImage, typePointer))
					{
						num++;
						botControlDiagnostics.LookupQualifiedAdded++;
					}
					if (string.IsNullOrEmpty(name) || string.Equals(name, klass, StringComparison.Ordinal))
					{
						continue;
					}
					if (TryAddLookupEntry(dict, namespaze, name, targetImage, typePointer))
					{
						num2++;
						botControlDiagnostics.LookupShortAdded++;
						botControlDiagnostics.RecordShortNameOwner(namespaze, name, type.FullName ?? type.Name, targetImage);
						continue;
					}
					num3++;
					botControlDiagnostics.LookupShortSkipped++;
					if (text == null && botControlDiagnostics.TryGetShortNameOwner(namespaze, name, targetImage, out var ownerType))
					{
						text = ownerType;
					}
				}
			}
			if (num3 > 0)
			{
				FixLogger.Warning($"Short lookup '{namespaze}.{name}' owned by '{text ?? "?"}'; skipped for '{type.FullName}' ({num3} images). Qualified key '{klass}' still added.");
			}
			botControlDiagnostics.RecordEvent($"Lookup {type.FullName}: klass='{klass}', images={num}, short +{num2}/skip{num3}, ptr=0x{typePointer.ToInt64():X}");
			FixLogger.Info($"Lookup {type.Name}: qualified on {num} image(s), short +{num2} skip {num3}");
		}

		private static bool TryAddLookupEntry(Dictionary<(string, string, IntPtr), IntPtr> dict, string namespaze, string klass, IntPtr image, IntPtr typePointer)
		{
			(string, string, IntPtr) key = (namespaze, klass, image);
			if (dict.ContainsKey(key))
			{
				return false;
			}
			dict.Add(key, typePointer);
			return true;
		}

		internal static bool TryBuildLookupNames(Type type, out string namespaze, out string klass)
		{
			namespaze = string.Empty;
			klass = string.Empty;
			if (type == null)
			{
				return false;
			}
			Stack<string> stack = new Stack<string>();
			Type type2 = type;
			while (type2 != null)
			{
				stack.Push(type2.Name);
				type2 = type2.DeclaringType;
			}
			klass = ((stack.Count <= 1) ? type.Name : string.Join("+", stack));
			if (string.IsNullOrEmpty(klass))
			{
				return false;
			}
			namespaze = type.Namespace ?? string.Empty;
			return true;
		}

		private static NestedTypeDiagnostics GetBotControlDiagnostics()
		{
			if (_botControlDiagnostics == null)
			{
				_botControlDiagnostics = new NestedTypeDiagnostics();
			}
			return _botControlDiagnostics;
		}

		private static bool IsInjectedType(Type type)
		{
			FieldInfo injectedTypesField = GetInjectedTypesField();
			if (injectedTypesField == null || (object)type == null || type.FullName == null)
			{
				return false;
			}
			object value = injectedTypesField.GetValue(null);
			if (value is ICollection<string> collection)
			{
				return collection.Contains(type.FullName);
			}
			if (value is IEnumerable enumerable)
			{
				foreach (object item in enumerable)
				{
					if (item is string text && text == type.FullName)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static FieldInfo GetInjectedTypesField()
		{
			if (_injectedTypesField != null)
			{
				return _injectedTypesField;
			}
			Type type = FindLoadedType("Il2CppInterop.Runtime.Injection.ClassInjector");
			_injectedTypesField = ((type == null) ? null : AccessTools.Field(type, "InjectedTypes"));
			return _injectedTypesField;
		}

		private static IEnumerable<IntPtr> GetTargetImages(Type type)
		{
			Type type2 = FindLoadedType("Il2CppInterop.Runtime.Attributes.ClassInjectionAssemblyTargetAttribute");
			Attribute attribute = ((type2 == null) ? null : Attribute.GetCustomAttribute(type, type2));
			if (attribute == null)
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(IL2CPP), "GetIl2CppImages", (Type[])null, (Type[])null);
				if (!(methodInfo == null))
				{
					return (IEnumerable<IntPtr>)methodInfo.Invoke(null, null);
				}
				return Array.Empty<IntPtr>();
			}
			return (IEnumerable<IntPtr>)AccessTools.Method(attribute.GetType(), "GetImagePointers", (Type[])null, (Type[])null).Invoke(attribute, null);
		}
	}
}

SlidesBotControl - V1.2.3.dll

Decompiled a day ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using AIGraph;
using AK;
using Agents;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Hook;
using BepInEx.Unity.IL2CPP.Utils;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using BetterBots.Components;
using BetterBots.Managers;
using BotControl;
using BotControl.CustomActions;
using BotControl.CustomActions.CustomActions;
using BotControl.CustomActions.Patches;
using BotControl.Menus;
using BotControl.Networking;
using BotControl.Patches;
using BotControl.SmartSelect;
using BotControl.SmartSelect.PressActions;
using BotControl.SmartSelect.PressActions.DoubleTapActions;
using BotControl.SmartSelect.PressTypes;
using CellMenu;
using ChainedPuzzles;
using CollisionRundown.Features.HUDs;
using CullingSystem;
using Enemies;
using ExteriorRendering;
using FluffyUnderware.DevTools.Extensions;
using GTFO.API;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppInterop.Runtime.Runtime;
using Il2CppInterop.Runtime.Runtime.VersionSpecific.Assembly;
using Il2CppInterop.Runtime.Runtime.VersionSpecific.Class;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Reflection;
using LevelGeneration;
using Localization;
using Microsoft.CodeAnalysis;
using Player;
using PrioritySet;
using SNetwork;
using SlideDrum;
using SlideDrum.sInputSystem;
using SlideMenu;
using TMPro;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("BotControl")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+gitd5013ac-dirty-dev.d5013acaeca679836731ad818ee8d06830e6585a")]
[assembly: AssemblyProduct("BotControl")]
[assembly: AssemblyTitle("BotControl")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[CompilerGenerated]
internal delegate void <>f__AnonymousDelegate0<T1, T2, T3>(T1 arg1, T2 arg2 = default(T2), T3 arg3 = default(T3));
[CompilerGenerated]
internal delegate void <>f__AnonymousDelegate1<T1>(T1 arg = default(T1));
[CompilerGenerated]
internal delegate void <>f__AnonymousDelegate2<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3 = 0.1f);
[CompilerGenerated]
internal delegate void <>f__AnonymousDelegate3<T1>(T1 arg = true);
[CompilerGenerated]
internal delegate void <>f__AnonymousDelegate4<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3 = false);
[CompilerGenerated]
internal delegate TResult <>f__AnonymousDelegate5<T1, T2, TResult>(T1 arg1, T2 arg2 = 0uL);
[CompilerGenerated]
internal delegate void <>f__AnonymousDelegate6<T1, T2, T3>(T1 arg1, T2 arg2 = false, T3 arg3 = default(T3));
[CompilerGenerated]
internal delegate void <>f__AnonymousDelegate7<T1, T2, T3, T4>(T1 arg1, T2 arg2, T3 arg3 = default(T3), T4 arg4 = default(T4));
[CompilerGenerated]
internal delegate void <>f__AnonymousDelegate8<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3 = 10);
[CompilerGenerated]
internal delegate void <>f__AnonymousDelegate9<T1, T2, T3, T4>(T1 arg1 = default(T1), T2 arg2 = default(T2), T3 arg3 = 0uL, T4 arg4 = default(T4));
[CompilerGenerated]
internal delegate void <>f__AnonymousDelegate10<T1, T2, T3>(T1 arg1, T2 arg2, T3 arg3 = "");
[CompilerGenerated]
internal delegate void <>f__AnonymousDelegate11<T1, T2>(T1 arg1, T2 arg2 = default(T2));
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;
		}
	}
}
public static class CustomActionRegistry
{
	private static readonly (Type ActionType, Func<PlayerAIBot, CustomActionBase.Descriptor> CreateDescriptor)[] Actions;

	static CustomActionRegistry()
	{
		Actions = (from t in typeof(CustomActionBase).Assembly.GetTypes()
			where t.IsClass && !t.IsAbstract && typeof(CustomActionBase).IsAssignableFrom(t)
			select (Action: t, Descriptor: t.GetNestedType("Descriptor", BindingFlags.Public | BindingFlags.NonPublic)) into pair
			where pair.Descriptor != null && typeof(CustomActionBase.Descriptor).IsAssignableFrom(pair.Descriptor) && !pair.Descriptor.IsAbstract
			select (Action: pair.Action, CreateDescriptorFactory(pair.Descriptor))).ToArray();
	}

	private static Func<PlayerAIBot, CustomActionBase.Descriptor> CreateDescriptorFactory(Type descriptorType)
	{
		ConstructorInfo? constructor = descriptorType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(PlayerAIBot) }, null);
		if (constructor == null)
		{
			throw new InvalidOperationException("No (PlayerAIBot) constructor on " + descriptorType.FullName);
		}
		ParameterExpression parameterExpression = Expression.Parameter(typeof(PlayerAIBot), "bot");
		return Expression.Lambda<Func<PlayerAIBot, CustomActionBase.Descriptor>>(Expression.New(constructor, parameterExpression), new ParameterExpression[1] { parameterExpression }).Compile();
	}

	public static void RegisterIl2CppTypes()
	{
		ClassInjector.RegisterTypeInIl2Cpp(typeof(CustomActionBase));
		ClassInjector.RegisterTypeInIl2Cpp(typeof(CustomActionBase.Descriptor));
		(Type, Func<PlayerAIBot, CustomActionBase.Descriptor>)[] actions = Actions;
		for (int i = 0; i < actions.Length; i++)
		{
			Type item = actions[i].Item1;
			ClassInjector.RegisterTypeInIl2Cpp(item);
			ClassInjector.RegisterTypeInIl2Cpp(item.GetNestedType("Descriptor", BindingFlags.Public | BindingFlags.NonPublic));
		}
	}

	public static void Setup(PlayerAIBot bot)
	{
		if ((Object)(object)bot == (Object)null)
		{
			throw new ArgumentNullException("bot");
		}
		dataStore orCreateData = zActions.GetOrCreateData(bot);
		(Type, Func<PlayerAIBot, CustomActionBase.Descriptor>)[] actions = Actions;
		for (int i = 0; i < actions.Length; i++)
		{
			CustomActionBase.Descriptor descriptor = actions[i].Item2(bot);
			if ((Object)(object)((Descriptor)descriptor).Bot == (Object)null)
			{
				((Descriptor)descriptor).Bot = bot;
			}
			CustomActionBase customActionBase = (CustomActionBase)(object)((Descriptor)descriptor).CreateAction();
			orCreateData.customActionDescriptors.Add(descriptor, (int?)null, (ConflictResolution?)null, (DuplicateValuePolicy?)null, (PlacementIndexBias?)null);
			orCreateData.customActionBases.Add(customActionBase, (int?)null, (ConflictResolution?)null, (DuplicateValuePolicy?)null, (PlacementIndexBias?)null);
		}
	}
}
[HarmonyPatch]
public static class UnlockActionPatch
{
	private static float s_hackSuccessChance = 0.25f;

	private static int s_hackMaxNrFaults = 3;

	private const uint LockMelterBackpackItemId = 116u;

	private const uint HackingToolBackpackItemId = 53u;

	private static bool useNewMethod = true;

	[HarmonyPatch(typeof(PlayerBotActionUnlock), "ChooseMethod")]
	[HarmonyPrefix]
	public static bool PreChooseMethod(PlayerBotActionUnlock __instance, ref bool __result)
	{
		if (!useNewMethod)
		{
			return true;
		}
		__result = ChooseMethod(__instance);
		return false;
	}

	private static EventDelegateFunc CreateEventDelegate(PlayerBotActionUnlock action)
	{
		return DelegateSupport.ConvertDelegate<EventDelegateFunc>((Delegate)new Action<Descriptor>(action.OnMethodActionEvent));
	}

	private static bool ChooseMethod(PlayerBotActionUnlock action)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Expected I4, but got Unknown
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		if ((int)action.m_method != 0)
		{
			return CommitChosenMethod(action);
		}
		if (action.m_desc == null)
		{
			throw new NullReferenceException();
		}
		int num = (int)action.m_desc.Method;
		if (UsesFlagResolution(num))
		{
			if (TryResolveFlagMethod(action, num, out var resolved))
			{
				action.m_method = resolved;
				if (!TryAssignMethodDescriptor(action, resolved))
				{
					return false;
				}
				return CommitChosenMethod(action);
			}
			action.m_method = (MethodEnum)0;
			return false;
		}
		action.m_method = (MethodEnum)num;
		if (num == 0)
		{
			MarkDescriptorFailed(action);
			return false;
		}
		if (!TryAssignMethodDescriptor(action, action.m_method))
		{
			return false;
		}
		return CommitChosenMethod(action);
	}

	private static bool CommitChosenMethod(PlayerBotActionUnlock action)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		if (action.m_desc == null)
		{
			throw new NullReferenceException();
		}
		action.m_desc.UsedMethod = action.m_method;
		return true;
	}

	private static void MarkDescriptorFailed(PlayerBotActionUnlock action)
	{
		if (action.m_desc == null)
		{
			throw new NullReferenceException();
		}
		((Descriptor)action.m_desc).SetCompletionStatus((StatusType)4);
	}

	private static bool UsesFlagResolution(int descriptorMethod)
	{
		if (descriptorMethod == 7)
		{
			return true;
		}
		return (descriptorMethod & (descriptorMethod - 1)) != 0;
	}

	private static bool TryResolveFlagMethod(PlayerBotActionUnlock action, int methodFlags, out MethodEnum resolved)
	{
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Invalid comparison between Unknown and I4
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Invalid comparison between Unknown and I4
		resolved = (MethodEnum)0;
		action.m_method = (MethodEnum)methodFlags;
		LG_WeakLock val = action.m_desc.Lock;
		PlayerAIBot bot = ((PlayerBotActionBase)action).m_bot;
		if ((Object)(object)bot == (Object)null)
		{
			throw new NullReferenceException();
		}
		if (!bot.WantsCrouch() && (methodFlags & 1) != 0)
		{
			if (bot.Backpack == null)
			{
				throw new NullReferenceException();
			}
			BackpackItem val2 = default(BackpackItem);
			if (bot.Backpack.TryGetBackpackItem((InventorySlot)10, ref val2))
			{
				if ((Object)(object)val == (Object)null)
				{
					throw new NullReferenceException();
				}
				if ((int)val.Status == 0)
				{
					resolved = (MethodEnum)1;
					return true;
				}
			}
		}
		if ((methodFlags & 2) != 0)
		{
			if (bot.Backpack == null)
			{
				throw new NullReferenceException();
			}
			BackpackItem val3 = default(BackpackItem);
			if (bot.Backpack.TryGetBackpackItem((InventorySlot)11, ref val3))
			{
				if (val3 == null)
				{
					throw new NullReferenceException();
				}
				if (val3.ItemID == 53)
				{
					if ((Object)(object)val == (Object)null)
					{
						throw new NullReferenceException();
					}
					if ((int)val.Status == 1)
					{
						resolved = (MethodEnum)2;
						return true;
					}
				}
			}
		}
		if ((methodFlags & 4) != 0)
		{
			if (bot.Backpack == null)
			{
				throw new NullReferenceException();
			}
			BackpackItem val4 = default(BackpackItem);
			if (bot.Backpack.TryGetBackpackItem((InventorySlot)5, ref val4))
			{
				if (val4 == null)
				{
					throw new NullReferenceException();
				}
				if (val4.ItemID == 116)
				{
					if ((Object)(object)val == (Object)null)
					{
						throw new NullReferenceException();
					}
					eWeakLockStatus status = val.Status;
					if ((int)status == 0 || (int)status == 1)
					{
						resolved = (MethodEnum)4;
						return true;
					}
				}
			}
		}
		return false;
	}

	private static bool TryAssignMethodDescriptor(PlayerBotActionUnlock action, MethodEnum method)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Expected I4, but got Unknown
		switch (method - 1)
		{
		case 0:
		{
			if (!TryCreateMeleeDescriptor(action, out var descriptor))
			{
				return false;
			}
			action.m_chosenMethod = descriptor;
			return true;
		}
		case 1:
			action.m_chosenMethod = (Descriptor)(object)CreateHackDescriptor(action);
			return true;
		case 3:
			action.m_chosenMethod = (Descriptor)(object)CreateMeltDescriptor(action);
			return true;
		default:
			MarkDescriptorFailed(action);
			return false;
		}
	}

	private static bool TryCreateMeleeDescriptor(PlayerBotActionUnlock action, out Descriptor descriptor)
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Expected O, but got Unknown
		descriptor = null;
		if (((PlayerBotActionBase)action).m_backpack == null)
		{
			throw new NullReferenceException();
		}
		BackpackItem val = default(BackpackItem);
		if (!((PlayerBotActionBase)action).m_backpack.TryGetBackpackItem((InventorySlot)10, ref val))
		{
			return false;
		}
		if (val == null)
		{
			throw new NullReferenceException();
		}
		MeleeWeaponThirdPerson weapon = ((Il2CppObjectBase)val.Instance).TryCast<MeleeWeaponThirdPerson>();
		Descriptor val2 = new Descriptor(((PlayerBotActionBase)action).m_bot);
		((Descriptor)val2).ParentActionBase = (PlayerBotActionBase)(object)action;
		((Descriptor)val2).Prio = ((Descriptor)action.m_desc).Prio;
		((Descriptor)val2).EventDelegate = CreateEventDelegate(action);
		val2.Haste = 0.75f;
		val2.Force = 1f;
		val2.Strike = true;
		val2.Loop = true;
		val2.Travel = true;
		if (action.m_desc == null)
		{
			throw new NullReferenceException();
		}
		LG_WeakLock obj = action.m_desc.Lock;
		if ((Object)(object)obj == (Object)null)
		{
			throw new NullReferenceException();
		}
		LG_WeakLockDamage componentInChildren = ((Component)obj).GetComponentInChildren<LG_WeakLockDamage>();
		if ((Object)(object)componentInChildren == (Object)null)
		{
			throw new NullReferenceException();
		}
		val2.TargetGameObject = ((Component)componentInChildren).gameObject;
		val2.Weapon = weapon;
		descriptor = (Descriptor)(object)val2;
		return true;
	}

	private static Descriptor CreateHackDescriptor(PlayerBotActionUnlock action)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Expected O, but got Unknown
		Descriptor val = new Descriptor(((PlayerBotActionBase)action).m_bot)
		{
			ParentActionBase = (PlayerBotActionBase)(object)action,
			Prio = ((Descriptor)action.m_desc).Prio,
			EventDelegate = CreateEventDelegate(action)
		};
		if (action.m_desc == null)
		{
			throw new NullReferenceException();
		}
		val.Lock = action.m_desc.Lock;
		val.MaxNrFaults = s_hackMaxNrFaults;
		val.SuccessChance = s_hackSuccessChance;
		return val;
	}

	private static Descriptor CreateMeltDescriptor(PlayerBotActionUnlock action)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Expected O, but got Unknown
		Descriptor val = new Descriptor(((PlayerBotActionBase)action).m_bot)
		{
			ParentActionBase = (PlayerBotActionBase)(object)action,
			Prio = ((Descriptor)action.m_desc).Prio,
			EventDelegate = CreateEventDelegate(action)
		};
		if (action.m_desc == null)
		{
			throw new NullReferenceException();
		}
		val.Lock = action.m_desc.Lock;
		return val;
	}
}
[Flags]
public enum CornerTag
{
	None = 0,
	Top = 1,
	MiddleY = 2,
	Bottom = 4,
	Left = 8,
	MiddleX = 0x10,
	Right = 0x20,
	Front = 0x40,
	MiddleZ = 0x80,
	Back = 0x100,
	Center = 0x92,
	All = 0x1FF
}
public struct BoundingPoint
{
	public Vector3 Position;

	public CornerTag Tags;

	public BoundingPoint(Vector3 pos, CornerTag tags)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		Position = pos;
		Tags = tags;
	}

	public bool Has(CornerTag tag)
	{
		return (Tags & tag) != 0;
	}

	public override string ToString()
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		return $"{Tags}: {Position}";
	}
}
public class BoundingBox
{
	[Flags]
	public enum BoundingSource
	{
		None = 0,
		MeshFilters = 1,
		Renderers = 2,
		Colliders = 4,
		All = 7
	}

	private readonly GameObject _go;

	private readonly List<BoundingPoint> _points = new List<BoundingPoint>();

	private List<GameObject> _debugMarkers = new List<GameObject>();

	public IEnumerable<BoundingPoint> Points => _points;

	public Vector3 Center { get; private set; }

	public Vector3 Size { get; private set; }

	public IEnumerable<Vector3> Front => GetCorners(CornerTag.Front);

	public IEnumerable<Vector3> Back => GetCorners(CornerTag.Back);

	public IEnumerable<Vector3> Top => GetCorners(CornerTag.Top);

	public IEnumerable<Vector3> Bottom => GetCorners(CornerTag.Bottom);

	public IEnumerable<Vector3> Left => GetCorners(CornerTag.Left);

	public IEnumerable<Vector3> Right => GetCorners(CornerTag.Right);

	public BoundingBox(GameObject go, BoundingSource sources = BoundingSource.All)
	{
		_go = go;
		Refresh(sources);
	}

	public void Refresh(BoundingSource sources = BoundingSource.All)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0287: Unknown result type (might be due to invalid IL or missing references)
		//IL_028c: 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_01d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_027e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0301: Unknown result type (might be due to invalid IL or missing references)
		//IL_0305: Unknown result type (might be due to invalid IL or missing references)
		//IL_030a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0314: Unknown result type (might be due to invalid IL or missing references)
		//IL_031f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0331: Unknown result type (might be due to invalid IL or missing references)
		//IL_033c: Unknown result type (might be due to invalid IL or missing references)
		//IL_034e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0359: Unknown result type (might be due to invalid IL or missing references)
		//IL_0438: Unknown result type (might be due to invalid IL or missing references)
		//IL_0461: Unknown result type (might be due to invalid IL or missing references)
		//IL_0467: Unknown result type (might be due to invalid IL or missing references)
		//IL_046c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0471: Unknown result type (might be due to invalid IL or missing references)
		//IL_0473: Unknown result type (might be due to invalid IL or missing references)
		//IL_0474: Unknown result type (might be due to invalid IL or missing references)
		//IL_0476: Unknown result type (might be due to invalid IL or missing references)
		//IL_047c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0481: Unknown result type (might be due to invalid IL or missing references)
		//IL_0486: Unknown result type (might be due to invalid IL or missing references)
		//IL_0490: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_037b: Unknown result type (might be due to invalid IL or missing references)
		//IL_038c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0391: Unknown result type (might be due to invalid IL or missing references)
		//IL_0396: Unknown result type (might be due to invalid IL or missing references)
		//IL_0399: Unknown result type (might be due to invalid IL or missing references)
		//IL_039b: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_04eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_050c: Unknown result type (might be due to invalid IL or missing references)
		//IL_051a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0241: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
		Quaternion rotation = _go.transform.rotation;
		_go.transform.rotation = Quaternion.identity;
		Transform parent = _go.transform.parent;
		_go.transform.parent = null;
		_points.Clear();
		Transform transform = _go.transform;
		List<Bounds> list = new List<Bounds>();
		if (sources.HasFlag(BoundingSource.MeshFilters))
		{
			foreach (MeshFilter componentsInChild in _go.GetComponentsInChildren<MeshFilter>())
			{
				if (!((Object)(object)componentsInChild.mesh == (Object)null))
				{
					Bounds bounds = componentsInChild.mesh.bounds;
					((Bounds)(ref bounds)).center = transform.InverseTransformPoint(((Component)componentsInChild).transform.TransformPoint(((Bounds)(ref bounds)).center));
					list.Add(bounds);
				}
			}
		}
		if (sources.HasFlag(BoundingSource.Renderers))
		{
			foreach (Renderer componentsInChild2 in _go.GetComponentsInChildren<Renderer>())
			{
				Bounds bounds2 = componentsInChild2.bounds;
				((Bounds)(ref bounds2)).center = transform.InverseTransformPoint(((Bounds)(ref bounds2)).center);
				list.Add(bounds2);
			}
		}
		if (sources.HasFlag(BoundingSource.Colliders))
		{
			foreach (Collider componentsInChild3 in _go.GetComponentsInChildren<Collider>())
			{
				Bounds bounds3 = componentsInChild3.bounds;
				((Bounds)(ref bounds3)).center = transform.InverseTransformPoint(((Bounds)(ref bounds3)).center);
				list.Add(bounds3);
			}
		}
		if (list.Count == 0)
		{
			Vector3 pos = (Center = transform.position);
			for (int i = 0; i < 3; i++)
			{
				for (int j = 0; j < 3; j++)
				{
					for (int k = 0; k < 3; k++)
					{
						CornerTag cornerTag = CornerTag.None;
						cornerTag = (CornerTag)((int)cornerTag | (i switch
						{
							1 => 16, 
							0 => 8, 
							_ => 32, 
						}));
						cornerTag = (CornerTag)((int)cornerTag | (j switch
						{
							1 => 2, 
							0 => 4, 
							_ => 1, 
						}));
						cornerTag = (CornerTag)((int)cornerTag | (k switch
						{
							1 => 128, 
							0 => 256, 
							_ => 64, 
						}));
						_points.Add(new BoundingPoint(pos, cornerTag));
					}
				}
			}
			_go.transform.rotation = rotation;
			return;
		}
		Bounds val = list[0];
		foreach (Bounds item in list.Skip(1))
		{
			Bounds current2 = item;
			((Bounds)(ref val)).Encapsulate(((Bounds)(ref current2)).min);
			((Bounds)(ref val)).Encapsulate(((Bounds)(ref current2)).max);
		}
		Size = ((Bounds)(ref val)).size;
		Center = transform.TransformPoint(((Bounds)(ref val)).center);
		Vector3 center = ((Bounds)(ref val)).center;
		Vector3 extents = ((Bounds)(ref val)).extents;
		float[] array = new float[3]
		{
			0f - extents.x,
			0f,
			extents.x
		};
		float[] array2 = new float[3]
		{
			0f - extents.y,
			0f,
			extents.y
		};
		float[] array3 = new float[3]
		{
			0f - extents.z,
			0f,
			extents.z
		};
		for (int l = 0; l < 3; l++)
		{
			for (int m = 0; m < 3; m++)
			{
				for (int n = 0; n < 3; n++)
				{
					Vector3 val2 = center + new Vector3(array[l], array2[m], array3[n]);
					Vector3 pos2 = transform.TransformPoint(val2);
					CornerTag cornerTag2 = CornerTag.None;
					cornerTag2 = (CornerTag)((int)cornerTag2 | (l switch
					{
						1 => 16, 
						0 => 8, 
						_ => 32, 
					}));
					cornerTag2 = (CornerTag)((int)cornerTag2 | (m switch
					{
						1 => 2, 
						0 => 4, 
						_ => 1, 
					}));
					cornerTag2 = (CornerTag)((int)cornerTag2 | (n switch
					{
						1 => 128, 
						0 => 256, 
						_ => 64, 
					}));
					_points.Add(new BoundingPoint(pos2, cornerTag2));
				}
			}
		}
		_go.transform.rotation = rotation;
		_go.transform.parent = parent;
		for (int num = 0; num < _points.Count; num++)
		{
			Vector3 val3 = _points[num].Position - transform.position;
			Vector3 pos3 = rotation * val3 + transform.position;
			_points[num] = new BoundingPoint(pos3, _points[num].Tags);
		}
		Vector3 val4 = Vector3.zero;
		foreach (BoundingPoint point in _points)
		{
			val4 += point.Position;
		}
		Center = val4 / (float)_points.Count;
	}

	public bool IsInside(Vector3 worldPoint)
	{
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		BoundingPoint[] array = _points.Where((BoundingPoint p) => !p.Has(CornerTag.MiddleX) && !p.Has(CornerTag.MiddleY) && !p.Has(CornerTag.MiddleZ)).ToArray();
		if (array.Length == 0)
		{
			return false;
		}
		Vector3 val = array[0].Position;
		Vector3 val2 = array[0].Position;
		for (int num = 1; num < array.Length; num++)
		{
			val = Vector3.Min(val, array[num].Position);
			val2 = Vector3.Max(val2, array[num].Position);
		}
		if (worldPoint.x >= val.x && worldPoint.x <= val2.x && worldPoint.y >= val.y && worldPoint.y <= val2.y)
		{
			if (worldPoint.z >= val.z)
			{
				return worldPoint.z <= val2.z;
			}
			return false;
		}
		return false;
	}

	public IEnumerable<Vector3> GetCorners(CornerTag include = CornerTag.All, CornerTag exclude = CornerTag.None)
	{
		foreach (BoundingPoint point in _points)
		{
			if (point.Has(include) && (exclude == CornerTag.None || !point.Has(exclude)))
			{
				yield return point.Position;
			}
		}
	}

	public IEnumerable<Vector3> CornersOnly()
	{
		foreach (BoundingPoint point in _points)
		{
			if (!point.Has(CornerTag.MiddleX) && !point.Has(CornerTag.MiddleY) && !point.Has(CornerTag.MiddleZ))
			{
				yield return point.Position;
			}
		}
	}

	public void ToggleDebug()
	{
		if (_debugMarkers.Count == 0)
		{
			ShowDebug();
		}
		else
		{
			ClearDebug();
		}
	}

	public void ShowDebug(Transform parent = null, float size = 0.2f)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Expected O, but got Unknown
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Expected O, but got Unknown
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		ClearDebug();
		foreach (Vector3 corner in GetCorners())
		{
			GameObject val = new GameObject("BB_DebugPoint");
			if ((Object)(object)parent != (Object)null)
			{
				val.transform.parent = parent;
			}
			val.transform.position = corner;
			TextMesh obj = val.AddComponent<TextMesh>();
			obj.text = "-";
			obj.characterSize = size;
			obj.anchor = (TextAnchor)4;
			obj.alignment = (TextAlignment)1;
			obj.color = Color.red;
			zDebug.DrawLine(corner, Center, Color.white, 0.01f).transform.SetParent(val.transform, true);
			_debugMarkers.Add(val);
		}
		BoundingPoint? boundingPoint = _points.FirstOrDefault((BoundingPoint p) => p.Has(CornerTag.Top) && p.Has(CornerTag.MiddleX) && p.Has(CornerTag.MiddleZ));
		if (boundingPoint.HasValue)
		{
			GameObject val2 = new GameObject("BB_DebugLabel");
			if ((Object)(object)parent != (Object)null)
			{
				val2.transform.parent = parent;
			}
			val2.transform.position = boundingPoint.Value.Position + Vector3.up * 0.1f;
			val2.transform.localScale = new Vector3(0.25f, 0.25f, 0.25f);
			_debugMarkers.Add(val2);
		}
	}

	public void ClearDebug()
	{
		foreach (GameObject debugMarker in _debugMarkers)
		{
			if ((Object)(object)debugMarker != (Object)null)
			{
				Object.Destroy((Object)(object)debugMarker);
			}
		}
		_debugMarkers.Clear();
	}
}
namespace CollisionRundown.Features.HUDs
{
	internal static class InGameTitle
	{
		public static PUI_InteractionPrompt Prompt;

		private static readonly Regex s_StripRichTextRegex = new Regex("\\<.+?\\>");

		private static int s_SmallTitleLength;

		private static int s_TitleLength;

		public static void DisplayDefault()
		{
			((TMP_Text)Prompt.m_headerText).maxVisibleCharacters = 0;
			((RectTransformComp)Prompt).SetVisible(true);
			CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(DoDefaultDisplay()), (Action)null);
		}

		public static void SetTitle(string smallTitle, string title)
		{
			string text = s_StripRichTextRegex.Replace(smallTitle, "");
			SetLength(titleLength: s_StripRichTextRegex.Replace(title, "").Length, smallTitleLength: text.Length);
			SetText(smallTitle + "\n<b><size=200%>" + title);
		}

		public static void SetLength(int smallTitleLength, int titleLength)
		{
			s_SmallTitleLength = smallTitleLength;
			s_TitleLength = titleLength;
		}

		private static IEnumerator DoDefaultDisplay()
		{
			((TMP_Text)Prompt.m_headerText).alpha = 1f;
			((TMP_Text)Prompt.m_headerText).maxVisibleCharacters = 0;
			Prompt.PlayIntro();
			CM_PageBase.PostSound(EVENTS.HUD_SCAN_COMPLETE_INDICATION, "Display IGT");
			yield return (object)new WaitForSeconds(0.33f);
			int visibleCount = 0;
			while (visibleCount <= s_SmallTitleLength)
			{
				visibleCount++;
				((TMP_Text)Prompt.m_headerText).maxVisibleCharacters = visibleCount;
				CM_PageBase.PostSound(EVENTS.HUD_EXIT_SCAN_INFO_TEXT_DISAPPEAR, "Type IGT");
				yield return (object)new WaitForSeconds(0.065f);
			}
			yield return (object)new WaitForSeconds(1f);
			while (visibleCount <= s_TitleLength + s_SmallTitleLength + 1)
			{
				visibleCount++;
				((TMP_Text)Prompt.m_headerText).maxVisibleCharacters = visibleCount;
				CM_PageBase.PostSound(EVENTS.HUD_EXIT_SCAN_INFO_TEXT_DISAPPEAR, "Type IGT");
				yield return (object)new WaitForSeconds(0.065f);
			}
			yield return (object)new WaitForSeconds(6.5f);
			CM_PageBase.PostSound(EVENTS.HUD_EXIT_SCAN_INFO_TEXT_APPEAR, "Hide IGT");
			Prompt.PlayIntro();
			yield return (object)new WaitForSeconds(0.33f);
			((RectTransformComp)Prompt).SetVisible(false);
		}

		private static void SetText(string rawText)
		{
			((TMP_Text)Prompt.m_headerText).SetText(rawText, true);
		}
	}
	[HarmonyPatch(typeof(InteractionGuiLayer), "Setup")]
	internal static class Patch_InteractionLayer_Setup
	{
		private static void Postfix(InteractionGuiLayer __instance)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			PUI_InteractionPrompt obj = ((Il2CppObjectBase)((GuiLayer)__instance).AddRectComp("Gui/Player/PUI_InteractionPrompt_CellUI", (GuiAnchor)3, new Vector2(0f, 258f), (Transform)null)).Cast<PUI_InteractionPrompt>();
			((Graphic)obj.m_headerText).color = Color.white;
			((TMP_Text)obj.m_headerText).fontSize = 24.5f;
			((TMP_Text)obj.m_headerText).fontSizeMin = 24.5f;
			((TMP_Text)obj.m_headerText).fontSizeMax = 24.5f;
			((TMP_Text)obj.m_headerText).rectTransform.sizeDelta = new Vector2(120f, -10f);
			obj.m_whiteBox.transform.localPosition = new Vector3(0f, -22.8f, 0f);
			obj.m_whiteBox.transform.localScale = new Vector3(1f, 1.35f, 1f);
			obj.m_whiteBoxWide.transform.localPosition = new Vector3(0f, -22.8f, 0f);
			obj.m_whiteBoxWide.transform.localScale = new Vector3(1f, 1.5f, 1f);
			obj.SetTimerFill(0f);
			((RectTransformComp)obj).SetVisible(false);
			InGameTitle.Prompt = obj;
			InGameTitle.SetTitle("Small debug title here", "Beeeeg debug title here");
		}
	}
}
namespace SlideMenu
{
	public class FlexibleMethodDefinition
	{
		public Delegate method;

		public object[] args;

		public FlexibleMethodDefinition(Delegate method)
		{
			this.method = method;
			args = Array.Empty<object>();
		}

		public FlexibleMethodDefinition(Delegate method, object[] args)
		{
			this.method = method;
			this.args = args;
		}

		public static implicit operator FlexibleMethodDefinition(Delegate d)
		{
			return new FlexibleMethodDefinition(d);
		}

		public object? Invoke()
		{
			return Invoke(args);
		}

		public object? Invoke(params object[] suppliedArgs)
		{
			if ((object)method == null)
			{
				throw new InvalidOperationException("No method assigned to FlexibleMethodDefinition.");
			}
			object[] array = ((suppliedArgs != null && suppliedArgs.Length != 0) ? suppliedArgs : args);
			try
			{
				return method.DynamicInvoke(array);
			}
			catch (TargetParameterCountException innerException)
			{
				throw new InvalidOperationException($"Parameter count mismatch. Expected {method.Method.GetParameters().Length}, got {((array != null) ? array.Length : 0)}.", innerException);
			}
			catch (Exception inner)
			{
				throw new TargetInvocationException("Error invoking method '" + method.Method.Name + "'.", inner);
			}
		}
	}
	public class FlexibleEvent
	{
		private readonly OrderedSet<Action> listeners = new OrderedSet<Action>();

		public FlexibleEvent Listen(Action method)
		{
			if (method == null)
			{
				return this;
			}
			listeners.Add(method);
			return this;
		}

		public FlexibleEvent Listen(FlexibleMethodDefinition method)
		{
			return Listen(method.method, method.args, method);
		}

		public FlexibleEvent Listen(Delegate method, object[] args, FlexibleMethodDefinition? fMethod = null)
		{
			if ((object)method == null)
			{
				return this;
			}
			ParameterInfo[] parameters = method.Method.GetParameters();
			object[] finalArgs = new object[parameters.Length];
			for (int i = 0; i < parameters.Length; i++)
			{
				if (i < args.Length && args[i] != new object())
				{
					finalArgs[i] = args[i];
					continue;
				}
				if (parameters[i].IsOptional)
				{
					finalArgs[i] = parameters[i].DefaultValue;
					continue;
				}
				throw new ArgumentException("Missing required argument '" + parameters[i].Name + "'");
			}
			listeners.Add(Wrapper);
			return this;
			void Wrapper()
			{
				method.DynamicInvoke(finalArgs);
				if (fMethod?.args != null)
				{
					for (int j = 0; j < finalArgs.Length && j < fMethod.args.Length; j++)
					{
						fMethod.args[j] = finalArgs[j];
					}
				}
			}
		}

		public void Unlisten(Action method)
		{
			listeners.Remove(method);
		}

		public void Unlisten(FlexibleMethodDefinition method)
		{
			listeners.Remove((Action)method.method);
		}

		public void ClearListeners()
		{
			listeners.Clear();
		}

		public void Invoke()
		{
			foreach (Action listener in listeners)
			{
				listener();
			}
		}
	}
	public class sMenu
	{
		public class sMenuNode
		{
			private class SelectionColorHandler
			{
				private sMenuNode node;

				private bool selected;

				private bool pressed;

				private static Color selectedOffset = new Color(0.1f, 0.1f, 0.1f);

				private static Color pressedOffset = new Color(0.3f, 0.2f, 0.5f);

				public SelectionColorHandler(sMenuNode Node)
				{
					node = Node;
				}

				internal void onClosed()
				{
					selected = false;
					pressed = false;
					UpdateOffset();
				}

				internal void onSelected()
				{
					selected = true;
					UpdateOffset();
				}

				internal void OnDeselected()
				{
					selected = false;
					UpdateOffset();
				}

				internal void OnPressed()
				{
					pressed = true;
					UpdateOffset();
				}

				internal void OnUnpressed()
				{
					pressed = false;
					UpdateOffset();
				}

				private void UpdateOffset()
				{
					//IL_0015: Unknown result type (might be due to invalid IL or missing references)
					//IL_002e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0033: Unknown result type (might be due to invalid IL or missing references)
					//IL_0038: Unknown result type (might be due to invalid IL or missing references)
					//IL_0051: Unknown result type (might be due to invalid IL or missing references)
					//IL_0056: Unknown result type (might be due to invalid IL or missing references)
					//IL_005b: Unknown result type (might be due to invalid IL or missing references)
					node.ColorOffset = new Color(0f, 0f, 0f);
					if (selected)
					{
						sMenuNode sMenuNode = node;
						sMenuNode.ColorOffset += selectedOffset;
					}
					if (pressed)
					{
						sMenuNode sMenuNode2 = node;
						sMenuNode2.ColorOffset += pressedOffset;
					}
				}
			}

			private string _title = "";

			private string _subtitle = "";

			private string _description = "";

			private string _text = "";

			private string _prefix = "";

			private string _suffix = "";

			public bool selected;

			public bool pressed;

			public bool held;

			public int frameFirstPressedAt = Time.frameCount;

			public float timeFirstPressedAt = Time.time;

			public int frameLastPressedAt = Time.frameCount;

			public float timeLastPressedAt = Time.time;

			public float lastTapTime = Time.time;

			public sMenu parrentMenu;

			private Dictionary<sMenuManager.nodeEvent, FlexibleEvent> _eventMap;

			public TextPart fullTextPart;

			public TextPart titlePart;

			public TextPart subtitlePart;

			public TextPart descriptionPart;

			public GameObject gameObject;

			private GameObject TextPartGameObject;

			private RectTransform rect;

			internal GameObject backgroundObject;

			internal RawImage backgroundImage;

			private SelectionColorHandler selectionColorHandler;

			private bool hasHoverText;

			private Color _color;

			private Color _colorOffset;

			private float holdThreshold = 0.2f;

			private float doubleTapThreshold = 0.3f;

			public string title
			{
				get
				{
					return _title.Trim();
				}
				set
				{
					_title = value;
					UpdateTitle();
				}
			}

			public string subtitle
			{
				get
				{
					return _subtitle.Trim();
				}
				set
				{
					_subtitle = value;
					UpdateSubtitle();
				}
			}

			public string description
			{
				get
				{
					return _description.Trim();
				}
				set
				{
					_description = value;
					UpdateDescription();
				}
			}

			public string text
			{
				get
				{
					return _text.Trim();
				}
				set
				{
					_text = value;
					UpdateText();
				}
			}

			public string prefix
			{
				get
				{
					return _prefix.Trim();
				}
				set
				{
					_prefix = value;
					UpdateText();
				}
			}

			public string suffix
			{
				get
				{
					return _suffix.Trim();
				}
				set
				{
					_suffix = value;
					UpdateText();
				}
			}

			public string fullText
			{
				get
				{
					return string.Join(" ", prefix, text, suffix).Trim();
				}
				[Obsolete("\nDon't assign to fullText. Use vars \"prefix\", \"text\" and \"suffix\" instead.\nYou probably want var \"text\".", true)]
				set
				{
				}
			}

			public bool closeOnPress { get; private set; }

			private Dictionary<sMenuManager.nodeEvent, FlexibleEvent> eventMap
			{
				get
				{
					if (_eventMap == null)
					{
						_eventMap = new Dictionary<sMenuManager.nodeEvent, FlexibleEvent>();
						sMenuManager.nodeEvent[] values = Enum.GetValues<sMenuManager.nodeEvent>();
						foreach (sMenuManager.nodeEvent key in values)
						{
							_eventMap[key] = new FlexibleEvent();
						}
					}
					return _eventMap;
				}
			}

			public Color color
			{
				get
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					return _color;
				}
				set
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					//IL_0008: Unknown result type (might be due to invalid IL or missing references)
					//IL_000d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0017: Unknown result type (might be due to invalid IL or missing references)
					Color val = _color;
					_color = value;
					if (val != value)
					{
						SetColor(_color);
					}
				}
			}

			public Color ColorOffset
			{
				get
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					return _colorOffset;
				}
				set
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					//IL_0008: Unknown result type (might be due to invalid IL or missing references)
					//IL_000d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0017: Unknown result type (might be due to invalid IL or missing references)
					Color colorOffset = _colorOffset;
					_colorOffset = value;
					if (colorOffset != value)
					{
						SetColor(_color);
					}
				}
			}

			public sMenuNode(string arg_Name, sMenu arg_parrentMenu, FlexibleMethodDefinition arg_Callback)
			{
				//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Expected O, but got Unknown
				//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d7: Expected O, but got Unknown
				//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e7: Expected O, but got Unknown
				//IL_0139: Unknown result type (might be due to invalid IL or missing references)
				//IL_0192: Unknown result type (might be due to invalid IL or missing references)
				//IL_0198: 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_01b4: 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_0267: Unknown result type (might be due to invalid IL or missing references)
				//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_0300: Unknown result type (might be due to invalid IL or missing references)
				//IL_0344: Unknown result type (might be due to invalid IL or missing references)
				gameObject = new GameObject("sMenuNode " + arg_Name);
				gameObject.transform.SetParent(((Component)arg_parrentMenu.getCanvas()).transform, false);
				backgroundObject = new GameObject("Background");
				TextPartGameObject = new GameObject("TextParts");
				TextPartGameObject.transform.SetParent(gameObject.transform, false);
				backgroundObject.transform.SetParent(gameObject.transform, false);
				backgroundObject.transform.localPosition = new Vector3(0f, 0f, 30f);
				backgroundImage = backgroundObject.AddComponent<RawImage>();
				backgroundImage.texture = (Texture)(object)sMenuManager.DefaultBackgroundImage;
				rect = gameObject.AddComponent<RectTransform>();
				RectTransform obj = rect;
				RectTransform obj2 = rect;
				Vector2 val = default(Vector2);
				((Vector2)(ref val))..ctor(0.5f, 0.5f);
				obj2.anchorMax = val;
				obj.anchorMin = val;
				rect.anchoredPosition = Vector2.zero;
				((Transform)rect).localScale = Vector3.one;
				parrentMenu = arg_parrentMenu;
				if (arg_Callback != null)
				{
					eventMap[sMenuManager.nodeEvent.OnUnpressedSelected].Listen(arg_Callback);
				}
				color = parrentMenu.getTextColor();
				VerticalLayoutGroup obj3 = TextPartGameObject.AddComponent<VerticalLayoutGroup>();
				((LayoutGroup)obj3).childAlignment = (TextAnchor)4;
				((HorizontalOrVerticalLayoutGroup)obj3).spacing = 2f;
				((HorizontalOrVerticalLayoutGroup)obj3).childControlWidth = true;
				((HorizontalOrVerticalLayoutGroup)obj3).childControlHeight = false;
				((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandWidth = true;
				((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandHeight = false;
				ContentSizeFitter obj4 = TextPartGameObject.AddComponent<ContentSizeFitter>();
				obj4.verticalFit = (FitMode)2;
				obj4.horizontalFit = (FitMode)2;
				((Object)(titlePart = new TextPart(TextPartGameObject, title ?? "", new Color(0.2f, 0.2f, 0.2f, 1f), TextPart.TextPartType.Title).SetScale(0.75f, 0.75f)).gameObject).name = "Title";
				((Object)(fullTextPart = new TextPart(TextPartGameObject, text ?? "", parrentMenu.textColor, TextPart.TextPartType.Main)).gameObject).name = "Text";
				((Object)(subtitlePart = new TextPart(TextPartGameObject, title ?? "", new Color(0.1f, 0.1f, 0.1f, 1f), TextPart.TextPartType.Subtitle).SetScale(0.75f, 0.75f)).gameObject).name = "Subtitle";
				((Object)(descriptionPart = new TextPart(TextPartGameObject, description, parrentMenu.textColor, TextPart.TextPartType.Description)).gameObject).name = "Description";
				text = arg_Name;
				selectionColorHandler = new SelectionColorHandler(this);
				AddListener(sMenuManager.nodeEvent.OnSelected, selectionColorHandler.onSelected);
				AddListener(sMenuManager.nodeEvent.OnDeselected, selectionColorHandler.OnDeselected);
				AddListener(sMenuManager.nodeEvent.OnPressed, selectionColorHandler.OnPressed);
				AddListener(sMenuManager.nodeEvent.OnUnpressed, selectionColorHandler.OnUnpressed);
				parrentMenu.AddListener(sMenuManager.menuEvent.OnClosed, selectionColorHandler.onClosed);
			}

			public sMenuNode Update()
			{
				if (selected)
				{
					eventMap[sMenuManager.nodeEvent.WhileSelected].Invoke();
					parrentMenu.selectedNode = this;
				}
				else
				{
					eventMap[sMenuManager.nodeEvent.WhileDeselected].Invoke();
				}
				if (!pressed)
				{
					eventMap[sMenuManager.nodeEvent.WhileUnpressed].Invoke();
				}
				return this;
			}

			public Vector3 GetRelativePosition()
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val = Vector3.Scale(new Vector3(rect.anchoredPosition.x, rect.anchoredPosition.y, 0f), ((Component)parrentMenu.getCanvas()).transform.localScale);
				Vector3 val2 = parrentMenu.gameObject.transform.TransformPoint(val);
				return ((Component)sMenuManager.mainCamera).transform.position - val2;
			}

			public sMenuNode SetPosition(float x, float y)
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				SetPosition(new Vector2(x, y));
				return this;
			}

			public sMenuNode SetPosition(Vector2 pos)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				rect.anchoredPosition = pos;
				return this;
			}

			public sMenuNode SetSize(float scale)
			{
				//IL_0004: Unknown result type (might be due to invalid IL or missing references)
				return this.SetSize(new Vector3(scale, scale, scale));
			}

			public sMenuNode SetSize(float x, float y)
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				this.SetSize(new Vector2(x, y));
				return this;
			}

			public sMenuNode SetSize(Vector2 scale)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				this.SetSize(new Vector3(scale.x, scale.y, ((Transform)rect).localScale.z));
				return this;
			}

			public sMenuNode SetSize(float x, float y, float z)
			{
				//IL_0004: Unknown result type (might be due to invalid IL or missing references)
				this.SetSize(new Vector3(x, y, z));
				return this;
			}

			public sMenuNode SetSize(Vector3 scale)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				((Transform)rect).localScale = scale;
				return this;
			}

			public sMenuNode SetCloseMenuOnPress(bool close)
			{
				closeOnPress = close;
				return this;
			}

			public sMenuNode FaceCamera()
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				Quaternion rotation = Quaternion.LookRotation(gameObject.transform.position - ((Component)sMenuManager.mainCamera).transform.position);
				setRotation(rotation);
				return this;
			}

			public sMenuNode setRotation(Quaternion rot)
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				gameObject.transform.rotation = rot;
				return this;
			}

			public sMenuNode Select()
			{
				if (selected)
				{
					return this;
				}
				selected = true;
				SetSize(sMenuManager.selectedNodeSizeMultiplier);
				eventMap[sMenuManager.nodeEvent.OnSelected].Invoke();
				parrentMenu.OnSelected.Invoke();
				return this;
			}

			public sMenuNode Deselect()
			{
				if (!selected)
				{
					return this;
				}
				selected = false;
				SetSize(1f);
				eventMap[sMenuManager.nodeEvent.OnDeselected].Invoke();
				parrentMenu.OnDeselected.Invoke();
				return this;
			}

			public sMenuNode Pressing()
			{
				frameLastPressedAt = Time.frameCount;
				timeLastPressedAt = Time.time;
				eventMap[sMenuManager.nodeEvent.WhilePressed].Invoke();
				if (Time.time - timeFirstPressedAt > holdThreshold)
				{
					if (held)
					{
						if (selected)
						{
							eventMap[sMenuManager.nodeEvent.WhileHeldSelected].Invoke();
						}
						else
						{
							eventMap[sMenuManager.nodeEvent.WhileHeld].Invoke();
						}
					}
					else
					{
						held = true;
						if (selected)
						{
							eventMap[sMenuManager.nodeEvent.OnHeldImmediateSelected].Invoke();
						}
						eventMap[sMenuManager.nodeEvent.OnHeldImmediate].Invoke();
					}
				}
				return this;
			}

			public sMenuNode Press()
			{
				frameFirstPressedAt = Time.frameCount;
				timeFirstPressedAt = Time.time;
				pressed = true;
				eventMap[sMenuManager.nodeEvent.OnPressed].Invoke();
				if (closeOnPress)
				{
					sMenuManager.CloseAllMenus();
					return this;
				}
				return this;
			}

			public sMenuNode Unpress()
			{
				if (pressed)
				{
					eventMap[sMenuManager.nodeEvent.OnUnpressed].Invoke();
					if (held)
					{
						eventMap[sMenuManager.nodeEvent.OnHeld].Invoke();
					}
					if (selected)
					{
						eventMap[sMenuManager.nodeEvent.OnUnpressedSelected].Invoke();
					}
					if (held && selected)
					{
						eventMap[sMenuManager.nodeEvent.OnHeldSelected].Invoke();
					}
					if (Time.time - timeFirstPressedAt < holdThreshold)
					{
						eventMap[sMenuManager.nodeEvent.OnTapped].Invoke();
						if (Time.time - lastTapTime <= doubleTapThreshold)
						{
							eventMap[sMenuManager.nodeEvent.OnDoubleTapped].Invoke();
						}
						else
						{
							zUpdater.InvokeStatic(new FlexibleMethodDefinition(new Action(InvokeTappedExclusive)), doubleTapThreshold - Time.deltaTime / 2f);
						}
						lastTapTime = Time.time;
					}
				}
				held = false;
				pressed = false;
				return this;
			}

			private void InvokeTappedExclusive()
			{
				if (Time.time - lastTapTime >= doubleTapThreshold - Time.deltaTime && !pressed)
				{
					eventMap[sMenuManager.nodeEvent.OnTappedExclusive].Invoke();
				}
			}

			public sMenuNode AddListener(sMenuManager.nodeEvent arg_event, Action arg_method)
			{
				return AddListener(arg_event, (FlexibleMethodDefinition)arg_method);
			}

			public sMenuNode AddListener(sMenuManager.nodeEvent arg_event, Delegate method, params object[] args)
			{
				FlexibleMethodDefinition arg_method = new FlexibleMethodDefinition(method, args);
				return AddListener(arg_event, arg_method);
			}

			public sMenuNode AddListener(sMenuManager.nodeEvent arg_event, FlexibleMethodDefinition arg_method)
			{
				if (eventMap.TryGetValue(arg_event, out var value))
				{
					value.Listen(arg_method);
				}
				return this;
			}

			public sMenuNode RemoveListener(sMenuManager.nodeEvent arg_event, Action arg_method)
			{
				if (eventMap.TryGetValue(arg_event, out var value))
				{
					value.Unlisten(arg_method);
				}
				return this;
			}

			public sMenuNode RemoveListener(sMenuManager.nodeEvent arg_event)
			{
				if (eventMap.TryGetValue(arg_event, out var value))
				{
					value.ClearListeners();
				}
				return this;
			}

			public sMenuNode RemoveListener(sMenuManager.nodeEvent arg_event, FlexibleMethodDefinition arg_method)
			{
				if (eventMap.TryGetValue(arg_event, out var value))
				{
					value.Unlisten(arg_method);
				}
				return this;
			}

			public sMenuNode ClearListeners(sMenuManager.nodeEvent arg_event)
			{
				if (eventMap.TryGetValue(arg_event, out var value))
				{
					value.ClearListeners();
				}
				return this;
			}

			public sMenuNode SetTitle(string arg_Title)
			{
				title = arg_Title ?? string.Empty;
				return this;
			}

			public sMenuNode SetSubtitle(string arg_Subtitle)
			{
				subtitle = arg_Subtitle ?? string.Empty;
				return this;
			}

			public sMenuNode SetDescription(string arg_Description)
			{
				description = arg_Description ?? string.Empty;
				return this;
			}

			public sMenuNode SetText(string arg_Text)
			{
				text = arg_Text ?? string.Empty;
				return this;
			}

			public sMenuNode SetPrefix(string arg_Prefix)
			{
				prefix = arg_Prefix ?? string.Empty;
				return this;
			}

			public sMenuNode SetSuffix(string arg_Suffix)
			{
				suffix = arg_Suffix ?? string.Empty;
				return this;
			}

			public sMenuNode SetColor(Color arg_Color)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_0064: Unknown result type (might be due to invalid IL or missing references)
				//IL_006f: Unknown result type (might be due to invalid IL or missing references)
				color = arg_Color;
				foreach (TextPart textPart in GetTextParts())
				{
					Color val = arg_Color;
					val.r += ColorOffset.r;
					val.g += ColorOffset.g;
					val.b += ColorOffset.b;
					val.a = arg_Color.a;
					textPart.SetColor(val);
				}
				return this;
			}

			public sMenuNode AddHoverText(sMenuPannel.Side side, string[] textList)
			{
				foreach (string text in textList)
				{
					AddHoverText(side, text);
				}
				return this;
			}

			public sMenuNode AddHoverText(sMenuPannel.Side side, string text)
			{
				sMenuPannel pannel = parrentMenu.AddPannel(side);
				string key = ((Object)gameObject).GetInstanceID().ToString();
				pannel.addLine(text, key);
				pannel.SetLineVisible(visible: false, text, key);
				if (!hasHoverText)
				{
					AddListener(sMenuManager.nodeEvent.OnSelected, delegate
					{
						pannel.SetKeyVisible(visible: true, key);
					});
					AddListener(sMenuManager.nodeEvent.OnDeselected, delegate
					{
						pannel.SetKeyVisible(visible: false, key);
					});
					hasHoverText = true;
				}
				return this;
			}

			public List<TextPart> GetTextParts(TextPart.TextPartType types = TextPart.TextPartType.All)
			{
				return (from f in GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
					where f.FieldType == typeof(TextPart)
					select f.GetValue(this) as TextPart into tp
					where tp != null && (types & tp.type) != 0
					select tp).ToList();
			}

			private void UpdateTitle()
			{
				if (titlePart != null)
				{
					titlePart.SetText(title);
				}
			}

			private void UpdateSubtitle()
			{
				if (subtitlePart != null)
				{
					subtitlePart.SetText(subtitle);
				}
			}

			private void UpdateDescription()
			{
				if (descriptionPart != null)
				{
					descriptionPart.SetText(description);
				}
			}

			private void UpdateText()
			{
				if (fullTextPart != null)
				{
					fullTextPart.SetText(fullText);
				}
			}
		}

		public class sMenuPannel
		{
			public enum Side
			{
				left,
				right,
				top,
				bottom
			}

			public Side side;

			public sMenu parrentMenu;

			public GameObject gameObject;

			public RectTransform rect;

			public Color color;

			public Dictionary<string, List<TextPart>> lines = new Dictionary<string, List<TextPart>>();

			public sMenuPannel(Side side, sMenu parrentMenu)
			{
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: Expected O, but got Unknown
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
				this.side = side;
				gameObject = new GameObject($"zMenuPannel {side}");
				gameObject.transform.SetParent(((Component)parrentMenu.getCanvas()).transform, false);
				this.parrentMenu = parrentMenu;
				color = parrentMenu.getTextColor();
				rect = gameObject.GetComponent<RectTransform>();
				if ((Object)(object)rect == (Object)null)
				{
					rect = gameObject.AddComponent<RectTransform>();
				}
				((Transform)rect).localScale = Vector3.one;
				rect.sizeDelta = new Vector2(300f, 0f);
				VerticalLayoutGroup obj = gameObject.AddComponent<VerticalLayoutGroup>();
				((LayoutGroup)obj).childAlignment = (TextAnchor)3;
				((HorizontalOrVerticalLayoutGroup)obj).spacing = 2f;
				((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = side == Side.top || side == Side.bottom;
				((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = false;
				((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = true;
				((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
				ContentSizeFitter obj2 = gameObject.AddComponent<ContentSizeFitter>();
				obj2.verticalFit = (FitMode)2;
				obj2.horizontalFit = (FitMode)2;
				UpdatePosition();
			}

			public sMenuPannel UpdatePosition(float margin = 0f)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_0114: Unknown result type (might be due to invalid IL or missing references)
				//IL_012e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0148: Unknown result type (might be due to invalid IL or missing references)
				//IL_0179: Unknown result type (might be due to invalid IL or missing references)
				//IL_0193: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
				Rect nodeBounds = parrentMenu.GetNodeBounds();
				Vector2 zero = Vector2.zero;
				switch (side)
				{
				case Side.right:
					rect.anchorMax = new Vector2(0f, 0.5f);
					rect.anchorMin = new Vector2(0f, 0.5f);
					rect.pivot = new Vector2(0f, 0.5f);
					((Vector2)(ref zero))..ctor(((Rect)(ref nodeBounds)).xMax + margin, 0f);
					break;
				case Side.left:
					rect.anchorMax = new Vector2(1f, 0.5f);
					rect.anchorMin = new Vector2(1f, 0.5f);
					rect.pivot = new Vector2(1f, 0.5f);
					((Vector2)(ref zero))..ctor(((Rect)(ref nodeBounds)).xMin - margin, 0f);
					break;
				case Side.top:
					rect.anchorMax = new Vector2(0.5f, 0f);
					rect.anchorMin = new Vector2(0.5f, 0f);
					rect.pivot = new Vector2(0.5f, 0f);
					((Vector2)(ref zero))..ctor(0f, ((Rect)(ref nodeBounds)).yMax + margin);
					break;
				case Side.bottom:
					rect.anchorMax = new Vector2(0.5f, 1f);
					rect.anchorMin = new Vector2(0.5f, 1f);
					rect.pivot = new Vector2(0.5f, 1f);
					((Vector2)(ref zero))..ctor(0f, ((Rect)(ref nodeBounds)).yMin - margin);
					break;
				}
				gameObject.transform.localPosition = Vector2.op_Implicit(zero);
				FaceCamera();
				return this;
			}

			public TextPart addLine(string lineText, string key = "Default")
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				TextPart textPart = new TextPart(gameObject, lineText, parrentMenu.textColor, TextPart.TextPartType.Pannel);
				textPart.gameObject.transform.SetParent(gameObject.transform, false);
				if (!lines.ContainsKey(key))
				{
					lines[key] = new List<TextPart>();
				}
				lines[key].Add(textPart);
				return textPart;
			}

			public sMenuPannel FaceCamera()
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				Quaternion rotation = Quaternion.LookRotation(gameObject.transform.position - ((Component)sMenuManager.mainCamera).transform.position);
				setRotation(rotation);
				return this;
			}

			public sMenuPannel setRotation(Quaternion rot)
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				gameObject.transform.rotation = rot;
				return this;
			}

			public TextPart GetLine(string lineText, string key)
			{
				TextPart result = null;
				foreach (TextPart item in lines[key])
				{
					if (item.text.Contains(lineText))
					{
						result = item;
						break;
					}
				}
				return result;
			}

			public sMenuPannel SetLineVisible(bool visible, string line, string key = "")
			{
				TextPart textPart = null;
				if (key == "")
				{
					foreach (string key2 in lines.Keys)
					{
						textPart = GetLine(line, key2);
						if (textPart != null)
						{
							break;
						}
					}
				}
				else if (lines.ContainsKey(key))
				{
					textPart = GetLine(line, key);
				}
				textPart.gameObject.SetActive(visible);
				return this;
			}

			public sMenuPannel SetKeyVisible(bool visible, string key)
			{
				if (!lines.ContainsKey(key))
				{
					return this;
				}
				foreach (TextPart item in lines[key])
				{
					item.gameObject.SetActive(visible);
				}
				return this;
			}

			public bool IsLineVisible(string line, string key = "")
			{
				TextPart line2 = GetLine(line, key);
				if (line2 != null)
				{
					return line2.gameObject.activeInHierarchy;
				}
				return false;
			}

			public bool IsKeyVisible(string key)
			{
				if (!lines.ContainsKey(key))
				{
					return false;
				}
				int num = 0;
				foreach (TextPart item in lines[key])
				{
					num = ((!item.gameObject.activeInHierarchy) ? (num - 1) : (num + 1));
				}
				return num > 0;
			}

			public sMenuPannel ToggleLineVisiblity(string line, string key = "")
			{
				if (!lines.ContainsKey(key))
				{
					return this;
				}
				bool flag = IsLineVisible(line, key);
				SetLineVisible(!flag, line, key);
				return this;
			}

			public sMenuPannel ToggleKeyVisiblity(string key)
			{
				if (!lines.ContainsKey(key))
				{
					return this;
				}
				bool flag = IsKeyVisible(key);
				SetKeyVisible(!flag, key);
				return this;
			}
		}

		public class TextPart
		{
			[Flags]
			public enum TextPartType
			{
				none = 0,
				Main = 1,
				Title = 2,
				Subtitle = 4,
				Description = 8,
				Pannel = 0x10,
				Default = 0x20,
				All = 0x3F
			}

			public TextPartType type;

			private string _text;

			private Color _textColor;

			private Color _colorOffset;

			private TextMeshPro textMesh;

			public string text
			{
				get
				{
					return _text;
				}
				set
				{
					_text = value;
					((TMP_Text)textMesh).text = value;
				}
			}

			public Color textColor
			{
				get
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					return _textColor;
				}
				set
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					//IL_0008: Unknown result type (might be due to invalid IL or missing references)
					//IL_000d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0017: Unknown result type (might be due to invalid IL or missing references)
					Color val = _textColor;
					_textColor = value;
					if (val != value)
					{
						I_SetColor(_textColor);
					}
				}
			}

			public Color ColorOffset
			{
				get
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					return _colorOffset;
				}
				set
				{
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					//IL_0008: Unknown result type (might be due to invalid IL or missing references)
					//IL_000d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0017: Unknown result type (might be due to invalid IL or missing references)
					Color colorOffset = _colorOffset;
					_colorOffset = value;
					if (colorOffset != value)
					{
						I_SetColor(_textColor);
					}
				}
			}

			public GameObject gameObject { get; private set; }

			public RectTransform rect { get; private set; }

			public TextPart(GameObject parent, string arg_Text, Color color, TextPartType type)
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Expected O, but got Unknown
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
				//IL_013b: Unknown result type (might be due to invalid IL or missing references)
				this.type = type;
				gameObject = new GameObject();
				gameObject.transform.position = Vector3.zero;
				gameObject.transform.rotation = Quaternion.identity;
				gameObject.transform.localScale = Vector3.one;
				gameObject.layer = 0;
				gameObject.tag = "Untagged";
				gameObject.SetActive(true);
				gameObject.transform.SetParent(parent.transform, false);
				((Object)gameObject).name = "TextPart " + arg_Text;
				rect = gameObject.AddComponent<RectTransform>();
				rect.anchoredPosition = Vector2.zero;
				((Transform)rect).localScale = Vector3.one;
				rect.sizeDelta = new Vector2(300f, 0f);
				textMesh = gameObject.AddComponent<TextMeshPro>();
				((TMP_Text)textMesh).enableAutoSizing = false;
				((TMP_Text)textMesh).fontSize = sMenuManager.defaultFontSize;
				((TMP_Text)textMesh).alignment = (TextAlignmentOptions)514;
				((Graphic)textMesh).color = color;
				text = arg_Text;
				ContentSizeFitter obj = gameObject.AddComponent<ContentSizeFitter>();
				obj.verticalFit = (FitMode)2;
				obj.horizontalFit = (FitMode)2;
			}

			public TextPart SetText(string newText)
			{
				text = newText;
				return this;
			}

			public TextPart SetPosition(Vector2 pos)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				SetPosition(pos.x, pos.y);
				return this;
			}

			public TextPart SetPosition(float x, float y)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				rect.anchoredPosition = new Vector2(x, y);
				return this;
			}

			public TextPart SetScale(float scale)
			{
				SetScale(scale, scale, 1f);
				return this;
			}

			public TextPart SetScale(Vector2 scale)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				SetScale(scale.x, scale.y, 1f);
				return this;
			}

			public TextPart SetScale(Vector3 scale)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				SetScale(scale.x, scale.y, scale.z);
				return this;
			}

			public TextPart SetScale(float x, float y)
			{
				SetScale(x, y, 1f);
				return this;
			}

			public TextPart SetScale(float x, float y, float z)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				((Transform)rect).localScale = new Vector3(x, y, z);
				return this;
			}

			private TextPart I_SetColor(Color color)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				((Graphic)textMesh).color = textColor + ColorOffset;
				return this;
			}

			public TextPart SetColor(Color color)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				textColor = color;
				((Graphic)textMesh).color = textColor + ColorOffset;
				return this;
			}

			public Color GetColor()
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return textColor;
			}
		}

		private string name;

		private sMenu _parrentMenu;

		internal int frameOpenedAt = Time.frameCount;

		internal float timeOpenedAt = Time.time;

		public GameObject gameObject;

		private Canvas canvas;

		public Vector3 RelativePosition = Vector3.zero;

		private Dictionary<sMenuManager.menuEvent, FlexibleEvent> eventMap;

		public Dictionary<string, List<sMenuNode>> catagories = new Dictionary<string, List<sMenuNode>>();

		private int catagoryIndex;

		private FlexibleEvent OnOpened = new FlexibleEvent();

		private FlexibleEvent WhileOpened = new FlexibleEvent();

		private FlexibleEvent OnClosed = new FlexibleEvent();

		private FlexibleEvent WhileClosed = new FlexibleEvent();

		private FlexibleEvent OnSelected = new FlexibleEvent();

		private FlexibleEvent WhileSelected = new FlexibleEvent();

		private FlexibleEvent OnDeselected = new FlexibleEvent();

		private FlexibleEvent WhileDeselected = new FlexibleEvent();

		private FlexibleEvent OnCatagoryChanged = new FlexibleEvent();

		private int pannelPositionWorkaround;

		private Vector3 canvasScale = new Vector3(0.003f, 0.003f, 0.003f);

		public float radius;

		public float rotationalOffset;

		private Color textColor = sMenuManager.defaultColor;

		private sMenuNode selectedNode;

		private RectTransform rect;

		private Dictionary<sMenuPannel.Side, sMenuPannel> pannels = new Dictionary<sMenuPannel.Side, sMenuPannel>();

		public IEnumerable<sMenuNode> allNodes
		{
			get
			{
				if (centerNode == null)
				{
					return nodes;
				}
				return new sMenuNode[1] { centerNode }.Concat(nodes.Where((sMenuNode n) => n != centerNode));
			}
		}

		public OrderedSet<sMenuNode> nodes { get; private set; } = new OrderedSet<sMenuNode>();

		public OrderedSet<sMenuNode> disabledNodes { get; private set; } = new OrderedSet<sMenuNode>();

		public sMenuNode centerNode { get; private set; }

		public sMenu parrentMenu
		{
			get
			{
				return _parrentMenu;
			}
			private set
			{
				_parrentMenu = value;
				if (value != null)
				{
					centerNode.ClearListeners(sMenuManager.nodeEvent.OnUnpressedSelected);
					centerNode.AddListener(sMenuManager.nodeEvent.OnUnpressedSelected, _parrentMenu.Open);
				}
			}
		}

		public List<sMenuNode> currentCatagory => catagories[currentCatagoryName];

		public string currentCatagoryName => catagories.Keys.ToArray().ElementAt(catagoryIndex);

		public sMenu(string arg_Name, sMenu arg_ParrentMenu = null)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Expected O, but got Unknown
			eventMap = new Dictionary<sMenuManager.menuEvent, FlexibleEvent>
			{
				{
					sMenuManager.menuEvent.OnOpened,
					OnOpened
				},
				{
					sMenuManager.menuEvent.WhileOpened,
					WhileOpened
				},
				{
					sMenuManager.menuEvent.OnClosed,
					OnClosed
				},
				{
					sMenuManager.menuEvent.WhileClosed,
					WhileClosed
				},
				{
					sMenuManager.menuEvent.OnSelected,
					OnSelected
				},
				{
					sMenuManager.menuEvent.WhileSelected,
					WhileSelected
				},
				{
					sMenuManager.menuEvent.OnDeselected,
					OnDeselected
				},
				{
					sMenuManager.menuEvent.WhileDeselected,
					WhileDeselected
				},
				{
					sMenuManager.menuEvent.OnCatagoryChanged,
					OnCatagoryChanged
				}
			};
			radius = sMenuManager.defaultRadius;
			name = arg_Name;
			gameObject = new GameObject("sMenu " + name);
			gameObject.transform.SetParent(sMenuManager.menuParrent.transform);
			setupCanvas();
			centerNode = new sMenuNode(arg_Callback: (arg_ParrentMenu == null) ? new FlexibleMethodDefinition(new Func<sMenu>(Close)) : new FlexibleMethodDefinition(new Action(arg_ParrentMenu.Open)), arg_Name: name, arg_parrentMenu: this).SetTitle((arg_ParrentMenu != null) ? arg_ParrentMenu.name : "Close");
			parrentMenu = arg_ParrentMenu;
			Close();
		}

		internal void UpdateCatagoryByScroll()
		{
			if (catagories.Count() == 0)
			{
				return;
			}
			float axis = Input.GetAxis("Mouse ScrollWheel");
			int num = (int)Mathf.Sign(axis);
			if (axis != 0f)
			{
				catagoryIndex += num;
				if (catagoryIndex >= catagories.Count())
				{
					catagoryIndex = 0;
				}
				if (catagoryIndex < 0)
				{
					catagoryIndex = catagories.Count() - 1;
				}
				SetCatagory(catagories.Keys.ElementAt(catagoryIndex));
			}
		}

		public void UpdateCatagoryNodes()
		{
			if (catagoryIndex >= catagories.Count())
			{
				return;
			}
			string text = catagories.Keys.ElementAt(catagoryIndex);
			centerNode.SetSubtitle("<color=#00CC8466>[ </color>" + text + "<color=#00CC8466> ]</color>");
			if (text.ToLower() == "all")
			{
				foreach (sMenuNode node in nodes)
				{
					EnableNode(node);
				}
				return;
			}
			foreach (sMenuNode node2 in nodes)
			{
				if (catagories[text].Contains(node2))
				{
					EnableNode(node2);
				}
				else
				{
					DisableNode(node2);
				}
			}
		}

		public void SetCatagory(string catagory)
		{
			if (!catagories.ContainsKey(catagory))
			{
				return;
			}
			centerNode.SetSubtitle("<color=#00CC8466>[ </color>" + catagory + "<color=#00CC8466> ]</color>");
			if (catagory.ToLower() == "all")
			{
				foreach (sMenuNode node in nodes)
				{
					EnableNode(node);
				}
				return;
			}
			foreach (sMenuNode node2 in nodes)
			{
				if (catagories[catagory].Contains(node2))
				{
					EnableNode(node2);
				}
				else
				{
					DisableNode(node2);
				}
			}
			catagoryIndex = catagories.Keys.ToList().IndexOf(catagory);
			UpdatePannelPositions();
			OnCatagoryChanged.Invoke();
		}

		public void AddCatagory(string catagory)
		{
			if (!catagories.ContainsKey(catagory))
			{
				catagories[catagory] = new List<sMenuNode>();
			}
		}

		public void AddNodeToCatagory(string catagory, sMenuNode node)
		{
			if (node != null)
			{
				if (!catagories.ContainsKey(catagory))
				{
					AddCatagory(catagory);
				}
				catagories[catagory].Add(node);
			}
		}

		public void AddNodeToCatagory(string catagory, string nodeName)
		{
			sMenuNode node = GetNode(nodeName);
			if (node != null)
			{
				AddNodeToCatagory(catagory, node);
			}
		}

		public void UpdatePosition()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)sMenuManager.mainCamera).transform.position - RelativePosition;
			setPosition(position);
		}

		public void Update()
		{
			if (gameObject.activeInHierarchy)
			{
				WhileOpened.Invoke();
			}
			else
			{
				WhileClosed.Invoke();
			}
			selectedNode = null;
			foreach (sMenuNode item in allNodes.Where((sMenuNode n) => n.gameObject.activeInHierarchy).ToList())
			{
				item.Update();
			}
			if (selectedNode != null)
			{
				WhileSelected.Invoke();
			}
			else
			{
				WhileDeselected.Invoke();
			}
			if (pannelPositionWorkaround < 2)
			{
				_UpdatePannelPositions();
			}
		}

		public void Lateupdate()
		{
			UpdatePosition();
			FaceCamera();
		}

		public void PreRender()
		{
			UpdatePosition();
			FaceCamera();
		}

		public sMenu Close()
		{
			setVisiblity(visible: false);
			if (sMenuManager.currentMenu == this)
			{
				sMenuManager.currentMenu = null;
			}
			OnClosed.Invoke();
			return this;
		}

		public void Open()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			timeOpenedAt = Time.time;
			frameOpenedAt = Time.frameCount;
			if (parrentMenu == null)
			{
				if (RelativePosition == Vector3.zero)
				{
					MoveInfrontOfCamera();
				}
			}
			else
			{
				sMenuNode node = parrentMenu.GetNode(name);
				SetRelativePosition(((Component)sMenuManager.mainCamera).transform.position - node.gameObject.transform.position);
			}
			FaceCamera();
			setVisiblity(visible: true);
			ArrangeNodes();
			sMenuManager.previousMenu = sMenuManager.currentMenu;
			sMenuManager.currentMenu = this;
			if (sMenuManager.previousMenu != null && sMenuManager.previousMenu != this)
			{
				sMenuManager.previousMenu.Close();
			}
			OnOpened.Invoke();
		}

		public sMenuPannel AddPannel(sMenuPannel.Side side, string initialText = "")
		{
			if (pannels.ContainsKey(side))
			{
				if (initialText != "")
				{
					pannels[side].addLine(initialText);
				}
				return pannels[side];
			}
			sMenuPannel sMenuPannel = new sMenuPannel(side, this);
			if (initialText != "")
			{
				sMenuPannel.addLine(initialText);
			}
			pannels[side] = sMenuPannel;
			return sMenuPannel;
		}

		public sMenu SetRelativePosition(float x, float y, float z)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			return SetRelativePosition(new Vector3(x, y, z));
		}

		public sMenu SetRelativePosition(Vector3 relativePosition)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			RelativePosition = relativePosition;
			return setPosition(((Component)sMenuManager.mainCamera).transform.position - RelativePosition);
		}

		public sMenu ResetRelativePosition(bool setPos = true)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			RelativePosition = Vector3.zero;
			if (setPos && (Object)(object)sMenuManager.mainCamera != (Object)null)
			{
				return setPosition(((Component)sMenuManager.mainCamera).transform.position - RelativePosition);
			}
			return this;
		}

		private void AddDebugVisuals()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)canvas == (Object)null)
			{
				Debug.LogWarning(Object.op_Implicit("zMenu: Tried to add debug visuals, but canvas is null!"));
				return;
			}
			GameObject val = new GameObject("DebugBackground");
			val.transform.SetParent(((Component)canvas).transform, false);
			((Graphic)val.AddComponent<Image>()).color = new Color(0.5f, 0.5f, 0.5f, 0.5f);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			GameObject val2 = new GameObject("DebugText");
			val2.transform.SetParent(((Component)canvas).transform, false);
			TextMeshPro obj = val2.AddComponent<TextMeshPro>();
			((TMP_Text)obj).text = "Hello from " + name;
			((TMP_Text)obj).fontSize = 24f;
			((TMP_Text)obj).alignment = (TextAlignmentOptions)514;
			((Graphic)obj).color = Color.white;
			RectTransform component2 = ((Component)obj).GetComponent<RectTransform>();
			component2.anchorMin = Vector2.zero;
			component2.anchorMax = Vector2.one;
			component2.offsetMin = Vector2.zero;
			component2.offsetMax = Vector2.zero;
		}

		private void setupCanvas()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)canvas))
			{
				GameObject val = new GameObject("Canvas");
				val.transform.SetParent(gameObject.transform, false);
				canvas = val.AddComponent<Canvas>();
				canvas.renderMode = (RenderMode)2;
				canvas.worldCamera = Camera.main;
				val.AddComponent<CanvasScaler>().dynamicPixelsPerUnit = 10f;
				rect = val.GetComponent<RectTransform>();
				((Transform)rect).localPosition = Vector3.zero;
				((Transform)rect).localScale = canvasScale;
				gameObject.transform.position = ((Component)sMenuManager.mainCamera).transform.position + ((Component)sMenuManager.mainCamera).transform.forward * 1f;
				gameObject.transform.rotation = Quaternion.LookRotation(gameObject.transform.position - ((Component)sMenuManager.mainCamera).transform.position);
			}
		}

		internal void Setsize(float scale)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			((Transform)rect).localScale = canvasScale * scale;
		}

		public sMenu ArrangeNodes()
		{
			List<sMenuNode> list = nodes.Where((sMenuNode n) => n.gameObject.activeInHierarchy).ToList();
			float num = 0f;
			if (rotationalOffset == 0f && list.Count() == 4)
			{
				num = 45f;
			}
			if (rotationalOffset == 0f && list.Count() == 2)
			{
				num = 90f;
			}
			float num2 = (rotationalOffset + num) * ((float)Math.PI / 180f);
			int count = list.Count;
			if (count != 0)
			{
				for (int num3 = 0; num3 < count; num3++)
				{
					float num4 = (float)Math.PI * 2f / (float)count * (float)num3 - (float)Math.PI / 2f + num2;
					float x = radius * Mathf.Cos(num4);
					float y = (0f - radius) * Mathf.Sin(num4);
					list[num3].SetPosition(x, y);
				}
			}
			UpdatePannelPositions();
			return this;
		}

		public sMenu UpdatePannelPositions()
		{
			pannelPositionWorkaround = 0;
			return _UpdatePannelPositions();
		}

		private sMenu _UpdatePannelPositions()
		{
			pannelPositionWorkaround++;
			foreach (sMenuPannel value in pannels.Values)
			{
				value.UpdatePosition();
			}
			return this;
		}

		public sMenu MoveInfrontOfCamera()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((Component)sMenuManager.mainCamera).transform.position + ((Component)sMenuManager.mainCamera).transform.forward * 1f;
			return SetRelativePosition(((Component)sMenuManager.mainCamera).transform.position - val);
		}

		public sMenu FaceCamera(bool menuOnly = false)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			Quaternion rotation = Quaternion.LookRotation(gameObject.transform.position - ((Component)sMenuManager.mainCamera).transform.position);
			setRotation(rotation);
			if (!menuOnly)
			{
				foreach (sMenuNode allNode in allNodes)
				{
					allNode.FaceCamera();
				}
			}
			return this;
		}

		public sMenu setPosition(float x, float y, float z)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			return setPosition(new Vector3(x, y, z));
		}

		public sMenu setPosition(Vector3 pos)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			gameObject.transform.position = pos;
			return this;
		}

		public sMenu setLocalPosition(float x, float y, float z)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			return setLocalPosition(new Vector3(x, y, z));
		}

		public sMenu setLocalPosition(Vector3 pos)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			gameObject.transform.localPosition = pos;
			return this;
		}

		public sMenu setRotation(Quaternion rot)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			gameObject.transform.rotation = rot;
			return this;
		}

		public sMenu AddListener(sMenuManager.menuEvent arg_event, Action arg_method)
		{
			return AddListener(arg_event, (FlexibleMethodDefinition)arg_method);
		}

		public sMenu AddListener(sMenuManager.menuEvent arg_event, Delegate method, params object[] args)
		{
			FlexibleMethodDefinition arg_method = new FlexibleMethodDefinition(method, args);
			return AddListener(arg_event, arg_method);
		}

		public sMenu AddListener(sMenuManager.menuEvent arg_event, FlexibleMethodDefinition arg_method)
		{
			if (eventMap.TryGetValue(arg_event, out var value))
			{
				value.Listen(arg_method);
			}
			return this;
		}

		public sMenu RemoveListener(sMenuManager.menuEvent arg_event, Action arg_method)
		{
			if (eventMap.TryGetValue(arg_event, out var value))
			{
				value.Unlisten(arg_method);
			}
			return this;
		}

		public sMenu RemoveListener(sMenuManager.menuEvent arg_event)
		{
			if (eventMap.TryGetValue(arg_event, out var value))
			{
				value.ClearListeners();
			}
			return this;
		}

		public sMenu RemoveListener(sMenuManager.menuEvent arg_event, FlexibleMethodDefinition arg_method)
		{
			if (eventMap.TryGetValue(arg_event, out var value))
			{
				value.Unlisten(arg_method);
			}
			return this;
		}

		public sMenu ClearListeners(sMenuManager.menuEvent arg_event)
		{
			if (eventMap.TryGetValue(arg_event, out var value))
			{
				value.ClearListeners();
			}
			return this;
		}

		public void DisableNode(sMenuNode node)
		{
			if (!disabledNodes.Contains(node))
			{
				disabledNodes.Add(node);
				node.gameObject.SetActive(false);
				ArrangeNodes();
			}
		}

		public void DisableNode(sMenu menu)
		{
			sMenuNode sMenuNode = nodes.FirstOrDefault((sMenuNode n) => n.text == menu.centerNode.text);
			if (sMenuNode != null)
			{
				DisableNode(sMenuNode);
			}
		}

		public void DisableNode(string nodeText)
		{
			sMenuNode sMenuNode = nodes.FirstOrDefault((sMenuNode n) => n.text == nodeText);
			if (sMenuNode != null)
			{
				DisableNode(sMenuNode);
			}
		}

		public void EnableNode(sMenuNode node)
		{