Decompiled source of CybergrindMusicExplorer v2.0.7

plugins/Jukebox/Jukebox.dll

Decompiled 2 weeks ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Xml;
using BepInEx;
using Discord;
using HarmonyLib;
using Jukebox.Assets;
using Jukebox.Components;
using Jukebox.Core.Collections;
using Jukebox.Core.Model.Song;
using Jukebox.Core.Model.Themes;
using Jukebox.Core.Themes;
using Jukebox.Input;
using Jukebox.UI;
using Jukebox.UI.Elements;
using Jukebox.UI.Windows;
using Jukebox.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using SettingsMenu.Components;
using SettingsMenu.Components.Pages;
using Steamworks;
using TMPro;
using TagLib;
using TagLib.Aac;
using TagLib.Aiff;
using TagLib.Ape;
using TagLib.Asf;
using TagLib.Audible;
using TagLib.Dsf;
using TagLib.Flac;
using TagLib.Gif;
using TagLib.IFD;
using TagLib.IFD.Entries;
using TagLib.IFD.Makernotes;
using TagLib.IFD.Tags;
using TagLib.IIM;
using TagLib.Id3v1;
using TagLib.Id3v2;
using TagLib.Image;
using TagLib.Image.NoMetadata;
using TagLib.Jpeg;
using TagLib.Matroska;
using TagLib.Mpeg;
using TagLib.Mpeg4;
using TagLib.MusePack;
using TagLib.NonContainer;
using TagLib.Ogg;
using TagLib.Ogg.Codecs;
using TagLib.Png;
using TagLib.Riff;
using TagLib.Tiff;
using TagLib.Tiff.Arw;
using TagLib.Tiff.Cr2;
using TagLib.Tiff.Dng;
using TagLib.Tiff.Nef;
using TagLib.Tiff.Pef;
using TagLib.Tiff.Rw2;
using TagLib.WavPack;
using TagLib.Xmp;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.Networking;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Jukebox")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Jukebox")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("B01B8657-61B6-4BC3-BFAF-F43D4C264B4B")]
[assembly: AssemblyFileVersion("2.0.7.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("2.0.7.0")]
namespace UnityEngine.UI
{
	[AddComponentMenu("Layout/Auto Expand Grid Layout Group", 152)]
	public class AutoExpandGridLayoutGroup : LayoutGroup
	{
		public enum Corner
		{
			UpperLeft,
			UpperRight,
			LowerLeft,
			LowerRight
		}

		public enum Axis
		{
			Horizontal,
			Vertical
		}

		public enum Constraint
		{
			Flexible,
			FixedColumnCount,
			FixedRowCount
		}

		[SerializeField]
		protected Corner m_StartCorner;

		[SerializeField]
		protected Axis m_StartAxis;

		[SerializeField]
		protected Vector2 m_CellSize = new Vector2(100f, 100f);

		[SerializeField]
		protected Vector2 m_Spacing = Vector2.zero;

		[SerializeField]
		protected Constraint m_Constraint;

		[SerializeField]
		protected int m_ConstraintCount = 2;

		public Corner startCorner
		{
			get
			{
				return m_StartCorner;
			}
			set
			{
				((LayoutGroup)this).SetProperty<Corner>(ref m_StartCorner, value);
			}
		}

		public Axis startAxis
		{
			get
			{
				return m_StartAxis;
			}
			set
			{
				((LayoutGroup)this).SetProperty<Axis>(ref m_StartAxis, value);
			}
		}

		public Vector2 cellSize
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return m_CellSize;
			}
			set
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				((LayoutGroup)this).SetProperty<Vector2>(ref m_CellSize, value);
			}
		}

		public Vector2 spacing
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return m_Spacing;
			}
			set
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				((LayoutGroup)this).SetProperty<Vector2>(ref m_Spacing, value);
			}
		}

		public Constraint constraint
		{
			get
			{
				return m_Constraint;
			}
			set
			{
				((LayoutGroup)this).SetProperty<Constraint>(ref m_Constraint, value);
			}
		}

		public int constraintCount
		{
			get
			{
				return m_ConstraintCount;
			}
			set
			{
				((LayoutGroup)this).SetProperty<int>(ref m_ConstraintCount, Mathf.Max(1, value));
			}
		}

		protected AutoExpandGridLayoutGroup()
		{
		}//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)


		public override void CalculateLayoutInputHorizontal()
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			((LayoutGroup)this).CalculateLayoutInputHorizontal();
			int num = 0;
			int num2 = 0;
			if (m_Constraint == Constraint.FixedColumnCount)
			{
				num = (num2 = m_ConstraintCount);
			}
			else if (m_Constraint == Constraint.FixedRowCount)
			{
				num = (num2 = Mathf.CeilToInt((float)((LayoutGroup)this).rectChildren.Count / (float)m_ConstraintCount - 0.001f));
			}
			else
			{
				num = 1;
				num2 = Mathf.CeilToInt(Mathf.Sqrt((float)((LayoutGroup)this).rectChildren.Count));
			}
			((LayoutGroup)this).SetLayoutInputForAxis((float)((LayoutGroup)this).padding.horizontal + (cellSize.x + spacing.x) * (float)num - spacing.x, (float)((LayoutGroup)this).padding.horizontal + (cellSize.x + spacing.x) * (float)num2 - spacing.x, -1f, 0);
		}

		public override void CalculateLayoutInputVertical()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_006c: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			if (m_Constraint == Constraint.FixedColumnCount)
			{
				num = Mathf.CeilToInt((float)((LayoutGroup)this).rectChildren.Count / (float)m_ConstraintCount - 0.001f);
			}
			else if (m_Constraint == Constraint.FixedRowCount)
			{
				num = m_ConstraintCount;
			}
			else
			{
				Rect rect = ((LayoutGroup)this).rectTransform.rect;
				float x = ((Rect)(ref rect)).size.x;
				int num2 = Mathf.Max(1, Mathf.FloorToInt((x - (float)((LayoutGroup)this).padding.horizontal + spacing.x + 0.001f) / (cellSize.x + spacing.x)));
				num = Mathf.CeilToInt((float)((LayoutGroup)this).rectChildren.Count / (float)num2);
			}
			float num3 = (float)((LayoutGroup)this).padding.vertical + (cellSize.y + spacing.y) * (float)num - spacing.y;
			((LayoutGroup)this).SetLayoutInputForAxis(num3, num3, -1f, 1);
		}

		public override void SetLayoutHorizontal()
		{
			SetCellsAlongAxis(0);
		}

		public override void SetLayoutVertical()
		{
			SetCellsAlongAxis(1);
		}

		private void SetCellsAlongAxis(int axis)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: 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_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: 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_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			if (axis == 0)
			{
				for (int i = 0; i < ((LayoutGroup)this).rectChildren.Count; i++)
				{
					RectTransform val = ((LayoutGroup)this).rectChildren[i];
					((DrivenRectTransformTracker)(ref base.m_Tracker)).Add((Object)(object)this, val, (DrivenTransformProperties)16134);
					val.anchorMin = Vector2.up;
					val.anchorMax = Vector2.up;
					val.sizeDelta = cellSize;
				}
				return;
			}
			Rect rect = ((LayoutGroup)this).rectTransform.rect;
			float x = ((Rect)(ref rect)).size.x;
			rect = ((LayoutGroup)this).rectTransform.rect;
			float y = ((Rect)(ref rect)).size.y;
			int num = 1;
			int num2 = 1;
			if (m_Constraint == Constraint.FixedColumnCount)
			{
				num = m_ConstraintCount;
				num2 = Mathf.CeilToInt((float)((LayoutGroup)this).rectChildren.Count / (float)num - 0.001f);
			}
			else if (m_Constraint != Constraint.FixedRowCount)
			{
				num = ((!(cellSize.x + spacing.x <= 0f)) ? Mathf.Max(1, Mathf.FloorToInt((x - (float)((LayoutGroup)this).padding.horizontal + spacing.x + 0.001f) / (cellSize.x + spacing.x))) : int.MaxValue);
				num2 = ((!(cellSize.y + spacing.y <= 0f)) ? Mathf.Max(1, Mathf.FloorToInt((y - (float)((LayoutGroup)this).padding.vertical + spacing.y + 0.001f) / (cellSize.y + spacing.y))) : int.MaxValue);
			}
			else
			{
				num2 = m_ConstraintCount;
				num = Mathf.CeilToInt((float)((LayoutGroup)this).rectChildren.Count / (float)num2 - 0.001f);
			}
			int num3 = (int)startCorner % 2;
			int num4 = (int)startCorner / 2;
			int num5;
			int num6;
			int num7;
			if (startAxis == Axis.Horizontal)
			{
				num5 = num;
				num6 = Mathf.Clamp(num, 1, ((LayoutGroup)this).rectChildren.Count);
				num7 = Mathf.Clamp(num2, 1, Mathf.CeilToInt((float)((LayoutGroup)this).rectChildren.Count / (float)num5));
			}
			else
			{
				num5 = num2;
				num7 = Mathf.Clamp(num2, 1, ((LayoutGroup)this).rectChildren.Count);
				num6 = Mathf.Clamp(num, 1, Mathf.CeilToInt((float)((LayoutGroup)this).rectChildren.Count / (float)num5));
			}
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor((float)num6 * cellSize.x + (float)(num6 - 1) * spacing.x, (float)num7 * cellSize.y + (float)(num7 - 1) * spacing.y);
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(((LayoutGroup)this).GetStartOffset(0, val2.x), ((LayoutGroup)this).GetStartOffset(1, val2.y));
			for (int j = 0; j < ((LayoutGroup)this).rectChildren.Count; j++)
			{
				int num8;
				int num9;
				if (startAxis == Axis.Horizontal)
				{
					num8 = j % num5;
					num9 = j / num5;
				}
				else
				{
					num8 = j / num5;
					num9 = j % num5;
				}
				if (num3 == 1)
				{
					num8 = num6 - 1 - num8;
				}
				if (num4 == 1)
				{
					num9 = num7 - 1 - num9;
				}
				Vector2 val4 = spacing;
				float num10 = (x - ((Vector2)(ref val4))[0] * (float)(num6 - 1)) / (float)num6;
				RectTransform obj = ((LayoutGroup)this).rectChildren[j];
				float x2 = val3.x;
				val4 = spacing;
				((LayoutGroup)this).SetChildAlongAxis(obj, 0, x2 + (num10 + ((Vector2)(ref val4))[0]) * (float)num8, num10);
				RectTransform obj2 = ((LayoutGroup)this).rectChildren[j];
				float y2 = val3.y;
				val4 = cellSize;
				float num11 = ((Vector2)(ref val4))[1];
				val4 = spacing;
				float num12 = y2 + (num11 + ((Vector2)(ref val4))[1]) * (float)num9;
				val4 = cellSize;
				((LayoutGroup)this).SetChildAlongAxis(obj2, 1, num12, ((Vector2)(ref val4))[1]);
			}
		}
	}
}
namespace Jukebox
{
	[BepInProcess("ULTRAKILL.exe")]
	[BepInPlugin("dev.flazhik.jukebox", "Jukebox", "2.0.7")]
	public class JukeboxPlugin : BaseUnityPlugin
	{
		[ExternalAsset("Assets/Jukebox/Bootstrap.prefab", typeof(GameObject))]
		private static GameObject bootstrap;

		public static string catalogDir;

		private static Harmony _harmony;

		private static bool motdShown;

		private static bool init;

		static JukeboxPlugin()
		{
			catalogDir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Assets");
		}

		private void Awake()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
			Addressables.InitializeAsync().WaitForCompletion();
			Addressables.LoadContentCatalogAsync(Path.Combine(catalogDir, "catalog.json"), true, (string)null).WaitForCompletion();
			_harmony = new Harmony("dev.flazhik.jukebox");
			Startup();
		}

