Decompiled source of SentinelaFuracao v1.0.0

plugins/SentrySound/NLayer.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Threading;
using System.Threading.Tasks;
using NLayer.Decoder;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("Mark Heath, Andrew Ward")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Fully Managed MPEG 1 & 2 Decoder for Layers 1, 2, & 3")]
[assembly: AssemblyFileVersion("1.16.0.0")]
[assembly: AssemblyInformationalVersion("1.16.0+c88b0d8abfa15c1e506106931ea8410170dc6326")]
[assembly: AssemblyProduct("NLayer")]
[assembly: AssemblyTitle("NLayer")]
[assembly: AssemblyVersion("1.16.0.0")]
namespace NLayer
{
	public enum MpegVersion
	{
		Unknown = 0,
		Version1 = 10,
		Version2 = 20,
		Version25 = 25
	}
	public enum MpegLayer
	{
		Unknown,
		LayerI,
		LayerII,
		LayerIII
	}
	public enum MpegChannelMode
	{
		Stereo,
		JointStereo,
		DualChannel,
		Mono
	}
	public enum StereoMode
	{
		Both,
		LeftOnly,
		RightOnly,
		DownmixToMono
	}
	public interface IMpegFrame
	{
		int SampleRate { get; }

		int SampleRateIndex { get; }

		int FrameLength { get; }

		int BitRate { get; }

		MpegVersion Version { get; }

		MpegLayer Layer { get; }

		MpegChannelMode ChannelMode { get; }

		int ChannelModeExtension { get; }

		int SampleCount { get; }

		int BitRateIndex { get; }

		bool IsCopyrighted { get; }

		bool HasCrc { get; }

		bool IsCorrupted { get; }

		void Reset();

		int ReadBits(int bitCount);
	}
	public class MpegFile : IDisposable
	{
		private Stream _stream;

		private bool _closeStream;

		private bool _eofFound;

		private MpegStreamReader _reader;

		private MpegFrameDecoder _decoder;

		private object _seekLock = new object();

		private long _position;

		private float[] _readBuf = new float[2304];

		private int _readBufLen;

		private int _readBufOfs;

		public int SampleRate => _reader.SampleRate;

		public int Channels => _reader.Channels;

		public bool CanSeek => _reader.CanSeek;

		public long Length => _reader.SampleCount * _reader.Channels * 4;

		public TimeSpan Duration
		{
			get
			{
				long sampleCount = _reader.SampleCount;
				if (sampleCount == -1)
				{
					return TimeSpan.Zero;
				}
				return TimeSpan.FromSeconds((double)sampleCount / (double)_reader.SampleRate);
			}
		}

		public long Position
		{
			get
			{
				return _position;
			}
			set
			{
				if (!_reader.CanSeek)
				{
					throw new InvalidOperationException("Cannot Seek!");
				}
				if (value < 0)
				{
					throw new ArgumentOutOfRangeException("value");
				}
				long num = value / 4 / _reader.Channels;
				int num2 = 0;
				if (num >= _reader.FirstFrameSampleCount)
				{
					num2 = _reader.FirstFrameSampleCount;
					num -= num2;
				}
				lock (_seekLock)
				{
					long num3 = _reader.SeekTo(num);
					if (num3 == -1)
					{
						throw new ArgumentOutOfRangeException("value");
					}
					_decoder.Reset();
					if (num2 != 0)
					{
						_decoder.DecodeFrame(_reader.NextFrame(), _readBuf, 0);
						num3 += num2;
					}
					_position = num3 * 4 * _reader.Channels;
					_eofFound = false;
					_readBufOfs = (_readBufLen = 0);
				}
			}
		}

		public TimeSpan Time
		{
			get
			{
				return TimeSpan.FromSeconds((double)_position / 4.0 / (double)_reader.Channels / (double)_reader.SampleRate);
			}
			set
			{
				Position = (long)(value.TotalSeconds * (double)_reader.SampleRate * (double)_reader.Channels * 4.0);
			}
		}

		public StereoMode StereoMode
		{
			get
			{
				return _decoder.StereoMode;
			}
			set
			{
				_decoder.StereoMode = value;
			}
		}

		public MpegFile(string fileName)
		{
			Init(File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.Read), closeStream: true);
		}

		public MpegFile(Stream stream)
		{
			Init(stream, closeStream: false);
		}

		private void Init(Stream stream, bool closeStream)
		{
			_stream = stream;
			_closeStream = closeStream;
			_reader = new MpegStreamReader(_stream);
			_decoder = new MpegFrameDecoder();
		}

		public void Dispose()
		{
			if (_closeStream)
			{
				_stream.Dispose();
				_closeStream = false;
			}
		}

		public void SetEQ(float[] eq)
		{
			_decoder.SetEQ(eq);
		}

		public int ReadSamples(byte[] buffer, int index, int count)
		{
			if (index < 0 || index + count > buffer.Length)
			{
				throw new ArgumentOutOfRangeException("index");
			}
			count -= count % 4;
			return ReadSamplesImpl(buffer, index, count, 32);
		}

		public int ReadSamples(float[] buffer, int index, int count)
		{
			if (index < 0 || index + count > buffer.Length)
			{
				throw new ArgumentOutOfRangeException("index");
			}
			return ReadSamplesImpl(buffer, index * 4, count * 4, 32) / 4;
		}

		public int ReadSamplesInt16(byte[] buffer, int index, int count)
		{
			if (index < 0 || index + count > buffer.Length * 2)
			{
				throw new ArgumentOutOfRangeException("index");
			}
			return ReadSamplesImpl(buffer, index, count, 16) * 2 / 4;
		}

		public int ReadSamplesInt8(byte[] buffer, int index, int count)
		{
			if (index < 0 || index + count > buffer.Length * 4)
			{
				throw new ArgumentOutOfRangeException("index");
			}
			return ReadSamplesImpl(buffer, index, count, 8) / 4;
		}

		private int ReadSamplesImpl(Array buffer, int index, int count, int bitDepth)
		{
			int num = 0;
			lock (_seekLock)
			{
				while (count > 0)
				{
					if (_readBufLen > _readBufOfs)
					{
						int num2 = _readBufLen - _readBufOfs;
						if (num2 > count)
						{
							num2 = count;
						}
						if (bitDepth == 32)
						{
							Buffer.BlockCopy(_readBuf, _readBufOfs, buffer, index, num2);
						}
						else
						{
							for (int i = 0; i < num2 / 4; i++)
							{
								switch (bitDepth)
								{
								case 8:
									buffer.SetValue((byte)Math.Round(127.5f * _readBuf[_readBufOfs / 4 + i] + 127.5f), index / 4 + i);
									break;
								case 16:
								{
									int num3 = (int)Math.Round(32767.5f * _readBuf[_readBufOfs / 4 + i] - 0.5f);
									if (num3 < 0)
									{
										num3 += 65536;
									}
									buffer.SetValue((byte)(num3 % 256), 2 * (index / 4 + i));
									buffer.SetValue((byte)(num3 / 256), 2 * (index / 4 + i) + 1);
									break;
								}
								}
							}
						}
						num += num2;
						count -= num2;
						index += num2;
						_position += num2;
						_readBufOfs += num2;
						if (_readBufOfs == _readBufLen)
						{
							_readBufLen = 0;
						}
					}
					if (_readBufLen != 0)
					{
						continue;
					}
					if (_eofFound)
					{
						break;
					}
					MpegFrame mpegFrame = _reader.NextFrame();
					if (mpegFrame == null)
					{
						_eofFound = true;
						break;
					}
					try
					{
						_readBufLen = _decoder.DecodeFrame(mpegFrame, _readBuf, 0) * 4;
						_readBufOfs = 0;
					}
					catch (InvalidDataException)
					{
						_decoder.Reset();
						_readBufOfs = (_readBufLen = 0);
					}
					catch (EndOfStreamException)
					{
						_eofFound = true;
						break;
					}
					finally
					{
						mpegFrame.ClearBuffer();
					}
				}
			}
			return num;
		}
	}
	public class MpegFrameDecoder
	{
		private LayerIDecoder _layerIDecoder;

		private LayerIIDecoder _layerIIDecoder;

		private LayerIIIDecoder _layerIIIDecoder;

		private float[] _eqFactors;

		private float[] _ch0;

		private float[] _ch1;

		public StereoMode StereoMode { get; set; }

		public MpegFrameDecoder()
		{
			_ch0 = new float[1152];
			_ch1 = new float[1152];
		}

		public void SetEQ(float[] eq)
		{
			if (eq != null)
			{
				float[] array = new float[32];
				for (int i = 0; i < eq.Length; i++)
				{
					array[i] = (float)Math.Pow(2.0, eq[i] / 6f);
				}
				_eqFactors = array;
			}
			else
			{
				_eqFactors = null;
			}
		}

		public int DecodeFrame(IMpegFrame frame, byte[] dest, int destOffset)
		{
			if (frame == null)
			{
				throw new ArgumentNullException("frame");
			}
			if (dest == null)
			{
				throw new ArgumentNullException("dest");
			}
			if (destOffset % 4 != 0)
			{
				throw new ArgumentException("Must be an even multiple of 4", "destOffset");
			}
			if ((dest.Length - destOffset) / 4 < ((frame.ChannelMode == MpegChannelMode.Mono) ? 1 : 2) * frame.SampleCount)
			{
				throw new ArgumentException("Buffer not large enough!  Must be big enough to hold the frame's entire output.  This is up to 9,216 bytes.", "dest");
			}
			return DecodeFrameImpl(frame, dest, destOffset / 4) * 4;
		}

		public int DecodeFrame(IMpegFrame frame, float[] dest, int destOffset)
		{
			if (frame == null)
			{
				throw new ArgumentNullException("frame");
			}
			if (dest == null)
			{
				throw new ArgumentNullException("dest");
			}
			if (dest.Length - destOffset < ((frame.ChannelMode == MpegChannelMode.Mono) ? 1 : 2) * frame.SampleCount)
			{
				throw new ArgumentException("Buffer not large enough!  Must be big enough to hold the frame's entire output.  This is up to 2,304 elements.", "dest");
			}
			return DecodeFrameImpl(frame, dest, destOffset);
		}

		private int DecodeFrameImpl(IMpegFrame frame, Array dest, int destOffset)
		{
			frame.Reset();
			LayerDecoderBase layerDecoderBase = null;
			switch (frame.Layer)
			{
			case MpegLayer.LayerI:
				if (_layerIDecoder == null)
				{
					_layerIDecoder = new LayerIDecoder();
				}
				layerDecoderBase = _layerIDecoder;
				break;
			case MpegLayer.LayerII:
				if (_layerIIDecoder == null)
				{
					_layerIIDecoder = new LayerIIDecoder();
				}
				layerDecoderBase = _layerIIDecoder;
				break;
			case MpegLayer.LayerIII:
				if (_layerIIIDecoder == null)
				{
					_layerIIIDecoder = new LayerIIIDecoder();
				}
				layerDecoderBase = _layerIIIDecoder;
				break;
			}
			if (layerDecoderBase != null)
			{
				layerDecoderBase.SetEQ(_eqFactors);
				layerDecoderBase.StereoMode = StereoMode;
				int num = layerDecoderBase.DecodeFrame(frame, _ch0, _ch1);
				if (frame.ChannelMode == MpegChannelMode.Mono)
				{
					Buffer.BlockCopy(_ch0, 0, dest, destOffset * 4, num * 4);
				}
				else
				{
					for (int i = 0; i < num; i++)
					{
						Buffer.BlockCopy(_ch0, i * 4, dest, destOffset * 4, 4);
						destOffset++;
						Buffer.BlockCopy(_ch1, i * 4, dest, destOffset * 4, 4);
						destOffset++;
					}
					num *= 2;
				}
				return num;
			}
			return 0;
		}

		public void Reset()
		{
			if (_layerIDecoder != null)
			{
				_layerIDecoder.ResetForSeek();
			}
			if (_layerIIDecoder != null)
			{
				_layerIIDecoder.ResetForSeek();
			}
			if (_layerIIIDecoder != null)
			{
				_layerIIIDecoder.ResetForSeek();
			}
		}
	}
}
namespace NLayer.Decoder
{
	internal class BitReservoir
	{
		private byte[] _buf = new byte[8192];

		private int _start;

		private int _end = -1;

		private int _bitsLeft;

		private long _bitsRead;

		public int BitsAvailable
		{
			get
			{
				if (_bitsLeft > 0)
				{
					return (_end + _buf.Length - _start) % _buf.Length * 8 + _bitsLeft;
				}
				return 0;
			}
		}

		public long BitsRead => _bitsRead;

		private static int GetSlots(IMpegFrame frame)
		{
			int num = frame.FrameLength - 4;
			if (frame.HasCrc)
			{
				num -= 2;
			}
			if (frame.Version == MpegVersion.Version1 && frame.ChannelMode != MpegChannelMode.Mono)
			{
				return num - 32;
			}
			if (frame.Version > MpegVersion.Version1 && frame.ChannelMode == MpegChannelMode.Mono)
			{
				return num - 9;
			}
			return num - 17;
		}

		public bool AddBits(IMpegFrame frame, int overlap)
		{
			int end = _end;
			int num = GetSlots(frame);
			while (--num >= 0)
			{
				int num2 = frame.ReadBits(8);
				if (num2 == -1)
				{
					throw new InvalidDataException("Frame did not have enough bytes!");
				}
				_buf[++_end] = (byte)num2;
				if (_end == _buf.Length - 1)
				{
					_end = -1;
				}
			}
			_bitsLeft = 8;
			if (end == -1)
			{
				return overlap == 0;
			}
			if ((end + 1 - _start + _buf.Length) % _buf.Length >= overlap)
			{
				_start = (end + 1 - overlap + _buf.Length) % _buf.Length;
				return true;
			}
			_start = end + overlap;
			return false;
		}

		public int GetBits(int count)
		{
			int readCount;
			int result = TryPeekBits(count, out readCount);
			if (readCount < count)
			{
				throw new InvalidDataException("Reservoir did not have enough bytes!");
			}
			SkipBits(count);
			return result;
		}

		public int Get1Bit()
		{
			if (_bitsLeft == 0)
			{
				throw new InvalidDataException("Reservoir did not have enough bytes!");
			}
			_bitsLeft--;
			_bitsRead++;
			int result = (_buf[_start] >> _bitsLeft) & 1;
			if (_bitsLeft == 0 && (_start = (_start + 1) % _buf.Length) != _end + 1)
			{
				_bitsLeft = 8;
			}
			return result;
		}

		public int TryPeekBits(int count, out int readCount)
		{
			if (count < 0 || count > 32)
			{
				throw new ArgumentOutOfRangeException("count", "Must return between 0 and 32 bits!");
			}
			if (_bitsLeft == 0 || count == 0)
			{
				readCount = 0;
				return 0;
			}
			int num = _buf[_start];
			if (count < _bitsLeft)
			{
				num >>= _bitsLeft - count;
				num &= (1 << count) - 1;
				readCount = count;
				return num;
			}
			num &= (1 << _bitsLeft) - 1;
			count -= _bitsLeft;
			readCount = _bitsLeft;
			int num2 = _start;
			while (count > 0 && (num2 = (num2 + 1) % _buf.Length) != _end + 1)
			{
				int num3 = Math.Min(count, 8);
				num <<= num3;
				num |= _buf[num2] >> (8 - num3) % 8;
				count -= num3;
				readCount += num3;
			}
			return num;
		}

		public void SkipBits(int count)
		{
			if (count > 0)
			{
				if (count > BitsAvailable)
				{
					throw new ArgumentOutOfRangeException("count");
				}
				int num = 8 - _bitsLeft + count;
				_start = (num / 8 + _start) % _buf.Length;
				_bitsLeft = 8 - num % 8;
				_bitsRead += count;
			}
		}

		public void RewindBits(int count)
		{
			_bitsLeft += count;
			_bitsRead -= count;
			while (_bitsLeft > 8)
			{
				_start--;
				_bitsLeft -= 8;
			}
			while (_start < 0)
			{
				_start += _buf.Length;
			}
		}

		public void FlushBits()
		{
			if (_bitsLeft < 8)
			{
				SkipBits(_bitsLeft);
			}
		}

		public void Reset()
		{
			_start = 0;
			_end = -1;
			_bitsLeft = 0;
		}
	}
	internal abstract class FrameBase
	{
		private static int _totalAllocation;

		private MpegStreamReader _reader;

		private byte[] _savedBuffer;

		internal static int TotalAllocation => Interlocked.CompareExchange(ref _totalAllocation, 0, 0);

		internal long Offset { get; private set; }

		internal int Length { get; set; }

		internal bool Validate(long offset, MpegStreamReader reader)
		{
			Offset = offset;
			_reader = reader;
			int num = Validate();
			if (num > 0)
			{
				Length = num;
				return true;
			}
			return false;
		}

		protected int Read(int offset, byte[] buffer)
		{
			return Read(offset, buffer, 0, buffer.Length);
		}

		protected int Read(int offset, byte[] buffer, int index, int count)
		{
			if (_savedBuffer != null)
			{
				if (index < 0 || index + count > buffer.Length)
				{
					return 0;
				}
				if (offset < 0 || offset >= _savedBuffer.Length)
				{
					return 0;
				}
				if (offset + count > _savedBuffer.Length)
				{
					count = _savedBuffer.Length - index;
				}
				Array.Copy(_savedBuffer, offset, buffer, index, count);
				return count;
			}
			return _reader.Read(Offset + offset, buffer, index, count);
		}

		protected int ReadByte(int offset)
		{
			if (_savedBuffer != null)
			{
				if (offset < 0)
				{
					throw new ArgumentOutOfRangeException();
				}
				if (offset >= _savedBuffer.Length)
				{
					return -1;
				}
				return _savedBuffer[offset];
			}
			return _reader.ReadByte(Offset + offset);
		}

		protected abstract int Validate();

		internal void SaveBuffer()
		{
			_savedBuffer = new byte[Length];
			_reader.Read(Offset, _savedBuffer, 0, Length);
			Interlocked.Add(ref _totalAllocation, Length);
		}

		internal void ClearBuffer()
		{
			Interlocked.Add(ref _totalAllocation, -Length);
			_savedBuffer = null;
		}

		internal virtual void Parse()
		{
		}
	}
	internal class Huffman
	{
		private class HuffmanListNode
		{
			internal byte Value;

			internal int Length;

			internal int Bits;

			internal int Mask;

			internal HuffmanListNode Next;
		}

		private static readonly byte[][,] _codeTables;

		private static readonly float[] _floatLookup;

		private static HuffmanListNode[] _llCache;

		private static int[] _llCacheMaxBits;

		private static readonly int[] LIN_BITS;

