Decompiled source of UiKit v1.0.0

BepInEx/plugins/DiceModders.UiKit.dll

Decompiled 21 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using DiceKingdoms.Game;
using DiceKingdoms.Interface;
using DiceKingdoms.Meta;
using DiceModders.UiKit.Custom;
using DiceModders.UiKit.Native;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.Localization;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("DiceModders.UiKit")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+c00eb7618c647446973ed0a890ba16337924bff9")]
[assembly: AssemblyProduct("UiKit")]
[assembly: AssemblyTitle("DiceModders.UiKit")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DiceModders.UiKit
{
	public sealed class CustomApi
	{
		private readonly UiScope _scope;

		public UiTheme Theme => _scope.Runtime.Theme;

		internal CustomApi(UiScope scope)
		{
			_scope = scope;
		}

		public UiWindow? Window(Action<UiWindow>? build = null)
		{
			if (!_scope.IsAlive)
			{
				UiLog.OnceError("custom:disposed-scope", "cannot create a window in a disposed scope");
				return null;
			}
			UiWindow uiWindow = UiGuard.Func("window.create", () => new UiWindow(_scope), _scope.Id);
			if (uiWindow == null)
			{
				return null;
			}
			_scope.Owned.Add(uiWindow);
			try
			{
				build?.Invoke(uiWindow);
				uiWindow.FinalizeBuild();
				if (uiWindow.IsAlive)
				{
					return uiWindow;
				}
				UiGuard.Run("window.cleanup", uiWindow.Dispose, _scope.Id);
				return null;
			}
			catch (Exception exception)
			{
				UiGuard.Report("window.build", exception, _scope.Id);
				UiGuard.Run("window.cleanup", uiWindow.Dispose, _scope.Id);
				return null;
			}
		}
	}
	public enum Layer
	{
		BehindGame,
		Game,
		AboveGame
	}
	public sealed class NativeApi
	{
		public TopBarApi TopBar { get; }

		public SettingsApi Settings { get; }

		public ScoreboardApi Scoreboard { get; }

		public RulesApi Rules { get; }

		internal NativeApi(UiScope scope)
		{
			TopBar = new TopBarApi(scope);
			Settings = new SettingsApi(scope);
			Scoreboard = new ScoreboardApi(scope);
			Rules = new RulesApi(scope);
		}
	}
	public enum OrnamentStyle
	{
		None,
		Border,
		BorderWithTwoCorners,
		BorderWithFourCorners,
		Classic
	}
	public enum TemplatePolicy
	{
		PreferNative,
		ManagedOnly,
		NativeOnly
	}
	public static class UiKit
	{
		private static UiKitRuntime? _runtime;

		public static bool IsInitialized => _runtime != null;

		public static bool IsDemoVisible
		{
			get
			{
				UiKitRuntime runtime = _runtime;
				if (runtime != null)
				{
					return UiGuard.Value("demo.visible", () => runtime.IsDemoVisible, fallback: false, "runtime");
				}
				return false;
			}
		}

		internal static UiKitRuntime? Initialize(BasePlugin? plugin, UiOptions? options = null)
		{
			return Initialize((plugin != null) ? plugin.Log : null, options);
		}

		internal static UiKitRuntime? Initialize(ManualLogSource? log, UiOptions? options = null)
		{
			if (_runtime != null)
			{
				UiLog.Warn("UiKit.Initialize called twice; keeping the existing runtime");
				return _runtime;
			}
			UiLog.SetLogger(log);
			UiLog.ResetOnce();
			try
			{
				_runtime = new UiKitRuntime(log, options);
				return _runtime;
			}
			catch (Exception ex)
			{
				_runtime = null;
				UiLog.Error("UiKit initialization failed: " + ex);
				return null;
			}
		}

		public static UiScope? CreateScope(string? id = null)
		{
			UiKitRuntime runtime = _runtime;
			if (runtime == null)
			{
				UiLog.OnceError("uikit:not-initialized", "UiKit.CreateScope called before the UiKit plugin initialized the runtime; returning null");
				return null;
			}
			return UiGuard.Func("scope.create", () => runtime.CreateScope(id), "runtime");
		}

		public static void ShowDemo()
		{
			RunDemo("demo.show", delegate(UiKitRuntime runtime)
			{
				runtime.ShowDemo();
			});
		}

		public static void HideDemo()
		{
			RunDemo("demo.hide", delegate(UiKitRuntime runtime)
			{
				runtime.HideDemo();
			});
		}

		public static void ToggleDemo()
		{
			RunDemo("demo.toggle", delegate(UiKitRuntime runtime)
			{
				runtime.ToggleDemo();
			});
		}

		public static void RebuildDemo()
		{
			RunDemo("demo.rebuild", delegate(UiKitRuntime runtime)
			{
				runtime.RebuildDemo();
			});
		}

		internal static void Shutdown()
		{
			UiKitRuntime runtime = _runtime;
			_runtime = null;
			if (runtime != null)
			{
				UiGuard.Run("runtime.shutdown", runtime.Dispose, "runtime");
			}
		}

		private static void RunDemo(string operation, Action<UiKitRuntime> action)
		{
			UiKitRuntime runtime = _runtime;
			if (runtime == null)
			{
				UiLog.OnceError("uikit:not-initialized", "the UiKit runtime is not available; demo command ignored");
				return;
			}
			UiGuard.Run(operation, delegate
			{
				action(runtime);
			}, "runtime");
		}
	}
	internal sealed class UiKitRuntime
	{
		private sealed class ReadyRegistration
		{
			internal UiScope Scope { get; }

			internal Action<UiScope> Build { get; }

			internal ReadyRegistration(UiScope scope, Action<UiScope> build)
			{
				Scope = scope;
				Build = build;
			}
		}

		private readonly List<UiScope> _scopes = new List<UiScope>();

		private readonly List<ReadyRegistration> _readyCallbacks = new List<ReadyRegistration>();

		private UnityAction<Scene, LoadSceneMode>? _sceneLoaded;

		private UnityAction<Scene>? _sceneUnloaded;

		private DemoController? _demo;

		private int _windowIndex;

		private int _scopeIndex;

		private bool _disposed;

		private bool _uiReady;

		private bool _uiReadyCandidate;

		internal AssetCatalog Assets { get; }

		internal TemplateCatalog Templates { get; }

		internal UiTheme Theme { get; }

		internal LayerCanvases Layers { get; }

		internal NativeUiHost NativeUi { get; }

		internal UiOptions Options { get; }

		internal bool IsDisposed => _disposed;

		internal bool IsUiReady => _uiReady;

		internal IReadOnlyList<UiScope> Scopes => _scopes;

		internal bool IsDemoVisible
		{
			get
			{
				if (_demo != null)
				{
					return _demo.IsVisible;
				}
				return false;
			}
		}

		internal UiKitRuntime(ManualLogSource? log, UiOptions? options)
		{
			Options = options ?? new UiOptions();
			UiLog.SetLogger(log);
			Assets = new AssetCatalog();
			Templates = new TemplateCatalog();
			Theme = new UiTheme(Assets);
			Layers = new LayerCanvases(this);
			NativeUi = new NativeUiHost();
			RegisterComponents();
			LayoutOnce.Begin();
			LayoutEvents.Activate();
			LayoutEvents.CanvasChanged += OnCanvasChanged;
			NativeHooks.Install(this);
			try
			{
				Action<Scene, LoadSceneMode> action = OnSceneLoaded;
				Action<Scene> action2 = OnSceneUnloaded;
				_sceneLoaded = DelegateSupport.ConvertDelegate<UnityAction<Scene, LoadSceneMode>>((Delegate)action);
				_sceneUnloaded = DelegateSupport.ConvertDelegate<UnityAction<Scene>>((Delegate)action2);
				SceneManager.sceneLoaded += _sceneLoaded;
				SceneManager.sceneUnloaded += _sceneUnloaded;
			}
			catch (Exception ex)
			{
				UiLog.Warn("could not subscribe to scene changes: " + ex.Message);
			}
			if (Options.EnableDemo)
			{
				UiGuard.Run("demo.create", delegate
				{
					_demo = new DemoController(this);
					_demo.Request();
					_demo.OnSceneLoaded();
				}, "runtime");
				if (_demo == null)
				{
					UiLog.Error("the built-in demo could not be created");
				}
			}
			UiGuard.Run("startup.ready", TryMarkUiReady, "runtime");
			RequestReadyProbe();
			UiLog.Info("UI kit runtime created");
		}

		internal void ShowDemo()
		{
			if (_disposed)
			{
				return;
			}
			UiGuard.Run("demo.show", delegate
			{
				if (_demo == null)
				{
					_demo = new DemoController(this);
				}
				_demo.Show();
			}, "runtime");
		}

		internal void HideDemo()
		{
			if (!_disposed)
			{
				UiGuard.Run("demo.hide", delegate
				{
					_demo?.Hide();
				}, "runtime");
			}
		}

		internal void ToggleDemo()
		{
			if (_disposed)
			{
				return;
			}
			UiGuard.Run("demo.toggle", delegate
			{
				if (_demo == null)
				{
					_demo = new DemoController(this);
				}
				_demo.Toggle();
			}, "runtime");
		}

		internal void RebuildDemo()
		{
			if (_disposed)
			{
				return;
			}
			UiGuard.Run("demo.rebuild", delegate
			{
				if (_demo == null)
				{
					_demo = new DemoController(this);
				}
				_demo.Rebuild();
			}, "runtime");
		}

		internal UiScope? CreateScope(string? id)
		{
			if (_disposed)
			{
				UiLog.OnceError("runtime:disposed", "cannot create a UiKit scope after the runtime has been disposed");
				return null;
			}
			string text = NormalizeScopeId(id);
			try
			{
				UiScope uiScope = new UiScope(this, text);
				_scopes.Add(uiScope);
				return uiScope;
			}
			catch (Exception value)
			{
				UiLog.Error($"could not create UiKit scope '{text}': {value}");
				return null;
			}
		}

		private string NormalizeScopeId(string? id)
		{
			if (!string.IsNullOrWhiteSpace(id))
			{
				return id.Trim();
			}
			return "scope-" + ++_scopeIndex;
		}

		internal void RemoveScope(UiScope scope)
		{
			if (scope != null)
			{
				_scopes.Remove(scope);
			}
		}

		internal void RegisterWhenReady(UiScope scope, Action<UiScope> build)
		{
			if (_disposed || scope == null || build == null)
			{
				return;
			}
			if (_uiReady)
			{
				UiGuard.Run("scope.ready", delegate
				{
					build(scope);
				}, scope.Id);
			}
			else
			{
				_readyCallbacks.Add(new ReadyRegistration(scope, build));
			}
		}

		internal void RemoveReady(UiScope scope)
		{
			if (scope == null)
			{
				return;
			}
			for (int num = _readyCallbacks.Count - 1; num >= 0; num--)
			{
				if (_readyCallbacks[num].Scope == scope)
				{
					_readyCallbacks.RemoveAt(num);
				}
			}
		}

		internal void TryMarkUiReady()
		{
			if (!_disposed && !_uiReady)
			{
				if (!HasUsableGameUi())
				{
					_uiReadyCandidate = false;
				}
				else if (!_uiReadyCandidate)
				{
					_uiReadyCandidate = true;
				}
				else
				{
					MarkUiReady();
				}
			}
		}

		internal void RequestReadyProbe()
		{
			if (!_disposed && !_uiReady)
			{
				LayoutOnce.Request(TryMarkUiReady);
			}
		}

		private bool HasUsableGameUi()
		{
			if ((Object)(object)UiGuard.Func("ready.bar", GameUi.FindActiveBar, "runtime") == (Object)null)
			{
				return false;
			}
			if ((Object)(object)UiGuard.Func("ready.layers", () => Layers.Get(Options.DefaultLayer), "runtime") == (Object)null)
			{
				return false;
			}
			return UiGuard.Value("ready.layer-refresh", delegate
			{
				Layers.Refresh();
				return true;
			}, fallback: false, "runtime");
		}

		private void MarkUiReady()
		{
			_uiReady = true;
			_uiReadyCandidate = false;
			UiLog.Info("game UI is ready; opening the content registration point");
			UiGuard.Run("ready.native", NativeUi.Refresh, "runtime");
			ReadyRegistration[] array = _readyCallbacks.ToArray();
			_readyCallbacks.Clear();
			int num = 0;
			foreach (ReadyRegistration registration in array)
			{
				UiScope scope = registration.Scope;
				if (scope != null && scope.IsAlive)
				{
					UiGuard.Run("scope.ready", delegate
					{
						registration.Build(scope);
					}, scope.Id);
					num++;
				}
			}
			if (num > 0)
			{
				UiLog.Info($"content registration point fired for {num} callback(s)");
			}
		}

		internal int NextWindowIndex()
		{
			return _windowIndex++;
		}

		private static void RegisterComponents()
		{
			Register<ClickRelay>();
			Register<SliderRelay>();
			Register<WindowDragHandler>();
			Register<PointerReceiver>();
			Register<AutoHeightText>();
			Register<WidthWatcher>();
			Register<ScrollPin>();
			Register<CanvasLayoutWatcher>();
			Register<DelegateLifetime>();
			Register<ScoreboardRowLifetime>();
			Register<SettingsScreenLifetime>();
		}

		private static void Register<T>() where T : class
		{
			try
			{
				ClassInjector.RegisterTypeInIl2Cpp<T>();
			}
			catch (Exception ex)
			{
				UiLog.Warn("could not register " + typeof(T).Name + ": " + ex.Message);
			}
		}

		private void OnCanvasChanged()
		{
			if (!_disposed)
			{
				UiGuard.Run("layout.windows", UiWindow.FitAllToScreen, "runtime");
				UiGuard.Run("layout.native", NativeUi.OnCanvasLayoutChanged, "runtime");
			}
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if (!_disposed)
			{
				if (!_uiReady)
				{
					_uiReadyCandidate = false;
				}
				UiGuard.Run("scene.assets", delegate
				{
					Assets.Invalidate();
					Templates.Invalidate();
				}, "runtime");
				UiGuard.Run("scene.delegates", Il2CppDelegates.Sweep, "runtime");
				UiGuard.Run("scene.layers", Layers.Refresh, "runtime");
				UiGuard.Run("scene.native", NativeUi.Refresh, "runtime");
				UiGuard.Run("scene.demo", delegate
				{
					_demo?.OnSceneLoaded();
				}, "runtime");
				UiGuard.Run("scene.ready", TryMarkUiReady, "runtime");
				RequestReadyProbe();
			}
		}

		private void OnSceneUnloaded(Scene scene)
		{
			if (!_disposed)
			{
				if (!_uiReady)
				{
					_uiReadyCandidate = false;
				}
				UiGuard.Run("scene.assets", delegate
				{
					Assets.Invalidate();
					Templates.Invalidate();
				}, "runtime");
				UiGuard.Run("scene.delegates", Il2CppDelegates.Sweep, "runtime");
				UiGuard.Run("scene.native", NativeUi.Detach, "runtime");
				UiGuard.Run("scene.native.refresh", NativeUi.RequestRefresh, "runtime");
			}
		}

		internal void Dispose()
		{
			if (_disposed)
			{
				return;
			}
			_disposed = true;
			_uiReady = false;
			_uiReadyCandidate = false;
			UiGuard.Run("runtime.unsubscribe", delegate
			{
				if ((Delegate)(object)_sceneLoaded != (Delegate)null)
				{
					SceneManager.sceneLoaded -= _sceneLoaded;
				}
				if ((Delegate)(object)_sceneUnloaded != (Delegate)null)
				{
					SceneManager.sceneUnloaded -= _sceneUnloaded;
				}
				LayoutEvents.CanvasChanged -= OnCanvasChanged;
				_sceneLoaded = null;
				_sceneUnloaded = null;
			}, "runtime");
			UiGuard.Run("runtime.layout", delegate
			{
				LayoutOnce.Clear();
				LayoutEvents.Clear();
			}, "runtime");
			DemoController demo = _demo;
			_demo = null;
			if (demo != null)
			{
				UiGuard.Run("demo.dispose", demo.Dispose, "runtime");
			}
			UiGuard.Run("native.hooks", NativeHooks.Uninstall, "runtime");
			UiGuard.Run("native.dispose", NativeUi.Dispose, "runtime");
			_readyCallbacks.Clear();
			UiScope[] array = _scopes.ToArray();
			_scopes.Clear();
			for (int num = array.Length - 1; num >= 0; num--)
			{
				UiGuard.Run("scope.dispose", array[num].Dispose, array[num].Id);
			}
			UiGuard.Run("runtime.pointer", PointerTracker.Clear, "runtime");
			UiGuard.Run("runtime.templates", Templates.Invalidate, "runtime");
			UiGuard.Run("runtime.assets", Assets.Invalidate, "runtime");
			UiGuard.Run("runtime.delegates", Il2CppDelegates.Clear, "runtime");
			UiGuard.Run("runtime.staging", Staging.Reset, "runtime");
			UiGuard.Run("runtime.layers", Layers.Dispose, "runtime");
			UiLog.Info("UI kit runtime disposed");
		}
	}
	internal sealed class UiOptions
	{
		public TemplatePolicy Templates { get; init; }

		public Layer DefaultLayer { get; init; } = Layer.AboveGame;

		public bool EnableDemo { get; init; }
	}
	public sealed class UiScope : IDisposable
	{
		private readonly List<IDisposable> _owned = new List<IDisposable>();

		internal UiKitRuntime Runtime { get; }

		public string Id { get; }

		public CustomApi Custom { get; }

		public NativeApi Native { get; }

		public bool IsDisposed { get; private set; }

		internal bool IsAlive
		{
			get
			{
				if (!IsDisposed)
				{
					return !Runtime.IsDisposed;
				}
				return false;
			}
		}

		internal List<IDisposable> Owned => _owned;

		internal UiScope(UiKitRuntime runtime, string id)
		{
			Runtime = runtime;
			Id = id;
			Custom = new CustomApi(this);
			Native = new NativeApi(this);
		}

		internal void RemoveOwned(IDisposable item)
		{
			if (item != null)
			{
				_owned.Remove(item);
			}
		}

		public UiScope WhenReady(Action<UiScope>? build)
		{
			if (build == null)
			{
				return this;
			}
			if (IsDisposed)
			{
				UiLog.OnceError("scope:ready-disposed:" + Id, "cannot register UI on disposed scope '" + Id + "'");
				return this;
			}
			if (Runtime.IsDisposed)
			{
				UiLog.OnceError("scope:ready-runtime:" + Id, "cannot register UI on scope '" + Id + "': the UiKit runtime is shutting down");
				return this;
			}
			try
			{
				Runtime.RegisterWhenReady(this, build);
			}
			catch (Exception value)
			{
				UiLog.Error($"scope '{Id}' ready registration failed: {value}");
			}
			return this;
		}

		public void Dispose()
		{
			if (IsDisposed)
			{
				return;
			}
			IsDisposed = true;
			try
			{
				Runtime.RemoveReady(this);
			}
			catch (Exception value)
			{
				UiLog.Error($"scope '{Id}' ready unregister failed: {value}");
			}
			IDisposable[] array = _owned.ToArray();
			_owned.Clear();
			for (int num = array.Length - 1; num >= 0; num--)
			{
				try
				{
					array[num].Dispose();
				}
				catch (Exception value2)
				{
					UiLog.Error($"scope '{Id}' dispose failed: {value2}");
				}
			}
			try
			{
				Runtime.RemoveScope(this);
			}
			catch (Exception value3)
			{
				UiLog.Error($"scope '{Id}' unregister failed: {value3}");
			}
		}
	}
	public sealed class UiTheme
	{
		private readonly AssetCatalog _assets;

		public TMP_FontAsset? Font => UiGuard.Func("theme.font", () => _assets.Font);

		public Material? FontMaterial => UiGuard.Func("theme.material", () => _assets.FontShadowMaterial);

		public Color TextColor => AssetCatalog.DefaultTextColor;

		internal Sprite? Panel => UiGuard.Func("theme.panel", () => _assets.PanelSprite);

		internal UiTheme(AssetCatalog assets)
		{
			_assets = assets;
		}

		public Sprite? Sprite(string? name)
		{
			return UiGuard.Func("theme.sprite", () => _assets.Sprite(name ?? string.Empty));
		}

		public Sprite? Icon(string? name)
		{
			return UiGuard.Func("theme.icon", () => _assets.Sprite(name ?? string.Empty));
		}

		public Sprite? Ornament(OrnamentStyle style)
		{
			return UiGuard.Func("theme.ornament", () => _assets.Ornament(style));
		}

		public IEnumerable<string> SpriteNames(string? contains = null)
		{
			try
			{
				return new List<string>(_assets.SpriteNames(contains));
			}
			catch (Exception exception)
			{
				UiGuard.Report("theme.sprite-names", exception);
				return Array.Empty<string>();
			}
		}

		internal Sprite? Button(AssetCatalog.ButtonVariant variant, AssetCatalog.ButtonState state)
		{
			return UiGuard.Func("theme.button", () => _assets.ButtonSprite(variant, state));
		}
	}
	internal sealed class DemoController
	{
		private const string DemoScopeId = "dicemodders.uikit.demo";

		private readonly UiKitRuntime _runtime;

		private readonly List<UiWindow> _windows = new List<UiWindow>();

		private UiScope? _scope;

		private UiWindow? _main;

		private ScoreboardColumnHandle? _scoreboard;

		private bool _requested;

		private bool _visible;

		private bool _built;

		public bool IsVisible
		{
			get
			{
				if (_visible && _built && _main != null)
				{
					return _main.IsAlive;
				}
				return false;
			}
		}

		public DemoController(UiKitRuntime runtime)
		{
			_runtime = runtime;
		}

		public void Request()
		{
			_requested = true;
		}

		public void Show()
		{
			_requested = true;
			if (!_built || _scope == null || _main == null || !_main.IsAlive)
			{
				DestroyScope();
				Build();
			}
			else
			{
				SetVisible(visible: true);
			}
		}

		public void Hide()
		{
			_requested = false;
			SetVisible(visible: false);
		}

		public void Toggle()
		{
			if (IsVisible)
			{
				Hide();
			}
			else
			{
				Show();
			}
		}

		public void Rebuild()
		{
			_requested = true;
			DestroyScope();
			Build();
		}

		public void OnSceneLoaded()
		{
			if (!_requested)
			{
				return;
			}
			try
			{
				if ((Object)(object)GameUi.FindActiveBar() == (Object)null)
				{
					UiLog.Info("demo is enabled and will be created after a scene with the game UI loads");
					return;
				}
				_runtime.Layers.Refresh();
				if (_built && _main != null && _main.IsAlive)
				{
					RefreshDemoScoreboard();
					return;
				}
				DestroyScope();
				Build();
			}
			catch (Exception ex)
			{
				UiLog.Error("demo scene hook failed: " + ex);
			}
		}

		public void Dispose()
		{
			_requested = false;
			DestroyScope();
		}

		private void Build()
		{
			//IL_0094: 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)
			if (_built)
			{
				return;
			}
			try
			{
				_runtime.Layers.Refresh();
				UiScope uiScope = _runtime.CreateScope("dicemodders.uikit.demo");
				if (uiScope == null)
				{
					UiLog.Error("demo could not create its UiKit scope");
					return;
				}
				_scope = uiScope;
				_built = true;
				_visible = true;
				_windows.Clear();
				BuildMain();
				uiScope.WhenReady(delegate(UiScope ui)
				{
					UiLog.Info("demo: the startup registration point fired");
					ui.Native.TopBar.AddIconButton("hammer", "UiKit demo", Toggle);
					bool interactable = true;
					TopBarButtonHandle toggleInteractable = null;
					toggleInteractable = ui.Native.TopBar.Add(new TopBarButtonSpec
					{
						Id = "uikit.demo.interactable",
						IconName = "hammer",
						Tooltip = "UiKit order 5; click toggles interactable",
						Order = 5,
						OnClick = delegate
						{
							interactable = !interactable;
							toggleInteractable?.SetInteractable(interactable);
						}
					});
					ui.Native.TopBar.Add(new TopBarButtonSpec
					{
						Id = "uikit.demo.order",
						IconName = "hammer",
						Tooltip = "UiKit order 15",
						Order = 15,
						OnClick = Toggle
					});
					if (ui.Native.TopBar.Get("uikit.demo.interactable") == null)
					{
						UiLog.Warn("demo: TopBar.Get did not return the ordered button");
					}
				});
				BuildDemoSettings();
				BuildNativeDemo(uiScope);
				BuildProbe(Layer.Game, "This window is on Layer.Game. It should sit in the HUD band, below the game's popups.", new Vector2(700f, 80f), OrnamentStyle.BorderWithTwoCorners);
				BuildProbe(Layer.BehindGame, "This window is on Layer.BehindGame. The game's own UI should draw over it.", new Vector2(760f, 300f), OrnamentStyle.None);
				UiLog.Info("demo windows created; use Rebuild inside the demo after the game's UI has loaded to re-scan native skins");
			}
			catch (Exception ex)
			{
				UiLog.Error("demo build failed: " + ex);
				DestroyScope();
			}
		}

		private void BuildMain()
		{
			UiScope scope = _scope;
			if (scope == null)
			{
				return;
			}
			UiText status = null;
			_main = scope.Custom.Window(delegate(UiWindow w)
			{
				w.Title("UiKit demo").Size(620f, 640f).Position(80f, 80f)
					.Draggable()
					.Fullscreenable()
					.FullscreenButton()
					.Closable()
					.Ornament(OrnamentStyle.Border);
				w.OnClose(Close);
				w.Body.Scroll(delegate(UiContainer body)
				{
					//IL_0099: Unknown result type (might be due to invalid IL or missing references)
					//IL_0310: Unknown result type (might be due to invalid IL or missing references)
					//IL_032e: Unknown result type (might be due to invalid IL or missing references)
					body.Paragraph("This is the library's built-in smoke test. It uses the same public API as a mod. The widgets below are native clones when their game templates are available, otherwise managed fallbacks. Use Rebuild after entering a match to re-scan the native templates.");
					body.Text($"Template policy: {_runtime.Options.Templates}");
					status = body.Text("Ready.");
					status?.Color(new Color(0.95f, 0.83f, 0.55f, 1f));
					body.Separator(3f);
					body.Text("Buttons");
					body.Row(delegate(UiContainer row)
					{
						row.Button("Click me", delegate
						{
							if (status != null)
							{
								status.Value = "Text button clicked.";
							}
						});
						row.Button("Disabled")?.Interactable(on: false);
						row.IconButton("hammer", delegate
						{
							if (status != null)
							{
								status.Value = "Icon button clicked.";
							}
						}, "UiKit demo icon button");
						Sprite val = _runtime.Theme.Icon("hammer");
						if ((Object)(object)val != (Object)null)
						{
							row.IconButton(val, delegate
							{
								if (status != null)
								{
									status.Value = "Sprite icon button clicked.";
								}
							}, "UiKit demo sprite icon");
							row.Button("Sprite icon", delegate
							{
								if (status != null)
								{
									status.Value = "Button sprite icon clicked.";
								}
							})?.Icon(val);
						}
					})?.Spacing(10f, 0f);
					body.Text("Toggle, slider and dropdown");
					body.Toggle("Toggle me", value: true, delegate(bool value)
					{
						if (status != null)
						{
							status.Value = "Toggle: " + value;
						}
					});
					body.Slider(0f, 100f, 50f, delegate(float value)
					{
						if (status != null)
						{
							status.Value = "Slider: " + value.ToString("0");
						}
					})?.Format("0");
					body.Dropdown(new string[3] { "First option", "Second option", "Third option" }, 0, delegate(int index)
					{
						if (status != null)
						{
							status.Value = "Dropdown index: " + index;
						}
					});
					body.Text("Grid");
					body.Grid(3, 90f, 32f, delegate(UiContainer grid)
					{
						for (int i = 0; i < 6; i++)
						{
							int number = i;
							grid.Button(number.ToString(), delegate
							{
								if (status != null)
								{
									status.Value = "Grid button " + number;
								}
							});
						}
					}).Height(72f);
					body.Text("Flexible grid");
					UiContainer? uiContainer = body.Grid(delegate(UiContainer grid)
					{
						for (int i = 0; i < 4; i++)
						{
							int number = i;
							grid.Button("Auto " + number, delegate
							{
								if (status != null)
								{
									status.Value = "Flexible grid button " + number;
								}
							});
						}
					});
					uiContainer?.Height(48f);
					uiContainer?.Spacing(10f, 4f);
					body.Text("Image pointer Move and wheel");
					UiImage picture = body.Image((Texture?)(object)Texture2D.whiteTexture);
					picture?.Height(90f).FillWidth();
					picture?.Tint(new Color(0.35f, 0.55f, 0.9f, 1f)).UvRect(new Rect(0f, 0f, 1f, 1f));
					picture?.OnPointer(delegate(UiPointerEvent e)
					{
						//IL_004c: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
						//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
						if (status != null && e.Kind == UiPointerKind.Move)
						{
							status.Value = $"Image Move uv=({e.Uv.x:0.00}, {e.Uv.y:0.00}) size={picture?.Size.x:0}x{picture?.Size.y:0}";
						}
					});
					picture?.OnScroll(delegate(float notches)
					{
						if (status != null)
						{
							status.Value = "Image wheel: " + notches.ToString("0.##");
						}
					});
					body.Text("Fixed and weighted layout");
					body.Row(delegate(UiContainer row)
					{
						row.Column(delegate(UiContainer fixedWidth)
						{
							fixedWidth.Text("Fixed 120");
						})?.FixedW(120f);
						row.Column(delegate(UiContainer one)
						{
							one.Text("Weight 1");
						})?.WeightW(1f);
						row.Column(delegate(UiContainer two)
						{
							two.Text("Weight 2");
						})?.WeightW(2f);
					})?.FixedH(48f);
					body.Text("Window ornament");
					body.Row(delegate(UiContainer row)
					{
						row.Button("Border", delegate
						{
							w.Ornament(OrnamentStyle.Border);
						});
						row.Button("Corners", delegate
						{
							w.Ornament(OrnamentStyle.BorderWithFourCorners);
						});
						row.Button("Classic", delegate
						{
							w.Ornament(OrnamentStyle.Classic);
						});
						row.Button("None", delegate
						{
							w.Ornament(OrnamentStyle.None);
						});
					});
					body.Separator();
					body.Button("Rebuild (re-scan native skins)", Rebuild);
					body.Button("Hide demo", Hide);
					body.Separator();
					body.Text("Scroll content");
					for (int num = 1; num <= 30; num++)
					{
						body.Text("Scroll row " + num);
					}
				}).FillHeight();
			});
			if (_main != null)
			{
				_windows.Add(_main);
			}
		}

		private void BuildDemoSettings()
		{
			UiScope scope = _scope;
			if (scope == null)
			{
				return;
			}
			scope.Native.Settings.AddTab("uikit.demo", "UiKit", delegate(SettingsTabHandle tab)
			{
				tab.AddHeader("UiKit native settings");
				tab.AddToggle("Demo toggle", value: true, delegate(bool value)
				{
					UiLog.Info("demo settings toggle: " + value);
				});
				tab.AddSlider("Demo slider", 0f, 100f, 50f, delegate(float value)
				{
					UiLog.Info("demo settings slider: " + value.ToString("0"));
				}, "0");
				tab.AddDropdown("Demo dropdown", new string[3] { "First", "Second", "Third" }, 0, delegate(int index)
				{
					UiLog.Info("demo settings dropdown: " + index);
				});
				tab.AddButton("Demo button", "Click", delegate
				{
					UiLog.Info("demo settings button clicked");
				});
				tab.AddInfo("Info rows wrap and can be updated through SetText.");
				tab.AddStepper("Stepper", () => "3", delegate(int delta)
				{
					UiLog.Info("demo settings step: " + delta);
				});
				tab.AddButtons("Buttons", ("One", delegate
				{
					UiLog.Info("demo settings buttons: one");
				}), ("Two", delegate
				{
					UiLog.Info("demo settings buttons: two");
				}));
			});
			int gameCount = 3;
			SettingsRowHandle gameInfo = null;
			scope.Native.Settings.AddBlock(new SettingsBlockSpec
			{
				Id = "uikit.demo.builtin.game",
				Page = SettingsPage.Game,
				Title = "UiKit demo block (Game)",
				Order = 10,
				Build = delegate(SettingsBlockHandle block)
				{
					gameInfo = block.AddInfo("Stable Info row on the game's own Game page.");
					block.AddToggle("Demo toggle", value: true, delegate(bool value)
					{
						gameInfo?.SetText("Game-page toggle: " + value);
					});
					block.AddSlider("Demo slider", 0f, 10f, 4f, delegate(float value)
					{
						gameInfo?.SetText("Game-page slider: " + value.ToString("0"));
					}, "0", wholeNumbers: true);
					block.AddDropdown("Demo dropdown", new string[3] { "First", "Second", "Third" }, 0, delegate(int index)
					{
						gameInfo?.SetText("Game-page dropdown: " + index);
					});
					block.AddStepper("Demo counter", () => gameCount.ToString(), delegate(int delta)
					{
						gameCount += delta;
						gameInfo?.SetText("Game-page counter: " + gameCount);
					});
					block.AddButtons("Demo buttons", ("Reset", delegate
					{
						gameCount = 3;
						gameInfo?.SetText("Game-page counter reset.");
					}), ("Notify", delegate
					{
						gameInfo?.SetText("Game-page button clicked.");
					}));
				}
			});
			int lobbyCount = 1;
			SettingsRowHandle lobbyInfo = null;
			scope.Native.Settings.AddBlock(new SettingsBlockSpec
			{
				Id = "uikit.demo.builtin.lobby",
				Page = SettingsPage.Lobby,
				Title = "UiKit demo block (Lobby)",
				Order = 10,
				Build = delegate(SettingsBlockHandle block)
				{
					lobbyInfo = block.AddInfo("This block is appended to the match-start settings box.");
					block.AddToggle("Lobby toggle", value: true, delegate(bool value)
					{
						lobbyInfo?.SetText("Lobby toggle: " + value);
					});
					block.AddStepper("Lobby counter", () => lobbyCount.ToString(), delegate(int delta)
					{
						lobbyCount += delta;
						lobbyInfo?.SetText("Lobby counter: " + lobbyCount);
					});
					block.AddButtons("Lobby buttons", ("Reset", delegate
					{
						lobbyCount = 1;
						lobbyInfo?.SetText("Lobby counter reset.");
					}));
				}
			});
		}

		private void BuildNativeDemo(UiScope scope)
		{
			_scoreboard = scope.Native.Scoreboard.AddColumn("uikit.demo.score", "UiKit demo column");
			RefreshDemoScoreboard();
			TechTree tree = FindDemoTree();
			if ((Object)(object)tree == (Object)null)
			{
				UiLog.Info("demo: no game tech tree is available, the Rules civilization demo is skipped");
				return;
			}
			scope.Native.Rules.AddCivilization("uikit.demo.civ", "UiKit civilization", () => tree);
		}

		private void RefreshDemoScoreboard()
		{
			ScoreboardColumnHandle scoreboard = _scoreboard;
			if (scoreboard == null || scoreboard.IsDisposed)
			{
				return;
			}
			Dictionary<Island, string> dictionary = new Dictionary<Island, string>();
			try
			{
				foreach (Island item in Object.FindObjectsOfType<Island>())
				{
					if (!((Object)(object)item == (Object)null) && !Staging.IsOurs(((Component)item).transform))
					{
						dictionary[item] = (Math.Abs(((Object)item).GetInstanceID()) % 100).ToString();
					}
				}
			}
			catch (Exception ex)
			{
				UiLog.OnceError("demo:scoreboard", "demo scoreboard values failed: " + ex);
			}
			scoreboard.SetValues(dictionary);
		}

		private static TechTree? FindDemoTree()
		{
			try
			{
				foreach (Object item in (Il2CppArrayBase<Object>)(object)Resources.FindObjectsOfTypeAll(Il2CppType.Of<Technologies>()))
				{
					Technologies val = ((item != null) ? ((Il2CppObjectBase)item).TryCast<Technologies>() : null);
					if (!((Object)(object)val == (Object)null))
					{
						return val.TechTree((Civilization)0);
					}
				}
			}
			catch (Exception ex)
			{
				UiLog.OnceError("demo:tech-tree", "could not read a game tech tree: " + ex);
			}
			return null;
		}

		private void BuildProbe(Layer layer, string text, Vector2 position, OrnamentStyle ornament)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			UiScope scope = _scope;
			if (scope != null)
			{
				UiWindow uiWindow = scope.Custom.Window(delegate(UiWindow w)
				{
					w.Title("Layer." + layer).Size(340f, 240f).Position(position.x, position.y)
						.Layer(layer)
						.Draggable()
						.Closable()
						.Ornament(ornament);
					w.Body.Paragraph(text);
					w.Body.Button("Bring to front", w.BringToFront);
				});
				if (uiWindow != null)
				{
					_windows.Add(uiWindow);
				}
			}
		}

		private void Close()
		{
			_requested = false;
			DestroyScope();
		}

		private void SetVisible(bool visible)
		{
			_visible = visible;
			foreach (UiWindow window in _windows)
			{
				if (window != null && window.IsAlive)
				{
					if (visible)
					{
						window.Show();
					}
					else
					{
						window.Hide();
					}
				}
			}
		}

		private void DestroyScope()
		{
			_built = false;
			_visible = false;
			_main = null;
			_scoreboard = null;
			_windows.Clear();
			UiScope scope = _scope;
			_scope = null;
			if (scope == null)
			{
				return;
			}
			try
			{
				scope.Dispose();
			}
			catch (Exception ex)
			{
				UiLog.Error("demo scope dispose failed: " + ex);
			}
		}
	}
	[BepInPlugin("DiceModders.UiKit", "UiKit", "1.0.0")]
	public sealed class Plugin : BasePlugin
	{
		public override void Load()
		{
			try
			{
				LoadCore();
			}
			catch (Exception ex)
			{
				((BasePlugin)this).Log.LogError((object)("UiKit plugin failed to load; the library will stay unavailable: " + ex));
			}
		}

		private void LoadCore()
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			ConfigEntry<bool> demo = ((BasePlugin)this).Config.Bind<bool>("Demo", "Enabled", false, "Show the library's built-in test windows after a scene with the game UI loads. Use the Rebuild button inside the demo after entering a match to re-scan native templates. Can also be enabled with the command-line flag --uikit-demo.");
			ConfigEntry<string> val = ((BasePlugin)this).Config.Bind<string>("Widgets", "Templates", "PreferNative", "Widget skin policy: PreferNative, ManagedOnly or NativeOnly.");
			TemplatePolicy result = TemplatePolicy.PreferNative;
			if (!Enum.TryParse<TemplatePolicy>(val.Value, ignoreCase: true, out result) || !Enum.IsDefined(typeof(TemplatePolicy), result))
			{
				ManualLogSource log = ((BasePlugin)this).Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(42, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("unknown Widgets/Templates value '");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(val.Value);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'; using ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<TemplatePolicy>(TemplatePolicy.PreferNative);
				}
				log.LogWarning(val2);
				result = TemplatePolicy.PreferNative;
			}
			if (UiKit.Initialize((BasePlugin?)(object)this, new UiOptions
			{
				Templates = result,
				EnableDemo = (demo.Value || HasCommandLineFlag("--uikit-demo"))
			}) == null)
			{
				((BasePlugin)this).Log.LogError((object)"UiKit runtime initialization failed; mods calling UiKit.CreateScope will receive null");
				return;
			}
			demo.SettingChanged += delegate
			{
				try
				{
					if (demo.Value)
					{
						UiKit.ShowDemo();
					}
					else
					{
						UiKit.HideDemo();
					}
				}
				catch (Exception ex)
				{
					((BasePlugin)this).Log.LogError((object)("UiKit demo toggle failed: " + ex));
				}
			};
		}

		public override bool Unload()
		{
			try
			{
				UiKit.Shutdown();
			}
			catch (Exception ex)
			{
				((BasePlugin)this).Log.LogError((object)("UiKit shutdown failed: " + ex));
			}
			return true;
		}

		private static bool HasCommandLineFlag(string flag)
		{
			string[] commandLineArgs = Environment.GetCommandLineArgs();
			for (int i = 0; i < commandLineArgs.Length; i++)
			{
				if (string.Equals(commandLineArgs[i], flag, StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
			}
			return false;
		}
	}
	internal sealed class AssetCatalog
	{
		internal enum ButtonVariant
		{
			Regular = 1,
			Selected
		}

		internal enum ButtonState
		{
			Ready,
			Hovered,
			Pressed,
			Disabled
		}

		public static readonly Color DefaultTextColor = new Color(0.969f, 0.94f, 0.893f, 1f);

		private readonly Dictionary<string, Sprite> _sprites = new Dictionary<string, Sprite>();

		private readonly Dictionary<string, Material> _materials = new Dictionary<string, Material>();

		private readonly Dictionary<string, TMP_FontAsset> _fonts = new Dictionary<string, TMP_FontAsset>();

		private bool _scanned;

		private float _nextRescan;

		private TMP_FontAsset? _font;

		public TMP_FontAsset? Font
		{
			get
			{
				if ((Object)(object)_font != (Object)null)
				{
					return _font;
				}
				TMP_FontAsset val = FontAsset("Main-Font-Normal");
				if ((Object)(object)val != (Object)null)
				{
					return _font = val;
				}
				TMP_FontAsset val2 = FontFromLive();
				if ((Object)(object)val2 != (Object)null)
				{
					return _font = val2;
				}
				try
				{
					return _font = TMP_Settings.defaultFontAsset;
				}
				catch
				{
					return null;
				}
			}
		}

		public Material? FontShadowMaterial => Material("Main-Font-Normal-Shadow");

		public Sprite? PanelSprite => Sprite("Background-3") ?? Sprite("Background-4");

		public void Invalidate()
		{
			_sprites.Clear();
			_materials.Clear();
			_fonts.Clear();
			_scanned = false;
			_nextRescan = 0f;
			_font = null;
		}

		private void Scan()
		{
			_sprites.Clear();
			_materials.Clear();
			_fonts.Clear();
			foreach (Object item in (Il2CppArrayBase<Object>)(object)Resources.FindObjectsOfTypeAll(Il2CppType.From(typeof(Sprite))))
			{
				Sprite val = ((item != null) ? ((Il2CppObjectBase)item).TryCast<Sprite>() : null);
				if (val != null && !string.IsNullOrEmpty(((Object)val).name))
				{
					_sprites.TryAdd(((Object)val).name, val);
				}
			}
			foreach (Object item2 in (Il2CppArrayBase<Object>)(object)Resources.FindObjectsOfTypeAll(Il2CppType.From(typeof(Material))))
			{
				Material val2 = ((item2 != null) ? ((Il2CppObjectBase)item2).TryCast<Material>() : null);
				if (val2 != null && !string.IsNullOrEmpty(((Object)val2).name))
				{
					_materials.TryAdd(((Object)val2).name, val2);
				}
			}
			foreach (Object item3 in (Il2CppArrayBase<Object>)(object)Resources.FindObjectsOfTypeAll(Il2CppType.From(typeof(TMP_FontAsset))))
			{
				TMP_FontAsset val3 = ((item3 != null) ? ((Il2CppObjectBase)item3).TryCast<TMP_FontAsset>() : null);
				if (val3 != null && !string.IsNullOrEmpty(((Object)val3).name))
				{
					_fonts.TryAdd(((Object)val3).name, val3);
				}
			}
			_scanned = true;
			_nextRescan = Time.realtimeSinceStartup + 3f;
		}

		private void EnsureScanned()
		{
			if (!_scanned)
			{
				Scan();
			}
		}

		private T? Lookup<T>(Dictionary<string, T> map, string? name) where T : Object
		{
			if (string.IsNullOrEmpty(name))
			{
				return default(T);
			}
			EnsureScanned();
			if (map.TryGetValue(name, out T value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			if (Time.realtimeSinceStartup < _nextRescan)
			{
				return default(T);
			}
			Scan();
			if (!map.TryGetValue(name, out value) || !((Object)(object)value != (Object)null))
			{
				return default(T);
			}
			return value;
		}

		public Sprite? Sprite(string? name)
		{
			return Lookup<Sprite>(_sprites, name);
		}

		public Material? Material(string? name)
		{
			return Lookup<Material>(_materials, name);
		}

		public TMP_FontAsset? FontAsset(string? name)
		{
			return Lookup<TMP_FontAsset>(_fonts, name);
		}

		public IEnumerable<string> SpriteNames(string? contains = null)
		{
			EnsureScanned();
			foreach (KeyValuePair<string, Sprite> sprite in _sprites)
			{
				if (!((Object)(object)sprite.Value == (Object)null) && (contains == null || sprite.Key.IndexOf(contains, StringComparison.OrdinalIgnoreCase) >= 0))
				{
					yield return sprite.Key;
				}
			}
		}

		public Sprite? ButtonSprite(ButtonVariant variant, ButtonState state)
		{
			return Sprite($"Button-{variant}-{state}");
		}

		public Sprite? Ornament(OrnamentStyle style)
		{
			return (Sprite?)(style switch
			{
				OrnamentStyle.Border => Sprite("Ornament-1"), 
				OrnamentStyle.BorderWithTwoCorners => Sprite("Ornament-2"), 
				OrnamentStyle.BorderWithFourCorners => Sprite("Ornament-5"), 
				OrnamentStyle.Classic => Sprite("Ornament-3"), 
				_ => null, 
			});
		}

		private TMP_FontAsset? FontFromLive()
		{
			try
			{
				foreach (TMP_Text item in Object.FindObjectsOfType<TMP_Text>())
				{
					if (!((Object)(object)item == (Object)null) && !((Object)(object)item.font == (Object)null) && ((Component)item).gameObject.activeInHierarchy)
					{
						return item.font;
					}
				}
			}
			catch
			{
			}
			return null;
		}
	}
	internal static class EventRelay
	{
		public static UnityAction? ToUnity(Action? action)
		{
			if (action == null)
			{
				return null;
			}
			return DelegateSupport.ConvertDelegate<UnityAction>((Delegate)(Action)delegate
			{
				try
				{
					action();
				}
				catch (Exception ex)
				{
					UiLog.Error("UI callback failed: " + ex);
				}
			});
		}

		public static UnityAction<float>? ToUnity(Action<float>? action)
		{
			if (action == null)
			{
				return null;
			}
			return DelegateSupport.ConvertDelegate<UnityAction<float>>((Delegate)(Action<float>)delegate(float value)
			{
				try
				{
					action(value);
				}
				catch (Exception ex)
				{
					UiLog.Error("UI callback failed: " + ex);
				}
			});
		}

		public static UnityAction<BaseEventData>? ToEvent(Action<BaseEventData>? action)
		{
			if (action == null)
			{
				return null;
			}
			return DelegateSupport.ConvertDelegate<UnityAction<BaseEventData>>((Delegate)(Action<BaseEventData>)delegate(BaseEventData data)
			{
				try
				{
					action(data);
				}
				catch (Exception ex)
				{
					UiLog.Error("UI event callback failed: " + ex);
				}
			});
		}
	}
	internal sealed class LayerCanvases : IDisposable
	{
		private readonly UiKitRuntime _runtime;

		private Canvas? _behind;

		private Canvas? _game;

		private Canvas? _above;

		private int _gameOrder;

		private int _behindOrder;

		private int _aboveOrder;

		private bool _initialized;

		internal event Action? OrdersChanged;

		public LayerCanvases(UiKitRuntime runtime)
		{
			_runtime = runtime;
		}

		public Canvas? Get(Layer layer)
		{
			Ensure();
			return (Canvas?)(layer switch
			{
				Layer.BehindGame => _behind, 
				Layer.Game => _game, 
				_ => _above, 
			});
		}

		public int OrderFor(Layer layer)
		{
			Ensure();
			return layer switch
			{
				Layer.BehindGame => _behindOrder, 
				Layer.Game => _gameOrder, 
				_ => _aboveOrder, 
			};
		}

		public void Refresh()
		{
			if (_initialized)
			{
				Canvas val = FindHudCanvas();
				ComputeOrders(val);
				ApplyOrder(_behind, _behindOrder);
				ApplyOrder(_game, _gameOrder);
				ApplyOrder(_above, _aboveOrder);
				ApplyRenderMode(_behind, Layer.BehindGame, val);
				ApplyRenderMode(_game, Layer.Game, val);
				ApplyRenderMode(_above, Layer.AboveGame, val);
				if ((Object)(object)val != (Object)null)
				{
					ApplySortingLayer(_behind, val);
					ApplySortingLayer(_game, val);
					ApplySortingLayer(_above, val);
					CopyScaler(val, ((Object)(object)_behind != (Object)null) ? ((Component)_behind).GetComponent<CanvasScaler>() : null);
					CopyScaler(val, ((Object)(object)_game != (Object)null) ? ((Component)_game).GetComponent<CanvasScaler>() : null);
					CopyScaler(val, ((Object)(object)_above != (Object)null) ? ((Component)_above).GetComponent<CanvasScaler>() : null);
				}
				NotifyOrdersChanged();
			}
		}

		private void NotifyOrdersChanged()
		{
			Action action = this.OrdersChanged;
			if (action == null)
			{
				return;
			}
			Delegate[] invocationList = action.GetInvocationList();
			foreach (Delegate obj in invocationList)
			{
				try
				{
					((Action)obj)();
				}
				catch (Exception ex)
				{
					UiLog.Error("layer order listener failed: " + ex.Message);
				}
			}
		}

		public void Invalidate()
		{
			Refresh();
		}

		private void Ensure()
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			if (!_initialized)
			{
				Canvas val = FindHudCanvas();
				ComputeOrders(val);
				Canvas val2 = null;
				Canvas val3 = null;
				Canvas val4 = null;
				try
				{
					val2 = Create("DiceModders UiKit [Behind]", Layer.BehindGame, _behindOrder, val);
					val3 = Create("DiceModders UiKit [Game]", Layer.Game, _gameOrder, val);
					val4 = Create("DiceModders UiKit [Above]", Layer.AboveGame, _aboveOrder, val);
				}
				catch (Exception ex)
				{
					Destroy(val4);
					Destroy(val3);
					Destroy(val2);
					UiLog.Error("could not create the shared UI layers: " + ex);
					return;
				}
				_behind = val2;
				_game = val3;
				_above = val4;
				_initialized = true;
				string value = (((Object)(object)val != (Object)null) ? ((object)val.renderMode/*cast due to .constrained prefix*/).ToString() : "no HUD");
				string value2 = (((Object)(object)val != (Object)null) ? ("'" + ((Object)val).name + "'") : "none");
				UiLog.Info($"UI layers ready (HUD {value2}, {value}, order {_gameOrder - 1}; game {_gameOrder}, behind {_behindOrder}, above {_aboveOrder})");
			}
		}

		private static Canvas Create(string name, Layer layer, int order, Canvas? hud)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = null;
			try
			{
				val = UiFactory.NewRect(name, null);
				GameObject gameObject = ((Component)val).gameObject;
				Object.DontDestroyOnLoad((Object)(object)gameObject);
				gameObject.layer = (((Object)(object)hud != (Object)null) ? ((Component)hud).gameObject.layer : 5);
				val.sizeDelta = new Vector2(1920f, 1080f);
				Canvas val2 = gameObject.AddComponent<Canvas>();
				ApplyRenderMode(val2, layer, hud);
				val2.sortingOrder = order;
				if ((Object)(object)hud != (Object)null)
				{
					val2.sortingLayerID = hud.sortingLayerID;
				}
				CanvasScaler target = gameObject.AddComponent<CanvasScaler>();
				CopyScaler(hud, target);
				gameObject.AddComponent<GraphicRaycaster>();
				LayoutEvents.Watch((Transform?)(object)val);
				return val2;
			}
			catch
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)val).gameObject);
				}
				throw;
			}
		}

		private static void ApplyRenderMode(Canvas? canvas, Layer layer, Canvas? hud)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)canvas == (Object)null))
			{
				if ((Object)(object)hud == (Object)null || (int)hud.renderMode == 0 || (Object)(object)hud.worldCamera == (Object)null)
				{
					canvas.renderMode = (RenderMode)0;
					return;
				}
				canvas.renderMode = (RenderMode)1;
				canvas.worldCamera = hud.worldCamera;
				float num = ((hud.planeDistance > 0.01f) ? hud.planeDistance : 100f);
				float num2 = (((Object)(object)hud.worldCamera != (Object)null) ? (hud.worldCamera.nearClipPlane + 0.01f) : 0.01f);
				canvas.planeDistance = layer switch
				{
					Layer.BehindGame => num + 10f, 
					Layer.Game => num, 
					_ => Mathf.Max(num2, num - 10f), 
				};
			}
		}

		private static void ApplyOrder(Canvas? canvas, int order)
		{
			if ((Object)(object)canvas != (Object)null)
			{
				canvas.sortingOrder = order;
			}
		}

		private static void ApplySortingLayer(Canvas? canvas, Canvas? hud)
		{
			if ((Object)(object)canvas != (Object)null && (Object)(object)hud != (Object)null)
			{
				canvas.sortingLayerID = hud.sortingLayerID;
			}
		}

		private static void CopyScaler(Canvas? source, CanvasScaler? target)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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)
			if (!((Object)(object)target == (Object)null))
			{
				CanvasScaler val = (((Object)(object)source != (Object)null) ? ((Component)source).GetComponent<CanvasScaler>() : null);
				if ((Object)(object)val == (Object)null)
				{
					target.uiScaleMode = (ScaleMode)1;
					target.referenceResolution = new Vector2(1920f, 1080f);
					target.screenMatchMode = (ScreenMatchMode)0;
					target.matchWidthOrHeight = 0.5f;
					target.referencePixelsPerUnit = 100f;
				}
				else
				{
					target.uiScaleMode = val.uiScaleMode;
					target.referenceResolution = val.referenceResolution;
					target.screenMatchMode = val.screenMatchMode;
					target.matchWidthOrHeight = val.matchWidthOrHeight;
					target.referencePixelsPerUnit = val.referencePixelsPerUnit;
					target.scaleFactor = val.scaleFactor;
					target.physicalUnit = val.physicalUnit;
					target.fallbackScreenDPI = val.fallbackScreenDPI;
					target.defaultSpriteDPI = val.defaultSpriteDPI;
				}
			}
		}

		private void ComputeOrders(Canvas? hud)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Invalid comparison between Unknown and I4
			int num = (((Object)(object)hud != (Object)null) ? hud.sortingOrder : 0);
			_gameOrder = num + 1;
			int num2 = num;
			int num3 = num;
			foreach (Canvas item in Object.FindObjectsOfType<Canvas>())
			{
				if (!((Object)(object)item == (Object)null) && item.isRootCanvas && ((Component)item).gameObject.activeInHierarchy && (int)item.renderMode != 2 && !((Object)((Component)item).gameObject).name.StartsWith("DiceModders UiKit") && item.sortingOrder <= 1000)
				{
					num2 = Mathf.Min(num2, item.sortingOrder);
					num3 = Mathf.Max(num3, item.sortingOrder);
				}
			}
			_behindOrder = num2 - 100;
			_aboveOrder = num3 + 100;
		}

		private static Canvas? FindHudCanvas()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Invalid comparison between Unknown and I4
			try
			{
				Canvas result = null;
				int num = int.MinValue;
				foreach (Canvas item in Object.FindObjectsOfType<Canvas>())
				{
					if (!((Object)(object)item == (Object)null) && item.isRootCanvas && ((Component)item).gameObject.activeInHierarchy && (int)item.renderMode != 2 && !((Object)((Component)item).gameObject).name.StartsWith("DiceModders UiKit"))
					{
						int num2 = 0;
						if (item.sortingOrder <= 100)
						{
							num2 += 10;
						}
						if (item.sortingOrder == 0)
						{
							num2 += 2;
						}
						if ((Object)(object)GameUi.FindBar(((Component)item).transform) != (Object)null)
						{
							num2 += 1000;
						}
						if (num2 > num)
						{
							num = num2;
							result = item;
						}
					}
				}
				return result;
			}
			catch
			{
				return null;
			}
		}

		public void Dispose()
		{
			this.OrdersChanged = null;
			UiGuard.Run("layers.behind", delegate
			{
				Destroy(_behind);
			});
			UiGuard.Run("layers.game", delegate
			{
				Destroy(_game);
			});
			UiGuard.Run("layers.above", delegate
			{
				Destroy(_above);
			});
			_behind = null;
			_game = null;
			_above = null;
			_initialized = false;
		}

		private static void Destroy(Canvas? canvas)
		{
			if (!((Object)(object)canvas == (Object)null))
			{
				Object.Destroy((Object)(object)((Component)canvas).gameObject);
			}
		}
	}
	internal static class LayoutEvents
	{
		private static bool _active;

		internal static event Action? CanvasChanged;

		public static void Activate()
		{
			_active = true;
			LayoutEvents.CanvasChanged = null;
		}

		public static void RequestCanvasChanged()
		{
			if (_active)
			{
				LayoutOnce.Request(NotifyCanvasChanged);
			}
		}

		public static void Watch(Transform? transform)
		{
			if (!_active || (Object)(object)transform == (Object)null)
			{
				return;
			}
			try
			{
				GameObject gameObject = ((Component)transform).gameObject;
				if (!((Object)(object)gameObject == (Object)null) && !((Object)(object)gameObject.GetComponent<CanvasLayoutWatcher>() != (Object)null))
				{
					gameObject.AddComponent<CanvasLayoutWatcher>();
				}
			}
			catch (Exception ex)
			{
				UiLog.Once("layout:watch", "could not watch a canvas for size changes: " + ex.Message);
			}
		}

		public static void Clear()
		{
			_active = false;
			LayoutEvents.CanvasChanged = null;
		}

		private static void NotifyCanvasChanged()
		{
			Action canvasChanged = LayoutEvents.CanvasChanged;
			if (canvasChanged == null)
			{
				return;
			}
			Delegate[] invocationList = canvasChanged.GetInvocationList();
			foreach (Delegate obj in invocationList)
			{
				try
				{
					((Action)obj)();
				}
				catch (Exception ex)
				{
					UiLog.Error("canvas layout listener failed: " + ex.Message);
				}
			}
		}
	}
	internal static class LayoutOnce
	{
		private static readonly List<Action> Pending = new List<Action>();

		private static WillRenderCanvases? _handler;

		private static bool _scheduled;

		private static bool _enabled = true;

		public static void Begin()
		{
			_enabled = true;
		}

		public static void Request(Action? action)
		{
			if (!_enabled || action == null)
			{
				return;
			}
			Pending.Add(action);
			if (_scheduled)
			{
				return;
			}
			try
			{
				WillRenderCanvases val = DelegateSupport.ConvertDelegate<WillRenderCanvases>((Delegate)new Action(Flush));
				if ((Delegate)(object)val == (Delegate)null)
				{
					Flush();
					return;
				}
				_handler = val;
				_scheduled = true;
				Canvas.willRenderCanvases += val;
			}
			catch (Exception ex)
			{
				_handler = null;
				_scheduled = false;
				UiLog.Once("layout:once", "could not schedule a layout callback: " + ex.Message);
				Flush();
			}
		}

		public static void Clear()
		{
			_enabled = false;
			Unsubscribe();
			Pending.Clear();
		}

		private static void Flush()
		{
			Unsubscribe();
			Action[] array = Pending.ToArray();
			Pending.Clear();
			for (int i = 0; i < array.Length; i++)
			{
				UiGuard.Callback("layout.once", array[i]);
			}
		}

		private static void Unsubscribe()
		{
			WillRenderCanvases handler = _handler;
			_handler = null;
			_scheduled = false;
			if ((Delegate)(object)handler == (Delegate)null)
			{
				return;
			}
			try
			{
				Canvas.willRenderCanvases -= handler;
			}
			catch (Exception ex)
			{
				UiLog.Once("layout:unsubscribe", "could not remove a layout callback: " + ex.Message);
			}
		}
	}
	internal static class SkinPolicy
	{
		public static bool AllowNative(UiKitRuntime runtime)
		{
			if (runtime != null)
			{
				return runtime.Options.Templates != TemplatePolicy.ManagedOnly;
			}
			return false;
		}

		public static bool AllowManaged(UiKitRuntime runtime)
		{
			if (runtime != null)
			{
				return runtime.Options.Templates != TemplatePolicy.NativeOnly;
			}
			return true;
		}

		public static T? TryNative<T>(string widget, Func<T?> create) where T : class
		{
			try
			{
				return create();
			}
			catch (Exception value)
			{
				UiLog.OnceError("skin:error:" + widget, $"native {widget} could not be created: {value}");
				return null;
			}
		}

		public static bool MissingNative(UiKitRuntime runtime, string widget)
		{
			if (AllowManaged(runtime))
			{
				UiLog.Once("skin:fallback:" + widget, "native " + widget + " template not found; using the managed fallback");
				return true;
			}
			UiLog.OnceError("skin:missing:" + widget, "native " + widget + " template not found and TemplatePolicy is NativeOnly; the widget was skipped");
			return false;
		}

		public static bool MissingManaged(UiKitRuntime runtime, string widget)
		{
			UiLog.OnceError("skin:managed-disabled:" + widget, widget + " needs a managed fallback, but TemplatePolicy is NativeOnly; the widget was skipped");
			return false;
		}
	}
	internal static class TmpTextSafety
	{
		public static bool EnsureMeasurable(TMP_Text? text)
		{
			if ((Object)(object)text == (Object)null)
			{
				return false;
			}
			try
			{
				if ((Object)(object)text.font == (Object)null)
				{
					return false;
				}
				if ((Object)(object)text.fontSharedMaterial == (Object)null)
				{
					Material material = ((TMP_Asset)text.font).material;
					if ((Object)(object)material == (Object)null)
					{
						return false;
					}
					text.fontSharedMaterial = material;
				}
				return true;
			}
			catch
			{
				return false;
			}
		}

		public static bool TryPreferredValues(TMP_Text? text, string? value, float width, float height, out Vector2 result)
		{
			//IL_0002: 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_0027: 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)
			result = default(Vector2);
			if (!EnsureMeasurable(text))
			{
				return false;
			}
			try
			{
				result = text.GetPreferredValues(value ?? string.Empty, width, height);
				if (float.IsNaN(result.x) || float.IsInfinity(result.x) || float.IsNaN(result.y) || float.IsInfinity(result.y))
				{
					result = default(Vector2);
					return false;
				}
				return true;
			}
			catch
			{
				return false;
			}
		}
	}
	internal static class UiFactory
	{
		private static readonly Il2CppReferenceArray<Type> RectTypes = BuildRectTypes();

		private static Il2CppReferenceArray<Type> BuildRectTypes()
		{
			return new Il2CppReferenceArray<Type>(1L) { [0] = Il2CppType.Of<RectTransform>() };
		}

		public static RectTransform NewRect(string name, Transform? parent)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			GameObject val = new GameObject(name, RectTypes);
			RectTransform component = val.GetComponent<RectTransform>();
			if ((Object)(object)parent != (Object)null)
			{
				((Transform)component).SetParent(parent, false);
				val.layer = ((Component)parent).gameObject.layer;
			}
			else
			{
				val.layer = 5;
			}
			return component;
		}

		public static void Stretch(RectTransform rect)
		{
			//IL_000b: 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_0021: 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)
			if (!((Object)(object)rect == (Object)null))
			{
				rect.anchorMin = Vector2.zero;
				rect.anchorMax = Vector2.one;
				rect.offsetMin = Vector2.zero;
				rect.offsetMax = Vector2.zero;
			}
		}

		public static Image AddImage(RectTransform? parent, string name, Sprite? sprite, Color? color = null, bool raycast = false)
		{
			//IL_0040: 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)
			Image obj = ((Component)NewRect(name, (Transform?)(object)parent)).gameObject.AddComponent<Image>();
			obj.sprite = sprite;
			obj.type = (Type)(((Object)(object)sprite != (Object)null) ? 1 : 0);
			((Graphic)obj).color = (Color)(((??)color) ?? Color.white);
			((Graphic)obj).raycastTarget = raycast;
			return obj;
		}

		public static TextMeshProUGUI AddText(RectTransform? parent, string name, string? value, float size, TextAlignmentOptions align, UiTheme? theme, bool raycast = false)
		{
			//IL_0031: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI obj = ((Component)NewRect(name, (Transform?)(object)parent)).gameObject.AddComponent<TextMeshProUGUI>();
			ApplyFont((TMP_Text?)(object)obj, theme);
			((TMP_Text)obj).text = value ?? string.Empty;
			((TMP_Text)obj).fontSize = size;
			((TMP_Text)obj).alignment = align;
			((Graphic)obj).color = theme?.TextColor ?? AssetCatalog.DefaultTextColor;
			((Graphic)obj).raycastTarget = raycast;
			return obj;
		}

		public static void ApplyFont(TMP_Text? text, UiTheme? theme)
		{
			if (!((Object)(object)text == (Object)null) && theme != null)
			{
				TMP_FontAsset font = theme.Font;
				if ((Object)(object)font != (Object)null)
				{
					text.font = font;
				}
				Material fontMaterial = theme.FontMaterial;
				if ((Object)(object)fontMaterial != (Object)null)
				{
					text.fontSharedMaterial = fontMaterial;
				}
				else if ((Object)(object)font != (Object)null)
				{
					text.fontSharedMaterial = ((TMP_Asset)font).material;
				}
			}
		}

		public static LayoutElement? Layout(RectTransform? rect)
		{
			if ((Object)(object)rect == (Object)null)
			{
				return null;
			}
			return ((Component)rect).gameObject.GetComponent<LayoutElement>() ?? ((Component)rect).gameObject.AddComponent<LayoutElement>();
		}

		public static void Destroy(Object obj)
		{
			if (obj != (Object)null)
			{
				Object.Destroy(obj);
			}
		}

		public static void Destroy(GameObject go)
		{
			if ((Object)(object)go != (Object)null)
			{
				Object.Destroy((Object)(object)go);
			}
		}
	}
	internal static class UiGuard
	{
		public static void Run(string operation, Action? action, string? scope = null)
		{
			if (action == null)
			{
				return;
			}
			try
			{
				action();
			}
			catch (Exception exception)
			{
				Report(operation, exception, scope);
			}
		}

		public static T? Func<T>(string operation, Func<T>? action, string? scope = null) where T : class?
		{
			if (action == null)
			{
				return null;
			}
			try
			{
				return action();
			}
			catch (Exception exception)
			{
				Report(operation, exception, scope);
				return null;
			}
		}

		public static T Value<T>(string operation, Func<T>? action, T fallback, string? scope = null)
		{
			if (action == null)
			{
				return fallback;
			}
			try
			{
				return action();
			}
			catch (Exception exception)
			{
				Report(operation, exception, scope);
				return fallback;
			}
		}

		public static void Callback(string operation, Action? callback)
		{
			if (callback == null)
			{
				return;
			}
			try
			{
				callback();
			}
			catch (Exception exception)
			{
				Report("callback." + operation, exception);
			}
		}

		public static void Report(string operation, Exception exception, string? scope = null)
		{
			string text = (string.IsNullOrWhiteSpace(scope) ? "uikit" : ("uikit[" + scope + "]"));
			try
			{
				UiLog.OnceError("guard:" + text + ":" + operation, $"{text}: {operation} failed: {exception}");
			}
			catch
			{
			}
		}

		public static string Text(string? value)
		{
			return value ?? string.Empty;
		}

		public static float Finite(float value, float fallback)
		{
			if (!float.IsNaN(value) && !float.IsInfinity(value))
			{
				return value;
			}
			return fallback;
		}
	}
	internal static class UiLog
	{
		private static ManualLogSource? _log;

		private static readonly HashSet<string> OnceKeys = new HashSet<string>();

		public static void SetLogger(ManualLogSource? log)
		{
			_log = log;
		}

		public static void ResetOnce()
		{
			lock (OnceKeys)
			{
				OnceKeys.Clear();
			}
		}

		public static void Info(string? message)
		{
			Write(delegate(ManualLogSource log)
			{
				log.LogInfo((object)message);
			});
		}

		public static void Warn(string? message)
		{
			Write(delegate(ManualLogSource log)
			{
				log.LogWarning((object)message);
			});
		}

		public static void Error(string? message)
		{
			Write(delegate(ManualLogSource log)
			{
				log.LogError((object)message);
			});
		}

		public static void Once(string key, string? message)
		{
			lock (OnceKeys)
			{
				if (!OnceKeys.Add(key))
				{
					return;
				}
			}
			Warn(message);
		}

		public static void InfoOnce(string key, string? message)
		{
			lock (OnceKeys)
			{
				if (!OnceKeys.Add(key))
				{
					return;
				}
			}
			Info(message);
		}

		public static void OnceError(string key, string? message)
		{
			lock (OnceKeys)
			{
				if (!OnceKeys.Add(key))
				{
					return;
				}
			}
			Error(message);
		}

		private static void Write(Action<ManualLogSource> write)
		{
			ManualLogSource log = _log;
			if (log == null)
			{
				return;
			}
			try
			{
				write(log);
			}
			catch
			{
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "DiceModders.UiKit";

		public const string PLUGIN_NAME = "UiKit";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace DiceModders.UiKit.Custom
{
	internal static class AutoHeightRegistry
	{
		private sealed class Binding
		{
			public Action? Callback;
		}

		private static readonly ConditionalWeakTable<AutoHeightText, Binding> Table = new ConditionalWeakTable<AutoHeightText, Binding>();

		public static void SetAfterMeasure(AutoHeightText? owner, Action? callback)
		{
			if (!((Object)(object)owner == (Object)null))
			{
				if (callback == null)
				{
					Table.Remove(owner);
					return;
				}
				if (Table.TryGetValue(owner, out Binding value))
				{
					value.Callback = callback;
					return;
				}
				Table.Add(owner, new Binding
				{
					Callback = callback
				});
			}
		}

		public static void Invoke(AutoHeightText? owner)
		{
			if (!((Object)(object)owner == (Object)null) && Table.TryGetValue(owner, out Binding value))
			{
				UiGuard.Callback("auto-height", value.Callback);
			}
		}

		public static void Clear(AutoHeightText? owner)
		{
			if ((Object)(object)owner != (Object)null)
			{
				Table.Remove(owner);
			}
		}
	}
	internal sealed class AutoHeightText : MonoBehaviour
	{
		private TMP_Text? _text;

		private LayoutElement? _layout;

		private float _lastHeight = -1f;

		private bool _scheduled;

		private WillRenderCanvases? _canvasHandler;

		public bool Enabled { get; private set; }

		public AutoHeightText(IntPtr ptr)
			: base(ptr)
		{
		}

		public void Bind(TMP_Text? text, LayoutElement? layout)
		{
			_text = text;
			_layout = layout;
		}

		public void SetEnabled(bool enabled)
		{
			Enabled = enabled;
			_lastHeight = -1f;
			if (enabled)
			{
				MeasureSoon();
			}
		}

		private void OnEnable()
		{
			if (Enabled)
			{
				MeasureSoon();
			}
		}

		private void Start()
		{
			if (Enabled)
			{
				MeasureSoon();
			}
		}

		private void OnRectTransformDimensionsChange()
		{
			if (Enabled)
			{
				Measure();
			}
		}

		public void MeasureNow()
		{
			if (Enabled)
			{
				Measure();
			}
		}

		public void Refresh()
		{
			MeasureSoon();
		}

		private void MeasureSoon()
		{
			if (Enabled && !_scheduled && !((Object)(object)_text == (Object)null))
			{
				WillRenderCanvases val = DelegateSupport.ConvertDelegate<WillRenderCanvases>((Delegate)new Action(OnWillRenderCanvases));
				if (!((Delegate)(object)val == (Delegate)null))
				{
					_scheduled = true;
					_canvasHandler = val;
					Canvas.willRenderCanvases += val;
				}
			}
		}

		private void OnWillRenderCanvases()
		{
			if ((Delegate)(object)_canvasHandler != (Delegate)null)
			{
				Canvas.willRenderCanvases -= _canvasHandler;
				_canvasHandler = null;
			}
			_scheduled = false;
			Measure();
		}

		private void Measure()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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)
			if (!Enabled)
			{
				return;
			}
			TMP_Text text = _text;
			LayoutElement layout = _layout;
			if ((Object)(object)text == (Object)null || (Object)(object)layout == (Object)null)
			{
				return;
			}
			float width;
			try
			{
				RectTransform rectTransform = text.rectTransform;
				if ((Object)(object)rectTransform == (Object)null)
				{
					return;
				}
				Rect rect = rectTransform.rect;
				width = ((Rect)(ref rect)).width;
			}
			catch (Exception)
			{
				return;
			}
			if (width < 1f || !TmpTextSafety.TryPreferredValues(text, text.text, width, 0f, out var result))
			{
				return;
			}
			float num = Mathf.Ceil(result.y);
			float num2 = Mathf.Ceil(text.fontSize * 1.2f);
			if (num < num2)
			{
				num = num2;
			}
			if (Mathf.Abs(num - _lastHeight) < 0.5f)
			{
				return;
			}
			_lastHeight = num;
			layout.minHeight = num;
			layout.preferredHeight = num;
			layout.flexibleHeight = 0f;
			Transform parent = ((Transform)text.rectTransform).parent;
			if ((Object)(object)parent != (Object)null)
			{
				RectTransform val = ((Il2CppObjectBase)parent).TryCast<RectTransform>();
				if ((Object)(object)val != (Object)null)
				{
					LayoutRebuilder.MarkLayoutForRebuild(val);
				}
			}
			AutoHeightRegistry.Invoke(this);
		}

		private void OnDisable()
		{
			if ((Delegate)(object)_canvasHandler != (Delegate)null)
			{
				Canvas.willRenderCanvases -= _canvasHandler;
				_canvasHandler = null;
			}
			_scheduled = false;
		}

		private void OnDestroy()
		{
			OnDisable();
			AutoHeightRegistry.Clear(this);
			_text = null;
			_layout = null;
		}
	}
	internal sealed class CanvasLayoutWatcher : MonoBehaviour
	{
		public CanvasLayoutWatcher(IntPtr ptr)
			: base(ptr)
		{
		}

		private void OnEnable()
		{
			LayoutEvents.RequestCanvasChanged();
		}

		private void OnRectTransformDimensionsChange()
		{
			LayoutEvents.RequestCanvasChanged();
		}
	}
	internal sealed class ClickRelay : MonoBehaviour
	{
		public ClickRelay(IntPtr ptr)
			: base(ptr)
		{
		}

		private void OnDestroy()
		{
			ClickRelayRegistry.Clear(this);
		}
	}
	internal static class ClickRelayRegistry
	{
		private sealed class Binding
		{
			public Button? Button;

			public UnityAction? Callback;
		}

		private static readonly ConditionalWeakTable<ClickRelay, Binding> Table = new ConditionalWeakTable<ClickRelay, Binding>();

		public static void Bind(ClickRelay relay, Button? button, Action? action)
		{
			if ((Object)(object)relay == (Object)null)
			{
				return;
			}
			Clear(relay);
			if (!((Object)(object)button == (Object)null) && action != null)
			{
				UnityAction val = EventRelay.ToUnity(action);
				if (!((Delegate)(object)val == (Delegate)null))
				{
					((UnityEvent)button.onClick).AddListener(val);
					Table.Add(relay, new Binding
					{
						Button = button,
						Callback = val
					});
				}
			}
		}

		public static void Clear(ClickRelay relay)
		{
			if (!((Object)(object)relay == (Object)null) && Table.TryGetValue(relay, out Binding value))
			{
				Table.Remove(relay);
				if ((Object)(object)value.Button != (Object)null && (Delegate)(object)value.Callback != (Delegate)null)
				{
					((UnityEvent)value.Button.onClick).RemoveListener(value.Callback);
				}
			}
		}
	}
	internal static class EventTriggerBinder
	{
		public static void Add(EventTrigger trigger, List<UnityAction<BaseEventData>>? keep, EventTriggerType type, UnityAction<BaseEventData>? action)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			if (!((Object)(object)trigger == (Object)null) && !((Delegate)(object)action == (Delegate)null))
			{
				Entry val = new Entry
				{
					eventID = type
				};
				((UnityEvent<BaseEventData>)(object)val.callback).AddListener(action);
				trigger.triggers.Add(val);
				keep?.Add(action);
			}
		}
	}
	internal sealed class PointerReceiver : MonoBehaviour
	{
		public RectTransform? Area;

		private EventTrigger? _trigger;

		private readonly List<UnityAction<BaseEventData>> _keep = new List<UnityAction<BaseEventData>>();

		private PointerTracker.Entry? _entry;

		private bool _hover;

		private Vector2 _lastLocal;

		private bool _hasLastLocal;

		public PointerReceiver(IntPtr ptr)
			: base(ptr)
		{
		}

		public void Bind(RectTransform? area)
		{
			Area = area;
			if ((Object)(object)_trigger == (Object)null)
			{
				EventTrigger val = (_trigger = ((Component)this).gameObject.GetComponent<EventTrigger>() ?? ((Component)this).gameObject.AddComponent<EventTrigger>());
				val.triggers.Clear();
				EventTriggerBinder.Add(val, _keep, (EventTriggerType)0, EventRelay.ToEvent(OnEnter));
				EventTriggerBinder.Add(val, _keep, (EventTriggerType)1, EventRelay.ToEvent(OnExit));
				EventTriggerBinder.Add(val, _keep, (EventTriggerType)2, EventRelay.ToEvent(OnDown));
				EventTriggerBinder.Add(val, _keep, (EventTriggerType)3, EventRelay.ToEvent(OnUp));
				EventTriggerBinder.Add(val, _keep, (EventTriggerType)4, EventRelay.ToEvent(OnClick));
				EventTriggerBinder.Add(val, _keep, (EventTriggerType)13, EventRelay.ToEvent(OnBeginDrag));
				EventTriggerBinder.Add(val, _keep, (EventTriggerType)5, EventRelay.ToEvent(OnDrag));
				EventTriggerBinder.Add(val, _keep, (EventTriggerType)14, EventRelay.ToEvent(OnEndDrag));
			}
			if (_entry == null)
			{
				_entry = PointerTracker.Add((Object?)(object)this, (Vector2 position) => _hover && (Object)(object)Area != (Object)null && ((Component)Area).gameObject.activeInHierarchy && RectTransformUtility.RectangleContainsScreenPoint(Area, position, PointerTracker.CameraFor(Area)), OnWheel, OnMove);
			}
		}

		private static Camera? CameraFor(RectTransform? rect)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)rect == (Object)null)
			{
				return null;
			}
			Canvas componentInParent = ((Component)rect).GetComponentInParent<Canvas>();
			componentInParent = (((Object)(object)componentInParent != (Object)null) ? componentInParent.rootCanvas : null);
			if (!((Object)(object)componentInParent != (Object)null) || (int)componentInParent.renderMode == 0)
			{
				return null;
			}
			return componentInParent.worldCamera;
		}

		private static float ScaleFor(RectTransform? rect)
		{
			if ((Object)(object)rect == (Object)null)
			{
				return 1f;
			}
			Canvas componentInParent = ((Component)rect).GetComponentInParent<Canvas>();
			componentInParent = (((Object)(object)componentInParent != (Object)null) ? componentInParent.rootCanvas : null);
			if (!((Object)(object)componentInParent != (Object)null) || !(componentInParent.scaleFactor > 0.0001f))
			{
				return 1f;
			}
			return componentInParent.scaleFactor;
		}

		private void Raise(int kind, PointerEventData? data, int button)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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)
			Action<UiPointerEvent> action = PointerRegistry.Pointer(this);
			Vector2 val = default(Vector2);
			if (action == null || (Object)(object)Area == (Object)null || data == null || !RectTransformUtility.ScreenPointToLocalPointInRectangle(Area, data.position, CameraFor(Area), ref val))
			{
				return;
			}
			Rect rect = Area.rect;
			Vector2 val2 = val - ((Rect)(ref rect)).min;
			Vector2 uv = default(Vector2);
			((Vector2)(ref uv))..ctor((((Rect)(ref rect)).width > 0.001f) ? (val2.x / ((Rect)(ref rect)).width) : 0f, (((Rect)(ref rect)).height > 0.001f) ? (val2.y / ((Rect)(ref rect)).height) : 0f);
			Vector2 delta = data.delta / ScaleFor(Area);
			try
			{
				action(new UiPointerEvent((UiPointerKind)kind, button, uv, val2, delta));
			}
			catch (Exception ex)
			{
				UiLog.Error("image pointer handler: " + ex);
			}
		}

		private void OnEnter(BaseEventData? data)
		{
			_hover = true;
			_hasLastLocal = false;
			Raise(5, (data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null, -1);
		}

		private void OnExit(BaseEventData? data)
		{
			_hover = false;
			_hasLastLocal = false;
			Raise(6, (data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null, -1);
		}

		private void OnDown(BaseEventData? data)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			PointerEventData val = ((data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null);
			Raise(0, val, (val == null) ? (-1) : ((int)val.button));
		}

		private void OnUp(BaseEventData? data)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			PointerEventData val = ((data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null);
			Raise(1, val, (val == null) ? (-1) : ((int)val.button));
		}

		private void OnClick(BaseEventData? data)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			PointerEventData val = ((data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null);
			Raise(2, val, (val == null) ? (-1) : ((int)val.button));
		}

		private void OnBeginDrag(BaseEventData? data)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			PointerEventData val = ((data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null);
			Raise(4, val, (val == null) ? (-1) : ((int)val.button));
		}

		private void OnDrag(BaseEventData? data)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			PointerEventData val = ((data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null);
			Raise(4, val, (val == null) ? (-1) : ((int)val.button));
		}

		private void OnEndDrag(BaseEventData? data)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			PointerEventData val = ((data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null);
			Raise(1, val, (val == null) ? (-1) : ((int)val.button));
		}

		private bool OnWheel(float notches)
		{
			Action<float> action = PointerRegistry.Scroll(this);
			if (action == null)
			{
				return false;
			}
			try
			{
				action(notches);
			}
			catch (Exception ex)
			{
				UiLog.Error("image scroll handler: " + ex);
			}
			return true;
		}

		private void OnMove(Vector2 screen)
		{
			//IL_001c: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			Action<UiPointerEvent> action = PointerRegistry.Pointer(this);
			RectTransform area = Area;
			Vector2 val = default(Vector2);
			if (action == null || (Object)(object)area == (Object)null || !RectTransformUtility.ScreenPointToLocalPointInRectangle(area, screen, PointerTracker.CameraFor(area), ref val))
			{
				return;
			}
			Rect rect = area.rect;
			Vector2 val2 = val - ((Rect)(ref rect)).min;
			if (_hasLastLocal && val2 == _lastLocal)
			{
				return;
			}
			Vector2 uv = default(Vector2);
			((Vector2)(ref uv))..ctor((((Rect)(ref rect)).width > 0.001f) ? (val2.x / ((Rect)(ref rect)).width) : 0f, (((Rect)(ref rect)).height > 0.001f) ? (val2.y / ((Rect)(ref rect)).height) : 0f);
			Vector2 delta = (_hasLastLocal ? (val2 - _lastLocal) : Vector2.zero);
			_lastLocal = val2;
			_hasLastLocal = true;
			try
			{
				action(new UiPointerEvent(UiPointerKind.Move, -1, uv, val2, delta));
			}
			catch (Exception ex)
			{
				UiLog.Error("image pointer handler: " + ex);
			}
		}

		private void OnDestroy()
		{
			PointerRegistry.Clear(this);
			PointerTracker.Remove(_entry);
			_entry = null;
			_keep.Clear();
		}
	}
	internal static class PointerRegistry
	{
		private sealed class Handlers
		{
			public Action<UiPointerEvent>? Pointer;

			public Action<float>? Scroll;
		}

		private static readonly ConditionalWeakTable<PointerReceiver, Handlers> Table = new ConditionalWeakTable<PointerReceiver, Handlers>();

		public static void SetPointer(PointerReceiver? owner, Action<UiPointerEvent>? handler)
		{
			if (!((Object)(object)owner == (Object)null))
			{
				if (!Table.TryGetValue(owner, out Handlers value))
				{
					value = new Handlers();
					Table.Add(owner, value);
				}
				value.Pointer = handler;
				if (value.Pointer == null && value.Scroll == null)
				{
					Table.Remove(owner);
				}
			}
		}

		public static void SetScroll(PointerReceiver? owner, Action<float>? handler)
		{
			if (!((Object)(object)owner == (Object)null))
			{
				if (!Table.TryGetValue(owner, out Handlers value))
				{
					value = new Handlers();
					Table.Add(owner, value);
				}
				value.Scroll = handler;
				if (value.Pointer == null && value.Scroll == null)
				{
					Table.Remove(owner);
				}
			}
		}

		public static Action<UiPointerEvent>? Pointer(PointerReceiver? owner)
		{
			if (!((Object)(object)owner != (Object)null) || !Table.TryGetValue(owner, out Handlers value))
			{
				return null;
			}
			return value.Pointer;
		}

		public static Action<float>? Scroll(PointerReceiver? owner)
		{
			if (!((Object)(object)owner != (Object)null) || !Table.TryGetValue(owner, out Handlers value))
			{
				return null;
			}
			return value.Scroll;
		}

		public static void Clear(PointerReceiver? owner)
		{
			if ((Object)(object)owner != (Object)null)
			{
				Table.Remove(owner);
			}
		}
	}
	internal sealed class ScrollPin : MonoBehaviour
	{
		private ScrollRect? _scroll;

		private UnityAction<Vector2>? _handler;

		private bool _pinned = true;

		private bool _applying;

		public ScrollPin(IntPtr ptr)
			: base(ptr)
		{
		}

		public void Bind(ScrollRect? scroll)
		{
			if (!((Object)(object)scroll == (Object)null))
			{
				_scroll = scroll;
				UnityAction<Vector2> val = DelegateSupport.ConvertDelegate<UnityAction<Vector2>>((Delegate)new Action<Vector2>(OnScroll));
				if (!((Delegate)(object)val == (Delegate)null))
				{
					_handler = val;
					((UnityEvent<Vector2>)(object)scroll.onValueChanged).AddListener(val);
				}
			}
		}

		private void OnScroll(Vector2 position)
		{
			if (!_applying && !((Object)(object)_scroll == (Object)null))
			{
				_pinned = _scroll.verticalNormalizedPosition > 0.999f;
			}
		}

		private void OnRectTransformDimensionsChange()
		{
			if (!((Object)(object)_scroll == (Object)null) && _pinned)
			{
				_applying = true;
				_scroll.verticalNormalizedPosition = 1f;
				_applying = false;
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)_scroll != (Object)null && (Delegate)(object)_handler != (Delegate)null)
			{
				((UnityEvent<Vector2>)(object)_scroll.onValueChanged).RemoveListener(_handler);
			}
			_scroll = null;
			_handler = null;
		}
	}
	internal sealed class SliderRelay : MonoBehaviour
	{
		public SliderRelay(IntPtr ptr)
			: base(ptr)
		{
		}

		private void OnDestroy()
		{
			SliderRelayRegistry.Clear(this);
		}
	}
	internal static class SliderRelayRegistry
	{
		private sealed class Binding
		{
			public Slider? Slider;

			public UnityAction<float>? Callback;
		}

		private static readonly ConditionalWeakTable<SliderRelay, Binding> Table = new ConditionalWeakTable<SliderRelay, Binding>();

		public static void Bind(SliderRelay relay, Slider? slider, Action<float>? action)
		{
			if ((Object)(object)relay == (Object)null)
			{
				return;
			}
			Clear(relay);
			if (!((Object)(object)slider == (Object)null) && action != null)
			{
				UnityAction<float> val = EventRelay.ToUnity(action);
				if (!((Delegate)(object)val == (Delegate)null))
				{
					((UnityEvent<float>)(object)slider.onValueChanged).AddListener(val);
					Table.Add(relay, new Binding
					{
						Slider = slider,
						Callback = val
					});
				}
			}
		}

		public static void Clear(SliderRelay relay)
		{
			if (!((Object)(object)relay == (Object)null) && Table.TryGetValue(relay, out Binding value))
			{
				Table.Remove(relay);
				if ((Object)(object)value.Slider != (Object)null && (Delegate)(object)value.Callback != (Delegate)null)
				{
					((UnityEvent<float>)(object)value.Slider.onValueChanged).RemoveListener(value.Callback);
				}
			}
		}
	}
	internal sealed class WidthWatcher : MonoBehaviour
	{
		private TMP_Text? _text;

		private float _lastWidth = -1f;

		public WidthWatcher(IntPtr ptr)
			: base(ptr)
		{
		}

		public void Bind(TMP_Text? text)
		{
			_text = text;
		}

		private void OnEnable()
		{
			_lastWidth = -1f;
		}

		private void OnRectTransformDimensionsChange()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			TMP_Text text = _text;
			if ((Object)(object)text == (Object)null)
			{
				return;
			}
			try
			{
				RectTransform rectTransform = text.rectTransform;
				if ((Object)(object)rectTransform == (Object)null)
				{
					return;
				}
				Rect rect = rectTransform.rect;
				float width = ((Rect)(ref rect)).width;
				if (!(Mathf.Abs(width - _lastWidth) < 0.5f))
				{
					_lastWidth = width;
					if (TmpTextSafety.EnsureMeasurable(text))
					{
						((Graphic)text).SetAllDirty();
						text.ForceMeshUpdate(false, false);
					}
				}
			}
			catch
			{
			}
		}

		private void OnDestroy()
		{
			_text = null;
		}
	}
	internal sealed class WindowDragHandler : MonoBehaviour
	{
		private RectTransform? _root;

		private float _minVisible = 8f;

		private bool _canDragNow = true;

		private bool _dragging;

		private bool _canDrag;

		private Canvas? _canvas;

		private EventTrigger? _trigger;

		private readonly List<UnityAction<BaseEventData>> _keep = new List<UnityAction<BaseEventData>>();

		public WindowDragHandler(IntPtr ptr)
			: base(ptr)
		{
		}

		public void Bind(RectTransform? root, float minVisible)
		{
			_root = root;
			_minVisible = minVisible;
			_canDragNow = true;
			_canvas = ((Component)this).GetComponentInParent<Canvas>();
			if ((Object)(object)_canvas != (Object)null)
			{
				_canvas = _canvas.rootCanvas;
			}
			if (!((Object)(object)_trigger != (Object)null))
			{
				EventTrigger val = (_trigger = ((Component)this).gameObject.GetComponent<EventTrigger>() ?? ((Component)this).gameObject.AddComponent<EventTrigger>());
				val.triggers.Clear();
				EventTriggerBinder.Add(val, _keep, (EventTriggerType)2, EventRelay.ToEvent(OnPointerDown));
				EventTriggerBinder.Add(val, _keep, (EventTriggerType)13, EventRelay.ToEvent(OnBeginDrag));
				EventTriggerBinder.Add(val, _keep, (EventTriggerType)5, EventRelay.ToEvent(OnDrag));
				EventTriggerBinder.Add(val, _keep, (EventTriggerType)14, EventRelay.ToEvent(OnEndDrag));
				EventTriggerBinder.Add(val, _keep, (EventTriggerType)4, EventRelay.ToEvent(OnPointerClick));
			}
		}

		public void SetCanDrag(bool canDrag)
		{
			_canDragNow = canDrag;
			if (!canDrag)
			{
				_dragging = false;
				_canDrag = false;
			}
		}

		private static bool IsInteractive(GameObject hit)
		{
			if ((Object)(object)hit == (Object)null)
			{
				return false;
			}
			if ((Object)(object)hit.GetComponentInParent<Selectable>() != (Object)null)
			{
				return true;
			}
			if ((Object)(object)hit.GetComponentInParent<ScrollRect>() != (Object)null)
			{
				return true;
			}
			return (Object)(object)hit.GetComponentInParent<TMP_InputField>() != (Object)null;
		}

		private void OnPointerDown(BaseEventData? data)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			PointerEventData val = ((data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null);
			if (val != null && (int)val.button == 0)
			{
				WindowDragRegistry.BringToFront(this);
				_canDrag = !IsInteractive(val.pointerCurrentRaycast.gameObject);
			}
		}

		private void OnBeginDrag(BaseEventData? data)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			PointerEventData val = ((data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null);
			_dragging = _canDrag && val != null && (int)val.button == 0;
		}

		private void OnDrag(BaseEventData? data)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			PointerEventData val = ((data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null);
			if (_dragging && !((Object)(object)_root == (Object)null) && val != null && _canDragNow)
			{
				float num = (((Object)(object)_canvas != (Object)null && _canvas.scaleFactor > 0.0001f) ? _canvas.scaleFactor : 1f);
				Vector2 position = _root.anchoredPosition + val.delta / num;
				ClampToParent(_root, ref position);
				_root.anchoredPosition = position;
			}
		}

		private void OnEndDrag(BaseEventData? data)
		{
			_dragging = false;
		}

		private void OnPointerClick(BaseEventData? data)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			PointerEventData val = ((data != null) ? ((Il2CppObjectBase)data).TryCast<PointerEventData>() : null);
			if (val != null && (int)val.button == 0 && val.clickCount >= 2 && !IsInteractive(val.pointerCurrentRaycast.gameObject))
			{
				WindowDragRegistry.DoubleClick(this);
			}
		}

		private void OnDisable()
		{
			_dragging = false;
			_canDrag = false;
		}

		private void ClampToParent(RectTransform root, ref Vector2 position)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (((Object)(object)((Transform)root).parent != (Object)null) ? ((Il2CppObjectBase)((Transform)root).parent).TryCast<RectTransform>() : null);
			if (!((Object)(object)val == (Object)null))
			{
				Rect rect = val.rect;
				Rect rect2 = root.rect;
				float num = 0f;
				float num2 = Mathf.Max(0f, ((Rect)(ref rect)).width - ((Rect)(ref rect2)).width);
				float num3 = 0f - Mathf.Max(0f, ((Rect)(ref rect)).height - _minVisible);
				float num4 = 0f;
				position.x = Mathf.Clamp(position.x, num, num2);
				position.y = Mathf.Clamp(position.y, num3, num4);
			}
		}

		private void OnDestroy()
		{
			WindowDragRegistry.Clear(this);
			_keep.Clear();
			_root = null;
		}
	}
	internal static class WindowDragRegistry
	{
		private sealed class Binding
		{
			public UnityAction? BringToFront;

			public UnityAction? DoubleClick;
		}

		private static readonly ConditionalWeakTable<WindowDragHandler, Binding> Table = new ConditionalWeakTable<WindowDragHandler, Binding>();

		public static void Bind(WindowDragHandler handler, Action? bringToFront, Action? doubleClick)
		{
			if (!((Object)(object)handler == (Object)null))
			{
				Table.Remove(handler);
				Table.Add(handler, new Binding
				{
					BringToFront = EventRelay.ToUnity(bringToFront),
					DoubleClick = EventRelay.ToUnity(doubleClick)
				});
			}
		}

		public static void BringToFront(WindowDragHandler handler)
		{
			if ((Object)(object)handler != (Object)null && Table.TryGetValue(handler, out Binding value))
			{
				UnityAction? bringToFront = value.BringToFront;
				if (bringToFront != null)
				{
					bringToFront.Invoke();
				}
			}
		}

		public static void DoubleClick(WindowDragHandler handler)
		{
			if ((Object)(object)handler != (Object)null && Table.TryGetValue(handler, out Binding value))
			{
				UnityAction? doubleClick = value.DoubleClick;
				if (doubleClick != null)
				{
					doubleClick.Invoke();
				}
			}
		}

		public static void Clear(WindowDragHandler handler)
		{
			if ((Object)(object)handler != (Object)null)
			{
				Table.Remove(handler);
			}
		}
	}
	internal static class PointerTracker
	{
		internal sealed class Entry
		{
			public Object? Owner;

			public Func<Vector2, bool>? Hover;

			public Func<float, bool>? Wheel;

			public Action<Vector2>? Move;

			public int WheelPriority;
		}

		private static readonly List<Entry> Entries = new List<Entry>();

		private static Action? _updateHandler;

		private static Vector2 _lastPosition;

		private static bool _hasLastPosition;

		private static bool _inputErrorLogged;

		private static int _dispatchDepth;

		public static Entry Add(Object? owner, Func<Vector2, bool>? hover, Func<float, bool>? wheel, Action<Vector2>? move, int wheelPriority = 0)
		{
			Entry entry = new Entry
			{
				Owner = owner,
				Hover = hover,
				Wheel = wheel,
				Move = move,
				WheelPriority = wheelPriority
			};
			Entries.Add(entry);
			EnsureInput();
			return entry;
		}

		public static void Remove(Entry? entry)
		{
			if (entry != null)
			{
				Entries.Remove(entry);
				DisposeIfIdle();
			}
		}

		public static void Clear()
		{
			Entries.Clear();
			DisposeInput();
		}

		private static void DisposeIfIdle()
		{
			if (Entries.Count == 0)
			{
				if (_dispatchDepth > 0)
				{
					LayoutOnce.Request(DisposeIfIdle);
				}
				else
				{
					DisposeInput();
				}
			}
		}

		private static void EndDispatch()
		{
			_dispatchDepth--;
			if (_dispatchDepth == 0 && Entries.Count == 0)
			{
				LayoutOnce.Request(DisposeIfIdle);
			}
		}

		private static void EnsureInput()
		{
			if ((Delegate)(object)_updateHandler != (Delegate)null || Entries.Count == 0)
			{
				return;
			}
			try
			{
				Action obj = DelegateSupport.ConvertDelegate<Action>((Delegate)new Action(OnInputAfterUpdate));
				if ((Delegate)(object)obj == (Delegate)null)
				{
					throw new InvalidOperationException("could not create the pointer update callback");
				}
				InputSystem.onAfterUpdate += obj;
				_updateHandler = obj;
			}
			catch (Exception ex)
			{
				DisposeInput();
				if (!_inputErrorLogged)
				{
					_inputErrorLogged = true;
					UiLog.Warn("pointer input could not be initialized; image Move and wheel callbacks are disabled: " + ex.Message);
				}
			}
		}

		private static void DisposeInput()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			Action updateHandler = _updateHandler;
			_updateHandler = null;
			_hasLastPosition = false;
			_lastPosition = default(Vector2);
			if ((Delegate)(object)updateHandler == (Delegate)null)
			{
				return;
			}
			try
			{
				InputSystem.onAfterUpdate -= updateHandler;
			}
			catch (Exception ex)
			{
				UiLog.Once("pointer:input-dispose", "could not remove the pointer update callback: " + ex.Message);
			}
		}

		private static void OnInputAfterUpdate()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or mis