		private void Startup()
		{
			_harmony.PatchAll();
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (scene != SceneManager.GetActiveScene())
			{
				return;
			}
			switch (SceneHelper.CurrentScene)
			{
			case "Bootstrap":
				SetDefaultPrefsValues();
				break;
			case "Main Menu":
				if (!init)
				{
					MonoSingleton<AssetsManager>.Instance.LoadAssets();
					MonoSingleton<AssetsManager>.Instance.RegisterPrefabs();
					init = true;
				}
				break;
			case "Endless":
				Object.Instantiate<GameObject>(bootstrap);
				if (!motdShown)
				{
					((MonoBehaviour)MonoSingleton<JukeboxManager>.Instance).StartCoroutine(Motd());
				}
				break;
			}
		}

		private static void SetDefaultPrefsValues()
		{
			foreach (KeyValuePair<string, object> item in new Dictionary<string, object>
			{
				{ "jukebox.volumeBoost", 0f },
				{ "jukebox.showTrackPanelIndefinitely", false },
				{ "jukebox.alwaysPlayIntro", true },
				{ "jukebox.discordAndSteamIntegration", true },
				{ "jukebox.enableTracksPreview", true },
				{ "jukebox.preventDuplicateTracks", false },
				{ "jukebox.nowPlayingHud", true },
				{ "jukebox.enableCalmThemes", true },
				{ "jukebox.songPanelStyle", 0 },
				{ "jukebox.currentPlaylist", "slot1" },
				{ "jukebox.calmThemeEnemiesThreshold", 2 },
				{ "jukebox.effects.parry", null },
				{ "jukebox.effects.wavecomplete", null },
				{ "jukebox.effects.gameover", null },
				{ "jukebox.effects.aww", null },
				{ "jukebox.effects.terminal-music", null }
			})
			{
				MonoSingleton<PrefsManager>.Instance.defaultValues.Add(item.Key, item.Value);
			}
		}

		private IEnumerator Motd()
		{
			yield return (object)new WaitForSeconds(1.5f);
			InputAction menu = MonoSingleton<JukeboxInputs>.Instance.Menu;
			string text = GeneralExtensions.Join<InputBinding>((IEnumerable<InputBinding>)(object)menu.bindings, (Func<InputBinding, string>)((InputBinding binding) => InputExtensions.GetBindingDisplayStringWithoutOverride(menu, binding, (DisplayStringOptions)0)), ", ");
			MonoSingleton<HudMessageReceiver>.Instance.SendHudMessage("Jukebox menu is available by pressing <color=orange>" + text + "</color>", "", "", 0, false, false, true);
			motdShown = true;
		}
	}
	internal static class PluginInfo
	{
		public const string GUID = "dev.flazhik.jukebox";

		public const string NAME = "Jukebox";

		public const string VERSION = "2.0.7";
	}
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					resourceMan = new ResourceManager("Jukebox.Resources", typeof(Resources).Assembly);
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal static byte[] Jukebox => (byte[])ResourceManager.GetObject("Jukebox", resourceCulture);

		internal Resources()
		{
		}
	}
}
namespace Jukebox.Utils
{
	public static class CompositeSongsUtils
	{
		private static readonly List<string> SpecialPostfixes = new List<string> { "intro", "loop", "calm", "calmloop", "calmintro" };

		public static JukeboxSongMetadata.CompositeProperties GetSongComponents(string guid, SoundtrackSong song)
		{
			return new JukeboxSongMetadata.CompositeProperties.Builder().GotIntroAndLoop((Object)(object)song.introClip != (Object)null).GotCalmIntro(val: false).GotCalmLoop(MonoSingleton<JukeboxManager>.Instance.calmThemes.FindCalmClipsFor(guid) != null)
				.Build;
		}

		public static JukeboxSongMetadata.CompositeProperties GetSongComponents(FileInfo fileInfo)
		{
			JukeboxSongMetadata.CompositeProperties.Builder builder = new JukeboxSongMetadata.CompositeProperties.Builder();
			List<FileInfo> source = (from file in fileInfo.Directory?.GetFiles()
				where WithoutPostfix(file).Name.Equals(fileInfo.Name)
				select file).Select(delegate(FileInfo file)
			{
				if (HasSpecialPostfix(file, "calmintro"))
				{
					builder.GotCalmIntro(val: true);
				}
				if (HasSpecialPostfix(file, "calmloop"))
				{
					builder.GotCalmLoop(val: true);
				}
				if (HasSpecialPostfix(file, "calm"))
				{
					builder.GotCalmTheme(val: true);
				}
				return file;
			}).ToList() ?? new List<FileInfo>();
			if (source.Any((FileInfo file) => HasSpecialPostfix(file, "intro")) && source.Any((FileInfo file) => HasSpecialPostfix(file, "loop")))
			{
				builder.GotIntroAndLoop(val: true);
			}
			return builder.Build;
		}

		public static FileInfo WithPostfix(FileInfo path, string postfix)
		{
			return new FileInfo(Path.GetDirectoryName(path.FullName) + "\\" + Path.GetFileNameWithoutExtension(path.FullName) + "_" + postfix + path.Extension);
		}

		public static FileInfo WithoutPostfix(FileInfo path)
		{
			if (HasAnySpecialPostfix(path))
			{
				return new FileInfo(Regex.Replace(path.FullName, "_[a-zA-Z]+\\.[a-zA-Z0-9]+$", path.Extension));
			}
			return path;
		}

		public static bool HasValidExtenstion(FileInfo path)
		{
			return CustomMusicFileBrowser.extensionTypeDict.Keys.Any((string extension) => path.Extension.ToLower().Equals(extension));
		}

		private static bool HasAnySpecialPostfix(FileInfo path)
		{
			return SpecialPostfixes.Any((string postfix) => HasSpecialPostfix(path, postfix));
		}

		private static bool HasSpecialPostfix(FileInfo path, string postfix)
		{
			return Path.GetFileNameWithoutExtension(path.Name).EndsWith("_" + postfix);
		}
	}
	public class GenericUtils
	{
		public static string FirstNonEmpty(params string[] options)
		{
			return options.FirstOrDefault((string option) => !string.IsNullOrEmpty(option));
		}
	}
	public static class FloatExtensions
	{
		public static string SecondsToHumanReadable(this float value)
		{
			int num = (int)value;
			int num2 = num / 60;
			int num3 = num - num2 * 60;
			return $"{num2:00}:{num3:00}";
		}
	}
	public static class IntExtensions
	{
		public static int Mod(this int num, int mod)
		{
			return (num % mod + mod) % mod;
		}
	}
	public abstract class ReflectionUtils
	{
		private const BindingFlags PrivateFields = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		public static object GetPrivate<T>(T instance, Type classType, string field)
		{
			return classType.GetField(field, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).GetValue(instance);
		}

		public static void SetPrivate<T, TV>(T instance, Type classType, string field, TV value)
		{
			classType.GetField(field, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.SetField).SetValue(instance, value);
		}

		public static IEnumerable<CodeInstruction> IL(params (OpCode, object)[] instructions)
		{
			return ((IEnumerable<(OpCode, object)>)instructions).Select((Func<(OpCode, object), CodeInstruction>)(((OpCode, object) i) => new CodeInstruction(i.Item1, i.Item2))).ToList();
		}
	}
	public static class ScrollingTextUnscaled
	{
		public static IEnumerator ShowText(TMP_Text text, string message, float secondsBetweenLetters = 0.005f, AudioSource clickAudio = null)
		{
			int currentLetter = 0;
			text.text = "";
			while (currentLetter < message.Length)
			{
				int num;
				if (message[currentLetter] == '<')
				{
					while (message[currentLetter] != '>' && currentLetter <= message.Length)
					{
						num = currentLetter + 1;
						currentLetter = num;
					}
				}
				else if (currentLetter < message.Length - 1)
				{
					while (currentLetter < message.Length - 1 && message[currentLetter + 1] == ' ')
					{
						num = currentLetter + 1;
						currentLetter = num;
					}
				}
				num = currentLetter + 1;
				currentLetter = num;
				text.text = message.Substring(0, currentLetter);
				if ((Object)(object)clickAudio != (Object)null && message[currentLetter - 1] != '\n' && message[currentLetter - 1] != ' ')
				{
					clickAudio.Play();
				}
				yield return (object)new WaitForSecondsRealtime(secondsBetweenLetters);
			}
		}

		public static IEnumerator HideText(TMP_Text text, float secondsBetweenLetters = 0.005f)
		{
			int currentLetter = text.text.Length - 1;
			string message = text.text;
			while (currentLetter >= 0)
			{
				int num;
				if (text.text[currentLetter] == '>')
				{
					while (text.text[currentLetter] != '<' && currentLetter >= 0)
					{
						num = currentLetter - 1;
						currentLetter = num;
					}
				}
				num = currentLetter - 1;
				currentLetter = num;
				text.text = message.Substring(0, currentLetter + 1);
				yield return (object)new WaitForSecondsRealtime(secondsBetweenLetters);
			}
		}
	}
	public static class StringExtensions
	{
	}
}
namespace Jukebox.UI
{
	public class JukeboxCredits : MonoBehaviour
	{
		[SerializeField]
		private TMP_Text terminalText;

		[SerializeField]
		private AudioSource click;

		[SerializeField]
		private GameObject firstWindow;

		[SerializeField]
		private GameObject secondWindow;

		[SerializeField]
		private List<GameObject> lastWindows;

		private string originalText;

		private void Awake()
		{
			originalText = terminalText.text;
		}

		private void OnEnable()
		{
			firstWindow.SetActive(false);
			secondWindow.SetActive(false);
			foreach (GameObject lastWindow in lastWindows)
			{
				lastWindow.SetActive(false);
			}
			((MonoBehaviour)this).StartCoroutine(ScrollingTextUnscaled.ShowText(terminalText, originalText, 0.01f, click));
			((MonoBehaviour)this).StartCoroutine(WindowsRoutine());
		}

		private IEnumerator WindowsRoutine()
		{
			yield return (object)new WaitForSecondsRealtime(1f);
			firstWindow.SetActive(true);
			yield return (object)new WaitForSecondsRealtime(1f);
			secondWindow.SetActive(true);
			yield return (object)new WaitForSecondsRealtime(2f);
			foreach (GameObject lastWindow in lastWindows)
			{
				lastWindow.SetActive(true);
			}
		}
	}
	public class JukeboxCustomContentButton : CustomContentButton
	{
		[SerializeField]
		public GameObject introAndLoopIcon;

		[SerializeField]
		public GameObject calmThemeIcon;
	}
	public class JukeboxUI : MonoBehaviour
	{
		[SerializeField]
		public GameObject jukeboxMenuTemplate;

		[SerializeField]
		public GameObject playbackMenuTemplate;

		[SerializeField]
		public GameObject nowPlayingHudTemplate;

		[SerializeField]
		public GameObject nowPlayingHudClassicTemplate;

		private GameObject jukeboxMenu;

		private GameObject playbackMenu;

		private GameObject nowPlayingHud;

		private GameObject nowPlayingHudClassic;

		private ReadOnlyCollection<JukeboxWindow> windows;

		protected void Awake()
		{
			InstantiateUI();
			windows = new ReadOnlyCollection<JukeboxWindow>(new List<JukeboxWindow>
			{
				jukeboxMenu.GetComponent<JukeboxWindow>(),
				playbackMenu.GetComponent<JukeboxPlaybackWindow>()
			});
			foreach (JukeboxWindow window in windows)
			{
				((Component)window).gameObject.SetActive(false);
			}
		}

		protected void Update()
		{
			ManageWindows();
		}

		private void ManageWindows()
		{
			if (GameIsPaused())
			{
				return;
			}
			if (MonoSingleton<InputManager>.Instance.InputSource.Pause.WasPerformedThisFrame)
			{
				foreach (JukeboxWindow window in windows)
				{
					if (window.IsOpened())
					{
						window.Close();
					}
				}
				return;
			}
			JukeboxWindow jukeboxWindow = windows.FirstOrDefault((JukeboxWindow w) => w.hotkey.ToInputAction().WasPerformedThisFrame());
			if ((Object)(object)jukeboxWindow != (Object)null)
			{
				foreach (JukeboxWindow window2 in windows)
				{
					if (InputExtensions.IsActionEqual(window2.hotkey.ToInputAction(), jukeboxWindow.hotkey.ToInputAction(), (string)null))
					{
						window2.Toggle();
					}
					else
					{
						window2.Close();
					}
				}
			}
			if (!windows.Any((JukeboxWindow w) => GameStateManager.Instance.IsStateActive(w.StateKey())) && MonoSingleton<OptionsManager>.Instance.paused)
			{
				MonoSingleton<JukeboxPauseManager>.Instance.UnPause();
			}
		}