		static Huffman()
		{
			_codeTables = new byte[17][,]
			{
				new byte[7, 2]
				{
					{ 2, 1 },
					{ 0, 0 },
					{ 2, 1 },
					{ 0, 16 },
					{ 2, 1 },
					{ 0, 1 },
					{ 0, 17 }
				},
				new byte[17, 2]
				{
					{ 2, 1 },
					{ 0, 0 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 16 },
					{ 0, 1 },
					{ 2, 1 },
					{ 0, 17 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 32 },
					{ 0, 33 },
					{ 2, 1 },
					{ 0, 18 },
					{ 2, 1 },
					{ 0, 2 },
					{ 0, 34 }
				},
				new byte[17, 2]
				{
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 0 },
					{ 0, 1 },
					{ 2, 1 },
					{ 0, 17 },
					{ 2, 1 },
					{ 0, 16 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 32 },
					{ 0, 33 },
					{ 2, 1 },
					{ 0, 18 },
					{ 2, 1 },
					{ 0, 2 },
					{ 0, 34 }
				},
				new byte[31, 2]
				{
					{ 2, 1 },
					{ 0, 0 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 16 },
					{ 0, 1 },
					{ 2, 1 },
					{ 0, 17 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 32 },
					{ 0, 2 },
					{ 2, 1 },
					{ 0, 33 },
					{ 0, 18 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 34 },
					{ 0, 48 },
					{ 2, 1 },
					{ 0, 3 },
					{ 0, 19 },
					{ 2, 1 },
					{ 0, 49 },
					{ 2, 1 },
					{ 0, 50 },
					{ 2, 1 },
					{ 0, 35 },
					{ 0, 51 }
				},
				new byte[31, 2]
				{
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 0 },
					{ 0, 16 },
					{ 0, 17 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 1 },
					{ 2, 1 },
					{ 0, 32 },
					{ 0, 33 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 18 },
					{ 2, 1 },
					{ 0, 2 },
					{ 0, 34 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 49 },
					{ 0, 19 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 48 },
					{ 0, 50 },
					{ 2, 1 },
					{ 0, 35 },
					{ 2, 1 },
					{ 0, 3 },
					{ 0, 51 }
				},
				new byte[71, 2]
				{
					{ 2, 1 },
					{ 0, 0 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 16 },
					{ 0, 1 },
					{ 8, 1 },
					{ 2, 1 },
					{ 0, 17 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 32 },
					{ 0, 2 },
					{ 0, 33 },
					{ 18, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 18 },
					{ 2, 1 },
					{ 0, 34 },
					{ 0, 48 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 49 },
					{ 0, 19 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 3 },
					{ 0, 50 },
					{ 2, 1 },
					{ 0, 35 },
					{ 0, 4 },
					{ 10, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 64 },
					{ 0, 65 },
					{ 2, 1 },
					{ 0, 20 },
					{ 2, 1 },
					{ 0, 66 },
					{ 0, 36 },
					{ 12, 1 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 51 },
					{ 0, 67 },
					{ 0, 80 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 52 },
					{ 0, 5 },
					{ 0, 81 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 21 },
					{ 2, 1 },
					{ 0, 82 },
					{ 0, 37 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 68 },
					{ 0, 53 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 83 },
					{ 0, 84 },
					{ 2, 1 },
					{ 0, 69 },
					{ 0, 85 }
				},
				new byte[71, 2]
				{
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 0 },
					{ 2, 1 },
					{ 0, 16 },
					{ 0, 1 },
					{ 2, 1 },
					{ 0, 17 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 33 },
					{ 0, 18 },
					{ 14, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 32 },
					{ 0, 2 },
					{ 2, 1 },
					{ 0, 34 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 48 },
					{ 0, 3 },
					{ 2, 1 },
					{ 0, 49 },
					{ 0, 19 },
					{ 14, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 50 },
					{ 0, 35 },
					{ 2, 1 },
					{ 0, 64 },
					{ 0, 4 },
					{ 2, 1 },
					{ 0, 65 },
					{ 2, 1 },
					{ 0, 20 },
					{ 0, 66 },
					{ 12, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 36 },
					{ 2, 1 },
					{ 0, 51 },
					{ 0, 80 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 67 },
					{ 0, 52 },
					{ 0, 81 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 21 },
					{ 2, 1 },
					{ 0, 5 },
					{ 0, 82 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 37 },
					{ 2, 1 },
					{ 0, 68 },
					{ 0, 53 },
					{ 2, 1 },
					{ 0, 83 },
					{ 2, 1 },
					{ 0, 69 },
					{ 2, 1 },
					{ 0, 84 },
					{ 0, 85 }
				},
				new byte[71, 2]
				{
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 0 },
					{ 0, 16 },
					{ 2, 1 },
					{ 0, 1 },
					{ 0, 17 },
					{ 10, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 32 },
					{ 0, 33 },
					{ 2, 1 },
					{ 0, 18 },
					{ 2, 1 },
					{ 0, 2 },
					{ 0, 34 },
					{ 12, 1 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 48 },
					{ 0, 3 },
					{ 0, 49 },
					{ 2, 1 },
					{ 0, 19 },
					{ 2, 1 },
					{ 0, 50 },
					{ 0, 35 },
					{ 12, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 65 },
					{ 0, 20 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 64 },
					{ 0, 51 },
					{ 2, 1 },
					{ 0, 66 },
					{ 0, 36 },
					{ 10, 1 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 4 },
					{ 0, 80 },
					{ 0, 67 },
					{ 2, 1 },
					{ 0, 52 },
					{ 0, 81 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 21 },
					{ 0, 82 },
					{ 2, 1 },
					{ 0, 37 },
					{ 0, 68 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 5 },
					{ 0, 84 },
					{ 0, 83 },
					{ 2, 1 },
					{ 0, 53 },
					{ 2, 1 },
					{ 0, 69 },
					{ 0, 85 }
				},
				new byte[127, 2]
				{
					{ 2, 1 },
					{ 0, 0 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 16 },
					{ 0, 1 },
					{ 10, 1 },
					{ 2, 1 },
					{ 0, 17 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 32 },
					{ 0, 2 },
					{ 2, 1 },
					{ 0, 33 },
					{ 0, 18 },
					{ 28, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 34 },
					{ 0, 48 },
					{ 2, 1 },
					{ 0, 49 },
					{ 0, 19 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 3 },
					{ 0, 50 },
					{ 2, 1 },
					{ 0, 35 },
					{ 0, 64 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 65 },
					{ 0, 20 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 4 },
					{ 0, 51 },
					{ 2, 1 },
					{ 0, 66 },
					{ 0, 36 },
					{ 28, 1 },
					{ 10, 1 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 80 },
					{ 0, 5 },
					{ 0, 96 },
					{ 2, 1 },
					{ 0, 97 },
					{ 0, 22 },
					{ 12, 1 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 67 },
					{ 0, 52 },
					{ 0, 81 },
					{ 2, 1 },
					{ 0, 21 },
					{ 2, 1 },
					{ 0, 82 },
					{ 0, 37 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 38 },
					{ 0, 54 },
					{ 0, 113 },
					{ 20, 1 },
					{ 8, 1 },
					{ 2, 1 },
					{ 0, 23 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 68 },
					{ 0, 83 },
					{ 0, 6 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 53 },
					{ 0, 69 },
					{ 0, 98 },
					{ 2, 1 },
					{ 0, 112 },
					{ 2, 1 },
					{ 0, 7 },
					{ 0, 100 },
					{ 14, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 114 },
					{ 0, 39 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 99 },
					{ 2, 1 },
					{ 0, 84 },
					{ 0, 85 },
					{ 2, 1 },
					{ 0, 70 },
					{ 0, 115 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 55 },
					{ 0, 101 },
					{ 2, 1 },
					{ 0, 86 },
					{ 0, 116 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 71 },
					{ 2, 1 },
					{ 0, 102 },
					{ 0, 117 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 87 },
					{ 0, 118 },
					{ 2, 1 },
					{ 0, 103 },
					{ 0, 119 }
				},
				new byte[127, 2]
				{
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 0 },
					{ 2, 1 },
					{ 0, 16 },
					{ 0, 1 },
					{ 8, 1 },
					{ 2, 1 },
					{ 0, 17 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 32 },
					{ 0, 2 },
					{ 0, 18 },
					{ 24, 1 },
					{ 8, 1 },
					{ 2, 1 },
					{ 0, 33 },
					{ 2, 1 },
					{ 0, 34 },
					{ 2, 1 },
					{ 0, 48 },
					{ 0, 3 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 49 },
					{ 0, 19 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 50 },
					{ 0, 35 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 64 },
					{ 0, 4 },
					{ 2, 1 },
					{ 0, 65 },
					{ 0, 20 },
					{ 30, 1 },
					{ 16, 1 },
					{ 10, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 66 },
					{ 0, 36 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 51 },
					{ 0, 67 },
					{ 0, 80 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 52 },
					{ 0, 81 },
					{ 0, 97 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 22 },
					{ 2, 1 },
					{ 0, 6 },
					{ 0, 38 },
					{ 2, 1 },
					{ 0, 98 },
					{ 2, 1 },
					{ 0, 21 },
					{ 2, 1 },
					{ 0, 5 },
					{ 0, 82 },
					{ 16, 1 },
					{ 10, 1 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 37 },
					{ 0, 68 },
					{ 0, 96 },
					{ 2, 1 },
					{ 0, 99 },
					{ 0, 54 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 112 },
					{ 0, 23 },
					{ 0, 113 },
					{ 16, 1 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 7 },
					{ 0, 100 },
					{ 0, 114 },
					{ 2, 1 },
					{ 0, 39 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 83 },
					{ 0, 53 },
					{ 2, 1 },
					{ 0, 84 },
					{ 0, 69 },
					{ 10, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 70 },
					{ 0, 115 },
					{ 2, 1 },
					{ 0, 55 },
					{ 2, 1 },
					{ 0, 101 },
					{ 0, 86 },
					{ 10, 1 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 85 },
					{ 0, 87 },
					{ 0, 116 },
					{ 2, 1 },
					{ 0, 71 },
					{ 0, 102 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 117 },
					{ 0, 118 },
					{ 2, 1 },
					{ 0, 103 },
					{ 0, 119 }
				},
				new byte[127, 2]
				{
					{ 12, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 16 },
					{ 0, 1 },
					{ 2, 1 },
					{ 0, 17 },
					{ 2, 1 },
					{ 0, 0 },
					{ 2, 1 },
					{ 0, 32 },
					{ 0, 2 },
					{ 16, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 33 },
					{ 0, 18 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 34 },
					{ 0, 49 },
					{ 2, 1 },
					{ 0, 19 },
					{ 2, 1 },
					{ 0, 48 },
					{ 2, 1 },
					{ 0, 3 },
					{ 0, 64 },
					{ 26, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 50 },
					{ 0, 35 },
					{ 2, 1 },
					{ 0, 65 },
					{ 0, 51 },
					{ 10, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 20 },
					{ 0, 66 },
					{ 2, 1 },
					{ 0, 36 },
					{ 2, 1 },
					{ 0, 4 },
					{ 0, 80 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 67 },
					{ 0, 52 },
					{ 2, 1 },
					{ 0, 81 },
					{ 0, 21 },
					{ 28, 1 },
					{ 14, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 82 },
					{ 0, 37 },
					{ 2, 1 },
					{ 0, 83 },
					{ 0, 53 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 96 },
					{ 0, 22 },
					{ 0, 97 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 98 },
					{ 0, 38 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 5 },
					{ 0, 6 },
					{ 0, 68 },
					{ 2, 1 },
					{ 0, 84 },
					{ 0, 69 },
					{ 18, 1 },
					{ 10, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 99 },
					{ 0, 54 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 112 },
					{ 0, 7 },
					{ 0, 113 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 23 },
					{ 0, 100 },
					{ 2, 1 },
					{ 0, 70 },
					{ 0, 114 },
					{ 10, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 39 },
					{ 2, 1 },
					{ 0, 85 },
					{ 0, 115 },
					{ 2, 1 },
					{ 0, 55 },
					{ 0, 86 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 101 },
					{ 0, 116 },
					{ 2, 1 },
					{ 0, 71 },
					{ 0, 102 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 117 },
					{ 0, 87 },
					{ 2, 1 },
					{ 0, 118 },
					{ 2, 1 },
					{ 0, 103 },
					{ 0, 119 }
				},
				new byte[511, 2]
				{
					{ 2, 1 },
					{ 0, 0 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 16 },
					{ 2, 1 },
					{ 0, 1 },
					{ 0, 17 },
					{ 28, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 32 },
					{ 0, 2 },
					{ 2, 1 },
					{ 0, 33 },
					{ 0, 18 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 34 },
					{ 0, 48 },
					{ 2, 1 },
					{ 0, 3 },
					{ 0, 49 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 19 },
					{ 2, 1 },
					{ 0, 50 },
					{ 0, 35 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 64 },
					{ 0, 4 },
					{ 0, 65 },
					{ 70, 1 },
					{ 28, 1 },
					{ 14, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 20 },
					{ 2, 1 },
					{ 0, 51 },
					{ 0, 66 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 36 },
					{ 0, 80 },
					{ 2, 1 },
					{ 0, 67 },
					{ 0, 52 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 81 },
					{ 0, 21 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 5 },
					{ 0, 82 },
					{ 2, 1 },
					{ 0, 37 },
					{ 2, 1 },
					{ 0, 68 },
					{ 0, 83 },
					{ 14, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 96 },
					{ 0, 6 },
					{ 2, 1 },
					{ 0, 97 },
					{ 0, 22 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 128 },
					{ 0, 8 },
					{ 0, 129 },
					{ 16, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 53 },
					{ 0, 98 },
					{ 2, 1 },
					{ 0, 38 },
					{ 0, 84 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 69 },
					{ 0, 99 },
					{ 2, 1 },
					{ 0, 54 },
					{ 0, 112 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 7 },
					{ 0, 85 },
					{ 0, 113 },
					{ 2, 1 },
					{ 0, 23 },
					{ 2, 1 },
					{ 0, 39 },
					{ 0, 55 },
					{ 72, 1 },
					{ 24, 1 },
					{ 12, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 24 },
					{ 0, 130 },
					{ 2, 1 },
					{ 0, 40 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 100 },
					{ 0, 70 },
					{ 0, 114 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 132 },
					{ 0, 72 },
					{ 2, 1 },
					{ 0, 144 },
					{ 0, 9 },
					{ 2, 1 },
					{ 0, 145 },
					{ 0, 25 },
					{ 24, 1 },
					{ 14, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 115 },
					{ 0, 101 },
					{ 2, 1 },
					{ 0, 86 },
					{ 0, 116 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 71 },
					{ 0, 102 },
					{ 0, 131 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 56 },
					{ 2, 1 },
					{ 0, 117 },
					{ 0, 87 },
					{ 2, 1 },
					{ 0, 146 },
					{ 0, 41 },
					{ 14, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 103 },
					{ 0, 133 },
					{ 2, 1 },
					{ 0, 88 },
					{ 0, 57 },
					{ 2, 1 },
					{ 0, 147 },
					{ 2, 1 },
					{ 0, 73 },
					{ 0, 134 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 160 },
					{ 2, 1 },
					{ 0, 104 },
					{ 0, 10 },
					{ 2, 1 },
					{ 0, 161 },
					{ 0, 26 },
					{ 68, 1 },
					{ 24, 1 },
					{ 12, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 162 },
					{ 0, 42 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 149 },
					{ 0, 89 },
					{ 2, 1 },
					{ 0, 163 },
					{ 0, 58 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 74 },
					{ 0, 150 },
					{ 2, 1 },
					{ 0, 176 },
					{ 0, 11 },
					{ 2, 1 },
					{ 0, 177 },
					{ 0, 27 },
					{ 20, 1 },
					{ 8, 1 },
					{ 2, 1 },
					{ 0, 178 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 118 },
					{ 0, 119 },
					{ 0, 148 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 135 },
					{ 0, 120 },
					{ 0, 164 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 105 },
					{ 0, 165 },
					{ 0, 43 },
					{ 12, 1 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 90 },
					{ 0, 136 },
					{ 0, 179 },
					{ 2, 1 },
					{ 0, 59 },
					{ 2, 1 },
					{ 0, 121 },
					{ 0, 166 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 106 },
					{ 0, 180 },
					{ 0, 192 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 12 },
					{ 0, 152 },
					{ 0, 193 },
					{ 60, 1 },
					{ 22, 1 },
					{ 10, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 28 },
					{ 2, 1 },
					{ 0, 137 },
					{ 0, 181 },
					{ 2, 1 },
					{ 0, 91 },
					{ 0, 194 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 44 },
					{ 0, 60 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 182 },
					{ 0, 107 },
					{ 2, 1 },
					{ 0, 196 },
					{ 0, 76 },
					{ 16, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 168 },
					{ 0, 138 },
					{ 2, 1 },
					{ 0, 208 },
					{ 0, 13 },
					{ 2, 1 },
					{ 0, 209 },
					{ 2, 1 },
					{ 0, 75 },
					{ 2, 1 },
					{ 0, 151 },
					{ 0, 167 },
					{ 12, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 195 },
					{ 2, 1 },
					{ 0, 122 },
					{ 0, 153 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 197 },
					{ 0, 92 },
					{ 0, 183 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 29 },
					{ 0, 210 },
					{ 2, 1 },
					{ 0, 45 },
					{ 2, 1 },
					{ 0, 123 },
					{ 0, 211 },
					{ 52, 1 },
					{ 28, 1 },
					{ 12, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 61 },
					{ 0, 198 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 108 },
					{ 0, 169 },
					{ 2, 1 },
					{ 0, 154 },
					{ 0, 212 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 184 },
					{ 0, 139 },
					{ 2, 1 },
					{ 0, 77 },
					{ 0, 199 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 124 },
					{ 0, 213 },
					{ 2, 1 },
					{ 0, 93 },
					{ 0, 224 },
					{ 10, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 225 },
					{ 0, 30 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 14 },
					{ 0, 46 },
					{ 0, 226 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 227 },
					{ 0, 109 },
					{ 2, 1 },
					{ 0, 140 },
					{ 0, 228 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 229 },
					{ 0, 186 },
					{ 0, 240 },
					{ 38, 1 },
					{ 16, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 241 },
					{ 0, 31 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 170 },
					{ 0, 155 },
					{ 0, 185 },
					{ 2, 1 },
					{ 0, 62 },
					{ 2, 1 },
					{ 0, 214 },
					{ 0, 200 },
					{ 12, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 78 },
					{ 2, 1 },
					{ 0, 215 },
					{ 0, 125 },
					{ 2, 1 },
					{ 0, 171 },
					{ 2, 1 },
					{ 0, 94 },
					{ 0, 201 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 15 },
					{ 2, 1 },
					{ 0, 156 },
					{ 0, 110 },
					{ 2, 1 },
					{ 0, 242 },
					{ 0, 47 },
					{ 32, 1 },
					{ 16, 1 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 216 },
					{ 0, 141 },
					{ 0, 63 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 243 },
					{ 2, 1 },
					{ 0, 230 },
					{ 0, 202 },
					{ 2, 1 },
					{ 0, 244 },
					{ 0, 79 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 187 },
					{ 0, 172 },
					{ 2, 1 },
					{ 0, 231 },
					{ 0, 245 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 217 },
					{ 0, 157 },
					{ 2, 1 },
					{ 0, 95 },
					{ 0, 232 },
					{ 30, 1 },
					{ 12, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 111 },
					{ 2, 1 },
					{ 0, 246 },
					{ 0, 203 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 188 },
					{ 0, 173 },
					{ 0, 218 },
					{ 8, 1 },
					{ 2, 1 },
					{ 0, 247 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 126 },
					{ 0, 127 },
					{ 0, 142 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 158 },
					{ 0, 174 },
					{ 0, 204 },
					{ 2, 1 },
					{ 0, 248 },
					{ 0, 143 },
					{ 18, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 219 },
					{ 0, 189 },
					{ 2, 1 },
					{ 0, 234 },
					{ 0, 249 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 159 },
					{ 0, 235 },
					{ 2, 1 },
					{ 0, 190 },
					{ 2, 1 },
					{ 0, 205 },
					{ 0, 250 },
					{ 14, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 221 },
					{ 0, 236 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 233 },
					{ 0, 175 },
					{ 0, 220 },
					{ 2, 1 },
					{ 0, 206 },
					{ 0, 251 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 191 },
					{ 0, 222 },
					{ 2, 1 },
					{ 0, 207 },
					{ 0, 238 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 223 },
					{ 0, 239 },
					{ 2, 1 },
					{ 0, 255 },
					{ 2, 1 },
					{ 0, 237 },
					{ 2, 1 },
					{ 0, 253 },
					{ 2, 1 },
					{ 0, 252 },
					{ 0, 254 }
				},
				new byte[511, 2]
				{
					{ 16, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 0 },
					{ 2, 1 },
					{ 0, 16 },
					{ 0, 1 },
					{ 2, 1 },
					{ 0, 17 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 32 },
					{ 0, 2 },
					{ 2, 1 },
					{ 0, 33 },
					{ 0, 18 },
					{ 50, 1 },
					{ 16, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 34 },
					{ 2, 1 },
					{ 0, 48 },
					{ 0, 49 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 19 },
					{ 2, 1 },
					{ 0, 3 },
					{ 0, 64 },
					{ 2, 1 },
					{ 0, 50 },
					{ 0, 35 },
					{ 14, 1 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 4 },
					{ 0, 20 },
					{ 0, 65 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 51 },
					{ 0, 66 },
					{ 2, 1 },
					{ 0, 36 },
					{ 0, 67 },
					{ 10, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 52 },
					{ 2, 1 },
					{ 0, 80 },
					{ 0, 5 },
					{ 2, 1 },
					{ 0, 81 },
					{ 0, 21 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 82 },
					{ 0, 37 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 68 },
					{ 0, 83 },
					{ 0, 97 },
					{ 90, 1 },
					{ 36, 1 },
					{ 18, 1 },
					{ 10, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 53 },
					{ 2, 1 },
					{ 0, 96 },
					{ 0, 6 },
					{ 2, 1 },
					{ 0, 22 },
					{ 0, 98 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 38 },
					{ 0, 84 },
					{ 2, 1 },
					{ 0, 69 },
					{ 0, 99 },
					{ 10, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 54 },
					{ 2, 1 },
					{ 0, 112 },
					{ 0, 7 },
					{ 2, 1 },
					{ 0, 113 },
					{ 0, 85 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 23 },
					{ 0, 100 },
					{ 2, 1 },
					{ 0, 114 },
					{ 0, 39 },
					{ 24, 1 },
					{ 16, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 70 },
					{ 0, 115 },
					{ 2, 1 },
					{ 0, 55 },
					{ 0, 101 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 86 },
					{ 0, 128 },
					{ 2, 1 },
					{ 0, 8 },
					{ 0, 116 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 129 },
					{ 0, 24 },
					{ 2, 1 },
					{ 0, 130 },
					{ 0, 40 },
					{ 16, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 71 },
					{ 0, 102 },
					{ 2, 1 },
					{ 0, 131 },
					{ 0, 56 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 117 },
					{ 0, 87 },
					{ 2, 1 },
					{ 0, 132 },
					{ 0, 72 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 144 },
					{ 0, 25 },
					{ 0, 145 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 146 },
					{ 0, 118 },
					{ 2, 1 },
					{ 0, 103 },
					{ 0, 41 },
					{ 92, 1 },
					{ 36, 1 },
					{ 18, 1 },
					{ 10, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 133 },
					{ 0, 88 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 9 },
					{ 0, 119 },
					{ 0, 147 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 57 },
					{ 0, 148 },
					{ 2, 1 },
					{ 0, 73 },
					{ 0, 134 },
					{ 10, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 104 },
					{ 2, 1 },
					{ 0, 160 },
					{ 0, 10 },
					{ 2, 1 },
					{ 0, 161 },
					{ 0, 26 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 162 },
					{ 0, 42 },
					{ 2, 1 },
					{ 0, 149 },
					{ 0, 89 },
					{ 26, 1 },
					{ 14, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 163 },
					{ 2, 1 },
					{ 0, 58 },
					{ 0, 135 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 120 },
					{ 0, 164 },
					{ 2, 1 },
					{ 0, 74 },
					{ 0, 150 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 105 },
					{ 0, 176 },
					{ 0, 177 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 27 },
					{ 0, 165 },
					{ 0, 178 },
					{ 14, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 90 },
					{ 0, 43 },
					{ 2, 1 },
					{ 0, 136 },
					{ 0, 151 },
					{ 2, 1 },
					{ 0, 179 },
					{ 2, 1 },
					{ 0, 121 },
					{ 0, 59 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 106 },
					{ 0, 180 },
					{ 2, 1 },
					{ 0, 75 },
					{ 0, 193 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 152 },
					{ 0, 137 },
					{ 2, 1 },
					{ 0, 28 },
					{ 0, 181 },
					{ 80, 1 },
					{ 34, 1 },
					{ 16, 1 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 91 },
					{ 0, 44 },
					{ 0, 194 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 11 },
					{ 0, 192 },
					{ 0, 166 },
					{ 2, 1 },
					{ 0, 167 },
					{ 0, 122 },
					{ 10, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 195 },
					{ 0, 60 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 12 },
					{ 0, 153 },
					{ 0, 182 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 107 },
					{ 0, 196 },
					{ 2, 1 },
					{ 0, 76 },
					{ 0, 168 },
					{ 20, 1 },
					{ 10, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 138 },
					{ 0, 197 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 208 },
					{ 0, 92 },
					{ 0, 209 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 183 },
					{ 0, 123 },
					{ 2, 1 },
					{ 0, 29 },
					{ 2, 1 },
					{ 0, 13 },
					{ 0, 45 },
					{ 12, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 210 },
					{ 0, 211 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 61 },
					{ 0, 198 },
					{ 2, 1 },
					{ 0, 108 },
					{ 0, 169 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 154 },
					{ 0, 184 },
					{ 0, 212 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 139 },
					{ 0, 77 },
					{ 2, 1 },
					{ 0, 199 },
					{ 0, 124 },
					{ 68, 1 },
					{ 34, 1 },
					{ 18, 1 },
					{ 10, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 213 },
					{ 0, 93 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 224 },
					{ 0, 14 },
					{ 0, 225 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 30 },
					{ 0, 226 },
					{ 2, 1 },
					{ 0, 170 },
					{ 0, 46 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 185 },
					{ 0, 155 },
					{ 2, 1 },
					{ 0, 227 },
					{ 0, 214 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 109 },
					{ 0, 62 },
					{ 2, 1 },
					{ 0, 200 },
					{ 0, 140 },
					{ 16, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 228 },
					{ 0, 78 },
					{ 2, 1 },
					{ 0, 215 },
					{ 0, 125 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 229 },
					{ 0, 186 },
					{ 2, 1 },
					{ 0, 171 },
					{ 0, 94 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 201 },
					{ 0, 156 },
					{ 2, 1 },
					{ 0, 241 },
					{ 0, 31 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 240 },
					{ 0, 110 },
					{ 0, 242 },
					{ 2, 1 },
					{ 0, 47 },
					{ 0, 230 },
					{ 38, 1 },
					{ 18, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 216 },
					{ 0, 243 },
					{ 2, 1 },
					{ 0, 63 },
					{ 0, 244 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 79 },
					{ 2, 1 },
					{ 0, 141 },
					{ 0, 217 },
					{ 2, 1 },
					{ 0, 187 },
					{ 0, 202 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 172 },
					{ 0, 231 },
					{ 2, 1 },
					{ 0, 126 },
					{ 0, 245 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 157 },
					{ 0, 95 },
					{ 2, 1 },
					{ 0, 232 },
					{ 0, 142 },
					{ 2, 1 },
					{ 0, 246 },
					{ 0, 203 },
					{ 34, 1 },
					{ 18, 1 },
					{ 10, 1 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 15 },
					{ 0, 174 },
					{ 0, 111 },
					{ 2, 1 },
					{ 0, 188 },
					{ 0, 218 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 173 },
					{ 0, 247 },
					{ 2, 1 },
					{ 0, 127 },
					{ 0, 233 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 158 },
					{ 0, 204 },
					{ 2, 1 },
					{ 0, 248 },
					{ 0, 143 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 219 },
					{ 0, 189 },
					{ 2, 1 },
					{ 0, 234 },
					{ 0, 249 },
					{ 16, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 159 },
					{ 0, 220 },
					{ 2, 1 },
					{ 0, 205 },
					{ 0, 235 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 190 },
					{ 0, 250 },
					{ 2, 1 },
					{ 0, 175 },
					{ 0, 221 },
					{ 14, 1 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 236 },
					{ 0, 206 },
					{ 0, 251 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 191 },
					{ 0, 237 },
					{ 2, 1 },
					{ 0, 222 },
					{ 0, 252 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 207 },
					{ 0, 253 },
					{ 0, 238 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 223 },
					{ 0, 254 },
					{ 2, 1 },
					{ 0, 239 },
					{ 0, 255 }
				},
				new byte[511, 2]
				{
					{ 2, 1 },
					{ 0, 0 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 16 },
					{ 2, 1 },
					{ 0, 1 },
					{ 0, 17 },
					{ 42, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 32 },
					{ 0, 2 },
					{ 2, 1 },
					{ 0, 33 },
					{ 0, 18 },
					{ 10, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 34 },
					{ 2, 1 },
					{ 0, 48 },
					{ 0, 3 },
					{ 2, 1 },
					{ 0, 49 },
					{ 0, 19 },
					{ 10, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 50 },
					{ 0, 35 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 64 },
					{ 0, 4 },
					{ 0, 65 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 20 },
					{ 2, 1 },
					{ 0, 51 },
					{ 0, 66 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 36 },
					{ 0, 80 },
					{ 2, 1 },
					{ 0, 67 },
					{ 0, 52 },
					{ 138, 1 },
					{ 40, 1 },
					{ 16, 1 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 5 },
					{ 0, 21 },
					{ 0, 81 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 82 },
					{ 0, 37 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 68 },
					{ 0, 53 },
					{ 0, 83 },
					{ 10, 1 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 96 },
					{ 0, 6 },
					{ 0, 97 },
					{ 2, 1 },
					{ 0, 22 },
					{ 0, 98 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 38 },
					{ 0, 84 },
					{ 2, 1 },
					{ 0, 69 },
					{ 0, 99 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 54 },
					{ 0, 112 },
					{ 0, 113 },
					{ 40, 1 },
					{ 18, 1 },
					{ 8, 1 },
					{ 2, 1 },
					{ 0, 23 },
					{ 2, 1 },
					{ 0, 7 },
					{ 2, 1 },
					{ 0, 85 },
					{ 0, 100 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 114 },
					{ 0, 39 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 70 },
					{ 0, 101 },
					{ 0, 115 },
					{ 10, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 55 },
					{ 2, 1 },
					{ 0, 86 },
					{ 0, 8 },
					{ 2, 1 },
					{ 0, 128 },
					{ 0, 129 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 24 },
					{ 2, 1 },
					{ 0, 116 },
					{ 0, 71 },
					{ 2, 1 },
					{ 0, 130 },
					{ 2, 1 },
					{ 0, 40 },
					{ 0, 102 },
					{ 24, 1 },
					{ 14, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 131 },
					{ 0, 56 },
					{ 2, 1 },
					{ 0, 117 },
					{ 0, 132 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 72 },
					{ 0, 144 },
					{ 0, 145 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 25 },
					{ 2, 1 },
					{ 0, 9 },
					{ 0, 118 },
					{ 2, 1 },
					{ 0, 146 },
					{ 0, 41 },
					{ 14, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 133 },
					{ 0, 88 },
					{ 2, 1 },
					{ 0, 147 },
					{ 0, 57 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 160 },
					{ 0, 10 },
					{ 0, 26 },
					{ 8, 1 },
					{ 2, 1 },
					{ 0, 162 },
					{ 2, 1 },
					{ 0, 103 },
					{ 2, 1 },
					{ 0, 87 },
					{ 0, 73 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 148 },
					{ 2, 1 },
					{ 0, 119 },
					{ 0, 134 },
					{ 2, 1 },
					{ 0, 161 },
					{ 2, 1 },
					{ 0, 104 },
					{ 0, 149 },
					{ 220, 1 },
					{ 126, 1 },
					{ 50, 1 },
					{ 26, 1 },
					{ 12, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 42 },
					{ 2, 1 },
					{ 0, 89 },
					{ 0, 58 },
					{ 2, 1 },
					{ 0, 163 },
					{ 2, 1 },
					{ 0, 135 },
					{ 0, 120 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 164 },
					{ 0, 74 },
					{ 2, 1 },
					{ 0, 150 },
					{ 0, 105 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 176 },
					{ 0, 11 },
					{ 0, 177 },
					{ 10, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 27 },
					{ 0, 178 },
					{ 2, 1 },
					{ 0, 43 },
					{ 2, 1 },
					{ 0, 165 },
					{ 0, 90 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 179 },
					{ 2, 1 },
					{ 0, 166 },
					{ 0, 106 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 180 },
					{ 0, 75 },
					{ 2, 1 },
					{ 0, 12 },
					{ 0, 193 },
					{ 30, 1 },
					{ 14, 1 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 181 },
					{ 0, 194 },
					{ 0, 44 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 167 },
					{ 0, 195 },
					{ 2, 1 },
					{ 0, 107 },
					{ 0, 196 },
					{ 8, 1 },
					{ 2, 1 },
					{ 0, 29 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 136 },
					{ 0, 151 },
					{ 0, 59 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 209 },
					{ 0, 210 },
					{ 2, 1 },
					{ 0, 45 },
					{ 0, 211 },
					{ 18, 1 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 30 },
					{ 0, 46 },
					{ 0, 226 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 121 },
					{ 0, 152 },
					{ 0, 192 },
					{ 2, 1 },
					{ 0, 28 },
					{ 2, 1 },
					{ 0, 137 },
					{ 0, 91 },
					{ 14, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 60 },
					{ 2, 1 },
					{ 0, 122 },
					{ 0, 182 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 76 },
					{ 0, 153 },
					{ 2, 1 },
					{ 0, 168 },
					{ 0, 138 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 13 },
					{ 2, 1 },
					{ 0, 197 },
					{ 0, 92 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 61 },
					{ 0, 198 },
					{ 2, 1 },
					{ 0, 108 },
					{ 0, 154 },
					{ 88, 1 },
					{ 86, 1 },
					{ 36, 1 },
					{ 16, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 139 },
					{ 0, 77 },
					{ 2, 1 },
					{ 0, 199 },
					{ 0, 124 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 213 },
					{ 0, 93 },
					{ 2, 1 },
					{ 0, 224 },
					{ 0, 14 },
					{ 8, 1 },
					{ 2, 1 },
					{ 0, 227 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 208 },
					{ 0, 183 },
					{ 0, 123 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 169 },
					{ 0, 184 },
					{ 0, 212 },
					{ 2, 1 },
					{ 0, 225 },
					{ 2, 1 },
					{ 0, 170 },
					{ 0, 185 },
					{ 24, 1 },
					{ 10, 1 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 155 },
					{ 0, 214 },
					{ 0, 109 },
					{ 2, 1 },
					{ 0, 62 },
					{ 0, 200 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 140 },
					{ 0, 228 },
					{ 0, 78 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 215 },
					{ 0, 229 },
					{ 2, 1 },
					{ 0, 186 },
					{ 0, 171 },
					{ 12, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 156 },
					{ 0, 230 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 110 },
					{ 0, 216 },
					{ 2, 1 },
					{ 0, 141 },
					{ 0, 187 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 231 },
					{ 0, 157 },
					{ 2, 1 },
					{ 0, 232 },
					{ 0, 142 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 203 },
					{ 0, 188 },
					{ 0, 158 },
					{ 0, 241 },
					{ 2, 1 },
					{ 0, 31 },
					{ 2, 1 },
					{ 0, 15 },
					{ 0, 47 },
					{ 66, 1 },
					{ 56, 1 },
					{ 2, 1 },
					{ 0, 242 },
					{ 52, 1 },
					{ 50, 1 },
					{ 20, 1 },
					{ 8, 1 },
					{ 2, 1 },
					{ 0, 189 },
					{ 2, 1 },
					{ 0, 94 },
					{ 2, 1 },
					{ 0, 125 },
					{ 0, 201 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 202 },
					{ 2, 1 },
					{ 0, 172 },
					{ 0, 126 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 218 },
					{ 0, 173 },
					{ 0, 204 },
					{ 10, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 174 },
					{ 2, 1 },
					{ 0, 219 },
					{ 0, 220 },
					{ 2, 1 },
					{ 0, 205 },
					{ 0, 190 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 235 },
					{ 0, 237 },
					{ 0, 238 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 217 },
					{ 0, 234 },
					{ 0, 233 },
					{ 2, 1 },
					{ 0, 222 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 221 },
					{ 0, 236 },
					{ 0, 206 },
					{ 0, 63 },
					{ 0, 240 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 243 },
					{ 0, 244 },
					{ 2, 1 },
					{ 0, 79 },
					{ 2, 1 },
					{ 0, 245 },
					{ 0, 95 },
					{ 10, 1 },
					{ 2, 1 },
					{ 0, 255 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 246 },
					{ 0, 111 },
					{ 2, 1 },
					{ 0, 247 },
					{ 0, 127 },
					{ 12, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 143 },
					{ 2, 1 },
					{ 0, 248 },
					{ 0, 249 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 159 },
					{ 0, 250 },
					{ 0, 175 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 251 },
					{ 0, 191 },
					{ 2, 1 },
					{ 0, 252 },
					{ 0, 207 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 253 },
					{ 0, 223 },
					{ 2, 1 },
					{ 0, 254 },
					{ 0, 239 }
				},
				new byte[512, 2]
				{
					{ 60, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 0 },
					{ 0, 16 },
					{ 2, 1 },
					{ 0, 1 },
					{ 0, 17 },
					{ 14, 1 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 32 },
					{ 0, 2 },
					{ 0, 33 },
					{ 2, 1 },
					{ 0, 18 },
					{ 2, 1 },
					{ 0, 34 },
					{ 2, 1 },
					{ 0, 48 },
					{ 0, 3 },
					{ 14, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 49 },
					{ 0, 19 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 50 },
					{ 0, 35 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 64 },
					{ 0, 4 },
					{ 0, 65 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 20 },
					{ 0, 51 },
					{ 2, 1 },
					{ 0, 66 },
					{ 0, 36 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 67 },
					{ 0, 52 },
					{ 0, 81 },
					{ 6, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 80 },
					{ 0, 5 },
					{ 0, 21 },
					{ 2, 1 },
					{ 0, 82 },
					{ 0, 37 },
					{ 250, 1 },
					{ 98, 1 },
					{ 34, 1 },
					{ 18, 1 },
					{ 10, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 68 },
					{ 0, 83 },
					{ 2, 1 },
					{ 0, 53 },
					{ 2, 1 },
					{ 0, 96 },
					{ 0, 6 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 97 },
					{ 0, 22 },
					{ 2, 1 },
					{ 0, 98 },
					{ 0, 38 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 84 },
					{ 0, 69 },
					{ 2, 1 },
					{ 0, 99 },
					{ 0, 54 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 113 },
					{ 0, 85 },
					{ 2, 1 },
					{ 0, 100 },
					{ 0, 70 },
					{ 32, 1 },
					{ 14, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 114 },
					{ 2, 1 },
					{ 0, 39 },
					{ 0, 55 },
					{ 2, 1 },
					{ 0, 115 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 112 },
					{ 0, 7 },
					{ 0, 23 },
					{ 10, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 101 },
					{ 0, 86 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 128 },
					{ 0, 8 },
					{ 0, 129 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 116 },
					{ 0, 71 },
					{ 2, 1 },
					{ 0, 24 },
					{ 0, 130 },
					{ 16, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 40 },
					{ 0, 102 },
					{ 2, 1 },
					{ 0, 131 },
					{ 0, 56 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 117 },
					{ 0, 87 },
					{ 2, 1 },
					{ 0, 132 },
					{ 0, 72 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 145 },
					{ 0, 25 },
					{ 2, 1 },
					{ 0, 146 },
					{ 0, 118 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 103 },
					{ 0, 41 },
					{ 2, 1 },
					{ 0, 133 },
					{ 0, 88 },
					{ 92, 1 },
					{ 34, 1 },
					{ 16, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 147 },
					{ 0, 57 },
					{ 2, 1 },
					{ 0, 148 },
					{ 0, 73 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 119 },
					{ 0, 134 },
					{ 2, 1 },
					{ 0, 104 },
					{ 0, 161 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 162 },
					{ 0, 42 },
					{ 2, 1 },
					{ 0, 149 },
					{ 0, 89 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 163 },
					{ 0, 58 },
					{ 2, 1 },
					{ 0, 135 },
					{ 2, 1 },
					{ 0, 120 },
					{ 0, 74 },
					{ 22, 1 },
					{ 12, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 164 },
					{ 0, 150 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 105 },
					{ 0, 177 },
					{ 2, 1 },
					{ 0, 27 },
					{ 0, 165 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 178 },
					{ 2, 1 },
					{ 0, 90 },
					{ 0, 43 },
					{ 2, 1 },
					{ 0, 136 },
					{ 0, 179 },
					{ 16, 1 },
					{ 10, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 144 },
					{ 2, 1 },
					{ 0, 9 },
					{ 0, 160 },
					{ 2, 1 },
					{ 0, 151 },
					{ 0, 121 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 166 },
					{ 0, 106 },
					{ 0, 180 },
					{ 12, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 26 },
					{ 2, 1 },
					{ 0, 10 },
					{ 0, 176 },
					{ 2, 1 },
					{ 0, 59 },
					{ 2, 1 },
					{ 0, 11 },
					{ 0, 192 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 75 },
					{ 0, 193 },
					{ 2, 1 },
					{ 0, 152 },
					{ 0, 137 },
					{ 67, 1 },
					{ 34, 1 },
					{ 16, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 28 },
					{ 0, 181 },
					{ 2, 1 },
					{ 0, 91 },
					{ 0, 194 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 44 },
					{ 0, 167 },
					{ 2, 1 },
					{ 0, 122 },
					{ 0, 195 },
					{ 10, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 60 },
					{ 2, 1 },
					{ 0, 12 },
					{ 0, 208 },
					{ 2, 1 },
					{ 0, 182 },
					{ 0, 107 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 196 },
					{ 0, 76 },
					{ 2, 1 },
					{ 0, 153 },
					{ 0, 168 },
					{ 16, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 138 },
					{ 0, 197 },
					{ 2, 1 },
					{ 0, 92 },
					{ 0, 209 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 183 },
					{ 0, 123 },
					{ 2, 1 },
					{ 0, 29 },
					{ 0, 210 },
					{ 9, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 45 },
					{ 0, 211 },
					{ 2, 1 },
					{ 0, 61 },
					{ 0, 198 },
					{ 85, 250 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 108 },
					{ 0, 169 },
					{ 2, 1 },
					{ 0, 154 },
					{ 0, 212 },
					{ 32, 1 },
					{ 16, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 184 },
					{ 0, 139 },
					{ 2, 1 },
					{ 0, 77 },
					{ 0, 199 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 124 },
					{ 0, 213 },
					{ 2, 1 },
					{ 0, 93 },
					{ 0, 225 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 30 },
					{ 0, 226 },
					{ 2, 1 },
					{ 0, 170 },
					{ 0, 185 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 155 },
					{ 0, 227 },
					{ 2, 1 },
					{ 0, 214 },
					{ 0, 109 },
					{ 20, 1 },
					{ 10, 1 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 62 },
					{ 2, 1 },
					{ 0, 46 },
					{ 0, 78 },
					{ 2, 1 },
					{ 0, 200 },
					{ 0, 140 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 228 },
					{ 0, 215 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 125 },
					{ 0, 171 },
					{ 0, 229 },
					{ 10, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 186 },
					{ 0, 94 },
					{ 2, 1 },
					{ 0, 201 },
					{ 2, 1 },
					{ 0, 156 },
					{ 0, 110 },
					{ 8, 1 },
					{ 2, 1 },
					{ 0, 230 },
					{ 2, 1 },
					{ 0, 13 },
					{ 2, 1 },
					{ 0, 224 },
					{ 0, 14 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 216 },
					{ 0, 141 },
					{ 2, 1 },
					{ 0, 187 },
					{ 0, 202 },
					{ 74, 1 },
					{ 2, 1 },
					{ 0, 255 },
					{ 64, 1 },
					{ 58, 1 },
					{ 32, 1 },
					{ 16, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 172 },
					{ 0, 231 },
					{ 2, 1 },
					{ 0, 126 },
					{ 0, 217 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 157 },
					{ 0, 232 },
					{ 2, 1 },
					{ 0, 142 },
					{ 0, 203 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 188 },
					{ 0, 218 },
					{ 2, 1 },
					{ 0, 173 },
					{ 0, 233 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 158 },
					{ 0, 204 },
					{ 2, 1 },
					{ 0, 219 },
					{ 0, 189 },
					{ 16, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 234 },
					{ 0, 174 },
					{ 2, 1 },
					{ 0, 220 },
					{ 0, 205 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 235 },
					{ 0, 190 },
					{ 2, 1 },
					{ 0, 221 },
					{ 0, 236 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 206 },
					{ 0, 237 },
					{ 2, 1 },
					{ 0, 222 },
					{ 0, 238 },
					{ 0, 15 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 240 },
					{ 0, 31 },
					{ 0, 241 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 242 },
					{ 0, 47 },
					{ 2, 1 },
					{ 0, 243 },
					{ 0, 63 },
					{ 18, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 244 },
					{ 0, 79 },
					{ 2, 1 },
					{ 0, 245 },
					{ 0, 95 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 246 },
					{ 0, 111 },
					{ 2, 1 },
					{ 0, 247 },
					{ 2, 1 },
					{ 0, 127 },
					{ 0, 143 },
					{ 10, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 248 },
					{ 0, 249 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 159 },
					{ 0, 175 },
					{ 0, 250 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 251 },
					{ 0, 191 },
					{ 2, 1 },
					{ 0, 252 },
					{ 0, 207 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 253 },
					{ 0, 223 },
					{ 2, 1 },
					{ 0, 254 },
					{ 0, 239 }
				},
				new byte[31, 2]
				{
					{ 2, 1 },
					{ 0, 0 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 8 },
					{ 0, 4 },
					{ 2, 1 },
					{ 0, 1 },
					{ 0, 2 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 12 },
					{ 0, 10 },
					{ 2, 1 },
					{ 0, 3 },
					{ 0, 6 },
					{ 6, 1 },
					{ 2, 1 },
					{ 0, 9 },
					{ 2, 1 },
					{ 0, 5 },
					{ 0, 7 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 14 },
					{ 0, 13 },
					{ 2, 1 },
					{ 0, 15 },
					{ 0, 11 }
				},
				new byte[31, 2]
				{
					{ 16, 1 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 0 },
					{ 0, 1 },
					{ 2, 1 },
					{ 0, 2 },
					{ 0, 3 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 4 },
					{ 0, 5 },
					{ 2, 1 },
					{ 0, 6 },
					{ 0, 7 },
					{ 8, 1 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 8 },
					{ 0, 9 },
					{ 2, 1 },
					{ 0, 10 },
					{ 0, 11 },
					{ 4, 1 },
					{ 2, 1 },
					{ 0, 12 },
					{ 0, 13 },
					{ 2, 1 },
					{ 0, 14 },
					{ 0, 15 }
				}
			};
			_llCache = new HuffmanListNode[_codeTables.Length];
			_llCacheMaxBits = new int[_codeTables.Length];
			LIN_BITS = new int[32]
			{
				0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
				0, 0, 0, 0, 0, 0, 1, 2, 3, 4,
				6, 8, 10, 13, 4, 5, 6, 7, 8, 9,
				11, 13
			};
			_floatLookup = new float[8207];
			for (int i = 0; i < 8207; i++)
			{
				_floatLookup[i] = (float)Math.Pow(i, 1.3333333333333333);
			}
		}

		internal static void Decode(BitReservoir br, int table, out float x, out float y)
		{
			if (table == 0 || table == 4 || table == 14)
			{
				x = (y = 0f);
				return;
			}
			byte num = DecodeSymbol(br, table);
			int num2 = num >> 4;
			int num3 = num & 0xF;
			int num4 = LIN_BITS[table];
			if (num4 > 0 && num2 == 15)
			{
				num2 += br.GetBits(num4);
			}
			if (num2 != 0 && br.Get1Bit() != 0)
			{
				x = 0f - _floatLookup[num2];
			}
			else
			{
				x = _floatLookup[num2];
			}
			if (num4 > 0 && num3 == 15)
			{
				num3 += br.GetBits(num4);
			}
			if (num3 != 0 && br.Get1Bit() != 0)
			{
				y = 0f - _floatLookup[num3];
			}
			else
			{
				y = _floatLookup[num3];
			}
		}

		internal static void Decode(BitReservoir br, int table, out float x, out float y, out float v, out float w)
		{
			byte num = DecodeSymbol(br, table);
			v = (w = (x = (y = 0f)));
			if ((num & 8u) != 0)
			{
				if (br.Get1Bit() == 1)
				{
					v = 0f - _floatLookup[1];
				}
				else
				{
					v = _floatLookup[1];
				}
			}
			if ((num & 4u) != 0)
			{
				if (br.Get1Bit() == 1)
				{
					w = 0f - _floatLookup[1];
				}
				else
				{
					w = _floatLookup[1];
				}
			}
			if ((num & 2u) != 0)
			{
				if (br.Get1Bit() == 1)
				{
					x = 0f - _floatLookup[1];
				}
				else
				{
					x = _floatLookup[1];
				}
			}
			if (((uint)num & (true ? 1u : 0u)) != 0)
			{
				if (br.Get1Bit() == 1)
				{
					y = 0f - _floatLookup[1];
				}
				else
				{
					y = _floatLookup[1];
				}
			}
		}

		private static byte DecodeSymbol(BitReservoir br, int table)
		{
			int maxBits;
			HuffmanListNode huffmanListNode = GetNode(table, out maxBits);
			int readCount;
			int num = br.TryPeekBits(maxBits, out readCount);
			if (readCount < maxBits)
			{
				num <<= maxBits - readCount;
			}
			while (huffmanListNode != null && huffmanListNode.Length <= readCount)
			{
				if ((num & huffmanListNode.Mask) == huffmanListNode.Bits)
				{
					br.SkipBits(huffmanListNode.Length);
					break;
				}
				huffmanListNode = huffmanListNode.Next;
			}
			if (huffmanListNode != null && huffmanListNode.Length <= readCount)
			{
				return huffmanListNode.Value;
			}
			return 0;
		}

		private static HuffmanListNode GetNode(int table, out int maxBits)
		{
			int num = table;
			if (num > 16)
			{
				num = ((num > 31) ? (num - 17) : ((num < 24) ? 13 : 14));
			}
			else
			{
				if (num > 13)
				{
					num--;
				}
				if (num > 3)
				{
					num--;
				}
				num--;
			}
			if (_llCache[num] == null)
			{
				_llCache[num] = InitTable(_codeTables[num], out maxBits);
				_llCacheMaxBits[num] = maxBits;
			}
			else
			{
				maxBits = _llCacheMaxBits[num];
			}
			return _llCache[num];
		}

		private static HuffmanListNode InitTable(byte[,] tree, out int maxBits)
		{
			List<byte> list = new List<byte>();
			List<int> list2 = new List<int>();
			List<int> list3 = new List<int>();
			int length = tree.GetLength(0);
			for (int i = 0; i < length; i++)
			{
				if (tree[i, 0] == 0)
				{
					int num = 0;
					int item = 0;
					int num2 = i;
					do
					{
						num2 = FindPreviousNode(tree, num2, out var bit);
						num |= bit << item++;
					}
					while (num2 > 0);
					list.Add(tree[i, 1]);
					list2.Add(item);
					list3.Add(num);
				}
			}
			return BuildLinkedList(list, list2, list3, out maxBits);
		}

		private static int FindPreviousNode(byte[,] tree, int idx, out int bit)
		{
			for (int num = idx - 1; num >= 0; num--)
			{
				if (tree[num, 0] != 0)
				{
					for (int i = 0; i < 2; i++)
					{
						if (num + tree[num, i] != idx)
						{
							continue;
						}
						if (tree[num, i] >= 250)
						{
							int result = FindPreviousNode(tree, num, out bit);
							if (bit != i)
							{
								throw new InvalidOperationException();
							}
							return result;
						}
						bit = i;
						return num;
					}
				}
			}
			throw new InvalidOperationException();
		}

		private static HuffmanListNode BuildLinkedList(List<byte> values, List<int> lengthList, List<int> codeList, out int maxBits)
		{
			HuffmanListNode[] array = new HuffmanListNode[lengthList.Count];
			maxBits = lengthList.Max();
			for (int j = 0; j < array.Length; j++)
			{
				int num = maxBits - lengthList[j];
				array[j] = new HuffmanListNode
				{
					Value = values[j],
					Length = lengthList[j],
					Bits = codeList[j] << num,
					Mask = (1 << lengthList[j]) - 1 << num
				};
			}
			Array.Sort(array, (HuffmanListNode i1, HuffmanListNode i2) => i1.Length - i2.Length);
			for (int k = 1; k < array.Length && array[k].Length < 99999; k++)
			{
				array[k - 1].Next = array[k];
			}
			return array[0];
		}
	}
	internal class ID3Frame : FrameBase
	{
		private int _version;

		internal int Version
		{
			get
			{
				if (_version == 0)
				{
					return 1;
				}
				return _version;
			}
		}

		internal static ID3Frame TrySync(uint syncMark)
		{
			if ((syncMark & 0xFFFFFF00u) == 1229206272)
			{
				return new ID3Frame
				{
					_version = 2
				};
			}
			if ((syncMark & 0xFFFFFF00u) == 1413564160)
			{
				if ((syncMark & 0xFF) == 43)
				{
					return new ID3Frame
					{
						_version = 1
					};
				}
				return new ID3Frame
				{
					_version = 0
				};
			}
			return null;
		}

		private ID3Frame()
		{
		}

		protected override int Validate()
		{
			switch (_version)
			{
			case 2:
			{
				byte[] array = new byte[7];
				if (Read(3, array) == 7)
				{
					byte b;
					switch (array[0])
					{
					case 2:
						b = 63;
						break;
					case 3:
						b = 31;
						break;
					case 4:
						b = 15;
						break;
					default:
						return -1;
					}
					int num = (array[3] << 21) | (array[4] << 14) | (array[5] << 7) | array[6];
					if (((array[2] & b) | (array[3] & 0x80) | (array[4] & 0x80) | (array[5] & 0x80) | (array[6] & 0x80)) == 0 && array[1] != byte.MaxValue)
					{
						return num + 10;
					}
				}
				break;
			}
			case 1:
				return 355;
			case 0:
				return 128;
			}
			return -1;
		}

		internal override void Parse()
		{
			switch (_version)
			{
			case 2:
				ParseV2();
				break;
			case 1:
				ParseV1Enh();
				break;
			case 0:
				ParseV1(3);
				break;
			}
		}

		private void ParseV1(int offset)
		{
		}

		private void ParseV1Enh()
		{
			ParseV1(230);
		}

		private void ParseV2()
		{
		}

		internal void Merge(ID3Frame newFrame)
		{
		}
	}
	internal abstract class LayerDecoderBase
	{
		protected const int SBLIMIT = 32;

		private const float INV_SQRT_2 = 0.70710677f;

		private static float[] DEWINDOW_TABLE = new float[512]
		{
			0f, -1.5259E-05f, -1.5259E-05f, -1.5259E-05f, -1.5259E-05f, -1.5259E-05f, -1.5259E-05f, -3.0518E-05f, -3.0518E-05f, -3.0518E-05f,
			-3.0518E-05f, -4.5776E-05f, -4.5776E-05f, -6.1035E-05f, -6.1035E-05f, -7.6294E-05f, -7.6294E-05f, -9.1553E-05f, -0.000106812f, -0.000106812f,
			-0.00012207f, -0.000137329f, -0.000152588f, -0.000167847f, -0.000198364f, -0.000213623f, -0.000244141f, -0.000259399f, -0.000289917f, -0.000320435f,
			-0.000366211f, -0.000396729f, -0.000442505f, -0.000473022f, -0.000534058f, -0.000579834f, -0.00062561f, -0.000686646f, -0.000747681f, -0.000808716f,
			-0.00088501f, -0.000961304f, -0.001037598f, -0.001113892f, -0.001205444f, -0.001296997f, -0.00138855f, -0.001480103f, -0.001586914f, -0.001693726f,
			-0.001785278f, -0.001907349f, -0.00201416f, -0.002120972f, -0.002243042f, -0.002349854f, -0.002456665f, -0.002578735f, -0.002685547f, -0.002792358f,
			-0.00289917f, -0.002990723f, -0.003082275f, -0.003173828f, 0.003250122f, 0.003326416f, 0.003387451f, 0.003433228f, 0.003463745f, 0.003479004f,
			0.003479004f, 0.003463745f, 0.003417969f, 0.003372192f, 0.00328064f, 0.003173828f, 0.003051758f, 0.002883911f, 0.002700806f, 0.002487183f,
			0.002227783f, 0.001937866f, 0.001617432f, 0.001266479f, 0.000869751f, 0.000442505f, -3.0518E-05f, -0.000549316f, -0.001098633f, -0.001693726f,
			-0.002334595f, -0.003005981f, -0.003723145f, -0.004486084f, -0.0052948f, -0.006118774f, -0.007003784f, -0.007919312f, -0.008865356f, -0.009841919f,
			-0.010848999f, -0.011886597f, -0.012939453f, -0.014022827f, -0.01512146f, -0.016235352f, -0.017349243f, -0.018463135f, -0.019577026f, -0.020690918f,
			-0.02178955f, -0.022857666f, -0.023910522f, -0.024932861f, -0.025909424f, -0.02684021f, -0.02772522f, -0.028533936f, -0.029281616f, -0.029937744f,
			-0.030532837f, -0.03100586f, -0.03138733f, -0.031661987f, -0.031814575f, -0.031845093f, -0.03173828f, -0.03147888f, 0.031082153f, 0.030517578f,
			0.029785156f, 0.028884888f, 0.027801514f, 0.026535034f, 0.02508545f, 0.023422241f, 0.021575928f, 0.01953125f, 0.01725769f, 0.014801025f,
			0.012115479f, 0.009231567f, 0.006134033f, 0.002822876f, -0.000686646f, -0.004394531f, -0.00831604f, -0.012420654f, -0.016708374f, -0.0211792f,
			-0.025817871f, -0.03060913f, -0.03555298f, -0.040634155f, -0.045837402f, -0.051132202f, -0.056533813f, -0.06199646f, -0.06752014f, -0.07305908f,
			-0.07862854f, -0.08418274f, -0.08970642f, -0.09516907f, -0.10054016f, -0.1058197f, -0.110946655f, -0.11592102f, -0.12069702f, -0.1252594f,
			-0.12956238f, -0.1335907f, -0.13729858f, -0.14067078f, -0.14367676f, -0.1462555f, -0.14842224f, -0.15011597f, -0.15130615f, -0.15196228f,
			-0.15206909f, -0.15159607f, -0.15049744f, -0.1487732f, -0.1463623f, -0.14326477f, -0.13945007f, -0.1348877f, -0.12957764f, -0.12347412f,
			-0.11657715f, -0.1088562f, 0.10031128f, 0.090927124f, 0.08068848f, 0.06959534f, 0.057617188f, 0.044784546f, 0.031082153f, 0.01651001f,
			0.001068115f, -0.015228271f, -0.03237915f, -0.050354004f, -0.06916809f, -0.088775635f, -0.10916138f, -0.13031006f, -0.15220642f, -0.17478943f,
			-0.19805908f, -0.22198486f, -0.24650574f, -0.2715912f, -0.2972107f, -0.32331848f, -0.34986877f, -0.37680054f, -0.40408325f, -0.43165588f,
			-0.45947266f, -0.48747253f, -0.51560974f, -0.54382324f, -0.57203674f, -0.6002197f, -0.6282959f, -0.6562195f, -0.6839142f, -0.71131897f,
			-0.7383728f, -0.7650299f, -0.791214f, -0.816864f, -0.84194946f, -0.8663635f, -0.89009094f, -0.9130554f, -0.9351959f, -0.95648193f,
			-0.9768524f, -0.99624634f, -1.0146179f, -1.0319366f, -1.0481567f, -1.0632172f, -1.0771179f, -1.0897827f, -1.1012115f, -1.1113739f,
			-1.120224f, -1.1277466f, -1.1339264f, -1.1387634f, -1.1422119f, -1.1442871f, 1.144989f, 1.1442871f, 1.1422119f, 1.1387634f,
			1.1339264f, 1.1277466f, 1.120224f, 1.1113739f, 1.1012115f, 1.0897827f, 1.0771179f, 1.0632172f, 1.0481567f, 1.0319366f,
			1.0146179f, 0.99624634f, 0.9768524f, 0.95648193f, 0.9351959f, 0.9130554f, 0.89009094f, 0.8663635f, 0.84194946f, 0.816864f,
			0.791214f, 0.7650299f, 0.7383728f, 0.71131897f, 0.6839142f, 0.6562195f, 0.6282959f, 0.6002197f, 0.57203674f, 0.54382324f,
			0.51560974f, 0.48747253f, 0.45947266f, 0.43165588f, 0.40408325f, 0.37680054f, 0.34986877f, 0.32331848f, 0.2972107f, 0.2715912f,
			0.24650574f, 0.22198486f, 0.19805908f, 0.17478943f, 0.15220642f, 0.13031006f, 0.10916138f, 0.088775635f, 0.06916809f, 0.050354004f,
			0.03237915f, 0.015228271f, -0.001068115f, -0.01651001f, -0.031082153f, -0.044784546f, -0.057617188f, -0.06959534f, -0.08068848f, -0.090927124f,
			0.10031128f, 0.1088562f, 0.11657715f, 0.12347412f, 0.12957764f, 0.1348877f, 0.13945007f, 0.14326477f, 0.1463623f, 0.1487732f,
			0.15049744f, 0.15159607f, 0.15206909f, 0.15196228f, 0.15130615f, 0.15011597f, 0.14842224f, 0.1462555f, 0.14367676f, 0.14067078f,
			0.13729858f, 0.1335907f, 0.12956238f, 0.1252594f, 0.12069702f, 0.11592102f, 0.110946655f, 0.1058197f, 0.10054016f, 0.09516907f,
			0.08970642f, 0.08418274f, 0.07862854f, 0.07305908f, 0.06752014f, 0.06199646f, 0.056533813f, 0.051132202f, 0.045837402f, 0.040634155f,
			0.03555298f, 0.03060913f, 0.025817871f, 0.0211792f, 0.016708374f, 0.012420654f, 0.00831604f, 0.004394531f, 0.000686646f, -0.002822876f,
			-0.006134033f, -0.009231567f, -0.012115479f, -0.014801025f, -0.01725769f, -0.01953125f, -0.021575928f, -0.023422241f, -0.02508545f, -0.026535034f,
			-0.027801514f, -0.028884888f, -0.029785156f, -0.030517578f, 0.031082153f, 0.03147888f, 0.03173828f, 0.031845093f, 0.031814575f, 0.031661987f,
			0.03138733f, 0.03100586f, 0.030532837f, 0.029937744f, 0.029281616f, 0.028533936f, 0.02772522f, 0.02684021f, 0.025909424f, 0.024932861f,
			0.023910522f, 0.022857666f, 0.02178955f, 0.020690918f, 0.019577026f, 0.018463135f, 0.017349243f, 0.016235352f, 0.01512146f, 0.014022827f,
			0.012939453f, 0.011886597f, 0.010848999f, 0.009841919f, 0.008865356f, 0.007919312f, 0.007003784f, 0.006118774f, 0.0052948f, 0.004486084f,
			0.003723145f, 0.003005981f, 0.002334595f, 0.001693726f, 0.001098633f, 0.000549316f, 3.0518E-05f, -0.000442505f, -0.000869751f, -0.001266479f,
			-0.001617432f, -0.001937866f, -0.002227783f, -0.002487183f, -0.002700806f, -0.002883911f, -0.003051758f, -0.003173828f, -0.00328064f, -0.003372192f,
			-0.003417969f, -0.003463745f, -0.003479004f, -0.003479004f, -0.003463745f, -0.003433228f, -0.003387451f, -0.003326416f, 0.003250122f, 0.003173828f,
			0.003082275f, 0.002990723f, 0.00289917f, 0.002792358f, 0.002685547f, 0.002578735f, 0.002456665f, 0.002349854f, 0.002243042f, 0.002120972f,
			0.00201416f, 0.001907349f, 0.001785278f, 0.001693726f, 0.001586914f, 0.001480103f, 0.00138855f, 0.001296997f, 0.001205444f, 0.001113892f,
			0.001037598f, 0.000961304f, 0.00088501f, 0.000808716f, 0.000747681f, 0.000686646f, 0.00062561f, 0.000579834f, 0.000534058f, 0.000473022f,
			0.000442505f, 0.000396729f, 0.000366211f, 0.000320435f, 0.000289917f, 0.000259399f, 0.000244141f, 0.000213623f, 0.000198364f, 0.000167847f,
			0.000152588f, 0.000137329f, 0.00012207f, 0.000106812f, 0.000106812f, 9.1553E-05f, 7.6294E-05f, 7.6294E-05f, 6.1035E-05f, 6.1035E-05f,
			4.5776E-05f, 4.5776E-05f, 3.0518E-05f, 3.0518E-05f, 3.0518E-05f, 3.0518E-05f, 1.5259E-05f, 1.5259E-05f, 1.5259E-05f, 1.5259E-05f,
			1.5259E-05f, 1.5259E-05f
		};

		private static float[] SYNTH_COS64_TABLE = new float[31]
		{
			0.500603f, 0.5024193f, 0.50547093f, 0.5097956f, 0.5154473f, 0.5224986f, 0.5310426f, 0.5411961f, 0.5531039f, 0.56694406f,
			0.582935f, 0.6013449f, 0.6225041f, 0.6468218f, 0.6748083f, 0.70710677f, 0.7445363f, 0.7881546f, 0.8393496f, 0.8999762f,
			0.9725682f, 1.0606776f, 1.1694399f, 1.306563f, 1.4841646f, 1.7224472f, 2.057781f, 2.5629156f, 3.4076085f, 5.1011486f,
			10.190008f
		};

		private List<float[]> _synBuf = new List<float[]>(2);

		private List<int> _bufOffset = new List<int>(2);

		private float[] _eq;

		private float[] ippuv = new float[512];

		private float[] ei32 = new float[16];

		private float[] eo32 = new float[16];

		private float[] oi32 = new float[16];

		private float[] oo32 = new float[16];

		private float[] ei16 = new float[8];

		private float[] eo16 = new float[8];

		private float[] oi16 = new float[8];

		private float[] oo16 = new float[8];

		private float[] ei8 = new float[4];

		private float[] tmp8 = new float[6];

		private float[] oi8 = new float[4];

		private float[] oo8 = new float[4];

		internal StereoMode StereoMode { get; set; }

		internal LayerDecoderBase()
		{
			StereoMode = StereoMode.Both;
		}

		internal abstract int DecodeFrame(IMpegFrame frame, float[] ch0, float[] ch1);

		internal void SetEQ(float[] eq)
		{
			if (eq == null || eq.Length == 32)
			{
				_eq = eq;
			}
		}

		internal virtual void ResetForSeek()
		{
			_synBuf.Clear();
			_bufOffset.Clear();
		}

		protected void InversePolyPhase(int channel, float[] data)
		{
			GetBufAndOffset(channel, out var synBuf, out var k);
			if (_eq != null)
			{
				for (int i = 0; i < 32; i++)
				{
					data[i] *= _eq[i];
				}
			}
			DCT32(data, synBuf, k);
			BuildUVec(ippuv, synBuf, k);
			DewindowOutput(ippuv, data);
		}

		private void GetBufAndOffset(int channel, out float[] synBuf, out int k)
		{
			while (_synBuf.Count <= channel)
			{
				_synBuf.Add(new float[1024]);
			}
			while (_bufOffset.Count <= channel)
			{
				_bufOffset.Add(0);
			}
			synBuf = _synBuf[channel];
			k = _bufOffset[channel];
			k = (k - 32) & 0x1FF;
			_bufOffset[channel] = k;
		}

		private void DCT32(float[] _in, float[] _out, int k)
		{
			for (int i = 0; i < 16; i++)
			{
				ei32[i] = _in[i] + _in[31 - i];
				oi32[i] = (_in[i] - _in[31 - i]) * SYNTH_COS64_TABLE[2 * i];
			}
			DCT16(ei32, eo32);
			DCT16(oi32, oo32);
			for (int i = 0; i < 15; i++)
			{
				_out[2 * i + k] = eo32[i];
				_out[2 * i + 1 + k] = oo32[i] + oo32[i + 1];
			}
			_out[30 + k] = eo32[15];
			_out[31 + k] = oo32[15];
		}

		private void DCT16(float[] _in, float[] _out)
		{
			float num = _in[0];
			float num2 = _in[15];
			ei16[0] = num + num2;
			oi16[0] = (num - num2) * SYNTH_COS64_TABLE[1];
			num = _in[1];
			num2 = _in[14];
			ei16[1] = num + num2;
			oi16[1] = (num - num2) * SYNTH_COS64_TABLE[5];
			num = _in[2];
			num2 = _in[13];
			ei16[2] = num + num2;
			oi16[2] = (num - num2) * SYNTH_COS64_TABLE[9];
			num = _in[3];
			num2 = _in[12];
			ei16[3] = num + num2;
			oi16[3] = (num - num2) * SYNTH_COS64_TABLE[13];
			num = _in[4];
			num2 = _in[11];
			ei16[4] = num + num2;
			oi16[4] = (num - num2) * SYNTH_COS64_TABLE[17];
			num = _in[5];
			num2 = _in[10];
			ei16[5] = num + num2;
			oi16[5] = (num - num2) * SYNTH_COS64_TABLE[21];
			num = _in[6];
			num2 = _in[9];
			ei16[6] = num + num2;
			oi16[6] = (num - num2) * SYNTH_COS64_TABLE[25];
			num = _in[7];
			num2 = _in[8];
			ei16[7] = num + num2;
			oi16[7] = (num - num2) * SYNTH_COS64_TABLE[29];
			DCT8(ei16, eo16);
			DCT8(oi16, oo16);
			_out[0] = eo16[0];
			_out[1] = oo16[0] + oo16[1];
			_out[2] = eo16[1];
			_out[3] = oo16[1] + oo16[2];
			_out[4] = eo16[2];
			_out[5] = oo16[2] + oo16[3];
			_out[6] = eo16[3];
			_out[7] = oo16[3] + oo16[4];
			_out[8] = eo16[4];
			_out[9] = oo16[4] + oo16[5];
			_out[10] = eo16[5];
			_out[11] = oo16[5] + oo16[6];
			_out[12] = eo16[6];
			_out[13] = oo16[6] + oo16[7];
			_out[14] = eo16[7];
			_out[15] = oo16[7];
		}

		private void DCT8(float[] _in, float[] _out)
		{
			ei8[0] = _in[0] + _in[7];
			ei8[1] = _in[3] + _in[4];
			ei8[2] = _in[1] + _in[6];
			ei8[3] = _in[2] + _in[5];
			tmp8[0] = ei8[0] + ei8[1];
			tmp8[1] = ei8[2] + ei8[3];
			tmp8[2] = (ei8[0] - ei8[1]) * SYNTH_COS64_TABLE[7];
			tmp8[3] = (ei8[2] - ei8[3]) * SYNTH_COS64_TABLE[23];
			tmp8[4] = (tmp8[2] - tmp8[3]) * 0.70710677f;
			_out[0] = tmp8[0] + tmp8[1];
			_out[2] = tmp8[2] + tmp8[3] + tmp8[4];
			_out[4] = (tmp8[0] - tmp8[1]) * 0.70710677f;
			_out[6] = tmp8[4];
			oi8[0] = (_in[0] - _in[7]) * SYNTH_COS64_TABLE[3];
			oi8[1] = (_in[1] - _in[6]) * SYNTH_COS64_TABLE[11];
			oi8[2] = (_in[2] - _in[5]) * SYNTH_COS64_TABLE[19];
			oi8[3] = (_in[3] - _in[4]) * SYNTH_COS64_TABLE[27];
			tmp8[0] = oi8[0] + oi8[3];
			tmp8[1] = oi8[1] + oi8[2];
			tmp8[2] = (oi8[0] - oi8[3]) * SYNTH_COS64_TABLE[7];
			tmp8[3] = (oi8[1] - oi8[2]) * SYNTH_COS64_TABLE[23];
			tmp8[4] = tmp8[2] + tmp8[3];
			tmp8[5] = (tmp8[2] - tmp8[3]) * 0.70710677f;
			oo8[0] = tmp8[0] + tmp8[1];
			oo8[1] = tmp8[4] + tmp8[5];
			oo8[2] = (tmp8[0] - tmp8[1]) * 0.70710677f;
			oo8[3] = tmp8[5];
			_out[1] = oo8[0] + oo8[1];
			_out[3] = oo8[1] + oo8[2];
			_out[5] = oo8[2] + oo8[3];
			_out[7] = oo8[3];
		}

		private void BuildUVec(float[] u_vec, float[] cur_synbuf, int k)
		{
			int num = 0;
			for (int i = 0; i < 8; i++)
			{
				for (int j = 0; j < 16; j++)
				{
					u_vec[num + j] = cur_synbuf[k + j + 16];
					u_vec[num + j + 17] = 0f - cur_synbuf[k + 31 - j];
				}
				k = (k + 32) & 0x1FF;
				for (int j = 0; j < 16; j++)
				{
					u_vec[num + j + 32] = 0f - cur_synbuf[k + 16 - j];
					u_vec[num + j + 48] = 0f - cur_synbuf[k + j];
				}
				u_vec[num + 16] = 0f;
				k = (k + 32) & 0x1FF;
				num += 64;
			}
		}

		private void DewindowOutput(float[] u_vec, float[] samples)
		{
			for (int i = 0; i < 512; i++)
			{
				u_vec[i] *= DEWINDOW_TABLE[i];
			}
			for (int j = 0; j < 32; j++)
			{
				float num = u_vec[j];
				num += u_vec[j + 32];
				num += u_vec[j + 64];
				num += u_vec[j + 96];
				num += u_vec[j + 128];
				num += u_vec[j + 160];
				num += u_vec[j + 192];
				num += u_vec[j + 224];
				num += u_vec[j + 256];
				num += u_vec[j + 288];
				num += u_vec[j + 320];
				num += u_vec[j + 352];
				num += u_vec[j + 384];
				num += u_vec[j + 416];
				num += u_vec[j + 448];
				num += u_vec[j + 480];
				u_vec[j] = num;
			}
			for (int k = 0; k < 32; k++)
			{
				samples[k] = u_vec[k];
			}
		}
	}
	internal class LayerIDecoder : LayerIIDecoderBase
	{
		private static readonly int[] _rateTable = new int[32];

		private static readonly int[][] _allocLookupTable = new int[1][] { new int[17]
		{
			4, 0, 2, 3, 4, 5, 6, 7, 8, 9,
			10, 11, 12, 13, 14, 15, 16
		} };

		internal static bool GetCRC(MpegFrame frame, ref uint crc)
		{
			return LayerIIDecoderBase.GetCRC(frame, _rateTable, _allocLookupTable, readScfsiBits: false, ref crc);
		}

		internal LayerIDecoder()
			: base(_allocLookupTable, 1)
		{
		}

		protected override int[] GetRateTable(IMpegFrame frame)
		{
			return _rateTable;
		}

		protected override void ReadScaleFactorSelection(IMpegFrame frame, int[][] scfsi, int channels)
		{
		}
	}
	internal class LayerIIDecoder : LayerIIDecoderBase
	{
		private static readonly int[][] _rateLookupTable = new int[5][]
		{
			new int[27]
			{
				3, 3, 3, 2, 2, 2, 2, 2, 2, 2,
				2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
				1, 1, 1, 0, 0, 0, 0
			},
			new int[30]
			{
				3, 3, 3, 2, 2, 2, 2, 2, 2, 2,
				2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
				1, 1, 1, 0, 0, 0, 0, 0, 0, 0
			},
			new int[8] { 4, 4, 5, 5, 5, 5, 5, 5 },
			new int[12]
			{
				4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
				5, 5
			},
			new int[30]
			{
				6, 6, 6, 6, 5, 5, 5, 5, 5, 5,
				5, 7, 7, 7, 7, 7, 7, 7, 7, 7,
				7, 7, 7, 7, 7, 7, 7, 7, 7, 7
			}
		};

		private static readonly int[][] _allocLookupTable = new int[8][]
		{
			new int[5] { 2, 0, -5, -7, 16 },
			new int[9] { 3, 0, -5, -7, 3, -10, 4, 5, 16 },
			new int[17]
			{
				4, 0, -5, -7, 3, -10, 4, 5, 6, 7,
				8, 9, 10, 11, 12, 13, 16
			},
			new int[17]
			{
				4, 0, -5, 3, 4, 5, 6, 7, 8, 9,
				10, 11, 12, 13, 14, 15, 16
			},
			new int[17]
			{
				4, 0, -5, -7, -10, 4, 5, 6, 7, 8,
				9, 10, 11, 12, 13, 14, 15
			},
			new int[9] { 3, 0, -5, -7, -10, 4, 5, 6, 9 },
			new int[17]
			{
				4, 0, -5, -7, 3, -10, 4, 5, 6, 7,
				8, 9, 10, 11, 12, 13, 14
			},
			new int[5] { 2, 0, -5, -7, 3 }
		};

		internal static bool GetCRC(MpegFrame frame, ref uint crc)
		{
			return LayerIIDecoderBase.GetCRC(frame, SelectTable(frame), _allocLookupTable, readScfsiBits: true, ref crc);
		}

		private static int[] SelectTable(IMpegFrame frame)
		{
			int num = frame.BitRate / ((frame.ChannelMode == MpegChannelMode.Mono) ? 1 : 2) / 1000;
			if (frame.Version == MpegVersion.Version1)
			{
				if ((num >= 56 && num <= 80) || (frame.SampleRate == 48000 && num >= 56))
				{
					return _rateLookupTable[0];
				}
				if (frame.SampleRate != 48000 && num >= 96)
				{
					return _rateLookupTable[1];
				}
				if (frame.SampleRate != 32000 && num <= 48)
				{
					return _rateLookupTable[2];
				}
				return _rateLookupTable[3];
			}
			return _rateLookupTable[4];
		}

		internal LayerIIDecoder()
			: base(_allocLookupTable, 3)
		{
		}

		protected override int[] GetRateTable(IMpegFrame frame)
		{
			return SelectTable(frame);
		}

		protected override void ReadScaleFactorSelection(IMpegFrame frame, int[][] scfsi, int channels)
		{
			for (int i = 0; i < 30; i++)
			{
				for (int j = 0; j < channels; j++)
				{
					if (scfsi[j][i] == 2)
					{
						scfsi[j][i] = frame.ReadBits(2);
					}
				}
			}
		}
	}
	internal abstract class LayerIIDecoderBase : LayerDecoderBase
	{
		protected const int SSLIMIT = 12;

		private static readonly float[] _groupedC = new float[5] { 0f, 0f, 1.3333334f, 1.6f, 1.7777778f };

		private static readonly float[] _groupedD = new float[5] { 0f, 0f, -0.5f, -0.5f, -0.5f };

		private static readonly float[] _C = new float[17]
		{
			0f, 0f, 1.3333334f, 1.1428572f, 1.0666667f, 1.032258f, 1.0158731f, 1.007874f, 1.0039216f, 1.0019569f,
			1.0009775f, 1.0004885f, 1.0002443f, 1.0001221f, 1.000061f, 1.0000305f, 1.0000153f
		};

		private static readonly float[] _D = new float[17]
		{
			0f,
			0f,
			-0.5f,
			-0.75f,
			-0.875f,
			-0.9375f,
			-31f / 32f,
			-63f / 64f,
			-127f / 128f,
			-0.99609375f,
			-0.9980469f,
			-0.99902344f,
			-0.9995117f,
			-0.99975586f,
			-0.9998779f,
			-0.99993896f,
			-0.9999695f
		};

		private static readonly float[] _denormalMultiplier = new float[64]
		{
			2f,
			1.587401f,
			1.2599211f,
			1f,
			0.7937005f,
			0.62996054f,
			0.5f,
			0.39685026f,
			0.31498027f,
			0.25f,
			0.19842513f,
			0.15749013f,
			0.125f,
			0.099212565f,
			0.07874507f,
			0.0625f,
			0.049606282f,
			0.039372534f,
			1f / 32f,
			0.024803141f,
			0.019686267f,
			1f / 64f,
			0.012401571f,
			0.009843133f,
			1f / 128f,
			0.0062007853f,
			0.0049215667f,
			0.00390625f,
			0.0031003926f,
			0.0024607833f,
			0.001953125f,
			0.0015501963f,
			0.0012303917f,
			0.0009765625f,
			0.00077509816f,
			0.00061519584f,
			0.00048828125f,
			0.00038754908f,
			0.00030759792f,
			0.00024414062f,
			0.00019377454f,
			0.00015379896f,
			0.00012207031f,
			9.688727E-05f,
			7.689948E-05f,
			6.1035156E-05f,
			4.8443635E-05f,
			3.844974E-05f,
			3.0517578E-05f,
			2.4221818E-05f,
			1.922487E-05f,
			1.5258789E-05f,
			1.2110909E-05f,
			9.612435E-06f,
			7.6293945E-06f,
			6.0554544E-06f,
			4.8062175E-06f,
			3.8146973E-06f,
			3.0277272E-06f,
			2.4031087E-06f,
			1.9073486E-06f,
			1.5138636E-06f,
			1.2015544E-06f,
			9.536743E-07f
		};

		private int _channels;

		private int _jsbound;

		private int _granuleCount;

		private int[][] _allocLookupTable;

		private int[][] _scfsi;

		private int[][] _samples;

		private int[][][] _scalefac;

		private float[] _polyPhaseBuf;

		private int[][] _allocation;

		protected static bool GetCRC(MpegFrame frame, int[] rateTable, int[][] allocLookupTable, bool readScfsiBits, ref uint crc)
		{
			int num = 0;
			int num2 = rateTable.Length;
			int num3 = num2;
			if (frame.ChannelMode == MpegChannelMode.JointStereo)
			{
				num3 = frame.ChannelModeExtension * 4 + 4;
			}
			int num4 = ((frame.ChannelMode == MpegChannelMode.Mono) ? 1 : 2);
			int i;
			for (i = 0; i < num3; i++)
			{
				int num5 = allocLookupTable[rateTable[i]][0];
				for (int j = 0; j < num4; j++)
				{
					int num6 = frame.ReadBits(num5);
					if (num6 > 0)
					{
						num += 2;
					}
					MpegFrame.UpdateCRC(num6, num5, ref crc);
				}
			}
			for (; i < num2; i++)
			{
				int num7 = allocLookupTable[rateTable[i]][0];
				int num8 = frame.ReadBits(num7);
				if (num8 > 0)
				{
					num += num4 * 2;
				}
				MpegFrame.UpdateCRC(num8, num7, ref crc);
			}
			if (readScfsiBits)
			{
				while (num >= 2)
				{
					MpegFrame.UpdateCRC(frame.ReadBits(2), 2, ref crc);
					num -= 2;
				}
			}
			return true;
		}

		protected LayerIIDecoderBase(int[][] allocLookupTable, int granuleCount)
		{
			_allocLookupTable = allocLookupTable;
			_granuleCount = granuleCount;
			_allocation = new int[2][]
			{
				new int[32],
				new int[32]
			};
			_scfsi = new int[2][]
			{
				new int[32],
				new int[32]
			};
			_samples = new int[2][]
			{
				new int[384 * _granuleCount],
				new int[384 * _granuleCount]
			};
			_scalefac = new int[2][][]
			{
				new int[3][],
				new int[3][]
			};
			for (int i = 0; i < 3; i++)
			{
				_scalefac[0][i] = new int[32];
				_scalefac[1][i] = new int[32];
			}
			_polyPhaseBuf = new float[32];
		}

		internal override int DecodeFrame(IMpegFrame frame, float[] ch0, float[] ch1)
		{
			InitFrame(frame);
			int[] rateTable = GetRateTable(frame);
			ReadAllocation(frame, rateTable);
			for (int i = 0; i < _scfsi[0].Length; i++)
			{
				_scfsi[0][i] = ((_allocation[0][i] != 0) ? 2 : (-1));
				_scfsi[1][i] = ((_allocation[1][i] != 0) ? 2 : (-1));
			}
			ReadScaleFactorSelection(frame, _scfsi, _channels);
			ReadScaleFactors(frame);
			ReadSamples(frame);
			return DecodeSamples(ch0, ch1);
		}

		private void InitFrame(IMpegFrame frame)
		{
			switch (frame.ChannelMode)
			{
			case MpegChannelMode.Mono:
				_channels = 1;
				_jsbound = 32;
				break;
			case MpegChannelMode.JointStereo:
				_channels = 2;
				_jsbound = frame.ChannelModeExtension * 4 + 4;
				break;
			default:
				_channels = 2;
				_jsbound = 32;
				break;
			}
		}

		protected abstract int[] GetRateTable(IMpegFrame frame);

		private void ReadAllocation(IMpegFrame frame, int[] rateTable)
		{
			int num = rateTable.Length;
			if (_jsbound > num)
			{
				_jsbound = num;
			}
			Array.Clear(_allocation[0], 0, 32);
			Array.Clear(_allocation[1], 0, 32);
			int i;
			for (i = 0; i < _jsbound; i++)
			{
				int[] array = _allocLookupTable[rateTable[i]];
				int bitCount = array[0];
				for (int j = 0; j < _channels; j++)
				{
					_allocation[j][i] = array[frame.ReadBits(bitCount) + 1];
				}
			}
			for (; i < num; i++)
			{
				int[] array2 = _allocLookupTable[rateTable[i]];
				_allocation[0][i] = (_allocation[1][i] = array2[frame.ReadBits(array2[0]) + 1]);
			}
		}

		protected abstract void ReadScaleFactorSelection(IMpegFrame frame, int[][] scfsi, int channels);

		private void ReadScaleFactors(IMpegFrame frame)
		{
			for (int i = 0; i < 32; i++)
			{
				for (int j = 0; j < _channels; j++)
				{
					switch (_scfsi[j][i])
					{
					case 0:
						_scalefac[j][0][i] = frame.ReadBits(6);
						_scalefac[j][1][i] = frame.ReadBits(6);
						_scalefac[j][2][i] = frame.ReadBits(6);
						break;
					case 1:
						_scalefac[j][0][i] = (_scalefac[j][1][i] = frame.ReadBits(6));
						_scalefac[j][2][i] = frame.ReadBits(6);
						break;
					case 2:
						_scalefac[j][0][i] = (_scalefac[j][1][i] = (_scalefac[j][2][i] = frame.ReadBits(6)));
						break;
					case 3:
						_scalefac[j][0][i] = frame.ReadBits(6);
						_scalefac[j][1][i] = (_scalefac[j][2][i] = frame.ReadBits(6));
						break;
					default:
						_scalefac[j][0][i] = 63;
						_scalefac[j][1][i] = 63;
						_scalefac[j][2][i] = 63;
						break;
					}
				}
			}
		}

		private void ReadSamples(IMpegFrame frame)
		{
			int num = 0;
			int num2 = 0;
			while (num < 12)
			{
				int num3 = 0;
				while (num3 < 32)
				{
					for (int i = 0; i < _channels; i++)
					{
						if (i == 0 || num3 < _jsbound)
						{
							int num4 = _allocation[i][num3];
							if (num4 != 0)
							{
								if (num4 < 0)
								{
									int num5 = frame.ReadBits(-num4);
									int num6 = (1 << -num4 / 2 + -num4 % 2 - 1) + 1;
									_samples[i][num2] = num5 % num6;
									num5 /= num6;
									_samples[i][num2 + 32] = num5 % num6;
									_samples[i][num2 + 64] = num5 / num6;
								}
								else
								{
									for (int j = 0; j < _granuleCount; j++)
									{
										_samples[i][num2 + 32 * j] = frame.ReadBits(num4);
									}
								}
							}
							else
							{
								for (int k = 0; k < _granuleCount; k++)
								{
									_samples[i][num2 + 32 * k] = 0;
								}
							}
						}
						else
						{
							for (int l = 0; l < _granuleCount; l++)
							{
								_samples[1][num2 + 32 * l] = _samples[0][num2 + 32 * l];
							}
						}
					}
					num3++;
					num2++;
				}
				num++;
				num2 += 32 * (_granuleCount - 1);
			}
		}

		private int DecodeSamples(float[] ch0, float[] ch1)
		{
			float[][] array = new float[2][];
			int num = 0;
			int num2 = _channels - 1;
			if (_channels == 1 || base.StereoMode == StereoMode.LeftOnly)
			{
				array[0] = ch0;
				num2 = 0;
			}
			else if (base.StereoMode == StereoMode.RightOnly)
			{
				array[1] = ch0;
				num = 1;
			}
			else
			{
				array[0] = ch0;
				array[1] = ch1;
			}
			int num3 = 0;
			for (int i = num; i <= num2; i++)
			{
				num3 = 0;
				for (int j = 0; j < _granuleCount; j++)
				{
					for (int k = 0; k < 12; k++)
					{
						int num4 = 0;
						while (num4 < 32)
						{
							int num5 = _allocation[i][num4];
							if (num5 != 0)
							{
								float[] array2;
								float[] array3;
								if (num5 < 0)
								{
									num5 = -num5 / 2 + -num5 % 2 - 1;
									array2 = _groupedC;
									array3 = _groupedD;
								}
								else
								{
									array2 = _C;
									array3 = _D;
								}
								_polyPhaseBuf[num4] = array2[num5] * ((float)(_samples[i][num3] << 16 - num5) / 32768f + array3[num5]) * _denormalMultiplier[_scalefac[i][j][num4]];
							}
							else
							{
								_polyPhaseBuf[num4] = 0f;
							}
							num4++;
							num3++;
						}
						InversePolyPhase(i, _polyPhaseBuf);
						Array.Copy(_polyPhaseBuf, 0, array[i], num3 - 32, 32);
					}
				}
			}
			if (_channels == 2 && base.StereoMode == StereoMode.DownmixToMono)
			{
				for (int l = 0; l < num3; l++)
				{
					ch0[l] = (ch0[l] + ch1[l]) / 2f;
				}
			}
			return num3;
		}
	}
	internal sealed class LayerIIIDecoder : LayerDecoderBase
	{
		private class HybridMDCT
		{
			private const float PI = MathF.PI;

			private static float[][] _swin;

			private static float[] icos72_table;

			private List<float[]> _prevBlock;

			private List<float[]> _nextBlock;

			private float[] _imdctTemp = new float[18];

			private float[] _imdctResult = new float[36];

			private const float sqrt32 = 0.8660254f;

			static HybridMDCT()
			{
				icos72_table = new float[35]
				{
					0.50047636f, 0.5019099f, 0.5043145f, 0.5077133f, 0.51213974f, 0.5176381f, 0.5242646f, 0.5320889f, 0.5411961f, 0.55168897f,
					0.56369096f, 0.57735026f, 0.59284455f, 0.61038727f, 0.6302362f, 0.65270364f, 0.67817086f, 0.70710677f, 0.7400936f, 0.7778619f,
					0.8213398f, 0.8717234f, 0.9305795f, 1f, 1.0828403f, 1.1831008f, 1.306563f, 1.4619021f, 1.6627548f, 1.9318516f,
					2.3101132f, 2.8793852f, 3.830649f, 5.7368565f, 11.462792f
				};
				_swin = new float[4][]
				{
					new float[36],
					new float[36],
					new float[36],
					new float[36]
				};
				for (int i = 0; i < 36; i++)
				{
					_swin[0][i] = (float)Math.Sin(0.0872664675116539 * ((double)i + 0.5));
				}
				for (int i = 0; i < 18; i++)
				{
					_swin[1][i] = (float)Math.Sin(0.0872664675116539 * ((double)i + 0.5));
				}
				for (int i = 18; i < 24; i++)
				{
					_swin[1][i] = 1f;
				}
				for (int i = 24; i < 30; i++)
				{
					_swin[1][i] = (float)Math.Sin(0.2617993950843811 * ((double)i + 0.5 - 18.0));
				}
				for (int i = 30; i < 36; i++)
				{
					_swin[1][i] = 0f;
				}
				for (int i = 0; i < 6; i++)
				{
					_swin[3][i] = 0f;
				}
				for (int i = 6; i < 12; i++)
				{
					_swin[3][i] = (float)Math.Sin(0.2617993950843811 * ((double)i + 0.5 - 6.0));
				}
				for (int i = 12; i < 18; i++)
				{
					_swin[3][i] = 1f;
				}
				for (int i = 18; i < 36; i++)
				{
					_swin[3][i] = (float)Math.Sin(0.0872664675116539 * ((double)i + 0.5));
				}
				for (int i = 0; i < 12; i++)
				{
					_swin[2][i] = (float)Math.Sin(0.2617993950843811 * ((double)i + 0.5));
				}
				for (int i = 12; i < 36; i++)
				{
					_swin[2][i] = 0f;
				}
			}

			internal HybridMDCT()
			{
				_prevBlock = new List<float[]>();
				_nextBlock = new List<float[]>();
			}

			internal void Reset()
			{
				_prevBlock.Clear();
				_nextBlock.Clear();
			}

			private void GetPrevBlock(int channel, out float[] prevBlock, out float[] nextBlock)
			{
				while (_prevBlock.Count <= channel)
				{
					_prevBlock.Add(new float[576]);
				}
				while (_nextBlock.Count <= channel)
				{
					_nextBlock.Add(new float[576]);
				}
				prevBlock = _prevBlock[channel];
				nextBlock = _nextBlock[channel];
				_nextBlock[channel] = prevBlock;
				_prevBlock[channel] = nextBlock;
			}

			internal void Apply(float[] fsIn, int channel, int blockType, bool doMixed)
			{
				GetPrevBlock(channel, out var prevBlock, out var nextBlock);
				int sbStart = 0;
				if (doMixed)
				{
					LongImpl(fsIn, 0, 2, nextBlock, 0);
					sbStart = 2;
				}
				if (blockType == 2)
				{
					ShortImpl(fsIn, sbStart, nextBlock);
				}
				else
				{
					LongImpl(fsIn, sbStart, 32, nextBlock, blockType);
				}
				for (int i = 0; i < 576; i++)
				{
					fsIn[i] += prevBlock[i];
				}
			}

			private void LongImpl(float[] fsIn, int sbStart, int sbLimit, float[] nextblck, int blockType)
			{
				int i = sbStart;
				int num = sbStart * 18;
				for (; i < sbLimit; i++)
				{
					Array.Copy(fsIn, num, _imdctTemp, 0, 18);
					LongIMDCT(_imdctTemp, _imdctResult);
					float[] array = _swin[blockType];
					int j;
					for (j = 0; j < 18; j++)
					{
						fsIn[num++] = _imdctResult[j] * array[j];
					}
					num -= 18;
					for (; j < 36; j++)
					{
						nextblck[num++] = _imdctResult[j] * array[j];
					}
				}
			}

			private static void LongIMDCT(float[] invec, float[] outvec)
			{
				float[] array = new float[17];
				float[] array2 = new float[18];
				float[] array3 = new float[9];
				float[] array4 = new float[9];
				float[] array5 = new float[9];
				float[] array6 = new float[9];
				int i;
				for (i = 0; i < 17; i++)
				{
					array[i] = invec[i] + invec[i + 1];
				}
				array3[0] = invec[0];
				array4[0] = array[0];
				int num = 0;
				i = 1;
				while (i < 9)
				{
					array3[i] = array[num + 1];
					array4[i] = array[num] + array[num + 2];
					i++;
					num += 2;
				}
				imdct_9pt(array3, array5);
				imdct_9pt(array4, array6);
				for (i = 0; i < 9; i++)
				{
					array6[i] *= ICOS36_A(i);
					array2[i] = (array5[i] + array6[i]) * ICOS72_A(i);
				}
				for (; i < 18; i++)
				{
					array2[i] = (array5[17 - i] - array6[17 - i]) * ICOS72_A(i);
				}
				outvec[0] = array2[9];
				outvec[1] = array2[10];
				outvec[2] = array2[11];
				outvec[3] = array2[12];
				outvec[4] = array2[13];
				outvec[5] = array2[14];
				outvec[6] = array2[15];
				outvec[7] = array2[16];
				outvec[8] = array2[17];
				outvec[9] = 0f - array2[17];
				outvec[10] = 0f - array2[16];
				outvec[11] = 0f - array2[15];
				outvec[12] = 0f - array2[14];
				outvec[13] = 0f - array2[13];
				outvec[14] = 0f - array2[12];
				outvec[15] = 0f - array2[11];
				outvec[16] = 0f - array2[10];
				outvec[17] = 0f - array2[9];
				outvec[35] = (outvec[18] = 0f - array2[8]);
				outvec[34] = (outvec[19] = 0f - array2[7]);
				outvec[33] = (outvec[20] = 0f - array2[6]);
				outvec[32] = (outvec[21] = 0f - array2[5]);
				outvec[31] = (outvec[22] = 0f - array2[4]);
				outvec[30] = (outvec[23] = 0f - array2[3]);
				outvec[29] = (outvec[24] = 0f - array2[2]);
				outvec[28] = (outvec[25] = 0f - array2[1]);
				outvec[27] = (outvec[26] = 0f - array2[0]);
			}

			private static float ICOS72_A(int i)
			{
				return icos72_table[2 * i];
			}

			private static float ICOS36_A(int i)
			{
				return icos72_table[4 * i + 1];
			}

			private static void imdct_9pt(float[] invec, float[] outvec)
			{
				float[] array = new float[5];
				float[] array2 = new float[4];
				float num = invec[6] / 2f + invec[0];
				float num2 = invec[0] - invec[6];
				float num3 = invec[2] - invec[4] - invec[8];
				array[0] = num + invec[2] * 0.9396926f + invec[4] * 0.76604444f + invec[8] * 0.17364818f;
				array[1] = num3 / 2f + num2;
				array[2] = num - invec[2] * 0.17364818f - invec[4] * 0.9396926f + invec[8] * 0.76604444f;
				array[3] = num - invec[2] * 0.76604444f + invec[4] * 0.17364818f - invec[8] * 0.9396926f;
				array[4] = num2 - num3;
				float num4 = invec[1] + invec[3];
				float num5 = invec[3] + invec[5];
				num = (invec[5] + invec[7]) * 0.5f + invec[1];
				array2[0] = num + num4 * 0.9396926f + num5 * 0.76604444f;
				array2[1] = (invec[1] - invec[5]) * 1.5f - invec[7];
				array2[2] = num - num4 * 0.17364818f - num5 * 0.9396926f;
				array2[3] = num - num4 * 0.76604444f + num5 * 0.17364818f;
				array2[0] += invec[7] * 0.17364818f;
				array2[1] -= invec[7] * 0.5f;
				array2[2] += invec[7] * 0.76604444f;
				array2[3] -= invec[7] * 0.9396926f;
				array2[0] *= 0.5077133f;
				array2[1] *= 0.57735026f;
				array2[2] *= 0.7778619f;
				array2[3] *= 1.4619021f;
				for (int i = 0; i < 4; i++)
				{
					outvec[i] = array[i] + array2[i];
				}
				outvec[4] = array[4];
				for (int i = 5; i < 9; i++)
				{
					outvec[i] = array[8 - i] - array2[8 - i];
				}
			}

			private void ShortImpl(float[] fsIn, int sbStart, float[] nextblck)
			{
				_ = _swin[2];
				int num = sbStart;
				int num2 = sbStart * 18;
				while (num < 32)
				{
					int i = 0;
					int num3 = 0;
					for (; i < 3; i++)
					{
						int num4 = num2 + i;
						for (int j = 0; j < 6; j++)
						{
							_imdctTemp[num3 + j] = fsIn[num4];
							num4 += 3;
						}
						num3 += 6;
					}
					Array.Clear(fsIn, num2, 6);
					ShortIMDCT(_imdctTemp, 0, _imdctResult);
					Array.Copy(_imdctResult, 0, fsIn, num2 + 6, 12);
					ShortIMDCT(_imdct

plugins/SentrySound/SentrySound.Core.dll

Decompiled 2 weeks ago
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using Microsoft.CodeAnalysis;
using NLayer;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("SentrySound.Core")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SentrySound.Core")]
[assembly: AssemblyTitle("SentrySound.Core")]
[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 SentrySound.Core
{
	public sealed record DecodedTrack(TrackInfo Info, float[] Samples, int PeakIndex = 0);
	public static class AudioDecoder
	{
		public const int MaxFrames = 16000000;

		public static string[] Discover(string directory)
		{
			return (from g in (from p in Directory.EnumerateFiles(directory)
					where Path.GetExtension(p).Equals(".mp3", StringComparison.OrdinalIgnoreCase) || Path.GetExtension(p).Equals(".wav", StringComparison.OrdinalIgnoreCase)
					select p).GroupBy<string, string>(Path.GetFileNameWithoutExtension, StringComparer.OrdinalIgnoreCase)
				select g.OrderBy((string p) => (!Path.GetExtension(p).Equals(".mp3", StringComparison.OrdinalIgnoreCase)) ? 1 : 0).ThenBy<string, string>((string p) => p, StringComparer.Ordinal).First()).OrderBy<string, string>((string p) => Path.GetFileName(p), StringComparer.OrdinalIgnoreCase).ToArray();
		}

		public static DecodedTrack Decode(string path, CancellationToken cancellation = default(CancellationToken))
		{
			return DecodeInternal(path, retainSamples: true, cancellation);
		}

		public static TrackInfo Inspect(string path, CancellationToken cancellation = default(CancellationToken))
		{
			return DecodeInternal(path, retainSamples: false, cancellation).Info;
		}

		private static DecodedTrack DecodeInternal(string path, bool retainSamples, CancellationToken cancellation)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			if (new FileInfo(path).Length > 67108864)
			{
				throw new InvalidDataException("Encoded file exceeds 64 MiB limit.");
			}
			byte[] array = File.ReadAllBytes(path);
			cancellation.ThrowIfCancellationRequested();
			using MemoryStream memoryStream = new MemoryStream(array, writable: false);
			int rate;
			int num;
			float[] array3;
			BinaryReader reader;
			if (Path.GetExtension(path).Equals(".mp3", StringComparison.OrdinalIgnoreCase))
			{
				MpegFile val = new MpegFile((Stream)memoryStream);
				try
				{
					rate = val.SampleRate;
					int channels = val.Channels;
					ValidateFormat(channels, rate);
					float[] array2 = new float[4096 * channels];
					List<float> list = (retainSamples ? new List<float>() : null);
					num = 0;
					int num2;
					while ((num2 = val.ReadSamples(array2, 0, array2.Length)) > 0)
					{
						cancellation.ThrowIfCancellationRequested();
						if (num2 % channels != 0)
						{
							throw new InvalidDataException("Incomplete MP3 sample frame.");
						}
						num += num2 / channels;
						if (num > 16000000)
						{
							throw new InvalidDataException("Decoded track exceeds memory limit.");
						}
						for (int i = 0; i < num2; i += channels)
						{
							float num3 = ((channels == 1) ? array2[i] : ((array2[i] + array2[i + 1]) * 0.5f));
							if (!float.IsFinite(num3))
							{
								throw new InvalidDataException("Invalid MP3 sample.");
							}
							list?.Add(Math.Clamp(num3, -1f, 1f));
						}
					}
					array3 = list?.ToArray() ?? Array.Empty<float>();
				}
				finally
				{
					((IDisposable)val)?.Dispose();
				}
			}
			else
			{
				reader = new BinaryReader(memoryStream, Encoding.ASCII, leaveOpen: true);
				try
				{
					if (Four() != "RIFF")
					{
						throw new InvalidDataException("Expected RIFF.");
					}
					reader.ReadUInt32();
					if (Four() != "WAVE")
					{
						throw new InvalidDataException("Expected WAVE.");
					}
					int num4 = 0;
					int num5 = 0;
					int num6 = 0;
					rate = 0;
					long num7 = -1L;
					uint num8 = 0u;
					while (memoryStream.Position + 8 <= memoryStream.Length)
					{
						string text = Four();
						uint num9 = reader.ReadUInt32();
						long position = memoryStream.Position;
						long num10 = position + num9 + (num9 & 1);
						if (num10 > memoryStream.Length)
						{
							throw new InvalidDataException("Truncated WAV chunk.");
						}
						if (text == "fmt ")
						{
							if (num9 < 16)
							{
								throw new InvalidDataException("Short WAV fmt chunk.");
							}
							num6 = reader.ReadUInt16();
							num4 = reader.ReadUInt16();
							rate = reader.ReadInt32();
							reader.ReadUInt32();
							reader.ReadUInt16();
							num5 = reader.ReadUInt16();
						}
						else if (text == "data")
						{
							num7 = position;
							num8 = num9;
						}
						memoryStream.Position = num10;
					}
					ValidateFormat(num4, rate);
					if (num6 != 1 || num5 != 16 || num7 < 0 || num8 % (num4 * 2) != 0L)
					{
						throw new InvalidDataException("Expected complete 16-bit PCM WAV frames.");
					}
					int num11;
					checked
					{
						num11 = (int)unchecked(num8 / checked(num4 * 2));
						num = num11;
						if (num11 > 16000000)
						{
							throw new InvalidDataException("Decoded track exceeds memory limit.");
						}
						array3 = (retainSamples ? new float[num11] : Array.Empty<float>());
						memoryStream.Position = num7;
					}
					for (int j = 0; j < num11; j++)
					{
						if (j % 4096 == 0)
						{
							cancellation.ThrowIfCancellationRequested();
						}
						float num12 = (float)reader.ReadInt16() / 32768f;
						if (num4 == 2)
						{
							num12 = (num12 + (float)reader.ReadInt16() / 32768f) * 0.5f;
						}
						if (retainSamples)
						{
							array3[j] = num12;
						}
					}
				}
				finally
				{
					if (reader != null)
					{
						((IDisposable)reader).Dispose();
					}
				}
			}
			if (num == 0)
			{
				throw new InvalidDataException("Empty audio track.");
			}
			int num13 = 0;
			for (int k = 1; k < array3.Length; k++)
			{
				if (Math.Abs(array3[k]) > Math.Abs(array3[num13]))
				{
					num13 = k;
				}
			}
			return new DecodedTrack(new TrackInfo(Path.GetFileName(path), Convert.ToHexString(SHA256.HashData(array)), num, rate), array3, num13);
			string Four()
			{
				return Encoding.ASCII.GetString(reader.ReadBytes(4));
			}
		}

		private static void ValidateFormat(int channels, int rate)
		{
			if (channels < 1 || channels > 2 || rate < 8000 || rate > 96000)
			{
				throw new InvalidDataException("Supported audio: mono/stereo, 8–96 kHz.");
			}
		}
	}
	public static class AudioPathResolver
	{
		public static string Resolve(string configuredPath, string assemblyLocation, string fallbackDirectory)
		{
			if (string.IsNullOrWhiteSpace(configuredPath))
			{
				throw new ArgumentException("Audio path cannot be empty.", "configuredPath");
			}
			if (Path.IsPathRooted(configuredPath))
			{
				return Path.GetFullPath(configuredPath);
			}
			string text = (string.IsNullOrWhiteSpace(assemblyLocation) ? null : Path.GetDirectoryName(Path.GetFullPath(assemblyLocation)));
			return Path.GetFullPath(Path.Combine(string.IsNullOrWhiteSpace(text) ? Path.GetFullPath(fallbackDirectory) : text, configuredPath));
		}
	}
	public static class DistanceGain
	{
		public static float Evaluate(float distance, float radius)
		{
			if (!float.IsFinite(distance) || !float.IsFinite(radius) || radius <= 0f)
			{
				return 0f;
			}
			return Math.Clamp(1f - Math.Max(0f, distance) / radius, 0f, 1f);
		}
	}
	public sealed record TrackInfo(string Name, string ContentHash, int Frames, int Rate)
	{
		public double Duration => (double)Frames / (double)Rate;
	}
	public sealed class Playlist
	{
		private readonly TrackInfo[] _tracks;

		private readonly int[] _order;

		public ulong Fingerprint { get; }

		public double Duration { get; }

		public IReadOnlyList<int> Order => Array.AsReadOnly(_order);

		public Playlist(IEnumerable<TrackInfo> tracks, uint seed)
		{
			_tracks = tracks.ToArray();
			if (_tracks.Length == 0 || _tracks.Any((TrackInfo t) => t.Frames <= 0 || t.Rate <= 0))
			{
				throw new ArgumentException("Playlist requires valid tracks.");
			}
			string s = string.Join("\n", _tracks.Select((TrackInfo t) => $"{t.Name.ToLowerInvariant()}|{t.ContentHash}|{t.Frames}|{t.Rate}"));
			Fingerprint = BinaryPrimitives.ReadUInt64LittleEndian(SHA256.HashData(Encoding.UTF8.GetBytes(s)));
			Duration = _tracks.Sum((TrackInfo t) => t.Duration);
			_order = Enumerable.Range(0, _tracks.Length).ToArray();
			uint state = ((seed == 0) ? 2654435769u : seed);
			for (int num = _order.Length - 1; num > 0; num--)
			{
				uint num2 = (uint)(num + 1);
				uint num3 = (0 - num2) % num2;
				uint num4;
				do
				{
					num4 = Next();
				}
				while (num4 < num3);
				int num5 = (int)(num4 % num2);
				ref int reference = ref _order[num];
				ref int reference2 = ref _order[num5];
				int num6 = _order[num5];
				int num7 = _order[num];
				reference = num6;
				reference2 = num7;
			}
			uint Next()
			{
				state ^= state << 13;
				state ^= state >> 17;
				state ^= state << 5;
				return state;
			}
		}

		public (int Index, double Position) Locate(double elapsed)
		{
			if (!double.IsFinite(elapsed) || elapsed < 0.0)
			{
				throw new ArgumentOutOfRangeException("elapsed");
			}
			double num = elapsed % Duration;
			int[] order = _order;
			foreach (int num2 in order)
			{
				if (num < _tracks[num2].Duration)
				{
					return (Index: num2, Position: num);
				}
				num -= _tracks[num2].Duration;
			}
			return (Index: _order[0], Position: 0.0);
		}

		public int NextIndex(int index)
		{
			int num = Array.IndexOf(_order, index);
			if (num < 0)
			{
				throw new ArgumentOutOfRangeException("index");
			}
			return _order[(num + 1) % _order.Length];
		}
	}
	public sealed class SessionTimeline
	{
		private double _anchorClock;

		private double _anchorPosition;

		public bool IsPlaying { get; private set; }

		public long Revision { get; private set; }

		public void Play(double clock, double positionSeconds = 0.0)
		{
			ValidateClock(clock);
			ValidatePosition(positionSeconds);
			_anchorClock = clock;
			_anchorPosition = positionSeconds;
			IsPlaying = true;
			Revision++;
		}

		public void Pause(double clock, double durationSeconds)
		{
			if (IsPlaying)
			{
				_anchorPosition = GetPosition(clock, durationSeconds);
				_anchorClock = clock;
				IsPlaying = false;
				Revision++;
			}
		}

		public void Resume(double clock)
		{
			ValidateClock(clock);
			if (!IsPlaying)
			{
				_anchorClock = clock;
				IsPlaying = true;
				Revision++;
			}
		}

		public void Seek(double clock, double positionSeconds)
		{
			ValidateClock(clock);
			ValidatePosition(positionSeconds);
			_anchorClock = clock;
			_anchorPosition = positionSeconds;
			Revision++;
		}

		public double GetPosition(double clock, double durationSeconds)
		{
			ValidateClock(clock);
			if (!double.IsFinite(durationSeconds) || durationSeconds <= 0.0)
			{
				return 0.0;
			}
			double val = (IsPlaying ? (clock - _anchorClock) : 0.0);
			double num = (_anchorPosition + Math.Max(0.0, val)) % durationSeconds;
			if (!(num < 0.0))
			{
				return num;
			}
			return num + durationSeconds;
		}

		private static void ValidateClock(double value)
		{
			if (!double.IsFinite(value) || value < 0.0)
			{
				throw new ArgumentOutOfRangeException("value", "Clock must be finite and non-negative.");
			}
		}

		private static void ValidatePosition(double value)
		{
			if (!double.IsFinite(value) || value < 0.0)
			{
				throw new ArgumentOutOfRangeException("value", "Position must be finite and non-negative.");
			}
		}
	}
	public static class SyncRules
	{
		public static bool AcceptEnvelope(ulong sender, ulong master, int protocol, ulong session, double elapsed, ulong sequence, ulong currentSession, ulong lastSequence)
		{
			if (master != 0L && sender == master && protocol == 2 && session != 0L && double.IsFinite(elapsed) && elapsed >= 0.0 && elapsed <= 2592000.0)
			{
				if (session == currentSession)
				{
					return sequence > lastSequence;
				}
				return true;
			}
			return false;
		}
	}
}

plugins/SentrySound/SentrySound.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using GTFO.API;
using HarmonyLib;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using SentrySound.Core;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("SentrySound")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SentrySound")]
[assembly: AssemblyTitle("SentrySound")]
[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 SentrySound
{
	internal sealed class AudioLibrary : IDisposable
	{
		private readonly CancellationTokenSource _cancel = new CancellationTokenSource();

		private readonly ManualLogSource _log;

		private readonly string _folder;

		private readonly Task<TrackInfo[]> _indexWorker;

		private readonly Dictionary<int, AudioClip> _clips = new Dictionary<int, AudioClip>();

		private readonly HashSet<int> _failed = new HashSet<int>();

		private readonly HashSet<int> _wanted = new HashSet<int>();

		private Task<DecodedTrack>? _decoder;

		private DecodedTrack? _pending;

		private AudioClip? _upload;

		private Il2CppStructArray<float>? _buffer;

		private int _decodeIndex = -1;

		private int _offset;

		private int _probeIndex;

		private float _probeValue;

		private bool _disposed;

		private int _wantedCurrent = -2;

		private int _wantedNext = -2;

		public List<TrackInfo> Tracks { get; } = new List<TrackInfo>();

		public bool Ready { get; private set; }

		public AudioLibrary(string folder, ManualLogSource log)
		{
			AudioLibrary audioLibrary = this;
			_folder = folder;
			_log = log;
			_indexWorker = Task.Run(delegate
			{
				//IL_0118: Unknown result type (might be due to invalid IL or missing references)
				//IL_011f: Expected O, but got Unknown
				//IL_0082: Unknown result type (might be due to invalid IL or missing references)
				//IL_0089: Expected O, but got Unknown
				List<TrackInfo> list = new List<TrackInfo>();
				string[] array = AudioDecoder.Discover(folder);
				if (array.Length > 256)
				{
					throw new InvalidDataException("Maximum 256 tracks per library.");
				}
				string[] array2 = array;
				bool flag = default(bool);
				foreach (string text in array2)
				{
					audioLibrary._cancel.Token.ThrowIfCancellationRequested();
					try
					{
						Stopwatch stopwatch = Stopwatch.StartNew();
						TrackInfo val = AudioDecoder.Inspect(text, audioLibrary._cancel.Token);
						list.Add(val);
						ManualLogSource log2 = audioLibrary._log;
						BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(23, 3, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Indexed ");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(val.Name);
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": ");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<double>(val.Duration, "0.00");
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("s; workerMs=");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<double>(stopwatch.Elapsed.TotalMilliseconds, "0.0");
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(".");
						}
						log2.LogInfo(val2);
					}
					catch (OperationCanceledException)
					{
						throw;
					}
					catch (Exception ex2)
					{
						ManualLogSource log3 = audioLibrary._log;
						BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(10, 2, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Skipped ");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(Path.GetFileName(text));
							((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(": ");
							((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex2.Message);
						}
						log3.LogError(val3);
					}
				}
				return list.ToArray();
			});
		}

		public AudioClip? GetClip(int index)
		{
			if (!_clips.TryGetValue(index, out AudioClip value))
			{
				return null;
			}
			return value;
		}

		public void EnsureTracks(int current, int next)
		{
			if (_disposed || !Ready)
			{
				return;
			}
			if (_wantedCurrent != current || _wantedNext != next)
			{
				_wantedCurrent = current;
				_wantedNext = next;
				_wanted.Clear();
				if (current >= 0)
				{
					_wanted.Add(current);
				}
				if (next >= 0)
				{
					_wanted.Add(next);
				}
				int[] array = _clips.Keys.Where((int i) => !_wanted.Contains(i)).ToArray();
				foreach (int key in array)
				{
					Object.Destroy((Object)(object)_clips[key]);
					_clips.Remove(key);
				}
			}
			if (_pending != (DecodedTrack)null && !_wanted.Contains(_decodeIndex))
			{
				DiscardUpload();
			}
			if (_decoder != null || _pending != (DecodedTrack)null)
			{
				return;
			}
			for (int num2 = 0; num2 < 2; num2++)
			{
				int num3 = ((num2 == 0) ? current : next);
				if (num3 < 0 || _clips.ContainsKey(num3) || _failed.Contains(num3))
				{
					continue;
				}
				TrackInfo expected = Tracks[num3];
				_decodeIndex = num3;
				_decoder = Task.Run(delegate
				{
					DecodedTrack obj = AudioDecoder.Decode(Path.Combine(_folder, expected.Name), _cancel.Token);
					if (obj.Info != expected)
					{
						throw new InvalidDataException("Audio changed after indexing. Restart the game on all clients.");
					}
					return obj;
				});
				break;
			}
		}

		public void Tick()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			if (_disposed)
			{
				return;
			}
			bool flag = default(bool);
			if (!Ready)
			{
				if (!_indexWorker.IsCompleted)
				{
					return;
				}
				try
				{
					Tracks.AddRange(_indexWorker.GetAwaiter().GetResult());
				}
				catch (Exception ex)
				{
					ManualLogSource log = _log;
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(22, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Audio catalog failed: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
					}
					log.LogError(val);
				}
				Ready = true;
				ManualLogSource log2 = _log;
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(64, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Audio library ready: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(Tracks.Count);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" tracks; two-track cache; total duration=");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<double>(Tracks.Sum((TrackInfo t) => t.Duration), "0.0");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("s.");
				}
				log2.LogInfo(val2);
			}
			Task<DecodedTrack>? decoder = _decoder;
			if (decoder != null && decoder.IsCompleted)
			{
				try
				{
					DecodedTrack result = _decoder.GetAwaiter().GetResult();
					if (_wanted.Contains(_decodeIndex))
					{
						_pending = result;
					}
					else
					{
						_decodeIndex = -1;
					}
				}
				catch (Exception ex2)
				{
					_failed.Add(_decodeIndex);
					ManualLogSource log3 = _log;
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(32, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Audio decode failed for index ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_decodeIndex);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex2);
					}
					log3.LogError(val);
					_decodeIndex = -1;
				}
				_decoder = null;
			}
			Stopwatch stopwatch = Stopwatch.StartNew();
			for (int num = 0; num < 16; num++)
			{
				if (!(stopwatch.Elapsed.TotalMilliseconds < 2.0))
				{
					break;
				}
				if (!(_pending != (DecodedTrack)null))
				{
					break;
				}
				UploadSlice();
			}
		}

		private void UploadSlice()
		{
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Expected O, but got Unknown
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: Expected O, but got Unknown
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Expected O, but got Unknown
			Stopwatch stopwatch = Stopwatch.StartNew();
			bool flag = default(bool);
			try
			{
				if ((Object)(object)_upload == (Object)null)
				{
					_upload = AudioClip.Create(_pending.Info.Name, _pending.Info.Frames, 1, _pending.Info.Rate, false);
					((Object)_upload).hideFlags = (HideFlags)32;
					_offset = 0;
					_probeIndex = _pending.PeakIndex;
					_probeValue = _pending.Samples[_probeIndex];
					return;
				}
				int num = Math.Min(32768, _pending.Samples.Length - _offset);
				if (_buffer == null)
				{
					_buffer = new Il2CppStructArray<float>(32768L);
				}
				Marshal.Copy(_pending.Samples, _offset, IntPtr.Add(((Il2CppObjectBase)_buffer).Pointer, 4 * IntPtr.Size), num);
				if (((Il2CppArrayBase<float>)(object)_buffer)[0] != _pending.Samples[_offset] || ((Il2CppArrayBase<float>)(object)_buffer)[num - 1] != _pending.Samples[_offset + num - 1])
				{
					throw new InvalidOperationException("Native PCM buffer copy failed.");
				}
				if (!AudioClip.SetData(_upload, _buffer, num, _offset))
				{
					throw new InvalidOperationException("PCM upload rejected.");
				}
				_offset += num;
				if (_offset >= _pending.Samples.Length)
				{
					Il2CppStructArray<float> val = new Il2CppStructArray<float>(1L);
					if (!_upload.GetData(val, _probeIndex) || Math.Abs(((Il2CppArrayBase<float>)(object)val)[0] - _probeValue) > 0.0001f)
					{
						throw new InvalidOperationException("PCM upload read-back mismatch.");
					}
					_clips.Add(_decodeIndex, _upload);
					ManualLogSource log = _log;
					BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(45, 3, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("PCM transfer verified: ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(_pending.Info.Name);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; cachedClips=");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(_clips.Count);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; peak=");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(Math.Abs(_probeValue), "0.000000");
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(".");
					}
					log.LogInfo(val2);
					_pending = null;
					_upload = null;
					_decodeIndex = -1;
				}
			}
			catch (Exception ex)
			{
				_failed.Add(_decodeIndex);
				ManualLogSource log2 = _log;
				BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(21, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Track upload failed: ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex);
				}
				log2.LogError(val3);
				DiscardUpload();
			}
			finally
			{
				if (stopwatch.Elapsed.TotalMilliseconds > 15.0)
				{
					ManualLogSource log3 = _log;
					BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(36, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("Performance: audio upload slice ");
						((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<double>(stopwatch.Elapsed.TotalMilliseconds, "0.0");
						((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" ms.");
					}
					log3.LogWarning(val4);
				}
			}
		}

		private void DiscardUpload()
		{
			if ((Object)(object)_upload != (Object)null)
			{
				Object.Destroy((Object)(object)_upload);
			}
			_upload = null;
			_pending = null;
			_decodeIndex = -1;
		}

		public void Dispose()
		{
			if (_disposed)
			{
				return;
			}
			_disposed = true;
			_cancel.Cancel();
			DiscardUpload();
			foreach (AudioClip value in _clips.Values)
			{
				if ((Object)(object)value != (Object)null)
				{
					Object.Destroy((Object)(object)value);
				}
			}
			_clips.Clear();
			Task.WhenAll((_decoder != null) ? new Task[2] { _indexWorker, _decoder } : new Task[1] { _indexWorker }).ContinueWith(delegate(Task task)
			{
				_ = task.Exception;
				_cancel.Dispose();
			}, TaskScheduler.Default);
		}
	}
	internal static class AudioSignalDiagnostics
	{
		public static string Levels(Il2CppStructArray<float> data)
		{
			double num = 0.0;
			double num2 = 0.0;
			int num3 = 0;
			for (int i = 0; i < ((Il2CppArrayBase<float>)(object)data).Length; i++)
			{
				float num4 = ((Il2CppArrayBase<float>)(object)data)[i];
				if (!float.IsFinite(num4))
				{
					num3++;
					continue;
				}
				num2 = Math.Max(num2, Math.Abs(num4));
				num += (double)num4 * (double)num4;
			}
			return FormattableString.Invariant($"peak={num2:0.000000}; rms={Math.Sqrt(num / (double)Math.Max(1, ((Il2CppArrayBase<float>)(object)data).Length)):0.000000}; invalid={num3}");
		}

		public static void Clip(ManualLogSource? log, AudioClip clip, string phase)
		{
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			bool flag = default(bool);
			try
			{
				Stopwatch stopwatch = Stopwatch.StartNew();
				int num = Math.Min(256, clip.samples);
				Il2CppStructArray<float> val = new Il2CppStructArray<float>((long)(num * clip.channels));
				double num2 = 0.0;
				double num3 = 0.0;
				long num4 = 0L;
				for (int i = 0; i < 3; i++)
				{
					int num5 = (int)((long)(clip.samples - num) * (long)i / 2);
					if (!clip.GetData(val, num5))
					{
						ManualLogSource val2 = log;
						if (val2 != null)
						{
							BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(48, 2, ref flag);
							if (flag)
							{
								((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Signal PCM [");
								((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(phase);
								((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("]: GetData returned false at frame ");
								((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(num5);
								((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(".");
							}
							val2.LogWarning(val3);
						}
						return;
					}
					int length = ((Il2CppArrayBase<float>)(object)val).Length;
					for (int j = 0; j < length; j++)
					{
						float num6 = ((Il2CppArrayBase<float>)(object)val)[j];
						if (!float.IsFinite(num6))
						{
							throw new InvalidDataException("Non-finite PCM sample.");
						}
						num2 = Math.Max(num2, Math.Abs(num6));
						num3 += (double)num6 * (double)num6;
						num4++;
					}
				}
				if (log != null)
				{
					log.LogInfo((object)FormattableString.Invariant($"Signal PCM windows [{phase}]: sampledValues={num4}; peak={num2:0.000000}; rms={Math.Sqrt(num3 / (double)Math.Max(1L, num4)):0.000000}; elapsedMs={stopwatch.Elapsed.TotalMilliseconds:0.00}. Quiet windows alone do not imply a silent track."));
				}
			}
			catch (Exception ex)
			{
				ManualLogSource val2 = log;
				if (val2 != null)
				{
					BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(27, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Signal PCM [");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(phase);
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("] unavailable: ");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex);
					}
					val2.LogWarning(val3);
				}
			}
		}

		public static void Output(ManualLogSource? log, AudioSource? source, string label)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			bool flag = default(bool);
			try
			{
				Il2CppStructArray<float> val = new Il2CppStructArray<float>(1024L);
				if ((Object)(object)source != (Object)null)
				{
					source.GetOutputData(val, 0);
				}
				else
				{
					AudioListener.GetOutputData(val, 0);
				}
				ManualLogSource val2 = log;
				if (val2 != null)
				{
					BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(30, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Signal output [");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(label);
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("; channel=0]: ");
						((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(Levels(val));
						((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(".");
					}
					val2.LogInfo(val3);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource val2 = log;
				if (val2 != null)
				{
					BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(30, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("Signal output [");
						((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(label);
						((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("] unavailable: ");
						((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<Exception>(ex);
					}
					val2.LogWarning(val4);
				}
			}
		}
	}
	internal sealed class LocalAudioListener : IDisposable
	{
		private readonly ManualLogSource _log;

		private GameObject? _holder;

		private AudioListener? _owned;

		private AudioListener? _active;

		private float _nextScan;

		private int _lastListenerId;

		public AudioListener? Active => _active;

		public LocalAudioListener(ManualLogSource log)
		{
			_log = log;
		}

		public void Refresh(bool hasSpeakers, bool forceScan = false)
		{
			//IL_0096: 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_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Expected O, but got Unknown
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Expected O, but got Unknown
			if (!hasSpeakers || !PlayerManager.HasLocalPlayerAgent())
			{
				if ((Object)(object)_owned != (Object)null)
				{
					((Behaviour)_owned).enabled = false;
				}
				_active = null;
				return;
			}
			PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent();
			LocalPlayerAgent val = ((localPlayerAgent != null) ? ((Il2CppObjectBase)localPlayerAgent).TryCast<LocalPlayerAgent>() : null);
			FPSCamera val2 = (((Object)(object)val != (Object)null) ? ((PlayerAgent)val).FPSCamera : null);
			if ((Object)(object)val2 == (Object)null)
			{
				if ((Object)(object)_owned != (Object)null)
				{
					((Behaviour)_owned).enabled = false;
				}
				_active = null;
				return;
			}
			if ((Object)(object)_holder != (Object)null)
			{
				_holder.transform.position = val2.Position;
				_holder.transform.rotation = val2.Rotation;
			}
			if (!forceScan && (Object)(object)_active != (Object)null && ((Behaviour)_active).isActiveAndEnabled && ((Object)(object)_active != (Object)(object)_owned || Time.unscaledTime < _nextScan))
			{
				return;
			}
			_nextScan = Time.unscaledTime + 1f;
			AudioListener val3 = null;
			foreach (AudioListener item in Object.FindObjectsOfType<AudioListener>())
			{
				if ((Object)(object)item != (Object)null && (Object)(object)item != (Object)(object)_owned && ((Behaviour)item).isActiveAndEnabled)
				{
					val3 = item;
					break;
				}
			}
			if ((Object)(object)val3 != (Object)null)
			{
				if ((Object)(object)_owned != (Object)null)
				{
					((Behaviour)_owned).enabled = false;
				}
				_active = val3;
			}
			else
			{
				if ((Object)(object)_owned == (Object)null)
				{
					_holder = new GameObject("SentrySound.LocalListener");
					((Object)_holder).hideFlags = (HideFlags)61;
					_holder.transform.position = val2.Position;
					_holder.transform.rotation = val2.Rotation;
					Object.DontDestroyOnLoad((Object)(object)_holder);
					_owned = _holder.AddComponent<AudioListener>();
					_log.LogInfo((object)"No active Unity AudioListener found. Created listener following the local player's camera.");
				}
				((Behaviour)_owned).enabled = true;
				_active = _owned;
			}
			int instanceID = ((Object)_active).GetInstanceID();
			if (instanceID != _lastListenerId)
			{
				_lastListenerId = instanceID;
				ManualLogSource log = _log;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(43, 4, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("Audio listener: ");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(((Object)((Component)_active).gameObject).name);
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("; owned=");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<bool>((Object)(object)_active == (Object)(object)_owned);
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("; volume=");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<float>(AudioListener.volume, "0.00");
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("; paused=");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<bool>(AudioListener.pause);
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(".");
				}
				log.LogInfo(val4);
			}
		}

		public void Dispose()
		{
			if ((Object)(object)_owned != (Object)null)
			{
				((Behaviour)_owned).enabled = false;
			}
			if ((Object)(object)_holder != (Object)null)
			{
				Object.Destroy((Object)(object)_holder);
			}
			_owned = null;
			_holder = null;
			_active = null;
		}
	}
	[BepInPlugin("dev.lucas.sentrysound", "SentinelaFuracao", "1.0.0")]
	[BepInProcess("GTFO.exe")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BasePlugin
	{
		private Harmony? _harmony;

		private SentryAudioHost? _host;

		internal static ManualLogSource? DiagnosticLog { get; private set; }

		public override void Load()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			DiagnosticLog = ((BasePlugin)this).Log;
			SentrySoundSettings settings = SentrySoundSettings.Bind(((BasePlugin)this).Config);
			_host = ((BasePlugin)this).AddComponent<SentryAudioHost>();
			_host.Initialize(settings, ((BasePlugin)this).Log);
			ManualLogSource log = ((BasePlugin)this).Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(66, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Audio host attached to BepInEx manager; flags=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<HideFlags>(((Object)((Component)_host).gameObject).hideFlags);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; active=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(((Component)_host).gameObject.activeInHierarchy);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; enabled=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(((Behaviour)_host).enabled);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
			}
			log.LogInfo(val);
			_harmony = new Harmony("dev.lucas.sentrysound");
			_harmony.PatchAll(typeof(Plugin).Assembly);
			ManualLogSource log2 = ((BasePlugin)this).Log;
			val = new BepInExInfoLogInterpolatedStringHandler(31, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("SentinelaFuracao");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.0.0");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded. Waiting for sentries.");
			}
			log2.LogInfo(val);
		}

		public override bool Unload()
		{
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			if ((Object)(object)_host != (Object)null)
			{
				_host.Shutdown();
				Object.Destroy((Object)(object)_host);
				_host = null;
			}
			return true;
		}
	}
	internal static class PluginInfo
	{
		public const string Guid = "dev.lucas.sentrysound";

		public const string Name = "SentinelaFuracao";

		public const string FolderName = "SentrySound";

		public const string Version = "1.0.0";
	}
	internal sealed class SentryAudioHost : MonoBehaviour
	{
		private sealed class Speaker
		{
			public GameObject Target { get; }

			public AudioSource Source { get; }

			public float CameraDistance { get; set; } = -1f;

			public Speaker(GameObject target, AudioSource source)
			{
				Target = target;
				Source = source;
			}
		}

		private readonly Dictionary<int, Speaker> _speakers = new Dictionary<int, Speaker>();

		private AudioLibrary? _library;

		private SessionSync? _sync;

		private bool _libraryRegistered;

		private int _trackIndex = -1;

		private double _trackPosition;

		private float _nextDriftCheck;

		private double _lastFrameStart;

		private double _lastUpdateMs;

		private double _lastLateUpdateMs;

		private double _nextGapLog;

		private SentrySoundSettings? _settings;

		private ManualLogSource? _log;

		private AudioClip? _clip;

		private LocalAudioListener? _listener;

		private float _nextDiagnostic;

		private int _diagnosticsRemaining;

		private double _previousDspTime;

		private bool _updateErrorReported;

		private bool _updateLoopReported;

		private bool _shutdown;

		private VolumePanel? _panel;

		private bool _panelErrorReported;

		public static SentryAudioHost? Instance { get; private set; }

		public SentryAudioHost(IntPtr pointer)
			: base(pointer)
		{
		}

		[HideFromIl2Cpp]
		public void Initialize(SentrySoundSettings settings, ManualLogSource log)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			Instance = this;
			_settings = settings;
			_panel = new VolumePanel(settings);
			_log = log;
			_listener = new LocalAudioListener(log);
			if (!settings.Enabled.Value)
			{
				log.LogInfo((object)"Audio is disabled in configuration.");
				return;
			}
			_sync = new SessionSync(log);
			string text = ResolveAudioPath(settings.AudioFolder.Value);
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(28, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Audio folder resolved to '");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'.");
			}
			log.LogInfo(val);
			_library = new AudioLibrary(text, log);
			log.LogInfo((object)"Preparing MP3/WAV playlist asynchronously; sentry audio waits until the library and host session are ready.");
		}

		[HideFromIl2Cpp]
		public void Attach(GameObject sentry)
		{
			//IL_005f: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Expected O, but got Unknown
			if (_settings == null || !_settings.Enabled.Value || (Object)(object)sentry == (Object)null)
			{
				return;
			}
			int instanceID = ((Object)sentry).GetInstanceID();
			if (_speakers.ContainsKey(instanceID))
			{
				return;
			}
			GameObject val = new GameObject($"SentrySound.Speaker.{instanceID}")
			{
				hideFlags = (HideFlags)61
			};
			val.transform.SetParent(((Component)this).transform, false);
			AudioSource val2 = val.AddComponent<AudioSource>();
			val2.playOnAwake = false;
			val2.loop = false;
			val2.spatialBlend = 1f;
			val2.rolloffMode = (AudioRolloffMode)1;
			val2.dopplerLevel = 0f;
			val2.minDistance = 2f;
			val2.maxDistance = 3f;
			val2.volume = 0f;
			_speakers.Add(instanceID, new Speaker(sentry, val2));
			_listener?.Refresh(hasSpeakers: true, forceScan: true);
			RefreshSpatialSpeakers();
			StartSpeaker(val2);
			_diagnosticsRemaining = 2;
			_nextDiagnostic = Time.unscaledTime + 1f;
			_previousDspTime = AudioSettings.dspTime;
			ManualLogSource log = _log;
			if (log != null)
			{
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(39, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Attached positional speaker to sentry ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(instanceID);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(".");
				}
				log.LogInfo(val3);
			}
		}

		[HideFromIl2Cpp]
		public void Detach(GameObject sentry)
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			if ((Object)(object)sentry == (Object)null)
			{
				return;
			}
			int instanceID = ((Object)sentry).GetInstanceID();
			if (!_speakers.Remove(instanceID, out Speaker value))
			{
				return;
			}
			_panel?.CloseForTarget(sentry);
			if ((Object)(object)value.Source != (Object)null)
			{
				value.Source.Stop();
				Object.Destroy((Object)(object)((Component)value.Source).gameObject);
			}
			if (_speakers.Count == 0)
			{
				_listener?.Refresh(hasSpeakers: false);
			}
			ManualLogSource log = _log;
			if (log != null)
			{
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(40, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Removed positional speaker from sentry ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(instanceID);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
				}
				log.LogInfo(val);
			}
		}

		[HideFromIl2Cpp]
		public void Shutdown()
		{
			if (_shutdown)
			{
				return;
			}
			_shutdown = true;
			_panel?.Shutdown();
			foreach (Speaker value in _speakers.Values)
			{
				if ((Object)(object)value.Source != (Object)null)
				{
					value.Source.Stop();
					Object.Destroy((Object)(object)((Component)value.Source).gameObject);
				}
			}
			_speakers.Clear();
			_listener?.Dispose();
			_listener = null;
			_sync?.Dispose();
			_library?.Dispose();
			_clip = null;
			if (Instance == this)
			{
				Instance = null;
			}
		}

		private void Update()
		{
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Expected O, but got Unknown
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Expected O, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			if (_shutdown || _settings == null)
			{
				return;
			}
			Stopwatch stopwatch = Stopwatch.StartNew();
			double num = (double)Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;
			bool flag = default(bool);
			if (_lastFrameStart > 0.0 && num - _lastFrameStart > 0.25 && num >= _nextGapLog)
			{
				_nextGapLog = num + 2.0;
				ManualLogSource log = _log;
				if (log != null)
				{
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(107, 4, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Frame gap=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<double>((num - _lastFrameStart) * 1000.0, "0");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ms; previous SentrySound Update=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<double>(_lastUpdateMs, "0.00");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ms; LateUpdate=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<double>(_lastLateUpdateMs, "0.00");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ms; state=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<eGameStateName>(GameStateManager.CurrentStateName);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". Gap alone does not identify the cause.");
					}
					log.LogWarning(val);
				}
			}
			_lastFrameStart = num;
			try
			{
				if (!_updateLoopReported)
				{
					_updateLoopReported = true;
					ManualLogSource? log2 = _log;
					if (log2 != null)
					{
						log2.LogInfo((object)"Audio host update loop active. Deploy a sentry to start positional playback.");
					}
				}
				_library?.Tick();
				if (!_libraryRegistered)
				{
					AudioLibrary? library = _library;
					if (library != null && library.Ready)
					{
						_sync?.SetLibrary(_library.Tracks);
						_libraryRegistered = true;
					}
				}
				_sync?.Tick();
				RefreshPlaylist();
				_panel?.Tick(FindPanelTarget);
				RemoveDestroyedSentries();
				LogPlaybackDiagnostics();
			}
			catch (Exception ex)
			{
				_panel?.Close();
				if (!_updateErrorReported)
				{
					ManualLogSource log = _log;
					if (log != null)
					{
						BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(21, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Audio update failed: ");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
						}
						log.LogError(val2);
					}
				}
				_updateErrorReported = true;
			}
			finally
			{
				_lastUpdateMs = stopwatch.Elapsed.TotalMilliseconds;
				if (_lastUpdateMs > 15.0)
				{
					ManualLogSource log = _log;
					if (log != null)
					{
						BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(35, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Performance: SentrySound Update=");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<double>(_lastUpdateMs, "0.00");
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ms.");
						}
						log.LogWarning(val);
					}
				}
			}
		}

		private void LateUpdate()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Expected O, but got Unknown
			if (_shutdown)
			{
				return;
			}
			Stopwatch stopwatch = Stopwatch.StartNew();
			bool flag = default(bool);
			try
			{
				_listener?.Refresh(_speakers.Count > 0);
				RefreshSpatialSpeakers();
			}
			catch (Exception ex)
			{
				if (!_updateErrorReported)
				{
					ManualLogSource log = _log;
					if (log != null)
					{
						BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(30, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Audio listener update failed: ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
						}
						log.LogError(val);
					}
				}
				_updateErrorReported = true;
			}
			finally
			{
				_lastLateUpdateMs = stopwatch.Elapsed.TotalMilliseconds;
				if (_lastLateUpdateMs > 15.0)
				{
					ManualLogSource log = _log;
					if (log != null)
					{
						BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(39, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Performance: SentrySound LateUpdate=");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<double>(_lastLateUpdateMs, "0.00");
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("ms.");
						}
						log.LogWarning(val2);
					}
				}
			}
		}

		private void OnDestroy()
		{
			if (!_shutdown)
			{
				ManualLogSource? log = _log;
				if (log != null)
				{
					log.LogWarning((object)"Audio host destroyed unexpectedly. Automatic speaker updates are no longer available on this host.");
				}
			}
			Shutdown();
		}

		private void OnGUI()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			if (_shutdown || _panelErrorReported)
			{
				return;
			}
			try
			{
				_panel?.Draw();
			}
			catch (Exception ex)
			{
				_panelErrorReported = true;
				_panel?.Close();
				ManualLogSource log = _log;
				if (log != null)
				{
					bool flag = default(bool);
					BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(31, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Volume panel rendering failed: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
					}
					log.LogError(val);
				}
			}
		}

		private GameObject? FindPanelTarget()
		{
			//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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			if (_panelErrorReported || !PlayerManager.HasLocalPlayerAgent())
			{
				return null;
			}
			PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent();
			LocalPlayerAgent val = ((localPlayerAgent != null) ? ((Il2CppObjectBase)localPlayerAgent).TryCast<LocalPlayerAgent>() : null);
			FPSCamera val2 = (((Object)(object)val != (Object)null) ? ((PlayerAgent)val).FPSCamera : null);
			if ((Object)(object)val2 == (Object)null)
			{
				return null;
			}
			GameObject result = null;
			float num = 0.8f;
			Vector3 val3 = val2.Rotation * Vector3.forward;
			foreach (Speaker value in _speakers.Values)
			{
				if ((Object)(object)value.Target == (Object)null)
				{
					continue;
				}
				Vector3 val4 = value.Target.transform.position - val2.Position;
				if (!(((Vector3)(ref val4)).magnitude > 4f))
				{
					float num2 = Vector3.Dot(val3, ((Vector3)(ref val4)).normalized);
					if (!(num2 <= num))
					{
						result = value.Target;
						num = num2;
					}
				}
			}
			return result;
		}

		private void RefreshPlaylist()
		{
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Expected O, but got Unknown
			if (_sync?.Playlist == null || _library == null)
			{
				_library?.EnsureTracks(-1, -1);
				if (_trackIndex < 0)
				{
					return;
				}
				foreach (Speaker value in _speakers.Values)
				{
					if ((Object)(object)value.Source != (Object)null)
					{
						value.Source.Stop();
					}
				}
				_trackIndex = -1;
				_clip = null;
				_panel?.Close();
				return;
			}
			(int, double) tuple = _sync.Playlist.Locate(_sync.Elapsed);
			_library.EnsureTracks(tuple.Item1, _sync.Playlist.NextIndex(tuple.Item1));
			_trackPosition = tuple.Item2;
			AudioClip clip = _library.GetClip(tuple.Item1);
			if ((Object)(object)clip == (Object)null)
			{
				if (_trackIndex >= 0)
				{
					foreach (Speaker value2 in _speakers.Values)
					{
						if ((Object)(object)value2.Source != (Object)null)
						{
							value2.Source.Stop();
						}
					}
				}
				_trackIndex = -1;
				_clip = null;
				return;
			}
			bool flag = _trackIndex != tuple.Item1 || (Object)(object)_clip != (Object)(object)clip;
			if (flag)
			{
				_trackIndex = tuple.Item1;
				_clip = clip;
				ManualLogSource log = _log;
				if (log != null)
				{
					bool flag2 = default(bool);
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(24, 2, ref flag2);
					if (flag2)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Now playing: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(_library.Tracks[_trackIndex].Name);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; offset=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<double>(_trackPosition, "0.000");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("s.");
					}
					log.LogInfo(val);
				}
			}
			bool flag3 = Time.unscaledTime >= _nextDriftCheck;
			if (flag3)
			{
				_nextDriftCheck = Time.unscaledTime + 2f;
			}
			foreach (Speaker value3 in _speakers.Values)
			{
				AudioSource source = value3.Source;
				if (!((Object)(object)source == (Object)null) && (flag || !source.isPlaying || (flag3 && (Object)(object)_clip != (Object)null && Math.Abs((double)source.timeSamples / (double)_clip.frequency - _trackPosition) > 0.2)))
				{
					StartSpeaker(source);
				}
			}
		}

		private void StartSpeaker(AudioSource source)
		{
			if (!((Object)(object)_clip == (Object)null) && !((Object)(object)source == (Object)null))
			{
				source.clip = _clip;
				int timeSamples = Math.Clamp((int)Math.Floor(_trackPosition * (double)_clip.frequency), 0, Math.Max(0, _clip.samples - 1));
				source.timeSamples = timeSamples;
				source.Play();
			}
		}

		private void LogPlaybackDiagnostics()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_01ca: 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_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Expected O, but got Unknown
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			if (_diagnosticsRemaining <= 0 || Time.unscaledTime < _nextDiagnostic)
			{
				return;
			}
			_diagnosticsRemaining--;
			_nextDiagnostic = Time.unscaledTime + 2f;
			AudioListener val = _listener?.Active;
			double dspTime = AudioSettings.dspTime;
			ManualLogSource log = _log;
			bool flag = default(bool);
			if (log != null)
			{
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(94, 6, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Audio diagnostics: listener=");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)(object)val != (Object)null) ? ((Object)((Component)val).gameObject).name : "NONE");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; listenerVolume=");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(AudioListener.volume, "0.00");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; paused=");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<bool>(AudioListener.pause);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; dspAdvance=");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<double>(dspTime - _previousDspTime, "0.000");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("s; outputRate=");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(AudioSettings.outputSampleRate);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; clipAlive=");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<bool>((Object)(object)_clip != (Object)null);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(".");
				}
				log.LogInfo(val2);
			}
			_previousDspTime = dspTime;
			AudioSignalDiagnostics.Output(_log, null, "Unity listener master");
			foreach (KeyValuePair<int, Speaker> speaker in _speakers)
			{
				AudioSource source = speaker.Value.Source;
				if ((Object)(object)source == (Object)null)
				{
					continue;
				}
				AudioSignalDiagnostics.Output(_log, source, $"sentry {speaker.Key}");
				float num = (((Object)(object)val != (Object)null) ? Vector3.Distance(((Component)source).transform.position, ((Component)val).transform.position) : (-1f));
				log = _log;
				if (log != null)
				{
					BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(99, 9, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Speaker ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(speaker.Key);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": playing=");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<bool>(source.isPlaying);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; active=");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<bool>(((Behaviour)source).isActiveAndEnabled);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; sample=");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(source.timeSamples);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; volume=");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(source.volume, "0.00");
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; mute=");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<bool>(source.mute);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; cameraDistance=");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(speaker.Value.CameraDistance, "0.0");
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("m; mappedDistance=");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(num, "0.0");
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("m; rolloff=");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<AudioRolloffMode>(source.rolloffMode);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(".");
					}
					log.LogInfo(val2);
				}
			}
		}

		private void RemoveDestroyedSentries()
		{
			if (_speakers.Count == 0)
			{
				return;
			}
			List<int> list = null;
			foreach (KeyValuePair<int, Speaker> speaker in _speakers)
			{
				if (!((Object)(object)speaker.Value.Target != (Object)null) || !((Object)(object)speaker.Value.Source != (Object)null))
				{
					if (list == null)
					{
						list = new List<int>();
					}
					list.Add(speaker.Key);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (int item in list)
			{
				AudioSource source = _speakers[item].Source;
				if ((Object)(object)source != (Object)null)
				{
					source.Stop();
					Object.Destroy((Object)(object)((Component)source).gameObject);
				}
				_speakers.Remove(item);
			}
		}

		private void RefreshSpatialSpeakers()
		{
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: 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_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: 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_0111: 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_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			if (_settings == null || _speakers.Count == 0)
			{
				return;
			}
			float value = _settings.Volume.Value;
			AudioListener val = _listener?.Active;
			object obj;
			if (!PlayerManager.HasLocalPlayerAgent())
			{
				obj = null;
			}
			else
			{
				PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent();
				obj = ((localPlayerAgent != null) ? ((Il2CppObjectBase)localPlayerAgent).TryCast<LocalPlayerAgent>() : null);
			}
			LocalPlayerAgent val2 = (LocalPlayerAgent)obj;
			FPSCamera val3 = (((Object)(object)val2 != (Object)null) ? ((PlayerAgent)val2).FPSCamera : null);
			foreach (Speaker value2 in _speakers.Values)
			{
				AudioSource source = value2.Source;
				if (!((Object)(object)source == (Object)null))
				{
					if ((Object)(object)value2.Target == (Object)null || (Object)(object)val3 == (Object)null || (Object)(object)val == (Object)null || !((Behaviour)val).isActiveAndEnabled)
					{
						source.volume = 0f;
						value2.CameraDistance = -1f;
						continue;
					}
					Vector3 val4 = Quaternion.Inverse(val3.Rotation) * (value2.Target.transform.position - val3.Position);
					Transform transform = ((Component)val).transform;
					((Component)source).transform.position = transform.position + transform.rotation * ((Vector3)(ref val4)).normalized;
					value2.CameraDistance = ((Vector3)(ref val4)).magnitude;
					source.volume = value * DistanceGain.Evaluate(value2.CameraDistance, _settings.MaximumDistance.Value);
				}
			}
		}

		private static string ResolveAudioPath(string configuredPath)
		{
			return AudioPathResolver.Resolve(configuredPath, typeof(Plugin).Assembly.Location, Path.Combine(Paths.PluginPath, "SentrySound"));
		}
	}
	[HarmonyPatch(typeof(SentryGunInstance), "OnGearSpawnComplete")]
	internal static class SentryDeployedPatch
	{
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void Postfix(SentryGunInstance __instance)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			ManualLogSource diagnosticLog = Plugin.DiagnosticLog;
			if (diagnosticLog != null)
			{
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(52, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Sentry spawn callback received; audioHostAvailable=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>((Object)(object)SentryAudioHost.Instance != (Object)null);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
				}
				diagnosticLog.LogInfo(val);
			}
			SentryAudioHost.Instance?.Attach(((Component)__instance).gameObject);
		}
	}
	[HarmonyPatch(typeof(SentryGunInstance), "SyncedPickup")]
	internal static class SentryPickedUpPatch
	{
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static void Prefix(SentryGunInstance __instance)
		{
			SentryAudioHost.Instance?.Detach(((Component)__instance).gameObject);
		}
	}
	internal sealed class SentrySoundSettings
	{
		private readonly ConfigFile _config;

		public ConfigEntry<bool> Enabled { get; }

		public ConfigEntry<string> AudioFolder { get; }

		public ConfigEntry<float> Volume { get; }

		public ConfigEntry<float> MaximumDistance { get; }

		public ConfigEntry<KeyCode> PanelKey { get; }

		private SentrySoundSettings(ConfigFile config)
		{
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Expected O, but got Unknown
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Expected O, but got Unknown
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Expected O, but got Unknown
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Expected O, but got Unknown
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Expected O, but got Unknown
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Expected O, but got Unknown
			_config = config;
			config.SaveOnConfigSet = false;
			float value = config.Bind<float>("Audio", "MasterVolume", 0.18f, (ConfigDescription)null).Value;
			float value2 = config.Bind<float>("Audio", "PersonalVolume", 1f, (ConfigDescription)null).Value;
			config.Bind<float>("Spatial", "MinimumDistance", 2f, (ConfigDescription)null);
			Enabled = config.Bind<bool>("General", "Enabled", true, "Play music from deployed sentries.");
			string value3 = config.Bind<string>("Audio", "File", "test-tone.wav", (ConfigDescription)null).Value;
			AudioFolder = config.Bind<string>("Audio", "Folder", Path.IsPathRooted(value3) ? Path.GetDirectoryName(value3) : Path.Combine("audio", Path.GetDirectoryName(value3) ?? ""), "Folder containing MP3 and 16-bit PCM WAV tracks. Relative to the folder containing SentrySound.dll, or absolute. Restart after changes.");
			Volume = config.Bind<float>("Audio", "Volume", Mathf.Clamp01(value * value2), new ConfigDescription("Local volume only. Never synchronized with other players.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			MaximumDistance = config.Bind<float>("Spatial", "MaximumDistance", 28f, new ConfigDescription("Fade from the sentry center to silence at this distance in metres.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 200f), Array.Empty<object>()));
			PanelKey = config.Bind<KeyCode>("Controls", "PanelKey", (KeyCode)121, "Open Volume while looking at a nearby sentry.");
			config.Remove(new ConfigDefinition("Audio", "MasterVolume"));
			config.Remove(new ConfigDefinition("Audio", "PersonalVolume"));
			config.Remove(new ConfigDefinition("Spatial", "MinimumDistance"));
			config.Remove(new ConfigDefinition("Audio", "File"));
			config.Save();
		}

		public void Save()
		{
			_config.Save();
		}

		public static SentrySoundSettings Bind(ConfigFile config)
		{
			return new SentrySoundSettings(config);
		}
	}
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	internal struct SyncRequest
	{
		public ulong Nonce;
	}
	[StructLayout(LayoutKind.Sequential, Pack = 1)]
	internal struct SyncSnapshot
	{
		public int Protocol;

		public ulong Session;

		public ulong Catalog;

		public ulong Sequence;

		public ulong Echo;

		public uint Seed;

		public double Elapsed;
	}
	internal sealed class SessionSync : IDisposable
	{
		private const string RequestEvent = "SentrySound.v2.request";

		private const string SnapshotEvent = "SentrySound.v2.snapshot";

		private static SessionSync? _active;

		private static bool _eventsRegistered;

		private readonly ConcurrentQueue<(ulong Sender, SyncSnapshot Snapshot)> _snapshots = new ConcurrentQueue<(ulong, SyncSnapshot)>();

		private readonly ConcurrentQueue<(ulong Sender, SyncRequest Request)> _requests = new ConcurrentQueue<(ulong, SyncRequest)>();

		private readonly Dictionary<ulong, double> _responseTimes = new Dictionary<ulong, double>();

		private readonly ManualLogSource _log;

		private TrackInfo[]? _tracks;

		private ulong _catalog;

		private ulong _session;

		private ulong _master;

		private ulong _sequence;

		private ulong _lastSequence;

		private ulong _nonce;

		private uint _seed;

		private double _anchor;

		private double _elapsed;

		private double _nextRequest;

		private double _requestTime;

		private bool _inLevel;

		private bool _mismatchReported;

		public Playlist? Playlist { get; private set; }

		public double Elapsed => _elapsed + Math.Max(0.0, Now - _anchor);

		private static double Now => (double)Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency;

		public SessionSync(ManualLogSource log)
		{
			_log = log;
			_active = this;
			if (_eventsRegistered)
			{
				return;
			}
			NetworkAPI.RegisterEvent<SyncRequest>("SentrySound.v2.request", (Action<ulong, SyncRequest>)delegate(ulong sender, SyncRequest payload)
			{
				SessionSync active = _active;
				if (active != null && active._requests.Count < 32)
				{
					active._requests.Enqueue((sender, payload));
				}
			});
			NetworkAPI.RegisterEvent<SyncSnapshot>("SentrySound.v2.snapshot", (Action<ulong, SyncSnapshot>)delegate(ulong sender, SyncSnapshot payload)
			{
				SessionSync active = _active;
				if (active != null && active._snapshots.Count < 32)
				{
					active._snapshots.Enqueue((sender, payload));
				}
			});
			_eventsRegistered = true;
		}

		public void SetLibrary(IEnumerable<TrackInfo> tracks)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			_tracks = tracks.ToArray();
			if (_tracks.Length != 0)
			{
				_catalog = new Playlist((IEnumerable<TrackInfo>)_tracks, 1u).Fingerprint;
			}
		}

		public void Tick()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_0009: Invalid comparison between Unknown and I4
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Invalid comparison between Unknown and I4
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Expected O, but got Unknown
			//IL_0401: Unknown result type (might be due to invalid IL or missing references)
			//IL_040b: Expected O, but got Unknown
			eGameStateName currentStateName = GameStateManager.CurrentStateName;
			bool flag = (int)currentStateName == 10;
			if (!flag && (int)currentStateName != 13)
			{
				if (_inLevel)
				{
					Reset();
				}
				_requests.Clear();
				_snapshots.Clear();
			}
			else
			{
				if (!flag)
				{
					return;
				}
				_inLevel = true;
				if (_tracks == null || _tracks.Length == 0 || !SNet.HasMaster)
				{
					_requests.Clear();
					_snapshots.Clear();
					return;
				}
				ulong lookup = SNet.Master.Lookup;
				if (_master != lookup)
				{
					_master = lookup;
					_lastSequence = 0uL;
					_nextRequest = 0.0;
					_responseTimes.Clear();
					ManualLogSource log = _log;
					bool flag2 = default(bool);
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(34, 2, ref flag2);
					if (flag2)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Session authority: ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<ulong>(lookup);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; localMaster=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(SNet.IsMaster);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
					}
					log.LogInfo(val);
				}
				if (SNet.IsMaster)
				{
					if (Playlist == null)
					{
						_seed = BitConverter.ToUInt32(RandomNumberGenerator.GetBytes(4));
						_session = BitConverter.ToUInt64(RandomNumberGenerator.GetBytes(8));
						if (_session == 0L)
						{
							_session = 1uL;
						}
						_anchor = Now;
						_elapsed = 0.0;
						Playlist = new Playlist((IEnumerable<TrackInfo>)_tracks, _seed);
						LogOrder("New expedition");
					}
					(ulong, SyncRequest) result;
					SNet_Player val2 = default(SNet_Player);
					while (_requests.TryDequeue(out result))
					{
						if ((!_responseTimes.TryGetValue(result.Item1, out var value) || !(Now - value < 1.0)) && SNet.TryGetPlayer(result.Item1, ref val2) && !val2.IsLocal)
						{
							_responseTimes[result.Item1] = Now;
							NetworkAPI.InvokeEvent<SyncSnapshot>("SentrySound.v2.snapshot", Snapshot(result.Item2.Nonce), val2, (SNet_ChannelType)2);
						}
					}
					_snapshots.Clear();
					return;
				}
				_requests.Clear();
				if (Now >= _nextRequest)
				{
					_nextRequest = Now + 3.0;
					_nonce++;
					_requestTime = Now;
					NetworkAPI.InvokeEvent<SyncRequest>("SentrySound.v2.request", new SyncRequest
					{
						Nonce = _nonce
					}, SNet.Master, (SNet_ChannelType)2);
				}
				(ulong, SyncSnapshot) result2;
				while (_snapshots.TryDequeue(out result2))
				{
					SyncSnapshot item = result2.Item2;
					if (item.Echo == 0L || item.Echo != _nonce || Now - _requestTime > 2.0 || !SyncRules.AcceptEnvelope(result2.Item1, lookup, item.Protocol, item.Session, item.Elapsed, item.Sequence, _session, _lastSequence))
					{
						continue;
					}
					if (item.Catalog != _catalog)
					{
						Playlist = null;
						if (!_mismatchReported)
						{
							_log.LogError((object)"Playlist mismatch with host. Use identical MP3/WAV files and names on every client. Sentry music muted.");
						}
						_mismatchReported = true;
						continue;
					}
					double num = (Now - _requestTime) / 2.0;
					bool num2 = Playlist == null || _session != item.Session || _seed != item.Seed;
					_lastSequence = item.Sequence;
					_session = item.Session;
					_seed = item.Seed;
					double num3 = item.Elapsed + num;
					if (num2 || Math.Abs(Elapsed - num3) > 0.08)
					{
						_elapsed = num3;
						_anchor = Now;
					}
					if (num2)
					{
						Playlist = new Playlist((IEnumerable<TrackInfo>)_tracks, _seed);
						LogOrder("Synchronized expedition");
					}
					_mismatchReported = false;
				}
			}
		}

		private SyncSnapshot Snapshot(ulong echo)
		{
			return new SyncSnapshot
			{
				Protocol = 2,
				Session = _session,
				Seed = _seed,
				Catalog = _catalog,
				Sequence = ++_sequence,
				Echo = echo,
				Elapsed = Elapsed
			};
		}

		private void LogOrder(string label)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			ManualLogSource log = _log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(36, 5, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(label);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": session=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<ulong>(_session);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; seed=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<uint>(_seed);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; catalog=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<ulong>(_catalog, "X16");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; order=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(string.Join(" -> ", Playlist.Order.Select((int i) => _tracks[i].Name)));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
			}
			log.LogInfo(val);
		}

		private void Reset()
		{
			_inLevel = false;
			Playlist = null;
			_session = (_master = (_lastSequence = 0uL));
			_nextRequest = 0.0;
			_mismatchReported = false;
			_responseTimes.Clear();
			_log.LogInfo((object)"Expedition playlist reset.");
		}

		public void Dispose()
		{
			if (_active == this)
			{
				_active = null;
			}
			Reset();
		}
	}
	internal sealed class VolumePanel
	{
		private readonly SentrySoundSettings _settings;

		private GameObject? _target;

		private CursorLockMode _previousLock;

		private bool _previousVisible;

		private bool _dirty;

		private static int _blockThroughFrame = -1;

		private static bool _waitingForRelease;

		public static bool IsOpen { get; private set; }

		public static bool BlocksInput
		{
			get
			{
				if (!IsOpen && !_waitingForRelease)
				{
					return Time.frameCount <= _blockThroughFrame;
				}
				return true;
			}
		}

		public VolumePanel(SentrySoundSettings settings)
		{
			_settings = settings;
		}

		public void Tick(Func<GameObject?> findTarget)
		{
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Invalid comparison between Unknown and I4
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Invalid comparison between Unknown and I4
			//IL_0090: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			if (!IsOpen && _waitingForRelease && !Input.GetMouseButton(0) && !Input.GetMouseButton(1))
			{
				_waitingForRelease = false;
				_blockThroughFrame = Time.frameCount + 1;
			}
			if (IsOpen)
			{
				object obj;
				if (!PlayerManager.HasLocalPlayerAgent())
				{
					obj = null;
				}
				else
				{
					PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent();
					obj = ((localPlayerAgent != null) ? ((Il2CppObjectBase)localPlayerAgent).TryCast<LocalPlayerAgent>() : null);
				}
				LocalPlayerAgent val = (LocalPlayerAgent)obj;
				FPSCamera val2 = (((Object)(object)val != (Object)null) ? ((PlayerAgent)val).FPSCamera : null);
				if ((Object)(object)_target == (Object)null || (Object)(object)val2 == (Object)null || !Application.isFocused || (int)FocusStateManager.CurrentState != 4 || Vector3.Distance(val2.Position, _target.transform.position) > 5f || Input.GetKeyDown(_settings.PanelKey.Value) || Input.GetKeyDown((KeyCode)27))
				{
					Close();
				}
				else
				{
					UnlockCursor();
				}
			}
			else
			{
				if (!_settings.Enabled.Value || !Application.isFocused || (int)FocusStateManager.CurrentState != 4 || !Input.GetKeyDown(_settings.PanelKey.Value))
				{
					return;
				}
				_target = findTarget();
				if (!((Object)(object)_target == (Object)null))
				{
					_previousLock = Cursor.lockState;
					_previousVisible = Cursor.visible;
					IsOpen = true;
					UnlockCursor();
					ManualLogSource? diagnosticLog = Plugin.DiagnosticLog;
					if (diagnosticLog != null)
					{
						diagnosticLog.LogInfo((object)"Local Volume panel opened.");
					}
				}
			}
		}

		public static void UnlockCursor()
		{
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
		}

		public void Close()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			if (!IsOpen)
			{
				return;
			}
			IsOpen = false;
			_target = null;
			_waitingForRelease = true;
			_blockThroughFrame = Time.frameCount + 1;
			if ((int)FocusStateManager.CurrentState == 4)
			{
				Cursor.lockState = _previousLock;
				Cursor.visible = _previousVisible;
			}
			bool flag = default(bool);
			ManualLogSource diagnosticLog;
			if (_dirty)
			{
				try
				{
					_settings.Save();
					_dirty = false;
				}
				catch (Exception ex)
				{
					diagnosticLog = Plugin.DiagnosticLog;
					if (diagnosticLog != null)
					{
						BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(29, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Could not save local Volume: ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
						}
						diagnosticLog.LogError(val);
					}
				}
			}
			diagnosticLog = Plugin.DiagnosticLog;
			if (diagnosticLog != null)
			{
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(35, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Local Volume panel closed; volume=");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(_settings.Volume.Value, "0.00");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(".");
				}
				diagnosticLog.LogInfo(val2);
			}
		}

		public void CloseForTarget(GameObject target)
		{
			if (IsOpen && (Object)(object)_target == (Object)(object)target)
			{
				Close();
			}
		}

		public void Shutdown()
		{
			Close();
			_waitingForRelease = false;
			_blockThroughFrame = -1;
		}

		public void Draw()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			if (IsOpen)
			{
				float num = Math.Min(380f, (float)Screen.width - 20f);
				float num2 = ((float)Screen.width - num) / 2f;
				float num3 = ((float)Screen.height - 190f) / 2f;
				GUI.Box(new Rect(num2, num3, num, 190f), "SentinelaFuracao");
				GUI.Label(new Rect(num2 + 24f, num3 + 34f, num - 48f, 26f), $"Volume  {Mathf.RoundToInt(_settings.Volume.Value * 100f)}%");
				float num4 = GUI.HorizontalSlider(new Rect(num2 + 24f, num3 + 72f, num - 48f, 24f), _settings.Volume.Value, 0f, 1f);
				if (Math.Abs(num4 - _settings.Volume.Value) > 0.0001f)
				{
					_settings.Volume.Value = Mathf.Clamp01(num4);
					_dirty = true;
				}
				GUI.Label(new Rect(num2 + 24f, num3 + 101f, num - 48f, 25f), "Altera somente o som para você.");
				if (GUI.Button(new Rect(num2 + num - 124f, num3 + 140f, 100f, 28f), "Fechar"))
				{
					Close();
				}
			}
		}
	}
	[HarmonyPatch(typeof(InputMapper), "FocusStateFilterPass")]
	internal static class VolumePanelInputPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(ref bool __result)
		{
			if (!VolumePanel.BlocksInput)
			{
				return true;
			}
			__result = false;
			return false;
		}
	}
	[HarmonyPatch(typeof(InputMapper), "get_PlayerHasFocus")]
	internal static class VolumePanelFocusPatch
	{
		[HarmonyPostfix]
		private static void Postfix(ref bool __result)
		{
			if (VolumePanel.BlocksInput)
			{
				__result = false;
			}
		}
	}
	[HarmonyPatch(typeof(InputMapper), "CheckLockMouse")]
	internal static class VolumePanelCursorPatch
	{
		[HarmonyPrefix]
		private static bool Prefix()
		{
			if (!VolumePanel.IsOpen)
			{
				return true;
			}
			VolumePanel.UnlockCursor();
			return false;
		}
	}
}