Decompiled source of Custom Menu v0.4.4
BepInEx/patchers/SlipSkid.CustomMenu.AudioBootstrap.dll
Decompiled 18 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx.Preloader.Core.Patching; using Microsoft.CodeAnalysis; using Mono.Cecil; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SlipSkid.CustomMenu.AudioBootstrap")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SlipSkid.CustomMenu.AudioBootstrap")] [assembly: AssemblyTitle("SlipSkid.CustomMenu.AudioBootstrap")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SlipSkid.CustomMenu.AudioBootstrap { [PatcherPluginInfo("slipskid.custommenu.audio", "Slip & Skid Custom Menu Audio Bootstrap", "0.1.0")] public sealed class CustomMenuAudioPatcher : BasePatcher { [TargetType("UnityEngine.AudioModule.dll", "UnityEngine.AudioClip")] public bool RestoreAudioClip(TypeDefinition clip) { return RestoreClipBindings(clip); } [TargetType("UnityEngine.AudioModule.dll", "UnityEngine.AudioSource")] public bool RestoreAudioSource(TypeDefinition source) { return RestoreSourceBindings(source); } public static bool RestoreSourceBindings(TypeDefinition source) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown if (((IEnumerable<MethodDefinition>)source.Methods).Any((MethodDefinition m) => ((MemberReference)m).Name == "UnPause" && !m.IsStatic && ((MethodReference)m).Parameters.Count == 0)) { return false; } source.Methods.Add(new MethodDefinition("UnPause", (MethodAttributes)134, ((MemberReference)source).Module.TypeSystem.Void) { ImplAttributes = ((IEnumerable<MethodDefinition>)source.Methods).First((MethodDefinition m) => ((MemberReference)m).Name == "Pause").ImplAttributes }); return true; } public static bool RestoreClipBindings(TypeDefinition clip) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown TypeSystem typeSystem = ((MemberReference)clip).Module.TypeSystem; return (byte)(0u | (Add(clip, "Construct_Internal", true, (TypeReference)(object)clip) ? 1u : 0u) | (Add(clip, "CreateUserSound", false, typeSystem.Void, typeSystem.String, typeSystem.Int32, typeSystem.Int32, typeSystem.Int32, typeSystem.Boolean) ? 1u : 0u) | (Add(clip, "SetData", true, typeSystem.Boolean, (TypeReference)clip, (TypeReference)new ArrayType(typeSystem.Single), typeSystem.Int32, typeSystem.Int32) ? 1u : 0u)) != 0; } private static bool Add(TypeDefinition type, string name, bool isStatic, TypeReference result, params TypeReference[] parameters) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown if (((IEnumerable<MethodDefinition>)type.Methods).Any((MethodDefinition m) => ((MemberReference)m).Name == name && m.IsStatic == isStatic && ((IEnumerable<ParameterDefinition>)((MethodReference)m).Parameters).Select((ParameterDefinition p) => ((MemberReference)((ParameterReference)p).ParameterType).FullName).SequenceEqual(parameters.Select((TypeReference p) => ((MemberReference)p).FullName)))) { return false; } MethodDefinition val = new MethodDefinition(name, (MethodAttributes)(1 | (isStatic ? 16 : 0) | 0x80), result) { ImplAttributes = ((IEnumerable<MethodDefinition>)type.Methods).First((MethodDefinition m) => ((MemberReference)m).Name == "GetName").ImplAttributes }; for (int num = 0; num < parameters.Length; num++) { ((MethodReference)val).Parameters.Add(new ParameterDefinition("arg" + num, (ParameterAttributes)0, parameters[num])); } type.Methods.Add(val); return true; } } }
BepInEx/plugins/SlipSkid.CustomMenu/NLayer.dll
Decompiled 18 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; 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: AssemblyCopyright("© Mark Heath 2026")] [assembly: AssemblyDescription("Fully Managed MPEG 1 & 2 Decoder for Layers 1, 2, & 3")] [assembly: AssemblyFileVersion("3.0.0.0")] [assembly: AssemblyInformationalVersion("3.0.0+046c7ce422970f8f0f0bc205d6c6341bcb7debf1")] [assembly: AssemblyProduct("NLayer")] [assembly: AssemblyTitle("NLayer")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/naudio/NLayer")] [assembly: AssemblyVersion("3.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace 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 int _encoderDelay; private int _encoderPadding; private bool _decoderDelaySkipped; private float[] _readBuf = new float[2304]; private int _readBufLen; private int _readBufOfs; public int SampleRate => _reader.SampleRate; public int Channels => OutputChannels; private int OutputChannels { get { if (StereoMode != StereoMode.Both) { return 1; } return _reader.Channels; } } public bool CanSeek => _reader.CanSeek; public long Length { get { long sampleCount = _reader.SampleCount; if (sampleCount < 0) { return -1L; } return (sampleCount - _encoderDelay - _encoderPadding) * OutputChannels * 4; } } public TimeSpan Duration { get { long sampleCount = _reader.SampleCount; if (sampleCount == -1) { return TimeSpan.Zero; } return TimeSpan.FromSeconds((double)(sampleCount - _encoderDelay - _encoderPadding) / (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 / OutputChannels; 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 * OutputChannels; _eofFound = false; _decoderDelaySkipped = num3 > 0 || _encoderDelay == 0; _readBufOfs = (_readBufLen = 0); } } } public TimeSpan Time { get { return TimeSpan.FromSeconds((double)_position / 4.0 / (double)OutputChannels / (double)_reader.SampleRate); } set { Position = (long)(value.TotalSeconds * (double)_reader.SampleRate * (double)OutputChannels * 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(); _encoderDelay = _reader.EncoderDelay; _encoderPadding = _reader.EncoderPadding; } 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 long GetTotalBytes() { long sampleCount = _reader.SampleCount; if (sampleCount < 0) { return long.MaxValue; } return (sampleCount - _encoderDelay - _encoderPadding) * OutputChannels * 4; } private bool TryFillReadBuffer() { while (true) { if (_eofFound) { return false; } MpegFrame mpegFrame = _reader.NextFrame(); if (mpegFrame == null) { _eofFound = true; return false; } try { _readBufLen = _decoder.DecodeFrame(mpegFrame, _readBuf, 0) * 4; _readBufOfs = 0; if (!_decoderDelaySkipped) { int num = _encoderDelay * OutputChannels * 4; if (num > 0 && num <= _readBufLen) { _readBufOfs = num; } _decoderDelaySkipped = true; if (_readBufOfs >= _readBufLen) { _readBufLen = (_readBufOfs = 0); } } } catch (InvalidDataException) { _decoder.Reset(); _readBufOfs = (_readBufLen = 0); continue; } catch (EndOfStreamException) { _eofFound = true; return false; } finally { mpegFrame.ClearBuffer(); } break; } return true; } private int AvailableBytes(long totalBytes, int count) { if (_readBufLen <= _readBufOfs) { return 0; } int num = _readBufLen - _readBufOfs; if (num > count) { num = count; } long num2 = totalBytes - _position; if (num > num2) { num = (int)num2; } return num; } private void AdvanceReadBuffer(int temp) { _position += temp; _readBufOfs += temp; if (_readBufOfs == _readBufLen) { _readBufLen = 0; } } private int ReadSamplesImpl(Array buffer, int index, int count, int bitDepth) { int num = 0; long totalBytes = GetTotalBytes(); lock (_seekLock) { while (count > 0) { if (_position >= totalBytes) { _eofFound = true; break; } int num2 = AvailableBytes(totalBytes, count); if (num2 > 0) { if (bitDepth == 32) { Buffer.BlockCopy(_readBuf, _readBufOfs, buffer, index, num2); } else { byte[] array = (byte[])buffer; int num3 = _readBufOfs / 4; int num4 = index / 4; int num5 = num2 / 4; if (bitDepth == 8) { for (int i = 0; i < num5; i++) { array[num4 + i] = (byte)Math.Round(127.5f * _readBuf[num3 + i] + 127.5f); } } else { for (int j = 0; j < num5; j++) { int num6 = (int)Math.Round(32767.5f * _readBuf[num3 + j] - 0.5f); if (num6 < 0) { num6 += 65536; } array[2 * (num4 + j)] = (byte)(num6 % 256); array[2 * (num4 + j) + 1] = (byte)(num6 / 256); } } } num += num2; count -= num2; index += num2; AdvanceReadBuffer(num2); } if (_readBufLen == 0 && !TryFillReadBuffer()) { break; } } } 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 < RequiredSampleCount(frame)) { 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 < RequiredSampleCount(frame)) { 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 DecodeToChannels(IMpegFrame frame) { 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) { return 0; } layerDecoderBase.SetEQ(_eqFactors); layerDecoderBase.StereoMode = StereoMode; return layerDecoderBase.DecodeFrame(frame, _ch0, _ch1); } private bool IsSingleChannel(IMpegFrame frame) { if (frame.ChannelMode != MpegChannelMode.Mono) { return StereoMode != StereoMode.Both; } return true; } private int DecodeFrameImpl(IMpegFrame frame, Array dest, int destOffset) { int num = DecodeToChannels(frame); if (num > 0) { if (IsSingleChannel(frame)) { Buffer.BlockCopy(_ch0, 0, dest, destOffset * 4, num * 4); } else if (dest is float[] array) { for (int i = 0; i < num; i++) { array[destOffset++] = _ch0[i]; array[destOffset++] = _ch1[i]; } num *= 2; } else { for (int j = 0; j < num; j++) { Buffer.BlockCopy(_ch0, j * 4, dest, destOffset * 4, 4); destOffset++; Buffer.BlockCopy(_ch1, j * 4, dest, destOffset * 4, 4); destOffset++; } num *= 2; } return num; } return 0; } private static int RequiredSampleCount(IMpegFrame frame) { return ((frame.ChannelMode == MpegChannelMode.Mono) ? 1 : 2) * frame.SampleCount; } 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 & 8) != 0) { if (br.Get1Bit() == 1) { v = 0f - _floatLookup[1]; } else { v = _floatLookup[1]; } } if ((num & 4) != 0) { if (br.Get1Bit() == 1) { w = 0f - _floatLookup[1]; } else { w = _floatLookup[1]; } } if ((num & 2) != 0) { if (br.Get1Bit() == 1) { x = 0f - _floatLookup[1]; } else { x = _floatLookup[1]; } } if ((num & 1) != 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 i = 0; i < array.Length; i++) { int num = maxBits - lengthList[i]; array[i] = new HuffmanListNode { Value = values[i], Length = lengthList[i], Bits = codeList[i] << num, Mask = (1 << lengthList[i]) - 1 << num }; } Array.Sort(array, (HuffmanListNode huffmanListNode, HuffmanListNode huffmanListNode2) => huffmanListNode.Length - huffmanListNode2.Length); for (int num2 = 1; num2 < array.Length && array[num2].Length < 99999; num2++) { array[num2 - 1].Next = array[num2]; } return array[0]; } } internal class ID3Frame : FrameBase { private int _version; private int _encoderDelay = -1; private int _encoderPadding = -1; private bool _v2Parsed; internal int EncoderDelay { get { if (_encoderDelay >= 0) { return _encoderDelay; } return 0; } } internal int EncoderPadding { get { if (_encoderPadding >= 0) { return _encoderPadding; } return 0; } } 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() { _v2Parsed = true; _encoderDelay = 0; _encoderPadding = 0; byte[] array = new byte[7]; if (Read(3, array) != 7) { return; } int num = array[0]; if (num != 3 && num != 4) { return; } int num2 = (array[3] << 21) | (array[4] << 14) | (array[5] << 7) | array[6]; int i = 10; int num3; for (byte[] array2 = new byte[10]; i < num2 + 10 && Read(i, array2, 0, 10) >= 10; i += 10 + num3) { if (array2[0] == 0) { break; } num3 = ((num != 4) ? ((array2[4] << 24) | (array2[5] << 16) | (array2[6] << 8) | array2[7]) : ((array2[4] << 21) | (array2[5] << 14) | (array2[6] << 7) | array2[7])); if (num3 <= 0) { break; } if (array2[0] == 84 && array2[1] == 88 && array2[2] == 88 && array2[3] == 88 && num3 < 4096) { byte[] array3 = new byte[num3]; if (Read(i + 10, array3, 0, num3) == num3) { TryParseITunSMPB(array3, num3); } } if (_encoderDelay > 0 || _encoderPadding > 0) { break; } } } private void TryParseITunSMPB(byte[] data, int length) { if (length < 2) { return; } int num = data[0]; string text; try { text = ((num == 1 || num == 2) ? Encoding.Unicode : Encoding.UTF8).GetString(data, 1, length - 1); } catch { return; } if (text.Length > 0 && text[0] == '\ufeff') { text = text.Substring(1); } int num2 = text.IndexOf('\0'); if (num2 >= 0 && !(text.Substring(0, num2) != "iTunSMPB")) { string text2 = text.Substring(num2 + 1).Trim(new char[1]); if (text2.Length > 0 && text2[0] == '\ufeff') { text2 = text2.Substring(1); } string[] array = text2.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (array.Length >= 3 && int.TryParse(array[1], NumberStyles.HexNumber, null, out var result) && int.TryParse(array[2], NumberStyles.HexNumber, null, out var result2)) { _encoderDelay = result; _encoderPadding = result2; } } } internal void ParseEagerIfNeeded() { if (_version == 2 && !_v2Parsed) { 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, 7 }, 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, -10 } }; 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 float[][] _chanBufs = new float[2][]; 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 - 2) + 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[][] chanBufs = _chanBufs; int num = 0; int num2 = _channels - 1; if (_channels == 1 || base.StereoMode == StereoMode.LeftOnly) { chanBufs[0] = ch0; num2 = 0; } else if (base.StereoMode == StereoMode.RightOnly) { chanBufs[1] = ch0; num = 1; } else { chanBufs[0] = ch0; chanBufs[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[] array; float[] array2; if (num5 < 0) { num5 = -num5 / 2 + -num5 % 2 - 1; array = _groupedC; array2 = _groupedD; } else { array = _C; array2 = _D; } _polyPhaseBuf[num4] = array[num5] * ((float)(_samples[i][num3] << 16 - num5) / 32768f + array2[num5]) * _denormalMultiplier[_scalefac[i][j][num4]]; } else { _polyPhaseBuf[num4] = 0f; } num4++; num3++; } InversePolyPhase(i, _polyPhaseBuf); Array.Copy(_polyPhaseBuf, 0, chanBufs[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 float[] _longImdct_H = new float[17]; private float[] _longImdct_h = new float[18]; private float[] _longImdct_even = new float[9]; private float[] _longImdct_odd = new float[9]; private float[] _longImdct_evenIdct = new float[9]; private float[] _longImdct_oddIdct = new float[9]; private float[] _imdct9pt_even_idct = new float[5]; private float[] _imdct9pt_odd_idct = new float[4]; private float[] _shortImdct_H = new float[6]; private float[] _shortImdct_h = new float[6]; private float[] _shortImdct_evenIdct = new float[3]; private float[] _shortImdct_oddIdct = new float[3]; 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 <
BepInEx/plugins/SlipSkid.CustomMenu/SlipSkid.CustomMenu.dll
Decompiled 18 hours agousing System; using System.Collections; 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.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Unity.Mono; using BepInEx.Unity.Mono.Bootstrap; using Microsoft.CodeAnalysis; using NLayer; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SlipSkid.CustomMenu")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.4.4.0")] [assembly: AssemblyInformationalVersion("0.4.4")] [assembly: AssemblyProduct("SlipSkid.CustomMenu")] [assembly: AssemblyTitle("SlipSkid.CustomMenu")] [assembly: AssemblyVersion("0.4.4.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SlipSkid.CustomMenu { internal static class BackgroundFiles { internal sealed class Pixels { internal int Width; internal int Height; internal byte[] Rgba; } private static readonly string[] Extensions = new string[5] { ".png", ".jpg", ".jpeg", ".bmp", ".tga" }; internal static string[] Find(string directory) { if (!Directory.Exists(directory)) { return Array.Empty<string>(); } return (from p in Directory.GetFiles(directory) where string.Equals(Path.GetFileNameWithoutExtension(p), "Background", StringComparison.OrdinalIgnoreCase) where Array.IndexOf(Extensions, Path.GetExtension(p).ToLowerInvariant()) >= 0 orderby Array.IndexOf(Extensions, Path.GetExtension(p).ToLowerInvariant()) select p).ThenBy<string, string>((string p) => p, StringComparer.Ordinal).ToArray(); } private static Pixels Create(int width, int height) { if (width <= 0 || height <= 0 || width > 8192 || height > 8192 || (long)width * (long)height > 16777216) { throw new InvalidDataException("BMP/TGA dimensions exceed 8192 per side or 16 megapixels."); } return new Pixels { Width = width, Height = height, Rgba = new byte[width * height * 4] }; } internal static Pixels Decode(byte[] bytes, string extension) { using MemoryStream input = new MemoryStream(bytes, writable: false); using BinaryReader r = new BinaryReader(input); if (extension == ".bmp") { return Bmp(r); } if (extension == ".tga") { return Tga(r); } throw new InvalidDataException("Expected BMP or TGA."); } private static Pixels Bmp(BinaryReader r) { if (r.ReadUInt16() != 19778) { throw new InvalidDataException("Invalid BMP signature."); } r.ReadUInt32(); r.ReadUInt32(); uint num = r.ReadUInt32(); uint num2 = r.ReadUInt32(); if (num2 < 40 || 14L + (long)num2 > r.BaseStream.Length) { throw new InvalidDataException("Unsupported BMP header."); } int num3 = r.ReadInt32(); int num4 = r.ReadInt32(); if (num4 == int.MinValue) { throw new InvalidDataException("Invalid BMP height."); } ushort num5 = r.ReadUInt16(); ushort num6 = r.ReadUInt16(); uint num7 = r.ReadUInt32(); if (num5 != 1 || (num6 != 24 && num6 != 32) || num7 != 0) { throw new InvalidDataException("BMP must be uncompressed 24-bit or 32-bit RGB."); } Pixels pixels = Create(num3, Math.Abs(num4)); int num8 = (num3 * num6 + 31) / 32 * 4; if (num < 14L + (long)num2 || num + (long)num8 * (long)pixels.Height > r.BaseStream.Length) { throw new InvalidDataException("Truncated BMP pixels."); } for (int i = 0; i < pixels.Height; i++) { r.BaseStream.Position = num + (long)i * (long)num8; int num9 = ((num4 > 0) ? i : (pixels.Height - 1 - i)); for (int j = 0; j < num3; j++) { int num10 = (num9 * num3 + j) * 4; byte b = r.ReadByte(); byte b2 = r.ReadByte(); byte b3 = r.ReadByte(); if (num6 == 32) { r.ReadByte(); } pixels.Rgba[num10] = b3; pixels.Rgba[num10 + 1] = b2; pixels.Rgba[num10 + 2] = b; pixels.Rgba[num10 + 3] = byte.MaxValue; } } return pixels; } private static Pixels Tga(BinaryReader r) { int num = r.ReadByte(); byte num2 = r.ReadByte(); int num3 = r.ReadByte(); r.BaseStream.Position = 12L; int num4 = r.ReadUInt16(); int num5 = r.ReadUInt16(); int num6 = r.ReadByte(); int num7 = r.ReadByte(); if (num2 != 0 || (num3 != 2 && num3 != 10) || (num6 != 24 && num6 != 32) || (num7 & 0xC0) != 0) { throw new InvalidDataException("TGA must be 24/32-bit true-color, uncompressed or RLE."); } Pixels pixels = Create(num4, num5); r.BaseStream.Position = 18 + num; int num8 = num4 * num5; int num9 = 0; while (num9 < num8) { int num10 = ((num3 == 10) ? r.ReadByte() : 0); bool flag = num3 == 10 && (num10 & 0x80) != 0; int num11 = ((num3 != 10) ? 1 : ((num10 & 0x7F) + 1)); if (num11 > num8 - num9) { throw new InvalidDataException("TGA RLE packet exceeds image."); } byte b = 0; byte b2 = 0; byte b3 = 0; byte b4 = byte.MaxValue; int num12 = 0; while (num12 < num11) { if (!flag || num12 == 0) { b3 = r.ReadByte(); b2 = r.ReadByte(); b = r.ReadByte(); b4 = ((num6 == 32) ? r.ReadByte() : byte.MaxValue); if ((num7 & 0xF) == 0) { b4 = byte.MaxValue; } } int num13 = num9 % num4; int num14 = num9 / num4; if ((num7 & 0x10) != 0) { num13 = num4 - 1 - num13; } if ((num7 & 0x20) != 0) { num14 = num5 - 1 - num14; } int num15 = (num14 * num4 + num13) * 4; pixels.Rgba[num15] = b; pixels.Rgba[num15 + 1] = b2; pixels.Rgba[num15 + 2] = b3; pixels.Rgba[num15 + 3] = b4; num12++; num9++; } } return pixels; } } [BepInPlugin("theidiotsinc.slipskid.custommenu", "Slip & Skid Custom Menu", "0.4.4")] public sealed class CustomMenu : BaseUnityPlugin { private sealed class TrackSnapshot { public AudioClip Intro; public AudioClip Main; } private GameObject overlay; private Texture2D backgroundTexture; private MenuAttribution attribution; private MenuModList modList; private bool loading; private string assets; private float nextRefresh; private Type mainMenuType; private readonly Dictionary<AudioSource, AudioClip> replacedOriginals = new Dictionary<AudioSource, AudioClip>(); private readonly Dictionary<AudioSource, bool> originalLoops = new Dictionary<AudioSource, bool>(); private readonly Dictionary<Object, TrackSnapshot> replacedTracks = new Dictionary<Object, TrackSnapshot>(); private readonly HashSet<Component> preparedPlayers = new HashSet<Component>(); private Type musicPlayerType; private AudioClip customClip; private bool loggedPlayerInspection; private bool earlySuppressionLogged; private float nextEarlyScan; private Task<PcmWave> preloadDecodeTask; private string preloadMusicPath; private float nextMusicScan; private Component cachedMainMenu; private void Awake() { assets = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "Assets"); mainMenuType = (from a in AppDomain.CurrentDomain.GetAssemblies() select a.GetType("Menus.MainMenu", throwOnError: false)).FirstOrDefault((Type t) => t != null); musicPlayerType = (from a in AppDomain.CurrentDomain.GetAssemblies() select a.GetType("Sounds.SplitScreenAudio.SplitScreenAudioMusicPlayer", throwOnError: false)).FirstOrDefault((Type t) => t != null); preloadMusicPath = Path.Combine(assets, "MenuMusic.mp3"); if (!File.Exists(preloadMusicPath)) { preloadMusicPath = Path.Combine(assets, "MenuMusic.wav"); } if (File.Exists(preloadMusicPath)) { string decodePath = preloadMusicPath; preloadDecodeTask = Task.Run(() => RadioAudioFiles.Decode(decodePath)); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Started early menu audio decoding: " + Path.GetFileName(decodePath))); } SceneManager.sceneLoaded += OnSceneLoaded; SceneManager.activeSceneChanged += OnActiveSceneChanged; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Custom Menu loaded; assets: " + assets)); } private void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; SceneManager.activeSceneChanged -= OnActiveSceneChanged; Cleanup(); } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if (!IsMenuScene()) { Cleanup(); } cachedMainMenu = null; nextRefresh = 0f; } private void OnActiveSceneChanged(Scene oldScene, Scene newScene) { if (!IsMenuScene()) { Cleanup(); } nextRefresh = 0f; } private void Update() { if (Time.unscaledTime < nextRefresh) { return; } nextRefresh = Time.unscaledTime + 0.25f; if (!IsMenuScene() || !HasActiveMainMenu()) { Cleanup(); return; } if ((Object)(object)modList == (Object)null) { modList = ((Component)this).gameObject.AddComponent<MenuModList>(); } if ((Object)(object)attribution == (Object)null) { attribution = MenuAttribution.Create(assets); } attribution.Top = Mathf.Max(122f, modList.Bottom + 12f); if (!loading && (Object)(object)overlay == (Object)null && (Object)(object)customClip == (Object)null) { ((MonoBehaviour)this).StartCoroutine(LoadAssets()); } if ((Object)(object)customClip == (Object)null && Time.unscaledTime >= nextEarlyScan) { nextEarlyScan = Time.unscaledTime + 0.05f; SuppressOriginalMenuUntilReady(); } if ((Object)(object)customClip != (Object)null && Time.unscaledTime >= nextMusicScan) { nextMusicScan = Time.unscaledTime + 0.25f; ReplaceOriginalMenuMusic(); } } private IEnumerator LoadAssets() { loading = true; SuppressOriginalMenuUntilReady(); string[] array = BackgroundFiles.Find(assets); foreach (string path in array) { try { Texture2D val = (backgroundTexture = LoadBackground(path)); overlay = new GameObject("CustomMenuBackground"); Object.DontDestroyOnLoad((Object)(object)overlay); Canvas obj = overlay.AddComponent<Canvas>(); obj.renderMode = (RenderMode)0; obj.sortingOrder = -1000; overlay.AddComponent<CanvasScaler>(); GameObject val2 = new GameObject("BackgroundImage"); val2.transform.SetParent(overlay.transform, false); RawImage obj2 = val2.AddComponent<RawImage>(); obj2.texture = (Texture)(object)val; ((Graphic)obj2).raycastTarget = false; RectTransform rectTransform = ((Graphic)obj2).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.offsetMin = Vector2.zero; rectTransform.offsetMax = Vector2.zero; AspectRatioFitter obj3 = val2.AddComponent<AspectRatioFitter>(); obj3.aspectMode = (AspectMode)4; obj3.aspectRatio = (float)((Texture)val).width / (float)((Texture)val).height; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Loaded menu background: " + Path.GetFileName(path))); } catch (Exception ex) { if ((Object)(object)overlay != (Object)null) { Object.Destroy((Object)(object)overlay); } if ((Object)(object)backgroundTexture != (Object)null) { Object.Destroy((Object)(object)backgroundTexture); } overlay = null; backgroundTexture = null; ((BaseUnityPlugin)this).Logger.LogWarning((object)("Background failed (" + Path.GetFileName(path) + "): " + ex.Message)); continue; } break; } string path2 = Path.Combine(assets, "MenuMusic.mp3"); if (!File.Exists(path2)) { path2 = Path.Combine(assets, "MenuMusic.wav"); } if (File.Exists(path2)) { Task<PcmWave> decodeTask = ((preloadDecodeTask != null && string.Equals(path2, preloadMusicPath, StringComparison.OrdinalIgnoreCase)) ? preloadDecodeTask : Task.Run(() => RadioAudioFiles.Decode(path2))); while (!decodeTask.IsCompleted) { yield return null; } if (!IsMenuScene()) { loading = false; yield break; } try { if (decodeTask.IsFaulted) { throw decodeTask.Exception.GetBaseException(); } if (decodeTask.IsCanceled) { throw new InvalidOperationException("Music decoding was cancelled"); } PcmWave result = decodeTask.Result; BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; MethodInfo method = typeof(AudioClip).GetMethod("Construct_Internal", bindingAttr); MethodInfo method2 = typeof(AudioClip).GetMethod("CreateUserSound", bindingAttr); MethodInfo method3 = typeof(AudioClip).GetMethod("SetData", bindingAttr, null, new Type[4] { typeof(AudioClip), typeof(float[]), typeof(int), typeof(int) }, null); if (method == null || method2 == null || method3 == null) { throw new InvalidOperationException("Custom Menu AudioBootstrap missing: install the patcher in BepInEx/patchers and restart."); } AudioClip val3 = (AudioClip)method.Invoke(null, null); method2.Invoke(val3, new object[5] { Path.GetFileName(path2), result.samples.Length / result.channels, result.channels, result.rate, false }); if (!(bool)method3.Invoke(null, new object[4] { val3, result.samples, result.samples.Length / result.channels, 0 })) { Object.Destroy((Object)(object)val3); throw new InvalidOperationException("Audio upload failed"); } customClip = val3; ReplaceOriginalMenuMusic(); nextMusicScan = Time.unscaledTime + 0.25f; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Custom menu MP3 decoded and ready: " + Path.GetFileName(path2))); } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Music failed: " + ex2)); } } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)("No MenuMusic.mp3 or MenuMusic.wav found in " + assets)); } yield return null; loading = false; } private static Texture2D LoadBackground(string path) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown if (new FileInfo(path).Length > 67108864) { throw new InvalidDataException("Background exceeds 64 MiB."); } byte[] array = File.ReadAllBytes(path); Texture2D val = null; try { string text = Path.GetExtension(path).ToLowerInvariant(); if (text == ".bmp" || text == ".tga") { BackgroundFiles.Pixels pixels = BackgroundFiles.Decode(array, text); val = new Texture2D(pixels.Width, pixels.Height, (TextureFormat)4, false); val.LoadRawTextureData(pixels.Rgba); val.Apply(false, true); } else { val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, array, true)) { throw new InvalidDataException("Unity could not decode this PNG/JPEG."); } } return val; } catch { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } throw; } } private bool HasActiveMainMenu() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) Scene scene; if ((Object)(object)cachedMainMenu != (Object)null && cachedMainMenu.gameObject.activeInHierarchy) { scene = cachedMainMenu.gameObject.scene; if (((Scene)(ref scene)).IsValid()) { return true; } } cachedMainMenu = null; if (mainMenuType == null) { return false; } Object[] array = Resources.FindObjectsOfTypeAll(mainMenuType); foreach (Object obj in array) { Component val = (Component)(object)((obj is Component) ? obj : null); if ((Object)(object)val != (Object)null) { scene = val.gameObject.scene; if (((Scene)(ref scene)).IsValid() && val.gameObject.activeInHierarchy) { cachedMainMenu = val; return true; } } } return false; } private bool IsMenuScene() { //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) Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; if (!name.Equals("MainMenu", StringComparison.OrdinalIgnoreCase)) { return name.StartsWith("MainMenu_", StringComparison.OrdinalIgnoreCase); } return true; } private void SuppressOriginalMenuUntilReady() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)customClip != (Object)null || musicPlayerType == null) { return; } Object[] array = Resources.FindObjectsOfTypeAll(musicPlayerType); foreach (Object obj in array) { Component val = (Component)(object)((obj is Component) ? obj : null); if ((Object)(object)val == (Object)null) { continue; } Scene scene = val.gameObject.scene; if (!((Scene)(ref scene)).IsValid()) { continue; } AudioSource val2 = ReadField<AudioSource>(val, "mainAudioSource"); AudioSource val3 = ReadField<AudioSource>(val, "secondaryAudioSource"); Object instance = ReadField<Object>(val, "currentTrack"); if (IsMenuAudio(((Object)(object)val2 == (Object)null) ? null : val2.clip) || IsMenuAudio(((Object)(object)val3 == (Object)null) ? null : val3.clip) || IsMenuAudio(ReadField<AudioClip>(instance, "main")) || IsMenuAudio(ReadField<AudioClip>(instance, "intro"))) { if ((Object)(object)val2 != (Object)null && val2.isPlaying) { val2.Stop(); } if ((Object)(object)val3 != (Object)null && (Object)(object)val3 != (Object)(object)val2 && val3.isPlaying) { val3.Stop(); } if (!earlySuppressionLogged) { earlySuppressionLogged = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Stopped original menu intro/loop while custom music decodes"); } } } } private static bool IsMenuAudio(AudioClip clip) { if ((Object)(object)clip != (Object)null) { if (!string.Equals(((Object)clip).name, "music_menu_intro", StringComparison.OrdinalIgnoreCase)) { return string.Equals(((Object)clip).name, "music_menu_loop", StringComparison.OrdinalIgnoreCase); } return true; } return false; } private void ReplaceOriginalMenuMusic() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_03ac: Unknown result type (might be due to invalid IL or missing references) //IL_03b1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)customClip == (Object)null) { return; } Scene scene; if (musicPlayerType != null) { Object[] array = Resources.FindObjectsOfTypeAll(musicPlayerType); foreach (Object obj in array) { Component val = (Component)(object)((obj is Component) ? obj : null); if ((Object)(object)val == (Object)null) { continue; } scene = val.gameObject.scene; if (!((Scene)(ref scene)).IsValid()) { continue; } AudioSource val2 = ReadField<AudioSource>(val, "mainAudioSource"); AudioSource val3 = ReadField<AudioSource>(val, "secondaryAudioSource"); Object val4 = ReadField<Object>(val, "currentTrack"); AudioClip val5 = ReadField<AudioClip>(val4, "main"); AudioClip val6 = ReadField<AudioClip>(val4, "intro"); bool flag = IsOriginalMenuClip(val5) || IsOriginalMenuClip(val6) || (val4 != (Object)null && replacedTracks.ContainsKey(val4)); bool flag2 = flag; if (!loggedPlayerInspection) { loggedPlayerInspection = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Music-player inspection: main=" + ClipLabel(((Object)(object)val2 == (Object)null) ? null : val2.clip) + ", secondary=" + ClipLabel(((Object)(object)val3 == (Object)null) ? null : val3.clip) + ", track.main=" + ClipLabel(val5) + ", track.intro=" + ClipLabel(val6))); } if (!flag2) { flag2 = ((Object)(object)val2 != (Object)null && IsOriginalMenuClip(val2.clip)) || ((Object)(object)val3 != (Object)null && IsOriginalMenuClip(val3.clip)); } if (!flag2) { continue; } if (flag && val4 != (Object)null && !replacedTracks.ContainsKey(val4)) { replacedTracks[val4] = new TrackSnapshot { Intro = val6, Main = val5 }; SetField(val4, "main", customClip); if ((Object)(object)val6 != (Object)null) { SetField(val4, "intro", customClip); } } if (preparedPlayers.Add(val)) { bool num = (Object)(object)val2 != (Object)null && val2.isPlaying; bool flag3 = (Object)(object)val3 != (Object)null && val3.isPlaying; PrepareMusicSource(val2, stop: true); if ((Object)(object)val3 != (Object)(object)val2) { PrepareMusicSource(val3, stop: true); } AudioSource val7 = ((num && (Object)(object)val2 != (Object)null) ? val2 : ((flag3 && (Object)(object)val3 != (Object)null) ? val3 : (((Object)(object)val2 != (Object)null) ? val2 : val3))); if ((Object)(object)val7 != (Object)null && ((Behaviour)val7).isActiveAndEnabled) { val7.Play(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Started custom menu audio after early suppression: " + ((Object)val7).name)); } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)"No enabled music source available to start custom menu audio"); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("Replaced both music-player audio sources and menu music track: " + ((Object)val).name)); } else { RefreshMusicSource(val2); if ((Object)(object)val3 != (Object)(object)val2) { RefreshMusicSource(val3); } if ((Object)(object)val2 != (Object)null && (Object)(object)val3 != (Object)null && val2.isPlaying && val3.isPlaying && (Object)(object)val2.clip == (Object)(object)customClip && (Object)(object)val3.clip == (Object)(object)customClip) { val3.Stop(); } } } } AudioSource[] array2 = Resources.FindObjectsOfTypeAll<AudioSource>(); foreach (AudioSource val8 in array2) { if ((Object)(object)val8 == (Object)null || !IsOriginalMenuClip(val8.clip)) { continue; } scene = ((Component)val8).gameObject.scene; if (((Scene)(ref scene)).IsValid()) { bool isPlaying = val8.isPlaying; PrepareMusicSource(val8, stop: true); if (isPlaying && ((Behaviour)val8).isActiveAndEnabled) { val8.Play(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("Replaced additional music_menu_loop source: " + ((Object)val8).name)); } } } private static string ClipLabel(AudioClip clip) { if (!((Object)(object)clip == (Object)null)) { return ((Object)clip).name; } return "none"; } private bool IsOriginalMenuClip(AudioClip clip) { return IsMenuAudio(clip); } private static T ReadField<T>(object instance, string name) where T : class { if (instance == null) { return null; } FieldInfo field = instance.GetType().GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null)) { return field.GetValue(instance) as T; } return null; } private static void SetField(object instance, string name, object value) { if (instance != null) { FieldInfo field = instance.GetType().GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { field.SetValue(instance, value); } } } private void PrepareMusicSource(AudioSource source, bool stop) { if (!((Object)(object)source == (Object)null)) { if (!replacedOriginals.ContainsKey(source)) { replacedOriginals[source] = source.clip; originalLoops[source] = source.loop; } if (stop) { source.Stop(); } source.clip = customClip; source.loop = true; } } private void RefreshMusicSource(AudioSource source) { if (!((Object)(object)source == (Object)null) && !((Object)(object)source.clip == (Object)(object)customClip)) { bool isPlaying = source.isPlaying; PrepareMusicSource(source, stop: true); if (isPlaying && ((Behaviour)source).isActiveAndEnabled) { source.Play(); } } } private void RestoreOriginalMusic() { foreach (KeyValuePair<Object, TrackSnapshot> replacedTrack in replacedTracks) { if (!(replacedTrack.Key == (Object)null)) { SetField(replacedTrack.Key, "intro", replacedTrack.Value.Intro); SetField(replacedTrack.Key, "main", replacedTrack.Value.Main); } } replacedTracks.Clear(); preparedPlayers.Clear(); foreach (KeyValuePair<AudioSource, AudioClip> replacedOriginal in replacedOriginals) { if (!((Object)(object)replacedOriginal.Key == (Object)null) && (Object)(object)replacedOriginal.Key.clip == (Object)(object)customClip) { replacedOriginal.Key.clip = replacedOriginal.Value; if (originalLoops.TryGetValue(replacedOriginal.Key, out var value)) { replacedOriginal.Key.loop = value; } } } replacedOriginals.Clear(); originalLoops.Clear(); loggedPlayerInspection = false; earlySuppressionLogged = false; } private void Cleanup() { if ((Object)(object)modList != (Object)null) { Object.Destroy((Object)(object)modList); } modList = null; if ((Object)(object)attribution != (Object)null) { Object.Destroy((Object)(object)((Component)attribution).gameObject); } attribution = null; RestoreOriginalMusic(); if ((Object)(object)overlay != (Object)null) { Object.Destroy((Object)(object)overlay); } if ((Object)(object)backgroundTexture != (Object)null) { Object.Destroy((Object)(object)backgroundTexture); } backgroundTexture = null; if ((Object)(object)customClip != (Object)null) { Object.Destroy((Object)(object)customClip); } overlay = null; customClip = null; nextMusicScan = 0f; nextEarlyScan = 0f; } } internal sealed class MenuAttribution : MonoBehaviour { internal float Top = 122f; private string path; private RectTransform drawer; private TextMeshProUGUI arrow; private TextMeshProUGUI body; private ScrollRect scroll; private bool expanded; private float progress; private const float Width = 520f; private const float Tab = 36f; internal static MenuAttribution Create(string assets) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("CustomMenuAttribution", new Type[4] { typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster) }); Object.DontDestroyOnLoad((Object)(object)val); Canvas component = val.GetComponent<Canvas>(); component.renderMode = (RenderMode)0; component.sortingOrder = 100; CanvasScaler component2 = val.GetComponent<CanvasScaler>(); component2.uiScaleMode = (ScaleMode)1; component2.referenceResolution = new Vector2(1920f, 1080f); component2.screenMatchMode = (ScreenMatchMode)0; component2.matchWidthOrHeight = 0.5f; MenuAttribution menuAttribution = val.AddComponent<MenuAttribution>(); menuAttribution.path = Path.Combine(assets, "attribution.txt"); menuAttribution.Build(val.transform); return menuAttribution; } private static RectTransform Rect(string name, Transform parent, Vector2 size, Vector2 position) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_0056: Unknown result type (might be due to invalid IL or missing references) RectTransform component = new GameObject(name, new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>(); ((Transform)component).SetParent(parent, false); Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 1f); component.pivot = val; Vector2 anchorMin = (component.anchorMax = val); component.anchorMin = anchorMin; component.sizeDelta = size; component.anchoredPosition = position; return component; } private static Image Background(RectTransform rect, Color color) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) Image obj = ((Component)rect).gameObject.AddComponent<Image>(); ((Graphic)obj).color = color; return obj; } private static TextMeshProUGUI Label(RectTransform rect, string text, float size, Color color) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI val = ((Component)rect).gameObject.AddComponent<TextMeshProUGUI>(); TextMeshProUGUI[] array = Resources.FindObjectsOfTypeAll<TextMeshProUGUI>(); foreach (TextMeshProUGUI val2 in array) { if ((Object)(object)val2 != (Object)(object)val && (Object)(object)((TMP_Text)val2).font != (Object)null) { Scene scene = ((Component)val2).gameObject.scene; if (((Scene)(ref scene)).IsValid()) { ((TMP_Text)val).font = ((TMP_Text)val2).font; break; } } } if ((Object)(object)((TMP_Text)val).font == (Object)null) { ((TMP_Text)val).font = TMP_Settings.defaultFontAsset; } ((TMP_Text)val).text = text; ((TMP_Text)val).fontSize = size; ((Graphic)val).color = color; ((TMP_Text)val).richText = false; ((Graphic)val).raycastTarget = false; return val; } private void Build(Transform parent) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) drawer = Rect("MusicCreditsDrawer", parent, new Vector2(520f, 174f), Vector2.zero); RectTransform obj = drawer; RectTransform obj2 = drawer; RectTransform obj3 = drawer; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(1f, 1f); obj3.pivot = val; Vector2 anchorMin = (obj2.anchorMax = val); obj.anchorMin = anchorMin; RectTransform val3 = Rect("ToggleMusicCredits", (Transform)(object)drawer, new Vector2(36f, 36f), Vector2.zero); Button obj4 = ((Component)val3).gameObject.AddComponent<Button>(); ((Selectable)obj4).targetGraphic = (Graphic)(object)Background(val3, new Color(0.06f, 0.12f, 0.17f, 0.96f)); Navigation navigation = default(Navigation); ((Navigation)(ref navigation)).mode = (Mode)0; ((Selectable)obj4).navigation = navigation; ColorBlock colors = ((Selectable)obj4).colors; ((ColorBlock)(ref colors)).highlightedColor = new Color(0.6f, 0.9f, 1f); ((Selectable)obj4).colors = colors; arrow = Label(Rect("Arrow", (Transform)(object)val3, val3.sizeDelta, Vector2.zero), "<", 24f, Color.white); ((TMP_Text)arrow).alignment = (TextAlignmentOptions)514; ((UnityEvent)obj4.onClick).AddListener(new UnityAction(Toggle)); RectTransform val4 = Rect("MusicCredits", (Transform)(object)drawer, new Vector2(484f, 174f), new Vector2(36f, 0f)); Background(val4, new Color(0.035f, 0.065f, 0.09f, 0.95f)); Label(Rect("Title", (Transform)(object)val4, new Vector2(440f, 26f), new Vector2(18f, -12f)), "MENU MUSIC", 16f, new Color(0.45f, 0.85f, 0.95f)); RectTransform val5 = Rect("CreditsViewport", (Transform)(object)val4, new Vector2(448f, 116f), new Vector2(18f, -46f)); ((Component)val5).gameObject.AddComponent<RectMask2D>(); RectTransform val6 = Rect("CreditsText", (Transform)(object)val5, new Vector2(448f, 116f), Vector2.zero); body = Label(val6, "", 18f, Color.white); ((TMP_Text)body).alignment = (TextAlignmentOptions)257; ((TMP_Text)body).enableWordWrapping = true; ((TMP_Text)body).overflowMode = (TextOverflowModes)0; scroll = ((Component)val5).gameObject.AddComponent<ScrollRect>(); scroll.viewport = val5; scroll.content = val6; scroll.horizontal = false; scroll.vertical = true; scroll.movementType = (MovementType)2; scroll.scrollSensitivity = 24f; Background(val5, Color.clear); Reload(); Position(); } private void Reload() { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) try { ((TMP_Text)body).text = (File.Exists(path) ? File.ReadAllText(path) : "Add music credits to Assets/attribution.txt."); if (string.IsNullOrWhiteSpace(((TMP_Text)body).text)) { ((TMP_Text)body).text = "No music attribution provided."; } } catch (Exception ex) { ((TMP_Text)body).text = "Could not read attribution.txt: " + ex.Message; } ((TMP_Text)body).rectTransform.sizeDelta = new Vector2(448f, Mathf.Max(116f, ((TMP_Text)body).GetPreferredValues(((TMP_Text)body).text, 448f, 0f).y + 6f)); scroll.verticalNormalizedPosition = 1f; } private void Toggle() { expanded = !expanded; if (expanded) { Reload(); } ((TMP_Text)arrow).text = (expanded ? ">" : "<"); } private void Update() { progress = Math.Max(0f, Math.Min(1f, progress + (expanded ? 1f : (-1f)) * Time.unscaledDeltaTime / 0.22f)); Position(); } private void Position() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) float num = progress * progress * (3f - 2f * progress); drawer.anchoredPosition = new Vector2(-12f + 496f * (1f - num), 0f - Top); } } internal sealed class MenuModList : MonoBehaviour { private TextMeshProUGUI label; private float retry; internal float Bottom { get; private set; } = 110f; private void Update() { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: 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_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)label) || Time.unscaledTime < retry) { return; } retry = Time.unscaledTime + 1f; TextMeshProUGUI val = ((IEnumerable<TextMeshProUGUI>)Resources.FindObjectsOfTypeAll<TextMeshProUGUI>()).FirstOrDefault((Func<TextMeshProUGUI, bool>)delegate(TextMeshProUGUI t) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)t)) { Scene scene = ((Component)t).gameObject.scene; if (((Scene)(ref scene)).IsValid() && Object.op_Implicit((Object)(object)((Graphic)t).canvas) && !string.IsNullOrEmpty(((TMP_Text)t).text)) { if (!((TMP_Text)t).text.Contains("WindowsPlayer")) { return ((TMP_Text)t).text.Contains("v_"); } return true; } } return false; }); if (Object.op_Implicit((Object)(object)val)) { Transform transform = ((Component)((Graphic)val).canvas.rootCanvas).transform; GameObject val2 = new GameObject("CustomMenuLoadedModVersions", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(transform, false); label = val2.AddComponent<TextMeshProUGUI>(); ((TMP_Text)label).font = ((TMP_Text)val).font; ((TMP_Text)label).fontSharedMaterial = ((TMP_Text)val).fontSharedMaterial; ((TMP_Text)label).fontSize = ((TMP_Text)val).fontSize; ((TMP_Text)label).fontStyle = ((TMP_Text)val).fontStyle; ((Graphic)label).color = ((Graphic)val).color; ((TMP_Text)label).characterSpacing = ((TMP_Text)val).characterSpacing; ((TMP_Text)label).wordSpacing = ((TMP_Text)val).wordSpacing; ((TMP_Text)label).lineSpacing = ((TMP_Text)val).lineSpacing; ((TMP_Text)label).richText = false; ((Graphic)label).raycastTarget = false; ((TMP_Text)label).enableAutoSizing = false; ((TMP_Text)label).enableWordWrapping = false; ((TMP_Text)label).alignment = (TextAlignmentOptions)260; ((TMP_Text)label).text = string.Join("\n", from p in ((BaseChainloader<BaseUnityPlugin>)(object)UnityChainloader.Instance).Plugins.Values.OrderBy<PluginInfo, string>((PluginInfo p) => p.Metadata.Name, StringComparer.OrdinalIgnoreCase) select p.Metadata.Name + " v" + (object)p.Metadata.Version); RectTransform rectTransform = ((TMP_Text)label).rectTransform; Vector2 val3 = (rectTransform.pivot = Vector2.one); Vector2 anchorMin = (rectTransform.anchorMax = val3); rectTransform.anchorMin = anchorMin; rectTransform.sizeDelta = new Vector2(750f, 800f); rectTransform.anchoredPosition = new Vector2(-12f, -12f); Vector3 lossyScale = ((TMP_Text)val).transform.lossyScale; Vector3 lossyScale2 = transform.lossyScale; ((Transform)rectTransform).localScale = new Vector3(lossyScale.x / lossyScale2.x, lossyScale.y / lossyScale2.y, 1f); Bottom = 12f + ((TMP_Text)label).preferredHeight * ((Transform)rectTransform).localScale.y; } } private void OnDestroy() { if (Object.op_Implicit((Object)(object)label)) { Object.Destroy((Object)(object)((Component)label).gameObject); } } } internal sealed class RadioAudioFile { internal string file; internal string path; internal string hash; } internal static class RadioAudioFiles { internal const long MaxFileBytes = 33554432L; internal const int MaxDecodedSamples = 33554432; internal static bool Supported(string path) { string extension = Path.GetExtension(path); if (!string.Equals(extension, ".wav", StringComparison.OrdinalIgnoreCase)) { return string.Equals(extension, ".mp3", StringComparison.OrdinalIgnoreCase); } return true; } internal static List<RadioAudioFile> Scan(string folder, Action<string> warn = null) { List<RadioAudioFile> list = new List<RadioAudioFile>(); HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); foreach (string item in Directory.EnumerateFiles(folder).Where(Supported).OrderBy<string, string>((string p) => p, StringComparer.OrdinalIgnoreCase) .ThenBy<string, string>((string p) => p, StringComparer.Ordinal)) { try { FileInfo fileInfo = new FileInfo(item); if (fileInfo.Length < 4 || fileInfo.Length > 33554432) { warn?.Invoke("Audio file skipped (empty or larger than 32 MiB): " + fileInfo.Name); continue; } string text; using (SHA256 sHA = SHA256.Create()) { using FileStream inputStream = File.OpenRead(item); text = BitConverter.ToString(sHA.ComputeHash(inputStream)).Replace("-", ""); } if (hashSet.Add(text)) { list.Add(new RadioAudioFile { file = fileInfo.Name, path = item, hash = text }); } } catch (IOException ex) { warn?.Invoke("Audio file skipped: " + Path.GetFileName(item) + " — " + ex.Message); } catch (UnauthorizedAccessException ex2) { warn?.Invoke("Audio file skipped: " + Path.GetFileName(item) + " — " + ex2.Message); } } return list; } internal static PcmWave Decode(string path, int maxSamples = 33554432) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown if (maxSamples <= 0 || maxSamples > 33554432) { throw new ArgumentOutOfRangeException("maxSamples"); } if (!Supported(path)) { throw new InvalidDataException("Use MP3 or PCM 16-bit WAV audio."); } long length = new FileInfo(path).Length; if (length < 4 || length > 33554432) { throw new InvalidDataException("Audio files must be non-empty and no larger than 32 MiB."); } if (string.Equals(Path.GetExtension(path), ".wav", StringComparison.OrdinalIgnoreCase)) { PcmWave pcmWave = PcmWave.Decode(File.ReadAllBytes(path)); if (pcmWave.samples.Length > maxSamples) { throw new InvalidDataException("Audio exceeds the decoded sample limit."); } return pcmWave; } using FileStream fileStream = File.OpenRead(path); MpegFile val = new MpegFile((Stream)fileStream); try { if ((val.Channels != 1 && val.Channels != 2) || val.SampleRate < 8000 || val.SampleRate > 192000) { throw new InvalidDataException("Use a mono or stereo MP3 with a supported sample rate."); } List<float[]> list = new List<float[]>(); int num = 0; while (true) { float[] array = new float[16384]; int num2 = val.ReadSamples(array, 0, array.Length); if (num2 == 0) { break; } if (num2 < 0 || num2 > array.Length || num > maxSamples - num2) { throw new InvalidDataException("Audio exceeds the decoded sample limit (128 MiB maximum)."); } for (int i = 0; i < num2; i++) { if (float.IsNaN(array[i]) || float.IsInfinity(array[i])) { throw new InvalidDataException("MP3 contains invalid decoded samples."); } array[i] = Math.Max(-1f, Math.Min(1f, array[i])); } if (num2 != array.Length) { Array.Resize(ref array, num2); } list.Add(array); num += num2; } if (num == 0 || num % val.Channels != 0) { throw new InvalidDataException("MP3 contains no complete audio samples."); } float[] array2 = new float[num]; int num3 = 0; foreach (float[] item in list) { Array.Copy(item, 0, array2, num3, item.Length); num3 += item.Length; } return new PcmWave { samples = array2, channels = val.Channels, rate = val.SampleRate }; } finally { ((IDisposable)val)?.Dispose(); } } } public sealed class PcmWave { public float[] samples; public int channels; public int rate; public static PcmWave Decode(byte[] bytes) { using MemoryStream memoryStream = new MemoryStream(bytes, writable: false); using BinaryReader binaryReader = new BinaryReader(memoryStream); if (bytes.Length < 12 || Encoding.ASCII.GetString(binaryReader.ReadBytes(4)) != "RIFF") { throw new InvalidDataException("Expected RIFF WAV"); } uint num = binaryReader.ReadUInt32(); if ((long)num + 8L > bytes.Length) { throw new InvalidDataException("Truncated WAV"); } long num2 = (long)num + 8L; if (Encoding.ASCII.GetString(binaryReader.ReadBytes(4)) != "WAVE") { throw new InvalidDataException("Expected WAV header"); } int num3 = 0; int num4 = 0; int num5 = 0; byte[] array = null; while (memoryStream.Position + 8 <= num2) { string text = Encoding.ASCII.GetString(binaryReader.ReadBytes(4)); uint num6 = binaryReader.ReadUInt32(); long num7 = memoryStream.Position + num6 + (num6 & 1); if (num7 > num2 || num6 > int.MaxValue) { throw new InvalidDataException("Truncated WAV chunk"); } if (text == "fmt ") { if (num6 < 16 || binaryReader.ReadUInt16() != 1) { throw new InvalidDataException("Use PCM 16-bit WAV"); } num3 = binaryReader.ReadUInt16(); num4 = binaryReader.ReadInt32(); binaryReader.ReadUInt32(); num5 = binaryReader.ReadUInt16(); int num8 = binaryReader.ReadUInt16(); if ((num3 != 1 && num3 != 2) || num4 < 8000 || num4 > 192000 || num8 != 16 || num5 != num3 * 2) { throw new InvalidDataException("Use mono/stereo PCM 16-bit WAV"); } } else if (text == "data") { array = binaryReader.ReadBytes((int)num6); } memoryStream.Position = num7; } if (num3 == 0 || array == null || array.Length == 0 || array.Length % num5 != 0) { throw new InvalidDataException("Missing or incomplete WAV samples"); } PcmWave pcmWave = new PcmWave { channels = num3, rate = num4, samples = new float[array.Length / 2] }; for (int i = 0; i < pcmWave.samples.Length; i++) { pcmWave.samples[i] = (float)(short)(array[i * 2] | (array[i * 2 + 1] << 8)) / 32768f; } return pcmWave; } } }