		private void InstantiateUI()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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)
			GameObject val = new GameObject
			{
				name = "JukeboxCanvas"
			};
			val.AddComponent<Canvas>();
			GameObject val2 = GameObject.Find("/Canvas");
			Canvas component = val.GetComponent<Canvas>();
			component.renderMode = (RenderMode)1;
			component.sortingOrder = val2.GetComponent<Canvas>().sortingOrder + 1;
			val.AddComponent<CanvasScaler>();
			val.AddComponent<GraphicRaycaster>();
			jukeboxMenu = Object.Instantiate<GameObject>(jukeboxMenuTemplate, val2.transform);
			playbackMenu = Object.Instantiate<GameObject>(playbackMenuTemplate, val2.transform);
			nowPlayingHud = Object.Instantiate<GameObject>(nowPlayingHudTemplate, GameObject.Find("/Player/Main Camera/HUD Camera/HUD/GunCanvas").transform, false);
			nowPlayingHudClassic = Object.Instantiate<GameObject>(nowPlayingHudClassicTemplate, val2.transform.Find("Crosshair Filler"), false);
		}

		private bool GameIsPaused()
		{
			return GameStateManager.Instance.IsStateActive("pause");
		}
	}
	public class ScrollUIImageUnscaled : MonoBehaviour
	{
		private RawImage img;

		public float xSpeed;

		public float ySpeed;

		private void Start()
		{
			img = ((Component)this).GetComponent<RawImage>();
		}

		private void Update()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: 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_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			Rect uvRect = img.uvRect;
			Vector2 val = ((Rect)(ref uvRect)).position + new Vector2(xSpeed, ySpeed) * Time.unscaledDeltaTime;
			while ((double)val.x > 1.0)
			{
				val.x -= 1f;
			}
			while ((double)val.x < -1.0)
			{
				val.x += 1f;
			}
			while ((double)val.y > 1.0)
			{
				val.y -= 1f;
			}
			while ((double)val.y < -1.0)
			{
				val.y += 1f;
			}
			RawImage obj = img;
			uvRect = img.uvRect;
			Vector2 val2 = ((Rect)(ref uvRect)).position + new Vector2(xSpeed, ySpeed) * Time.unscaledDeltaTime;
			uvRect = img.uvRect;
			obj.uvRect = new Rect(val2, ((Rect)(ref uvRect)).size);
		}
	}
}
namespace Jukebox.UI.Windows
{
	public class JukeboxMenuWindow : JukeboxWindow
	{
		[SerializeField]
		protected Button[] buttons;

		[SerializeField]
		protected GameObject activeBgObject;

		public override string StateKey()
		{
			return "jukeboxMenu";
		}

		protected override void Awake()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			base.Awake();
			Button[] array = buttons;
			foreach (Button button in array)
			{
				((UnityEvent)button.onClick).AddListener((UnityAction)delegate
				{
					//IL_0046: Unknown result type (might be due to invalid IL or missing references)
					activeBgObject.transform.SetParent(((Component)button).transform);
					activeBgObject.transform.SetSiblingIndex(0);
					activeBgObject.transform.localPosition = Vector3.zero;
				});
			}
		}
	}
	public class JukeboxPlaybackWindow : JukeboxWindow
	{
		public override string StateKey()
		{
			return "jukeboxPlayback";
		}
	}
	public abstract class JukeboxWindow : MonoBehaviour
	{
		[SerializeField]
		public InputActionReference hotkey;

		public abstract string StateKey();

		public void Open()
		{
			((Component)this).gameObject.SetActive(true);
			MonoSingleton<JukeboxPauseManager>.Instance.Pause(StateKey(), ((Component)this).gameObject);
		}

		public void Close()
		{
			GameStateManager.Instance.PopState(StateKey());
			((Component)this).gameObject.SetActive(false);
		}

		public void Toggle()
		{
			if (IsOpened())
			{
				Close();
			}
			else
			{
				Open();
			}
		}

		protected virtual void Awake()
		{
			if ((Object)(object)hotkey != (Object)null)
			{
				hotkey = InputActionReference.Create(MonoSingleton<InputManager>.Instance.InputSource.Actions.asset.FindAction(hotkey.ToInputAction().id));
			}
		}

		public bool IsOpened()
		{
			return ((Component)this).gameObject.activeSelf;
		}
	}
}
namespace Jukebox.UI.Themes
{
	public class ThemeSettingsMenu : MonoBehaviour
	{
		[SerializeField]
		private Counter threshold;

		[SerializeField]
		private GameObject enemyTemplate;

		[SerializeField]
		private List<AssetReferenceT<SpawnableObject>> enemies;

		private void Awake()
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			JukeboxThemesManager themesManager = MonoSingleton<JukeboxThemesManager>.Instance;
			threshold.SetDefaultValue(MonoSingleton<PrefsManager>.Instance.GetIntLocal("jukebox.calmThemeEnemiesThreshold", 0));
			threshold.OnChanged += OnThresholdChanged;
			foreach (AssetReferenceT<SpawnableObject> enemy2 in enemies)
			{
				AsyncOperationHandle<SpawnableObject> val = enemy2.LoadAssetAsync();
				SpawnableObject enemy = val.WaitForCompletion();
				Addressables.Release<SpawnableObject>(val);
				GameObject val2 = Object.Instantiate<GameObject>(enemyTemplate, enemyTemplate.transform.parent);
				Sprite gridIcon = enemy.gridIcon;
				((Component)val2.transform.Find("Icon")).GetComponentInChildren<Image>().sprite = gridIcon;
				((Component)val2.transform.Find("Title")).GetComponentInChildren<TMP_Text>().text = enemy.objectName;
				Counter counter = val2.GetComponentInChildren<Counter>();
				Toggle toggle = val2.GetComponentInChildren<Toggle>();
				int? thresholdFor = themesManager.GetThresholdFor(enemy.enemyType);
				if (!thresholdFor.HasValue)
				{
					toggle.isOn = false;
					counter.SetDefaultValue(0);
				}
				else
				{
					counter.SetDefaultValue(thresholdFor.Value);
				}
				counter.OnChanged += delegate(int value)
				{
					//IL_001d: Unknown result type (might be due to invalid IL or missing references)
					toggle.isOn = true;
					themesManager.SetThresholdFor(enemy.enemyType, value);
				};
				((UnityEvent<bool>)(object)toggle.onValueChanged).AddListener((UnityAction<bool>)delegate(bool on)
				{
					//IL_003b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0014: Unknown result type (might be due to invalid IL or missing references)
					if (on)
					{
						themesManager.SetThresholdFor(enemy.enemyType, counter.Value);
					}
					else
					{
						themesManager.DisableThresholdFor(enemy.enemyType);
					}
				});
				val2.SetActive(true);
			}
		}

		private void OnDestroy()
		{
			threshold.OnChanged -= OnThresholdChanged;
		}

		private static void OnThresholdChanged(int value)
		{
			MonoSingleton<PrefsManager>.Instance.SetIntLocal("jukebox.calmThemeEnemiesThreshold", value);
		}
	}
}
namespace Jukebox.UI.SongPanel
{
	public class ClassicSongPanel : SongPanel
	{
		protected override SongPanelStyle Style => SongPanelStyle.Classic;

		protected override IEnumerator FadeIn(JukeboxSongMetadata metadata)
		{
			float time = 0f;
			while ((double)time < (double)panelApproachTime)
			{
				time += Time.unscaledDeltaTime;
				panelGroup.alpha = (active ? (time / panelApproachTime) : 0f);
				yield return null;
			}
			panelGroup.alpha = (active ? 1 : 0);
		}

		protected override IEnumerator Await()
		{
			float time = panelStayTime;
			while ((double)time > 0.0 || showIndefinitely)
			{
				panelGroup.alpha = (active ? 1 : 0);
				if ((double)time > 0.0)
				{
					time -= Time.unscaledDeltaTime;
				}
				yield return null;
			}
		}

		protected override IEnumerator FadeOut()
		{
			float time = panelApproachTime;
			while ((double)time > 0.0)
			{
				time -= Time.unscaledDeltaTime;
				panelGroup.alpha = (active ? (time / panelApproachTime) : 0f);
				yield return null;
			}
			panelGroup.alpha = 0f;
		}
	}
	public class JukeboxSongPanel : SongPanel
	{
		[SerializeField]
		public Vector2 startDimensions;

		[SerializeField]
		public Vector2 targetDimensions;

		private Coroutine rollingTextRoutine;

		protected override SongPanelStyle Style => SongPanelStyle.Jukebox;

		protected override IEnumerator FadeIn(JukeboxSongMetadata metadata)
		{
			((Graphic)base.text).color = new Color(1f, 1f, 1f, 1f);
			RectTransform rect = ((Component)panelGroup).GetComponent<RectTransform>();
			rect.sizeDelta = startDimensions;
			string text = ((!string.IsNullOrEmpty(metadata.Artist)) ? ("<color=#999>" + metadata.Artist + "</color>") : string.Empty);
			if (rollingTextRoutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(rollingTextRoutine);
			}
			base.text.text = string.Empty;
			rollingTextRoutine = ((MonoBehaviour)this).StartCoroutine(ScrollingTextUnscaled.ShowText(base.text, metadata.Title.ToUpper() + " " + text, 0.022f));
			float time = 0f;
			while (time < panelApproachTime)
			{
				panelGroup.alpha = (active ? 1 : 0);
				time += Time.unscaledDeltaTime;
				if (time > panelApproachTime)
				{
					time = panelApproachTime;
				}
				rect.sizeDelta = startDimensions + (targetDimensions - startDimensions) * time / panelApproachTime;
				yield return null;
			}
		}

		protected override IEnumerator Await()
		{
			float time = panelStayTime;
			while ((double)time > 0.0 || showIndefinitely)
			{
				panelGroup.alpha = (active ? 1 : 0);
				if ((double)time > 0.0)
				{
					time -= Time.unscaledDeltaTime;
				}
				yield return null;
			}
		}

		protected override IEnumerator FadeOut()
		{
			rollingTextRoutine = ((MonoBehaviour)this).StartCoroutine(ScrollingTextUnscaled.HideText(text, 0.022f));
			RectTransform rect = ((Component)panelGroup).GetComponent<RectTransform>();
			float time = panelApproachTime;
			yield return (object)new WaitUntil((Func<bool>)(() => text.text.Length <= 20));
			while ((double)time > 0.0)
			{
				panelGroup.alpha = (active ? 1 : 0);
				time -= Time.unscaledDeltaTime;
				if (time < 0f)
				{
					time = 0f;
				}
				rect.sizeDelta = startDimensions + (targetDimensions - startDimensions) * time / panelApproachTime;
				yield return null;
			}
			panelGroup.alpha = 0f;
		}
	}
	public class PlaylistSelectable : DirectoryTreeBrowser<JukeboxSong>
	{
		[SerializeField]
		public GameObject selectPlaylistPanel;

		[SerializeField]
		public string playlistName;

		[SerializeField]
		public Button button;

		[SerializeField]
		public GameObject empty;

		protected override int maxPageLength => 6;

		protected override IDirectoryTree<JukeboxSong> baseDirectory
		{
			get
			{
				JukeboxPlaylist jukeboxPlaylist;
				using (StreamReader streamReader = new StreamReader(System.IO.File.Open(JukeboxPlaylist.PathForPlaylist(playlistName), FileMode.OpenOrCreate)))
				{
					jukeboxPlaylist = JsonConvert.DeserializeObject<JukeboxPlaylist>(streamReader.ReadToEnd());
				}
				List<SongIdentifier> source = ((jukeboxPlaylist != null) ? ((Playlist)jukeboxPlaylist).ids : new List<SongIdentifier>());
				return (IDirectoryTree<JukeboxSong>)(object)new FakeDirectoryTree<JukeboxSong>("Songs", from id in source
					where (int)id.type != 1 || new FileInfo(id.path).Exists
					select MonoSingleton<JukeboxSongsLoader>.Instance.Load(id), (IEnumerable<IDirectoryTree<JukeboxSong>>)null, (IDirectoryTree<JukeboxSong>)null);
			}
		}

		private void Awake()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			((UnityEvent)button.onClick).AddListener((UnityAction)delegate
			{
				MonoSingleton<PrefsManager>.Instance.SetStringLocal("jukebox.currentPlaylist", playlistName);
				MonoSingleton<JukeboxManager>.Instance.playlistEditor.ReloadPlaylist();
				selectPlaylistPanel.SetActive(false);
			});
		}

		private void OnEnable()
		{
			base.currentDirectory = ((DirectoryTreeBrowser<JukeboxSong>)this).baseDirectory;
			((DirectoryTreeBrowser<JukeboxSong>)this).Rebuild(true);
		}

		protected override Action BuildLeaf(JukeboxSong item, int indexInPage)
		{
			GameObject go = Object.Instantiate<GameObject>(base.itemButtonTemplate, base.itemButtonTemplate.transform.parent);
			go.SetActive(true);
			go.GetComponent<Image>().sprite = item.Metadata.Icon;
			return delegate
			{
				Object.Destroy((Object)(object)go);
			};
		}

		public override void Rebuild(bool setToPageZero = true)
		{
			base.Rebuild(setToPageZero);
			Transform itemParent = base.itemParent;
			LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform)(object)((itemParent is RectTransform) ? itemParent : null));
			empty.SetActive(!base.currentDirectory.files.Any());
		}
	}
	public abstract class SongPanel : MonoBehaviour
	{
		[SerializeField]
		public CanvasGroup panelGroup;

		[SerializeField]
		public Sprite defaultIcon;

		[SerializeField]
		public float panelApproachTime;

		[SerializeField]
		public float panelStayTime;

		public TMP_Text text;

		public Image icon;

		protected bool showIndefinitely;

		protected bool active;

		private Coroutine displayRoutine;

		protected abstract SongPanelStyle Style { get; }

		protected abstract IEnumerator FadeIn(JukeboxSongMetadata metadata);

		protected abstract IEnumerator Await();

		protected abstract IEnumerator FadeOut();

		public void Awake()
		{
			PrefsManager.onPrefChanged = (Action<string, object>)Delegate.Combine(PrefsManager.onPrefChanged, new Action<string, object>(OnPrefChanged));
			JukeboxMusicPlayer.onNextSong = (Action<JukeboxSong>)Delegate.Combine(JukeboxMusicPlayer.onNextSong, new Action<JukeboxSong>(OnNextSong));
			JukeboxMusicPlayer.onStop = (Action)Delegate.Combine(JukeboxMusicPlayer.onStop, new Action(OnStop));
			showIndefinitely = MonoSingleton<PrefsManager>.Instance.GetBoolLocal("jukebox.showTrackPanelIndefinitely", false);
			active = MonoSingleton<PrefsManager>.Instance.GetIntLocal("jukebox.songPanelStyle", 0) == (int)Style;
		}

		public void OnDestroy()
		{
			PrefsManager.onPrefChanged = (Action<string, object>)Delegate.Remove(PrefsManager.onPrefChanged, new Action<string, object>(OnPrefChanged));
			JukeboxMusicPlayer.onNextSong = (Action<JukeboxSong>)Delegate.Remove(JukeboxMusicPlayer.onNextSong, new Action<JukeboxSong>(OnNextSong));
			JukeboxMusicPlayer.onStop = (Action)Delegate.Remove(JukeboxMusicPlayer.onStop, new Action(OnStop));
		}

		private IEnumerator ShowPanelRoutine(JukeboxSongMetadata metadata)
		{
			string text = ((!string.IsNullOrEmpty(metadata.Artist)) ? ("<color=#999>" + metadata.Artist + "</color>") : string.Empty);
			this.text.text = metadata.Title.ToUpper() + " " + text;
			icon.sprite = (((Object)(object)metadata.Icon != (Object)null) ? metadata.Icon : defaultIcon);
			yield return FadeIn(metadata);
			yield return Await();
			yield return FadeOut();
		}

		private void OnNextSong(JukeboxSong song)
		{
			active = MonoSingleton<PrefsManager>.Instance.GetIntLocal("jukebox.songPanelStyle", 0) == (int)Style;
			if (displayRoutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(displayRoutine);
			}
			displayRoutine = ((MonoBehaviour)this).StartCoroutine(ShowPanelRoutine(song.Metadata));
		}

		private void OnStop()
		{
			active = false;
		}

		private void OnPrefChanged(string key, object value)
		{
			if (key.Equals("jukebox.showTrackPanelIndefinitely"))
			{
				showIndefinitely = (bool)value;
			}
			if (key.Equals("jukebox.songPanelStyle"))
			{
				active = (int)value == (int)Style;
			}
		}
	}
	public class SongPanelOption : MonoBehaviour
	{
		private static readonly Color Active = new Color(0.68f, 0.68f, 0.68f, 0.25f);

		private static readonly Color Inactive = new Color(0f, 0f, 0f, 0.59f);

		public SongPanelStyle style;

		private void Start()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			((Graphic)((Component)this).gameObject.GetComponent<Image>()).color = ((MonoSingleton<PrefsManager>.Instance.GetIntLocal("jukebox.songPanelStyle", 0) == (int)style) ? Active : Inactive);
		}

		public void Select()
		{
			//IL_003e: 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)
			Button[] componentsInChildren = ((Component)((Component)this).transform.parent).GetComponentsInChildren<Button>();
			foreach (Button val in componentsInChildren)
			{
				((Graphic)((Component)val).gameObject.GetComponent<Image>()).color = (((Object)(object)val == (Object)(object)((Component)this).gameObject.GetComponent<Button>()) ? Active : Inactive);
			}
			MonoSingleton<PrefsManager>.Instance.SetIntLocal("jukebox.songPanelStyle", (int)style);
		}
	}
	public enum SongPanelStyle
	{
		Jukebox,
		Classic
	}
}
namespace Jukebox.UI.Elements
{
	public class Counter : MonoBehaviour
	{
		[SerializeField]
		private TextMeshProUGUI textValue;

		[SerializeField]
		private CounterButton increase;

		[SerializeField]
		private CounterButton decrease;

		[SerializeField]
		private int minValue;

		[SerializeField]
		private int maxValue;

		private int tmpValue;

		private IEnumerator changeValueRoutine;

		public int Value { get; set; }

		public event Action<int> OnChanged;

		public void Awake()
		{
			AddEvents(increase, delegate
			{
				tmpValue = ChangeValue((int i) => i + 1);
			});
			AddEvents(decrease, delegate
			{
				tmpValue = ChangeValue((int i) => i - 1);
			});
		}

		public void SetDefaultValue(int defaultValue)
		{
			Value = defaultValue;
			tmpValue = defaultValue;
			((TMP_Text)textValue).text = defaultValue.ToString();
		}

		private void AddEvents(CounterButton button, Action<int> callback)
		{
			button.OnDown += delegate
			{
				changeValueRoutine = ChangeValueRoutine(callback);
				((MonoBehaviour)this).StartCoroutine(changeValueRoutine);
			};
			button.OnUp += SaveValue;
			button.OnExit += SaveValue;
		}

		private void SaveValue()
		{
			if (changeValueRoutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(changeValueRoutine);
			}
			Value = tmpValue;
			((TMP_Text)textValue).text = Value.ToString();
			this.OnChanged?.Invoke(Value);
		}

		private IEnumerator ChangeValueRoutine(Action<int> callback)
		{
			callback(tmpValue);
			yield return (object)new WaitForSecondsRealtime(0.3f);
			while (true)
			{
				callback(tmpValue);
				yield return (object)new WaitForSecondsRealtime(0.1f);
			}
		}

		private int ChangeValue(Func<int, int> operation)
		{
			int result = ValidateOperation(operation);
			((TMP_Text)textValue).text = result.ToString();
			return result;
		}

		private int ValidateOperation(Func<int, int> operation)
		{
			int num = operation(tmpValue);
			if (num >= minValue && num <= maxValue)
			{
				return num;
			}
			return tmpValue;
		}
	}
	public class CounterButton : Button
	{
		public bool pressed;

		public event Action OnDown;

		public event Action OnUp;

		public event Action OnExit;

		public override void OnPointerDown(PointerEventData eventData)
		{
			pressed = true;
			((Selectable)this).OnPointerDown(eventData);
			this.OnDown?.Invoke();
		}

		public override void OnPointerUp(PointerEventData eventData)
		{
			pressed = false;
			((Selectable)this).OnPointerUp(eventData);
			this.OnUp?.Invoke();
		}

		public override void OnPointerExit(PointerEventData eventData)
		{
			((Selectable)this).OnPointerExit(eventData);
			if (pressed)
			{
				this.OnExit?.Invoke();
			}
			pressed = false;
		}
	}
}
namespace Jukebox.UI.Effects
{
	public class SoundEffectButton : MonoBehaviour
	{
		[SerializeField]
		private string prefsKey;

		[SerializeField]
		private TMP_Text title;

		[SerializeField]
		private TMP_Text fileNameText;

		[SerializeField]
		private TMP_Text browserWindowTitle;

		protected void Awake()
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			ChangeFileName(MonoSingleton<PrefsManager>.Instance.GetStringLocal(prefsKey, (string)null));
			PrefsManager.onPrefChanged = (Action<string, object>)Delegate.Combine(PrefsManager.onPrefChanged, new Action<string, object>(OnPrefChanged));
			((UnityEvent)((Component)this).GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				browserWindowTitle.text = "Select file for " + title.text;
			});
		}

		protected void OnDestroy()
		{
			PrefsManager.onPrefChanged = (Action<string, object>)Delegate.Remove(PrefsManager.onPrefChanged, new Action<string, object>(OnPrefChanged));
		}

		private void OnPrefChanged(string key, object value)
		{
			if (key.Equals(prefsKey))
			{
				ChangeFileName((string)value);
			}
		}

		private void ChangeFileName(string fileName)
		{
			fileNameText.text = ((fileName != null) ? new FileInfo(fileName).Name : "Default");
		}
	}
}
namespace Jukebox.UI.Decorators
{
	public class ControlBindDecorator : MonoBehaviour
	{
		[SerializeField]
		public InputActionReference action;

		protected void Awake()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			InputAction val = MonoSingleton<InputManager>.Instance.InputSource.Actions.asset.FindAction(action.ToInputAction().id);
			((Component)this).GetComponentInChildren<ControlsOptionsKey>().RebuildBindings(val, MonoSingleton<InputManager>.Instance.InputSource.Actions.KeyboardMouseScheme);
		}
	}
	public abstract class UIDecorator<T> : MonoBehaviour where T : MonoBehaviour
	{
		[SerializeField]
		public GameObject hint;

		protected GameObject control;

		protected abstract GameObject Template();

		protected abstract void Init();

		public void Start()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			control = Object.Instantiate<GameObject>(Template(), ((Component)this).transform);
			control.transform.position = ((Component)this).transform.position;
			Object.Destroy((Object)(object)hint);
			Init();
			Object.Destroy((Object)(object)((Component)this).GetComponent<T>());
		}
	}
	public class SliderDecorator : UIDecorator<SliderDecorator>
	{
		[AddressableAsset("Assets/Prefabs/UI/Settings/Elements/Slider Button.prefab", typeof(GameObject))]
		private static GameObject sliderTemplate;

		[SerializeField]
		public float minValue;

		[SerializeField]
		public float maxValue;

		[SerializeField]
		public SliderValueToTextConfig sliderConfig;

		protected override GameObject Template()
		{
			return sliderTemplate;
		}

		protected override void Init()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			Slider componentInChildren = ((Component)this).GetComponentInChildren<Slider>();
			componentInChildren.minValue = minValue;
			componentInChildren.maxValue = maxValue;
			((SliderValueToText)ReflectionUtils.GetPrivate<SettingsSlider>(((Component)this).GetComponentInChildren<SettingsSlider>(), typeof(SettingsSlider), "sliderValueToText")).ConfigureFrom(sliderConfig);
		}
	}
}
namespace Jukebox.Patches
{
	[HarmonyPatch(typeof(AudioMixerController))]
	public static class AudioMixerControllerPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(AudioMixerController), "Update")]
		public static void AudioMixerController_Update_Postfix(AudioMixerController __instance)
		{
			if (!((Object)(object)MonoSingleton<JukeboxManager>.Instance == (Object)null))
			{
				__instance.musicSound.SetFloat("allVolume", __instance.CalculateVolume(__instance.musicVolume) + MonoSingleton<JukeboxManager>.Instance.player.VolumeBoost);
			}
		}
	}
	[HarmonyPatch(typeof(DiscordController))]
	public static class DiscordControllerPatch
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UpdateActivityHandler <>9__0_0;

			internal void <DiscordController_UpdateWave_Prefix>b__0_0(Result _)
			{
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(DiscordController), "UpdateWave")]
		public static bool DiscordController_UpdateWave_Prefix(int wave)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Expected O, but got Unknown
			if (JukeboxMusicPlayer.CurrentSong == null || !MonoSingleton<PrefsManager>.Instance.GetBoolLocal("jukebox.discordAndSteamIntegration", false))
			{
				return true;
			}
			if ((Object)(object)DiscordController.Instance == (Object)null)
			{
				return false;
			}
			bool num = (bool)ReflectionUtils.GetPrivate<DiscordController>(DiscordController.Instance, typeof(DiscordController), "disabled");
			Activity val = (Activity)ReflectionUtils.GetPrivate<DiscordController>(DiscordController.Instance, typeof(DiscordController), "cachedActivity");
			ActivityManager val2 = (ActivityManager)ReflectionUtils.GetPrivate<DiscordController>(DiscordController.Instance, typeof(DiscordController), "activityManager");
			Discord val3 = (Discord)ReflectionUtils.GetPrivate<DiscordController>(DiscordController.Instance, typeof(DiscordController), "discord");
			if (num)
			{
				return false;
			}
			val.Details = $"WAVE: {wave} | \ud83c\udfb5 {JukeboxMusicPlayer.CurrentSong.ArtistAndTrack}";
			ReflectionUtils.SetPrivate<DiscordController, Activity>(DiscordController.Instance, typeof(DiscordController), "cachedActivity", val);
			if (val3 == null || val2 == null)
			{
				return false;
			}
			Activity val4 = val;
			object obj = <>c.<>9__0_0;
			if (obj == null)
			{
				UpdateActivityHandler val5 = delegate
				{
				};
				<>c.<>9__0_0 = val5;
				obj = (object)val5;
			}
			val2.UpdateActivity(val4, (UpdateActivityHandler)obj);
			return false;
		}
	}
	[HarmonyPatch(typeof(FinalCyberRank))]
	public static class FinalCyberRankPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(FinalCyberRank), "GameOver")]
		public static bool FinalCyberRank_GameOver_Prefix()
		{
			if ((Object)(object)MonoSingleton<JukeboxManager>.Instance.player != (Object)null)
			{
				MonoSingleton<JukeboxManager>.Instance.player.Stop();
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(InputActions))]
	public static class InputActionsPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public static void InputActions_Constructor_Postfix(InputActions __instance)
		{
			if (__instance.asset.FindActionMap("Jukebox", false) == null)
			{
				MergeInputActionAssets(__instance);
			}
		}

		private static void MergeInputActionAssets(InputActions ukInputActions)
		{
			if (Resources.FindObjectsOfTypeAll(typeof(InputActionAsset)).Length == 0)
			{
				Debug.LogError((object)"Couldn't load InputActionAsset");
				return;
			}
			string text = "{\r\n                \"maps\": [\r\n                    {\r\n                        \"name\": \"Jukebox\",\r\n                        \"id\": \"9dda5277-7734-4ec3-ad76-c8c0e5763d02\",\r\n                        \"actions\": [\r\n                            {\r\n                                \"name\": \"Next Track\",\r\n                                \"type\": \"Button\",\r\n                                \"id\": \"09c701ba-74bc-4818-80a7-d1049e88ed97\",\r\n                                \"expectedControlType\": \"Button\",\r\n                                \"processors\": \"\",\r\n                                \"interactions\": \"\",\r\n                                \"initialStateCheck\": false\r\n                            },\r\n                            {\r\n                                \"name\": \"Jukebox Menu\",\r\n                                \"type\": \"Button\",\r\n                                \"id\": \"2031a43b-3913-4384-a334-02669e72c30d\",\r\n                                \"expectedControlType\": \"Button\",\r\n                                \"processors\": \"\",\r\n                                \"interactions\": \"\",\r\n                                \"initialStateCheck\": false\r\n                            },\r\n                            {\r\n                                \"name\": \"Disable Player\",\r\n                                \"type\": \"Button\",\r\n                                \"id\": \"3675ceba-90d0-46f5-b634-d6c13d208ff6\",\r\n                                \"expectedControlType\": \"Button\",\r\n                                \"processors\": \"\",\r\n                                \"interactions\": \"\",\r\n                                \"initialStateCheck\": false\r\n                            },\r\n                            {\r\n                                \"name\": \"Playback Menu\",\r\n                                \"type\": \"Button\",\r\n                                \"id\": \"fa8430f8-91e7-454b-91f7-8b0147642ef9\",\r\n                                \"expectedControlType\": \"Button\",\r\n                                \"processors\": \"\",\r\n                                \"interactions\": \"\",\r\n                                \"initialStateCheck\": false\r\n                            }\r\n                        ],\r\n                        \"bindings\": [\r\n                            {\r\n                                \"name\": \"\",\r\n                                \"id\": \"8ec3310e-3f25-46a8-9a97-347d624fb616\",\r\n                                \"path\": \"<Keyboard>/f3\",\r\n                                \"interactions\": \"\",\r\n                                \"processors\": \"\",\r\n                                \"groups\": \"Keyboard & Mouse\",\r\n                                \"action\": \"Next Track\",\r\n                                \"isComposite\": false,\r\n                                \"isPartOfComposite\": false\r\n                            },\r\n                            {\r\n                                \"name\": \"\",\r\n                                \"id\": \"b6df442f-c08f-4187-940a-9b684fa729c5\",\r\n                                \"path\": \"<Keyboard>/f4\",\r\n                                \"interactions\": \"\",\r\n                                \"processors\": \"\",\r\n                                \"groups\": \"Keyboard & Mouse\",\r\n                                \"action\": \"Jukebox Menu\",\r\n                                \"isComposite\": false,\r\n                                \"isPartOfComposite\": false\r\n                            },\r\n                            {\r\n                                \"name\": \"\",\r\n                                \"id\": \"48676d48-feb2-406e-bc66-91f1aa7b11f1\",\r\n                                \"path\": \"<Keyboard>/backquote\",\r\n                                \"interactions\": \"\",\r\n                                \"processors\": \"\",\r\n                                \"groups\": \"Keyboard & Mouse\",\r\n                                \"action\": \"Playback Menu\",\r\n                                \"isComposite\": false,\r\n                                \"isPartOfComposite\": false\r\n                            },\r\n                            {\r\n                                \"name\": \"\",\r\n                                \"id\": \"b86c9dc7-c6a1-4490-8aaa-bcb7dc1aa3cd\",\r\n                                \"path\": \"<Keyboard>/f10\",\r\n                                \"interactions\": \"\",\r\n                                \"processors\": \"\",\r\n                                \"groups\": \"Keyboard & Mouse\",\r\n                                \"action\": \"Disable Player\",\r\n                                \"isComposite\": false,\r\n                                \"isPartOfComposite\": false\r\n                            }\r\n                        ]\r\n                    }\r\n                ]\r\n            }";
			InputActionSetupExtensions.AddActionMap(ukInputActions.asset, InputActionMap.FromJson(text)[0]);
		}
	}
	[HarmonyPatch(typeof(InputManager))]
	public static class InputManagerPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(InputManager), "Rebind")]
		public static bool InputManager_Rebind_Prefix(InputManager __instance, InputAction action, int? existingIndex, Action onComplete, Action onCancel, InputControlScheme scheme)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			if (action.actionMap.name != "Jukebox")
			{
				return true;
			}
			__instance.WaitForButton((Action<string>)delegate(string path)
			{
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_0097: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_0082: Unknown result type (might be due to invalid IL or missing references)
				//IL_009d: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				if (path == "<Mouse>/leftButton")
				{
					onComplete?.Invoke();
				}
				else if (((IEnumerable<InputBinding>)(object)action.bindings).Any((InputBinding binding) => InputSystem.FindControl(((InputBinding)(ref binding)).path) == InputSystem.FindControl(path)))
				{
					onComplete?.Invoke();
				}
				else
				{
					BindingSyntax val = ((!existingIndex.HasValue) ? InputActionSetupExtensions.AddBinding(action, default(InputBinding)) : InputActionSetupExtensions.ChangeBinding(action, existingIndex.GetValueOrDefault()));
					val = ((BindingSyntax)(ref val)).WithPath(path);
					((BindingSyntax)(ref val)).WithGroup(((InputControlScheme)(ref scheme)).bindingGroup);
					__instance.actionModified?.Invoke(action);
					if (onComplete != null)
					{
						onComplete();
					}
				}
			}, (Action)delegate
			{
				onCancel?.Invoke();
			}, ((IEnumerable<DeviceRequirement>)(object)((InputControlScheme)(ref scheme)).deviceRequirements).Select((DeviceRequirement requirement) => ((DeviceRequirement)(ref requirement)).controlPath).ToList());
			return false;
		}
	}
	[HarmonyPatch(typeof(ScreenZone))]
	public static class ScreenZonePatch
	{
		private static PreviewHelper helper;

		private static ScreenZone cgTerminal;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ScreenZone), "Awake")]
		public static void ScreenZone_Awake_Postfix(ScreenZone __instance)
		{
			if (!(((Object)__instance).name != "Cybergrind Shop"))
			{
				PreviewHelper previewHelper = default(PreviewHelper);
				if (!((Component)__instance).TryGetComponent<PreviewHelper>(ref previewHelper))
				{
					((Component)__instance).gameObject.AddComponent<PreviewHelper>();
				}
				cgTerminal = __instance;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(ScreenZone), "Update")]
		public static bool ScreenZone_Update_Prefix(bool ___inZone, ScreenZone __instance)
		{
			if ((Object)(object)cgTerminal != (Object)(object)__instance)
			{
				return true;
			}
			if ((Object)(object)helper == (Object)null)
			{
				PreviewHelper previewHelper = default(PreviewHelper);
				if (!((Component)__instance).TryGetComponent<PreviewHelper>(ref previewHelper))
				{
					return true;
				}
				helper = previewHelper;
			}
			helper.inZone = ___inZone;
			return true;
		}
	}
	[HarmonyPatch(typeof(SteamController))]
	public static class SteamControllerPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(SteamController), "UpdateWave")]
		public static bool SteamController_UpdateWave_Prefix(int wave)
		{
			if (JukeboxMusicPlayer.CurrentSong == null || !MonoSingleton<PrefsManager>.Instance.GetBoolLocal("jukebox.discordAndSteamIntegration", false))
			{
				return true;
			}
			if (!SteamClient.IsValid)
			{
				return false;
			}
			SteamFriends.SetRichPresence("wave", $"WAVE: {wave} | \ud83c\udfb5 {JukeboxMusicPlayer.CurrentSong.ArtistAndTrack}");
			return false;
		}
	}
}
namespace Jukebox.Input
{
	[ConfigureSingleton(/*Could not decode attribute arguments.*/)]
	public class JukeboxInputs : MonoSingleton<JukeboxInputs>
	{
		private InputActionMap jukeboxActionMap;

		public InputAction Menu { get; private set; }

		public InputAction Playback { get; private set; }

		public InputAction NextTrack { get; private set; }

		public InputAction DisablePlayer { get; private set; }

		protected void Awake()
		{
			base.Awake();
			jukeboxActionMap = MonoSingleton<InputManager>.Instance.InputSource.Actions.asset.FindActionMap("Jukebox", false);
			Menu = jukeboxActionMap.FindAction("Jukebox Menu", false);
			Playback = jukeboxActionMap.FindAction("Playback Menu", false);
			NextTrack = jukeboxActionMap.FindAction("Next Track", false);
			DisablePlayer = jukeboxActionMap.FindAction("Disable Player", false);
			ResetM1Bindings();
		}

		private void ResetM1Bindings()
		{
			ResetLeftClick(Menu, "<Keyboard>/f4");
			ResetLeftClick(Playback, "<Keyboard>/backquote");
			ResetLeftClick(NextTrack, "<Keyboard>/f3");
			ResetLeftClick(DisablePlayer, "<Keyboard>/f10");
		}

		private void ResetLeftClick(InputAction binding, string defaultBinding)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (((IEnumerable<InputBinding>)(object)binding.bindings).Any((InputBinding b) => ((InputBinding)(ref b)).path == "<Mouse>/leftButton"))
			{
				BindingSyntax val = InputActionSetupExtensions.ChangeBinding(binding, InputActionRebindingExtensions.GetBindingIndex(Menu, (string)null, (string)null));
				val = ((BindingSyntax)(ref val)).WithPath(defaultBinding);
				((BindingSyntax)(ref val)).WithGroup("Keyboard & Mouse");
			}
		}
	}
}
namespace Jukebox.Core.Themes
{
	[CreateAssetMenu(menuName = "Jukebox/Calm theme")]
	public class CalmThemeEntry : ScriptableObject
	{
		[SerializeField]
		public AssetReferenceSoundtrackSong reference;

		[SerializeField]
		public List<AssetReferenceT<AudioClip>> calmVariationClips;
	}
	[CreateAssetMenu(menuName = "Jukebox/Calm Themes Data")]
	public class SoundtrackCalmThemes : ScriptableObject
	{
		[SerializeField]
		public CalmThemeEntry[] calmClips;

		public List<AssetReferenceT<AudioClip>> FindCalmClipsFor(string guid)
		{
			CalmThemeEntry calmThemeEntry = MonoSingleton<JukeboxManager>.Instance.calmThemes.calmClips.FirstOrDefault((CalmThemeEntry variation) => ((AssetReference)variation.reference).AssetGUID == guid);
			if (!((Object)(object)calmThemeEntry != (Object)null))
			{
				return null;
			}
			return calmThemeEntry.calmVariationClips;
		}
	}
}
namespace Jukebox.Core.Model.Themes
{
	[JsonObject(/*Could not decode attribute arguments.*/)]
	public class JukeboxThemesConfig
	{
		public class CalmThemeConfig
		{
			[JsonProperty(/*Could not decode attribute arguments.*/)]
			public Dictionary<EnemyType, int> SpecialEnemies = new Dictionary<EnemyType, int>
			{
				{
					(EnemyType)19,
					1
				},
				{
					(EnemyType)5,
					1
				},
				{
					(EnemyType)26,
					1
				},
				{
					(EnemyType)2,
					1
				},
				{
					(EnemyType)7,
					2
				}
			};
		}

		[JsonProperty("calmThemeConfig")]
		public CalmThemeConfig CalmTheme = new CalmThemeConfig();
	}
}
namespace Jukebox.Core.Model.Song
{
	public sealed class JukeboxCustomSong : JukeboxSong
	{
		[ExternalAsset("Assets/Jukebox/Textures/music_note.png", typeof(Sprite))]
		private static Sprite defaultIcon;

		private readonly List<UnityWebRequest> requests = new List<UnityWebRequest>();

		private List<DownloadHandlerAudioClip> handles;

		protected override Lazy<JukeboxSongMetadata> GetMetadata => new Lazy<JukeboxSongMetadata>(delegate
		{
			JukeboxSongMetadata jukeboxSongMetadata = JukeboxSongMetadata.From(new FileInfo(base.Id.path));
			if ((Object)(object)jukeboxSongMetadata.Icon == (Object)null)
			{
				jukeboxSongMetadata.Icon = defaultIcon;
			}
			return jukeboxSongMetadata;
		});

		private JukeboxCustomSong(string path)
			: base(new SongIdentifier(path, (IdentifierType)1))
		{
		}//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Expected O, but got Unknown


		~JukeboxCustomSong()
		{
			requests.ForEach(delegate(UnityWebRequest request)
			{
				request.Dispose();
			});
		}

		public static JukeboxCustomSong Create(string path)
		{
			return new JukeboxCustomSong(path);
		}

		protected override IEnumerator AcquireInternal(IEnumerator callback)
		{
			handles = new List<DownloadHandlerAudioClip>();
			if (base.Metadata.Composite.GotIntroAndLoop)
			{
				yield return Download(CompositeSongsUtils.WithPostfix(new FileInfo(base.Id.path), "intro"), delegate(AudioClip c)
				{
					base.IntroClip = c;
				});
			}
			yield return Download(base.Metadata.Composite.GotIntroAndLoop ? CompositeSongsUtils.WithPostfix(new FileInfo(base.Id.path), "loop") : new FileInfo(base.Id.path), delegate(AudioClip c)
			{
				base.Clips = new List<AudioClip> { c };
			});
			if (base.Metadata.Composite.GotCalmIntro)
			{
				yield return Download(CompositeSongsUtils.WithPostfix(new FileInfo(base.Id.path), "calmintro"), delegate(AudioClip c)
				{
					base.CalmIntroClip = c;
				});
			}
			if (base.Metadata.Composite.GotCalmTheme)
			{
				yield return Download(CompositeSongsUtils.WithPostfix(new FileInfo(base.Id.path), "calm"), delegate(AudioClip c)
				{
					base.CalmClips = new List<AudioClip> { c };
				});
			}
			if (base.Metadata.Composite.GotCalmLoop)
			{
				yield return Download(CompositeSongsUtils.WithPostfix(new FileInfo(base.Id.path), "calmloop"), delegate(AudioClip c)
				{
					base.CalmClips = new List<AudioClip> { c };
				});
			}
			yield return callback;
			IEnumerator Download(FileSystemInfo path, Action<AudioClip> downloadCallback)
			{
				UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(new Uri(path.FullName).AbsoluteUri, CustomMusicFileBrowser.extensionTypeDict[path.Extension.ToLower()]);
				requests.Add(audioClip);
				DownloadHandler downloadHandler = audioClip.downloadHandler;
				DownloadHandlerAudioClip handle = (DownloadHandlerAudioClip)(object)((downloadHandler is DownloadHandlerAudioClip) ? downloadHandler : null);
				handles.Add(handle);
				if (handle != null)
				{
					handle.streamAudio = true;
					audioClip.SendWebRequest();
					yield return audioClip;
					downloadCallback(handle.audioClip);
				}
			}
		}

		protected override void DisposeInternal()
		{
			DisposeOfRequests();
			DisposeOfHandlers();
			handles = null;
			DestroyClipIfPresent(base.IntroClip);
			foreach (AudioClip clip in base.Clips)
			{
				DestroyClipIfPresent(clip);
			}
		}

		private void DisposeOfRequests()
		{
			requests.ForEach(delegate(UnityWebRequest request)
			{
				request.Dispose();
			});
		}

		private void DisposeOfHandlers()
		{
			handles.ForEach(delegate(DownloadHandlerAudioClip request)
			{
				((DownloadHandler)request).Dispose();
			});
		}

		private static void DestroyClipIfPresent(AudioClip clip)
		{
			if ((Object)(object)clip != (Object)null)
			{
				Object.Destroy((Object)(object)clip);
			}
		}
	}
	public class JukeboxPlaylist : Playlist
	{
		public static string currentPath => Path.Combine(Playlist.directory.FullName, MonoSingleton<PrefsManager>.Instance.GetStringLocal("jukebox.currentPlaylist", (string)null) + ".json");

		public JukeboxPlaylist()
		{
		}

		public JukeboxPlaylist(IEnumerable<SongIdentifier> passedIds)
			: base(MonoSingleton<PrefsManager>.Instance.GetBoolLocal("jukebox.preventDuplicateTracks", false) ? passedIds.Distinct() : passedIds)
		{
		}

		public static string PathForPlaylist(string name)
		{
			return Path.Combine(Playlist.directory.FullName, name + ".json");
		}

		public void Add(SongIdentifier id)
		{
			if (!MonoSingleton<PrefsManager>.Instance.GetBoolLocal("jukebox.preventDuplicateTracks", false) || !((Playlist)this).ids.Contains(id))
			{
				((Playlist)this).Add(id);
			}
		}

		public void RemoveDuplicates()
		{
			List<SongIdentifier> list = ((Playlist)this).ids.Distinct().ToList();
			((Playlist)this).ids.Clear();
			foreach (SongIdentifier item in list)
			{
				Add(item);
			}
		}

		public void RemoveNonExisting()
		{
			List<SongIdentifier> list = ((Playlist)this).ids.Where((SongIdentifier id) => (int)id.type == 0 || new FileInfo(id.path).Exists).ToList();
			((Playlist)this).ids.Clear();
			foreach (SongIdentifier item in list)
			{
				Add(item);
			}
		}
	}
	public abstract class JukeboxSong
	{
		private readonly Lazy<JukeboxSongMetadata> lazyMetadata;

		public SongIdentifier Id { get; }

		public JukeboxSongMetadata Metadata => lazyMetadata.Value;

		public AudioClip IntroClip { get; protected set; }

		public AudioClip CalmIntroClip { get; protected set; }

		public List<AudioClip> Clips { get; protected set; }

		public List<AudioClip> CalmClips { get; protected set; }

		public int MaxClipsIfNotRepeating { get; protected set; }

		public bool IsCustom => (int)Id.type == 1;

		public string ArtistAndTrack
		{
			get
			{
				if (Metadata.Artist == null)
				{
					return Metadata.Title;
				}
				return Metadata.Artist + " — " + Metadata.Title;
			}
		}

		protected abstract Lazy<JukeboxSongMetadata> GetMetadata { get; }

		protected JukeboxSong(SongIdentifier id)
		{
			Id = id;
			lazyMetadata = GetMetadata;
		}

		public IEnumerator Acquire(IEnumerator callback)
		{
			yield return AcquireInternal(callback);
			Dispose();
		}

		private void Dispose()
		{
			DisposeInternal();
			IntroClip = null;
			CalmIntroClip = null;
			Clips = null;
			CalmClips = null;
			MaxClipsIfNotRepeating = -1;
		}

		protected abstract IEnumerator AcquireInternal(IEnumerator callback);

		protected abstract void DisposeInternal();
	}
	public static class JukeboxSongFactory
	{
		public static JukeboxSong Create(SongIdentifier id)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			IdentifierType type = id.type;
			if ((int)type != 0)
			{
				if ((int)type == 1)
				{
					return JukeboxCustomSong.Create(id.path);
				}
				throw new ArgumentOutOfRangeException();
			}
			return JukeboxSoundtrackSong.Create(id.path);
		}
	}
	public class JukeboxSongMetadata
	{
		public class CompositeProperties
		{
			public class Builder
			{
				public CompositeProperties Build { get; }

				public Builder()
				{
					Build = new CompositeProperties();
				}

				public Builder GotIntroAndLoop(bool val)
				{
					Build.GotIntroAndLoop = val;
					return this;
				}

				public Builder GotCalmIntro(bool val)
				{
					Build.GotCalmIntro = val;
					return this;
				}

				public Builder GotCalmTheme(bool val)
				{
					Build.GotCalmTheme = val;
					return this;
				}

				public Builder GotCalmLoop(bool val)
				{
					Build.GotCalmLoop = val;
					return this;
				}
			}

			public bool GotIntroAndLoop { get; private set; }

			public bool GotCalmIntro { get; private set; }

			public bool GotCalmTheme { get; private set; }

			public bool GotCalmLoop { get; private set; }

			private CompositeProperties()
			{
			}
		}

		public readonly CompositeProperties Composite;

		public Sprite Icon { get; set; }

		public string Title { get; }

		public string Artist { get; }

		private JukeboxSongMetadata(Sprite icon, string title, CompositeProperties composite, string artist = null)
		{
			Icon = icon;
			Title = title;
			Composite = composite;
			Artist = artist;
		}

		public static JukeboxSongMetadata From(FileInfo srcFile)
		{
			CompositeProperties songComponents = CompositeSongsUtils.GetSongComponents(srcFile);
			FileInfo fileInfo = (songComponents.GotIntroAndLoop ? CompositeSongsUtils.WithPostfix(srcFile, "intro") : srcFile);
			try
			{
				TagLib.Tag tag = TagLib.File.Create(fileInfo.FullName).Tag;
				return new JukeboxSongMetadata(LoadCover(tag), (!string.IsNullOrEmpty(tag.Title)) ? tag.Title : Path.GetFileNameWithoutExtension(srcFile.Name), songComponents, GenericUtils.FirstNonEmpty(tag.FirstPerformer, tag.FirstComposer, tag.FirstAlbumArtist));
			}
			catch (Exception)
			{
				return new JukeboxSongMetadata(null, fileInfo.Name, songComponents);
			}
		}

		public static JukeboxSongMetadata From(AssetReferenceSoundtrackSong reference)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			AsyncOperationHandle<SoundtrackSong> val = ((AssetReferenceT<SoundtrackSong>)(object)reference).LoadAssetAsync();
			val.WaitForCompletion();
			SoundtrackSong result = val.Result;
			return new JukeboxSongMetadata(result.icon, result.songName, CompositeSongsUtils.GetSongComponents(((AssetReference)reference).AssetGUID, result), result.extraLevelBit);
		}

		private static Sprite LoadCover(TagLib.Tag tag)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			if (tag.Pictures.Length == 0)
			{
				return null;
			}
			using MemoryStream memoryStream = new MemoryStream(tag.Pictures[0].Data.Data);
			try
			{
				memoryStream.Seek(0L, SeekOrigin.Begin);
				Texture2D val = new Texture2D(2, 2);
				ImageConversion.LoadImage(val, memoryStream.ToArray());
				return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
			}
			catch (Exception)
			{
				return null;
			}
		}
	}
	public sealed class JukeboxSoundtrackSong : JukeboxSong
	{
		private AsyncOperationHandle<SoundtrackSong> handle;

		private readonly List<AsyncOperationHandle<AudioClip>> calmClipsHandles = new List<AsyncOperationHandle<AudioClip>>();

		protected override Lazy<JukeboxSongMetadata> GetMetadata => new Lazy<JukeboxSongMetadata>(() => JukeboxSongMetadata.From(new AssetReferenceSoundtrackSong(base.Id.path)));

		private JukeboxSoundtrackSong(string path)
			: base(new SongIdentifier(path, (IdentifierType)0))
		{
		}//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Expected O, but got Unknown


		public static JukeboxSoundtrackSong Create(string path)
		{
			return new JukeboxSoundtrackSong(path);
		}

		protected override IEnumerator AcquireInternal(IEnumerator callback)
		{
			handle = Addressables.LoadAssetAsync<SoundtrackSong>((object)base.Id.path);
			yield return handle;
			SoundtrackSong addressable = handle.Result;
			base.IntroClip = addressable.introClip;
			base.Clips = addressable.clips;
			List<AssetReferenceT<AudioClip>> list = MonoSingleton<JukeboxManager>.Instance.calmThemes.FindCalmClipsFor(base.Id.path);
			if (list != null)
			{
				base.CalmClips = new List<AudioClip>();
				foreach (AsyncOperationHandle<AudioClip> calmClipHandle in list.Select((AssetReferenceT<AudioClip> clip) => Addressables.LoadAssetAsync<AudioClip>((object)((AssetReference)clip).AssetGUID)))
				{
					calmClipsHandles.Add(calmClipHandle);
					yield return calmClipHandle;
					base.CalmClips.Add(calmClipHandle.Result);
				}
			}
			base.MaxClipsIfNotRepeating = addressable.maxClipsIfNotRepeating;
			yield return callback;
		}

		protected override void DisposeInternal()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			Addressables.Release<SoundtrackSong>(handle);
			foreach (AsyncOperationHandle<AudioClip> calmClipsHandle in calmClipsHandles)
			{
				Addressables.Release<AudioClip>(calmClipsHandle);
			}
			calmClipsHandles.Clear();
			handle = default(AsyncOperationHandle<SoundtrackSong>);
		}
	}
}
namespace Jukebox.Core.Collections
{
	public class JukeboxFileTree : IDirectoryTree<JukeboxSong>, IDirectoryTree
	{
		public string name { get; private set; }

		public IDirectoryTree<JukeboxSong> parent { get; set; }

		public IEnumerable<IDirectoryTree<JukeboxSong>> children { get; private set; }

		public IEnumerable<JukeboxSong> files { get; private set; }

		private DirectoryInfo RealDirectory { get; }

		public JukeboxFileTree(string path, IDirectoryTree<JukeboxSong> parent = null)
		{
			RealDirectory = new DirectoryInfo(path);
			this.parent = parent;
			Refresh();
		}

		private JukeboxFileTree(DirectoryInfo realDirectory, IDirectoryTree<JukeboxSong> parent = null)
		{
			RealDirectory = realDirectory;
			this.parent = parent;
			Refresh();
		}

		public void Refresh()
		{
			RealDirectory.Create();
			name = RealDirectory.Name;
			children = from dir in RealDirectory.GetDirectories()
				select new JukeboxFileTree(dir, this);
			files = (from file in RealDirectory.GetFiles().Where(CompositeSongsUtils.HasValidExtenstion)
				group file by CompositeSongsUtils.WithoutPostfix(file).FullName into @group
				select MonoSingleton<JukeboxSongsLoader>.Instance.Load(new SongIdentifier(@group.Key, (IdentifierType)1))).ToList();
		}

		public override bool Equals(object obj)
		{
			if (obj != null && !(GetType() != obj.GetType()))
			{
				return string.Equals(RealDirectory.FullName, (obj as DirectoryInfo)?.FullName, StringComparison.InvariantCultureIgnoreCase);
			}
			return false;
		}

		public override int GetHashCode()
		{
			return RealDirectory.GetHashCode();
		}

		public IEnumerable<JukeboxSong> GetFilesRecursive()
		{
			return children.SelectMany((IDirectoryTree<JukeboxSong> child) => child.GetFilesRecursive()).Concat(files);
		}
	}
}
namespace Jukebox.Components
{
	public class CybergrindEffectsChanger : MonoBehaviour
	{
		private const string TerminalPath = "/FirstRoom/Room/Cybergrind Shop/Music";

		private CrowdReactions crowdReactions;

		private PrefsManager prefsManager;

		private AudioClip awwDefault;

		private AudioClip cheerDefault;

		private AudioClip cheerLongDefault;

		private AudioClip terminalMusicDefault;

		private AudioClip gameOverDefault;

		private static AudioSource EndMusicAudioSource
		{
			get
			{
				//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();
				return ((Scene)(ref activeScene)).GetRootGameObjects().First((GameObject o) => ((Object)o).name == "EndMusic").GetComponent<AudioSource>();
			}
		}

		private static AudioSource MenuMusicAudioSource => GameObject.Find("/FirstRoom/Room/Cybergrind Shop/Music").GetComponent<AudioSource>();

		private void Awake()
		{
			crowdReactions = MonoSingleton<CrowdReactions>.Instance;
			prefsManager = MonoSingleton<PrefsManager>.Instance;
			awwDefault = Object.Instantiate<AudioClip>(crowdReactions.aww, ((Component)this).gameObject.transform);
			cheerDefault = Object.Instantiate<AudioClip>(crowdReactions.cheer, ((Component)this).gameObject.transform);
			cheerLongDefault = Object.Instantiate<AudioClip>(crowdReactions.cheerLong, ((Component)this).gameObject.transform);
			terminalMusicDefault = Object.Instantiate<AudioClip>(MenuMusicAudioSource.clip, ((Component)this).gameObject.transform);
			gameOverDefault = Object.Instantiate<AudioClip>(EndMusicAudioSource.clip, ((Component)this).gameObject.transform);
			((MonoBehaviour)this).StartCoroutine(Setup());
			PrefsManager.onPrefChanged = (Action<string, object>)Delegate.Combine(PrefsManager.onPrefChanged, new Action<string, object>(OnPrefChanged));
		}

		private void OnDestroy()
		{
			PrefsManager.onPrefChanged = (Action<string, object>)Delegate.Remove(PrefsManager.onPrefChanged, new Action<string, object>(OnPrefChanged));
		}

		private IEnumerator Setup()
		{
			yield return PrepareParrySfx();
			yield return PrepareWaveCompleteSfx();
			yield return PrepareAwwSfx();
			yield return PrepareGameOverSfx();
			yield return PrepareTerminalMusic();
		}

		private IEnumerator PrepareParrySfx()
		{
			yield return PrepareClip(prefsManager.GetStringLocal("jukebox.effects.parry", (string)null), delegate(AudioClip clip)
			{
				crowdReactions.cheer = clip;
			}, cheerDefault);
		}

		private IEnumerator PrepareWaveCompleteSfx()
		{
			yield return PrepareClip(prefsManager.GetStringLocal("jukebox.effects.wavecomplete", (string)null), delegate(AudioClip clip)
			{
				crowdReactions.cheerLong = clip;
			}, cheerLongDefault);
		}

		private IEnumerator PrepareAwwSfx()
		{
			yield return PrepareClip(prefsManager.GetStringLocal("jukebox.effects.aww", (string)null), delegate(AudioClip clip)
			{
				crowdReactions.aww = clip;
			}, awwDefault);
		}

		private IEnumerator PrepareGameOverSfx()
		{
			yield return PrepareClip(prefsManager.GetStringLocal("jukebox.effects.gameover", (string)null), delegate(AudioClip clip)
			{
				EndMusicAudioSource.clip = clip;
			}, gameOverDefault);
		}

		private IEnumerator PrepareTerminalMusic()
		{
			AudioSource terminalMusic = MenuMusicAudioSource;
			yield return PrepareClip(prefsManager.GetStringLocal("jukebox.effects.terminal-music", (string)null), delegate(AudioClip clip)
			{
				terminalMusic.Stop();
				terminalMusic.volume = 1f;
				terminalMusic.clip = clip;
				terminalMusic.Play();
			}, terminalMusicDefault);
		}

		private IEnumerator PrepareClip(string path, Action<AudioClip> callback, AudioClip fallback)
		{
			if (path != null)
			{
				yield return Download(new FileInfo(path), callback);
			}
			else
			{
				callback(fallback);
			}
		}

		private IEnumerator Download(FileSystemInfo path, Action<AudioClip> callback)
		{
			DownloadHandlerAudioClip handler = new DownloadHandlerAudioClip(new Uri(path.FullName).AbsoluteUri, CustomMusicFileBrowser.extensionTypeDict[path.Extension.ToLower()]);
			UnityWebRequest wr = new UnityWebRequest(new Uri(path.FullName).AbsoluteUri, "GET", (DownloadHandler)(object)handler, (UploadHandler)null);
			try
			{
				yield return wr.SendWebRequest();
				if (wr.responseCode == 200)
				{
					callback(handler.audioClip);
				}
			}
			finally
			{
				((IDisposable)wr)?.Dispose();
			}
		}

		private void OnPrefChanged(string key, object value)
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			switch (key)
			{
			case "jukebox.effects.wavecomplete":
				((MonoBehaviour)this).StartCoroutine(PrepareWaveCompleteSfx());
				break;
			case "jukebox.effects.aww":
				((MonoBehaviour)this).StartCoroutine(PrepareAwwSfx());
				break;
			case "jukebox.effects.gameover":
				((MonoBehaviour)this).StartCoroutine(PrepareGameOverSfx());
				break;
			case "jukebox.effects.terminal-music":
				((MonoBehaviour)this).StartCoroutine(PrepareTerminalMusic());
				break;
			case "jukebox.effects.parry":
				((AudioSource)ReflectionUtils.GetPrivate<CrowdReactions>(crowdReactions, typeof(CrowdReactions), "aud")).Stop();
				((MonoBehaviour)this).StartCoroutine(PrepareParrySfx());
				break;
			}
		}
	}
	public class JukeboxEffectsBrowser : DirectoryTreeBrowser<FileInfo>
	{
		private static readonly DirectoryInfo EffectsDirectory = new DirectoryInfo(Path.Combine(Directory.GetParent(Application.dataPath).FullName, "Cybergrind", "Effects"));

		[SerializeField]
		private JukeboxTerminalPanel navigator;

		[SerializeField]
		private GameObject effectsMenu;

		private string currentPrefKey;

		protected override int maxPageLength => 3;

		protected override IDirectoryTree<FileInfo> baseDirectory => (IDirectoryTree<FileInfo>)new FileDirectoryTree(EffectsDirectory, (IDirectoryTree<FileInfo>)null);

		public void NextPage()
		{
			base.SetPage((base.currentPage != base.maxPages - 1) ? (base.currentPage + 1) : 0);
		}

		public void PreviousPage()
		{
			base.SetPage((base.currentPage == 0) ? (base.maxPages - 1) : (base.currentPage - 1));
		}

		public void SetCurrentPrefKey(string key)
		{
			currentPrefKey = key;
		}

		public void ResetToDefault()
		{
			MonoSingleton<PrefsManager>.Instance.SetStringLocal(currentPrefKey, (string)null);
		}

		protected override Action BuildLeaf(FileInfo item, int indexInPage)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			GameObject go = Object.Instantiate<GameObject>(base.itemButtonTemplate, base.itemParent);
			CustomContentButton component = go.GetComponent<CustomContentButton>();
			component.text.text = item.Name;
			go.SetActive(true);
			((UnityEvent)component.button.onClick).AddListener((UnityAction)delegate
			{
				MonoSingleton<PrefsManager>.Instance.SetStringLocal(currentPrefKey, item.FullName);
				navigator.GoToNoMenu(effectsMenu);
			});
			return delegate
			{
				Object.Destroy((Object)(object)go);
			};
		}

		public void OpenEffectsFolder()
		{
			Application.OpenURL(new Uri(EffectsDirectory.FullName).AbsoluteUri);
		}

		public override void Rebuild(bool setToPageZero = true)
		{
			Transform itemParent = base.itemParent;
			LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform)(object)((itemParent is RectTransform) ? itemParent : null));
			base.Rebuild(setToPageZero);
		}
	}
	public class JukeboxMusicChanger : MonoBehaviour
	{
		private enum ThemeVariation
		{
			Battle,
			Calm
		}

		private const int FadeSpeed = 1;

		public AudioSource clean;

		public AudioSource battle;

		private JukeboxThemesManager themesManager;

		private Coroutine updateRoutine;

		private ThemeVariation currentTheme;

		private static bool CalmThemesAllowed => MonoSingleton<PrefsManager>.Instance.GetBoolLocal("jukebox.enableCalmThemes", false);

		public void Awake()
		{
			themesManager = MonoSingleton<JukeboxThemesManager>.Instance;
		}

		private void Update()
		{
			if (!((Object)(object)clean.clip == (Object)null))
			{
				if (currentTheme == ThemeVariation.Calm)
				{
					clean.volume = Mathf.MoveTowards(clean.volume, 1f, 1f * Time.deltaTime);
					battle.volume = Mathf.MoveTowards(battle.volume, 0f, 1f * Time.deltaTime);
				}
				else
				{
					clean.volume = Mathf.MoveTowards(clean.volume, 0f, 1f * Time.deltaTime);
					battle.volume = Mathf.MoveTowards(battle.volume, 1f, 1f * Time.deltaTime);
				}
			}
		}

		public void ChangeTo(AudioClip battleTheme, AudioClip calmTheme)
		{
			if (updateRoutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(updateRoutine);
			}
			battle.time = 0f;
			clean.time = 0f;
			clean.clip = calmTheme;
			battle.clip = battleTheme;
			battle.Play();
			battle.volume = 1f;
			if ((Object)(object)clean.clip != (Object)null)
			{
				clean.Play();
				if (CalmThemesAllowed && themesManager.FewEnemies)
				{
					clean.volume = 1f;
					battle.volume = 0f;
				}
			}
			updateRoutine = ((MonoBehaviour)this).StartCoroutine(SlowUpdate());
		}

		private IEnumerator SlowUpdate()
		{
			while (true)
			{
				if (CalmThemesAllowed && themesManager.FewEnemies)
				{
					PlayCalmTheme();
				}
				else
				{
					PlayBattleTheme();
				}
				yield return (object)new WaitForSecondsRealtime(0.1f);
			}
		}

		private void PlayBattleTheme()
		{
			if (currentTheme != 0)
			{
				currentTheme = ThemeVariation.Battle;
				if ((Object)(object)clean.clip != (Object)null)
				{
					battle.timeSamples = clean.timeSamples;
				}
			}
		}

		private void PlayCalmTheme()
		{
			if (currentTheme != ThemeVariation.Calm)
			{
				currentTheme = ThemeVariation.Calm;
				if ((Object)(object)clean.clip != (Object)null)
				{
					clean.timeSamples = battle.timeSamples;
				}
			}
		}
	}
	public class JukeboxThemesManager : MonoSingleton<JukeboxThemesManager>
	{
		private static readonly string PreferencesPath = Path.Combine(Directory.GetParent(Application.dataPath).FullName, "Preferences", "JukeboxThemes.json");

		private PrefsManager prefsManager;

		private EnemyTracker enemyTracker;

		private JukeboxThemesConfig preferences = new JukeboxThemesConfig();

		private bool isDirty;

		public bool FewEnemies
		{
			get
			{
				if (EnemiesAlive <= CalmThemeThreshold)
				{
					return SpecialEnemiesThresholdReached();
				}
				return false;
			}
		}

		private int CalmThemeThreshold => prefsManager.GetIntLocal("jukebox.calmThemeEnemiesThreshold", 0);

		private int EnemiesAlive => enemyTracker.enemies.Count((EnemyIdentifier enemy) => !enemy.dead);

		protected override void Awake()
		{
			base.Awake();
			prefsManager = MonoSingleton<PrefsManager>.Instance;
			enemyTracker = MonoSingleton<EnemyTracker>.Instance;
			LoadPreferences();
			((MonoBehaviour)this).InvokeRepeating("SlowUpdate", 0f, 3f);
		}

		private void SlowUpdate()
		{
			if (isDirty)
			{
				SavePreferences();
				isDirty = false;
			}
		}

		protected override void OnDestroy()
		{
			SavePreferences();
			isDirty = false;
			base.OnDestroy();
		}

		public int? GetThresholdFor(EnemyType type)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (!preferences.CalmTheme.SpecialEnemies.ContainsKey(type))
			{
				return null;
			}
			return preferences.CalmTheme.SpecialEnemies[type];
		}

		public void SetThresholdFor(EnemyType type, int value)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			preferences.CalmTheme.SpecialEnemies[type] = value;
			isDirty = true;
		}

		public void DisableThresholdFor(EnemyType type)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if (preferences.CalmTheme.SpecialEnemies.ContainsKey(type))
			{
				preferences.CalmTheme.SpecialEnemies.Remove(type);
				isDirty = true;
			}
		}

		private bool SpecialEnemiesThresholdReached()
		{
			return (from enemy in enemyTracker.enemies
				where !enemy.dead
				select enemy.enemyType into type
				group type by type).All((IGrouping<EnemyType, EnemyType> group) => !preferences.CalmTheme.SpecialEnemies.ContainsKey(group.Key) || preferences.CalmTheme.SpecialEnemies[group.Key] >= group.Count());
		}

		private void LoadPreferences()
		{
			JukeboxThemesConfig jukeboxThemesConfig;
			using (StreamReader streamReader = new StreamReader(System.IO.File.Open(PreferencesPath, FileMode.OpenOrCreate)))
			{
				jukeboxThemesConfig = JsonConvert.DeserializeObject<JukeboxThemesConfig>(streamReader.ReadToEnd());
			}
			if (jukeboxThemesConfig?.CalmTheme == null)
			{
				SavePreferences();
			}
			else
			{
				preferences = jukeboxThemesConfig;
			}
		}

		private void SavePreferences()
		{
			System.IO.File.WriteAllText(PreferencesPath, JsonConvert.SerializeObject((object)preferences));
		}
	}
	public class DeckShuffled<T> : IEnumerable<T>, IEnumerable
	{
		private List<T> current;

		public DeckShuffled(IEnumerable<T> target)
		{
			current = Randomize(target).ToList();
		}

		public void Reshuffle()
		{
			if (current.Count > 1)
			{
				IEnumerable<T> source = current.Take(Mathf.FloorToInt((float)(current.Count / 2)));
				IEnumerable<T> source2 = current.Skip(Mathf.FloorToInt((float)(current.Count / 2)));
				current = Randomize(source).Concat(Randomize(source2)).ToList();
			}
		}

		private static IEnumerable<T> Randomize(IEnumerable<T> source)
		{
			T[] arr = source.ToArray();
			int i = arr.Length - 1;
			while (i > 0)
			{
				int swapIndex = Random.Range(0, i + 1);
				yield return arr[swapIndex];
				arr[swapIndex] = arr[i];
				int num = i - 1;
				i = num;
			}
			yield return arr[0];
		}

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

		IEnumerator IEnumerable.GetEnumerator()
		{
			return current.GetEnumerator();
		}
	}
	public class JukeboxFileBrowser : DirectoryTreeBrowser<JukeboxSong>
	{
		private static readonly string MusicPath = Path.Combine(Directory.GetParent(Application.dataPath).FullName, "CyberGrind", "Music");

		[SerializeField]
		private JukeboxTerminalPanel navigator;

		[SerializeField]
		private JukeboxPlaylistEditor playlistEditorLogic;

		[SerializeField]
		private GameObject playlistEditor;

		[Header("Load all warning")]
		[SerializeField]
		private TMP_Text loadAllWarningText;

		[SerializeField]
		private GameObject yesAndNoButtons;

		[SerializeField]
		private GameObject imADumbassButton;

		protected override int maxPageLength => 4;

		protected override IDirectoryTree<JukeboxSong> baseDirectory => new JukeboxFileTree(MusicPath);

		public void NextPage()
		{
			base.SetPage((base.currentPage != base.maxPages - 1) ? (base.currentPage + 1) : 0);
		}

		public void PreviousPage()
		{
			base.SetPage((base.currentPage == 0) ? (base.maxPages - 1) : (base.currentPage - 1));
		}

		public void LoadAllFromCurrentFolder()
		{
			foreach (JukeboxSong file in base.currentDirectory.files)
			{
				playlistEditorLogic.playlist.Add(file.Id);
			}
			((DirectoryTreeBrowser<JukeboxSong>)playlistEditorLogic).Rebuild(true);
		}

		public void SetWarningText()
		{
			if (!base.currentDirectory.files.Any())
			{
				yesAndNoButtons.SetActive(false);
				imADumbassButton.SetActive(true);
				loadAllWarningText.text = ((!base.currentDirectory.children.Any()) ? "Oh, I get it. \"Yes, I would like to add a whopping total of 0 songs\". Very funny." : "This folder contains no songs.");
			}
			else if (base.currentDirectory.files.Count() == 1)
			{
				loadAllWarningText.text = "It's a single song in there, but ok. Would you like me to add it?";
			}
			else
			{
				loadAllWarningText.text = $"Do you want to add <color=green>{base.currentDirectory.files.Count()}</color> tracks " + "from the folder <color=yellow>" + base.currentDirectory.name + "</color> to your playlist?";
			}
		}

		protected override Action BuildLeaf(JukeboxSong song, int indexInPage)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			GameObject go = Object.Instantiate<GameObject>(base.itemButtonTemplate, base.itemParent, false);
			JukeboxCustomContentButton component = go.GetComponent<JukeboxCustomContentButton>();
			JukeboxSongMetadata metadata = song.Metadata;
			((Un