Decompiled source of ClientPortals v0.1.5

plugins/ClientPortals.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using GUIFramework;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("ClientPortals")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+f5256f535aa6fbf2a8c7752c6578d61135a2f0ed")]
[assembly: AssemblyProduct("ClientPortals")]
[assembly: AssemblyTitle("ClientPortals")]
[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]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
	[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 ClientPortals
{
	public readonly struct PortalPos : IEquatable<PortalPos>
	{
		public readonly int X;

		public readonly int Y;

		public readonly int Z;

		public PortalPos(int x, int y, int z)
		{
			X = x;
			Y = y;
			Z = z;
		}

		public static PortalPos Of(Vector3 p)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			return new PortalPos(Mathf.RoundToInt(p.x * 10f), Mathf.RoundToInt(p.y * 10f), Mathf.RoundToInt(p.z * 10f));
		}

		public bool Equals(PortalPos o)
		{
			if (X == o.X && Y == o.Y)
			{
				return Z == o.Z;
			}
			return false;
		}

		public override bool Equals(object obj)
		{
			if (obj is PortalPos o)
			{
				return Equals(o);
			}
			return false;
		}

		public override int GetHashCode()
		{
			return (((X * 397) ^ Y) * 397) ^ Z;
		}

		public static bool operator ==(PortalPos a, PortalPos b)
		{
			return a.Equals(b);
		}

		public static bool operator !=(PortalPos a, PortalPos b)
		{
			return !a.Equals(b);
		}

		public override string ToString()
		{
			return $"({(float)X / 10f:0.0}, {(float)Y / 10f:0.0}, {(float)Z / 10f:0.0})";
		}
	}
	public sealed class PortalEntry
	{
		public Vector3 Position;

		public Quaternion Rotation = Quaternion.identity;

		public string Name = "";

		public long Stamp;

		public bool Removed;

		public PortalPos Key => PortalPos.Of(Position);

		public PortalEntry Clone()
		{
			return (PortalEntry)MemberwiseClone();
		}
	}
	public sealed class Atlas
	{
		private const int Version = 1;

		private readonly Dictionary<PortalPos, PortalEntry> entries = new Dictionary<PortalPos, PortalEntry>();

		public IEnumerable<PortalEntry> All => entries.Values;

		public IEnumerable<PortalEntry> Known => entries.Values.Where((PortalEntry e) => !e.Removed);

		public int KnownCount => entries.Values.Count((PortalEntry e) => !e.Removed);

		public bool TryGet(PortalPos key, out PortalEntry entry)
		{
			return entries.TryGetValue(key, out entry);
		}

		public bool Knows(PortalPos key)
		{
			if (entries.TryGetValue(key, out var value))
			{
				return !value.Removed;
			}
			return false;
		}

		public bool Observe(Vector3 position, Quaternion rotation, string name, long stamp)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			PortalPos key = PortalPos.Of(position);
			if (name == null)
			{
				name = "";
			}
			if (entries.TryGetValue(key, out var value))
			{
				bool removed = value.Removed;
				if (removed || value.Name != name || Quaternion.Angle(value.Rotation, rotation) > 1f)
				{
					value.Position = position;
					value.Rotation = rotation;
					value.Name = name;
					value.Removed = false;
					value.Stamp = Math.Max(stamp, value.Stamp + 1);
				}
				return removed;
			}
			entries[key] = new PortalEntry
			{
				Position = position,
				Rotation = rotation,
				Name = name,
				Stamp = stamp
			};
			return true;
		}

		public bool Forget(PortalPos key, long stamp)
		{
			if (!entries.TryGetValue(key, out var value) || value.Removed)
			{
				return false;
			}
			value.Removed = true;
			value.Stamp = Math.Max(stamp, value.Stamp + 1);
			return true;
		}

		public int Merge(Atlas other)
		{
			return Merge(other.All);
		}

		public int Merge(IEnumerable<PortalEntry> incoming)
		{
			int num = 0;
			foreach (PortalEntry item in incoming)
			{
				PortalPos key = item.Key;
				if (entries.TryGetValue(key, out var value))
				{
					if (item.Stamp <= value.Stamp)
					{
						continue;
					}
					if (value.Removed && !item.Removed)
					{
						num++;
					}
				}
				else if (!item.Removed)
				{
					num++;
				}
				entries[key] = item.Clone();
			}
			return num;
		}

		public int PruneRemoved(long before)
		{
			List<PortalPos> list = (from kv in entries
				where kv.Value.Removed && kv.Value.Stamp < before
				select kv.Key).ToList();
			foreach (PortalPos item in list)
			{
				entries.Remove(item);
			}
			return list.Count;
		}

		public byte[] Serialize()
		{
			using MemoryStream memoryStream = new MemoryStream();
			using (DeflateStream output = new DeflateStream(memoryStream, CompressionMode.Compress, leaveOpen: true))
			{
				using BinaryWriter binaryWriter = new BinaryWriter(output);
				binaryWriter.Write(1);
				binaryWriter.Write(entries.Count);
				foreach (PortalEntry value in entries.Values)
				{
					binaryWriter.Write(value.Position.x);
					binaryWriter.Write(value.Position.y);
					binaryWriter.Write(value.Position.z);
					binaryWriter.Write(value.Rotation.x);
					binaryWriter.Write(value.Rotation.y);
					binaryWriter.Write(value.Rotation.z);
					binaryWriter.Write(value.Rotation.w);
					binaryWriter.Write(value.Name ?? "");
					binaryWriter.Write(value.Stamp);
					binaryWriter.Write(value.Removed);
				}
			}
			return memoryStream.ToArray();
		}

		public static Atlas Deserialize(byte[] data)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			Atlas atlas = new Atlas();
			if (data == null || data.Length == 0)
			{
				return atlas;
			}
			try
			{
				using BinaryReader binaryReader = new BinaryReader(new DeflateStream(new MemoryStream(data), CompressionMode.Decompress));
				if (binaryReader.ReadInt32() != 1)
				{
					return atlas;
				}
				int num = binaryReader.ReadInt32();
				List<PortalEntry> list = new List<PortalEntry>(num);
				for (int i = 0; i < num; i++)
				{
					list.Add(new PortalEntry
					{
						Position = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()),
						Rotation = new Quaternion(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()),
						Name = binaryReader.ReadString(),
						Stamp = binaryReader.ReadInt64(),
						Removed = binaryReader.ReadBoolean()
					});
				}
				atlas.Merge(list);
				return atlas;
			}
			catch (Exception)
			{
				return new Atlas();
			}
		}
	}
	internal static class Compat
	{
		private const string TagConnectedPortalsGuid = "neobotics.valheim_mod.tagconnectedportals";

		private const string OverheadTextGuid = "ModdedWolf.Teleporter_Overhead_Text";

		private const string ZenModLibGuid = "ZenDragon.Zen.ModLib";

		public static bool TagConnectedPortals => Chainloader.PluginInfos.ContainsKey("neobotics.valheim_mod.tagconnectedportals");

		public static bool OverheadText => Chainloader.PluginInfos.ContainsKey("ModdedWolf.Teleporter_Overhead_Text");

		private static KeyCode ZenAltKey
		{
			get
			{
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				if (!Chainloader.PluginInfos.TryGetValue("ZenDragon.Zen.ModLib", out var value) || !Object.op_Implicit((Object)(object)value.Instance))
				{
					return (KeyCode)0;
				}
				ConfigEntry<KeyCode> val = default(ConfigEntry<KeyCode>);
				if (!value.Instance.Config.TryGetEntry<KeyCode>("Input", "Alternate Interact Key", ref val))
				{
					return (KeyCode)0;
				}
				return val.Value;
			}
		}

		public static void Log()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			KeyCode zenAltKey = ZenAltKey;
			if ((int)zenAltKey != 0)
			{
				KeyboardShortcut value = Plugin.TravelKey.Value;
				if (zenAltKey == ((KeyboardShortcut)(ref value)).MainKey)
				{
					Debug.Log((object)string.Format("[{0}] Zen.ModLib's Alternate Interact Key is {1}, like TravelKey: at a portal it opens the destinations", "ClientPortals", zenAltKey));
				}
			}
			if (TagConnectedPortals)
			{
				Debug.Log((object)"[ClientPortals] TagConnectedPortals is installed: renaming both ends of a pair is left to it (RenameBoth is off)");
			}
			if (OverheadText)
			{
				Debug.Log((object)"[ClientPortals] Teleporter Overhead Text is installed: portal names above portals are left to it (Labels are off)");
			}
		}
	}
	public enum SortMode
	{
		Name,
		Nearest,
		Farthest
	}
	public enum ListTab
	{
		All,
		Favorites,
		Ignored
	}
	public sealed class ListOptions
	{
		public SortMode Sort;

		public ListTab Tab;

		public bool FavoritesFirst = true;

		public bool HideNearby;

		public float HideNearbyDistance = 30f;

		public bool HideTwins;

		public string Search = "";
	}
	public static class Destinations
	{
		public const float SamePortal = 1.5f;

		private static readonly Regex Tags = new Regex("<[^>]*>", RegexOptions.Compiled);

		public static string DisplayName(string tag, string unnamed = "Unnamed portal")
		{
			string text = Tags.Replace(tag ?? "", "").Trim();
			if (text.Length != 0)
			{
				return text;
			}
			return unnamed;
		}

		public static string Fold(string s)
		{
			return (s ?? "").ToLowerInvariant().Replace('ё', 'е');
		}

		public static bool IsUnnamed(PortalEntry e)
		{
			return DisplayName(e.Name, "").Length == 0;
		}

		public static List<PortalEntry> List(IEnumerable<PortalEntry> known, Vector3 from, Vector3 viewer, ListOptions o, Func<PortalPos, bool> isFavorite, Func<PortalEntry, bool> isIgnored, out int hidden)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			hidden = 0;
			List<PortalEntry> list = new List<PortalEntry>();
			foreach (PortalEntry item in known)
			{
				if (item.Removed)
				{
					continue;
				}
				float num = Vector3.Distance(from, item.Position);
				if (!(num < 1.5f) && isIgnored(item) == (o.Tab == ListTab.Ignored))
				{
					if (o.Tab != ListTab.Ignored && o.HideNearby && num < o.HideNearbyDistance)
					{
						hidden++;
					}
					else
					{
						list.Add(item);
					}
				}
			}
			if (o.Tab != ListTab.Ignored && o.HideTwins)
			{
				hidden += RemoveNearerTwins(list, from);
			}
			string search = Fold(o.Search).Trim();
			IEnumerable<PortalEntry> source = list;
			if (o.Tab == ListTab.Favorites)
			{
				source = source.Where((PortalEntry e) => isFavorite(e.Key));
			}
			if (search.Length > 0)
			{
				source = source.Where((PortalEntry e) => Fold(DisplayName(e.Name, "")).IndexOf(search, StringComparison.Ordinal) >= 0);
			}
			IOrderedEnumerable<PortalEntry> source2 = (o.FavoritesFirst ? source.OrderByDescending((PortalEntry e) => isFavorite(e.Key)) : source.OrderBy((PortalEntry _) => 0));
			return (o.Sort switch
			{
				SortMode.Nearest => source2.ThenBy((PortalEntry e) => Vector3.Distance(viewer, e.Position)).ThenBy<PortalEntry, string>((PortalEntry e) => DisplayName(e.Name), StringComparer.OrdinalIgnoreCase), 
				SortMode.Farthest => source2.ThenByDescending((PortalEntry e) => Vector3.Distance(viewer, e.Position)).ThenBy<PortalEntry, string>((PortalEntry e) => DisplayName(e.Name), StringComparer.OrdinalIgnoreCase), 
				_ => source2.ThenBy<PortalEntry, string>((PortalEntry e) => DisplayName(e.Name), StringComparer.OrdinalIgnoreCase).ThenBy((PortalEntry e) => Vector3.Distance(viewer, e.Position)), 
			}).ToList();
		}

		public static int RemoveNearerTwins(List<PortalEntry> portals, Vector3 from)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, PortalEntry> farthest = new Dictionary<string, PortalEntry>();
			foreach (PortalEntry portal in portals)
			{
				string text = Fold(DisplayName(portal.Name, ""));
				if (text.Length != 0 && (!farthest.TryGetValue(text, out var value) || Vector3.Distance(from, portal.Position) > Vector3.Distance(from, value.Position)))
				{
					farthest[text] = portal;
				}
			}
			return portals.RemoveAll(delegate(PortalEntry e)
			{
				string text2 = Fold(DisplayName(e.Name, ""));
				return text2.Length > 0 && farthest[text2] != e;
			});
		}

		public static SortMode Next(SortMode mode)
		{
			return mode switch
			{
				SortMode.Name => SortMode.Nearest, 
				SortMode.Nearest => SortMode.Farthest, 
				_ => SortMode.Name, 
			};
		}

		public static int Step(int selected, int delta, int count)
		{
			if (count <= 0)
			{
				return -1;
			}
			return Mathf.Clamp(selected + delta, 0, count - 1);
		}

		public static float ScrollTo(int index, float rowPitch, float rowHeight, float viewHeight, float scroll)
		{
			if (index < 0)
			{
				return scroll;
			}
			float num = (float)index * rowPitch;
			float num2 = num + rowHeight;
			if (num < scroll)
			{
				return num;
			}
			if (num2 > scroll + viewHeight)
			{
				return num2 - viewHeight;
			}
			return scroll;
		}
	}
	internal static class Journal
	{
		private const string AtlasKeyPrefix = "ClientPortals.Atlas.";

		private const string FavoritesKeyPrefix = "ClientPortals.Favorites.";

		private const string IgnoredKeyPrefix = "ClientPortals.Ignored.";

		private const string IgnoreUnnamedKeyPrefix = "ClientPortals.IgnoreUnnamed.";

		private const string LastViewKey = "ClientPortals.LastView";

		private static readonly long RemovedLifetime = TimeSpan.FromDays(60.0).Ticks;

		private static Player owner;

		private static long world;

		private static Atlas atlas;

		private static readonly HashSet<PortalPos> favorites = new HashSet<PortalPos>();

		private static readonly HashSet<PortalPos> ignored = new HashSet<PortalPos>();

		private static bool ignoreUnnamed;

		private static readonly Dictionary<ZDOID, uint> seenRevision = new Dictionary<ZDOID, uint>();

		public static Atlas Current
		{
			get
			{
				if (!Ensure())
				{
					return null;
				}
				return atlas;
			}
		}

		public static long Now
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)ZNet.instance))
				{
					return DateTime.UtcNow.Ticks;
				}
				return ZNet.instance.GetTime().Ticks;
			}
		}

		public static bool LastViewMap
		{
			get
			{
				if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && Player.m_localPlayer.m_customData.TryGetValue("ClientPortals.LastView", out var value))
				{
					return value == "Map";
				}
				return false;
			}
			set
			{
				if (Object.op_Implicit((Object)(object)Player.m_localPlayer))
				{
					Player.m_localPlayer.m_customData["ClientPortals.LastView"] = (value ? "Map" : "List");
				}
			}
		}

		private static bool Ensure()
		{
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer) || !Object.op_Implicit((Object)(object)ZNet.instance))
			{
				return false;
			}
			long worldUID = ZNet.instance.GetWorldUID();
			if ((Object)(object)localPlayer != (Object)(object)owner || worldUID != world || atlas == null)
			{
				Load(localPlayer, worldUID);
			}
			return true;
		}

		private static void Load(Player player, long uid)
		{
			owner = player;
			world = uid;
			favorites.Clear();
			ignored.Clear();
			seenRevision.Clear();
			ignoreUnnamed = false;
			Dictionary<string, string> customData = player.m_customData;
			if (customData.TryGetValue("ClientPortals.Atlas." + uid, out var value))
			{
				atlas = Atlas.Deserialize(FromBase64(value));
				if (customData.TryGetValue("ClientPortals.Favorites." + uid, out var value2))
				{
					ReadSet(FromBase64(value2), favorites);
				}
				if (customData.TryGetValue("ClientPortals.Ignored." + uid, out var value3))
				{
					ReadSet(FromBase64(value3), ignored);
				}
				ignoreUnnamed = customData.TryGetValue("ClientPortals.IgnoreUnnamed." + uid, out var value4) && value4 == "1";
			}
			else
			{
				atlas = new Atlas();
			}
			atlas.PruneRemoved(Now - RemovedLifetime);
		}

		public static void Save()
		{
			if (Object.op_Implicit((Object)(object)owner) && atlas != null)
			{
				owner.m_customData["ClientPortals.Atlas." + world] = Convert.ToBase64String(atlas.Serialize());
				owner.m_customData["ClientPortals.Favorites." + world] = Convert.ToBase64String(WriteSet(favorites));
				owner.m_customData["ClientPortals.Ignored." + world] = Convert.ToBase64String(WriteSet(ignored));
				if (ignoreUnnamed)
				{
					owner.m_customData["ClientPortals.IgnoreUnnamed." + world] = "1";
				}
				else
				{
					owner.m_customData.Remove("ClientPortals.IgnoreUnnamed." + world);
				}
			}
		}

		public static bool Learn(ZDO zdo, bool announce)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			Atlas current = Current;
			if (current == null || !PortalWorld.IsPortal(zdo))
			{
				return false;
			}
			PortalWorld.Remember(zdo);
			PortalPos key = PortalPos.Of(zdo.GetPosition());
			PortalEntry entry;
			bool flag = current.TryGet(key, out entry) && !entry.Removed;
			uint dataRevision = zdo.DataRevision;
			if (flag && seenRevision.TryGetValue(zdo.m_uid, out var value) && value == dataRevision)
			{
				return false;
			}
			seenRevision[zdo.m_uid] = dataRevision;
			string text = PortalWorld.Tag(zdo);
			bool num = !flag || entry.Name != text;
			bool flag2 = current.Observe(zdo.GetPosition(), zdo.GetRotation(), text, Now);
			if (num || flag2)
			{
				Save();
			}
			if (flag2 && announce)
			{
				Plugin.Message(Texts.T("new", Destinations.DisplayName(text, Texts.T("unnamed"))), (MessageType)1);
			}
			return flag2;
		}

		public static void Refresh(ZDO zdo)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Atlas current = Current;
			if (current != null && current.Knows(PortalPos.Of(zdo.GetPosition())))
			{
				Learn(zdo, announce: false);
			}
		}

		public static bool Forget(PortalPos key)
		{
			Atlas current = Current;
			if (current == null || !current.Forget(key, Now))
			{
				return false;
			}
			Save();
			return true;
		}

		public static void Moved(PortalPos from, ZDO now)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (!Ensure())
			{
				return;
			}
			PortalPos portalPos = PortalPos.Of(now.GetPosition());
			if (!(portalPos == from))
			{
				if (favorites.Remove(from))
				{
					favorites.Add(portalPos);
				}
				if (ignored.Remove(from))
				{
					ignored.Add(portalPos);
				}
				atlas.Forget(from, Now);
				Learn(now, announce: false);
				Save();
			}
		}

		public static int Merge(IEnumerable<PortalEntry> entries)
		{
			Atlas current = Current;
			if (current == null)
			{
				return 0;
			}
			int result = current.Merge(entries);
			Save();
			return result;
		}

		public static bool IsFavorite(PortalPos key)
		{
			if (Ensure())
			{
				return favorites.Contains(key);
			}
			return false;
		}

		public static void ToggleFavorite(PortalPos key)
		{
			if (Ensure())
			{
				if (!favorites.Remove(key))
				{
					favorites.Add(key);
				}
				Save();
			}
		}

		public static bool IsIgnored(PortalEntry e)
		{
			if (Ensure())
			{
				if (!ignored.Contains(e.Key))
				{
					if (ignoreUnnamed)
					{
						return Destinations.IsUnnamed(e);
					}
					return false;
				}
				return true;
			}
			return false;
		}

		public static bool ToggleIgnored(PortalEntry e)
		{
			if (!Ensure())
			{
				return false;
			}
			bool flag = !IsIgnored(e);
			if (Destinations.IsUnnamed(e))
			{
				ignoreUnnamed = flag;
				if (!flag)
				{
					foreach (PortalEntry item in atlas.Known)
					{
						if (Destinations.IsUnnamed(item))
						{
							ignored.Remove(item.Key);
						}
					}
				}
			}
			else if (flag)
			{
				ignored.Add(e.Key);
			}
			else
			{
				ignored.Remove(e.Key);
			}
			Save();
			return flag;
		}

		private static byte[] WriteSet(HashSet<PortalPos> set)
		{
			using MemoryStream memoryStream = new MemoryStream();
			using BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
			binaryWriter.Write(1);
			binaryWriter.Write(set.Count);
			foreach (PortalPos item in set)
			{
				binaryWriter.Write(item.X);
				binaryWriter.Write(item.Y);
				binaryWriter.Write(item.Z);
			}
			binaryWriter.Flush();
			return memoryStream.ToArray();
		}

		private static void ReadSet(byte[] data, HashSet<PortalPos> into)
		{
			if (data == null || data.Length < 8)
			{
				return;
			}
			try
			{
				using BinaryReader binaryReader = new BinaryReader(new MemoryStream(data));
				if (binaryReader.ReadInt32() == 1)
				{
					int num = binaryReader.ReadInt32();
					for (int i = 0; i < num; i++)
					{
						into.Add(new PortalPos(binaryReader.ReadInt32(), binaryReader.ReadInt32(), binaryReader.ReadInt32()));
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[ClientPortals] could not read a portal set: " + ex.Message));
			}
		}

		private static byte[] FromBase64(string s)
		{
			try
			{
				return Convert.FromBase64String(s);
			}
			catch (FormatException)
			{
				return null;
			}
		}
	}
	internal static class Learner
	{
		private const float Interval = 1f;

		private const float MissingFor = 5f;

		private const float PairRequestInterval = 5f;

		private static float next;

		private static readonly Dictionary<PortalPos, float> missingSince = new Dictionary<PortalPos, float>();

		private static readonly Dictionary<ZDOID, float> pairRequested = new Dictionary<ZDOID, float>();

		private static readonly HashSet<PortalPos> present = new HashSet<PortalPos>();

		public static void Tick()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			if (Time.time < next)
			{
				return;
			}
			next = Time.time + 1f;
			Player localPlayer = Player.m_localPlayer;
			Atlas current = Journal.Current;
			if (!Object.op_Implicit((Object)(object)localPlayer) || current == null || !Object.op_Implicit((Object)(object)ZNet.instance) || ((Character)localPlayer).IsTeleporting())
			{
				return;
			}
			Vector3 position = ((Component)localPlayer).transform.position;
			float value = Plugin.NearbyDistance.Value;
			bool flag = ZNet.instance.IsServer() && Plugin.HostKnowsAll.Value;
			present.Clear();
			foreach (ZDO item in PortalWorld.Loaded())
			{
				if (PortalWorld.IsPortal(item))
				{
					Vector3 position2 = item.GetPosition();
					present.Add(PortalPos.Of(position2));
					bool flag2 = Utils.DistanceXZ(position, position2) <= value;
					if (flag)
					{
						Journal.Learn(item, announce: false);
					}
					else if (flag2 && Plugin.Nearby.Value)
					{
						Journal.Learn(item, announce: true);
					}
					else
					{
						Journal.Refresh(item);
					}
					if (flag2 && Plugin.TagPairs.Value)
					{
						LearnPair(item);
					}
				}
			}
			if (Plugin.ForgetMissing.Value)
			{
				CheckMissing(current, position, value);
			}
		}

		private static void LearnPair(ZDO portal)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			ZDOID connectionZDOID = portal.GetConnectionZDOID((ConnectionType)1);
			if (!((ZDOID)(ref connectionZDOID)).IsNone())
			{
				if (!pairRequested.TryGetValue(connectionZDOID, out var value) || Time.time - value > 5f)
				{
					pairRequested[connectionZDOID] = Time.time;
					ZDOMan.instance.RequestZDO(connectionZDOID);
				}
				ZDO zDO = ZDOMan.instance.GetZDO(connectionZDOID);
				if (zDO != null)
				{
					Journal.Learn(zDO, announce: true);
				}
			}
		}

		private static void CheckMissing(Atlas atlas, Vector3 here, float nearby)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			List<PortalEntry> list = null;
			foreach (PortalEntry item in atlas.Known)
			{
				PortalPos key = item.Key;
				float value;
				if (present.Contains(key) || Utils.DistanceXZ(here, item.Position) > nearby || !ZoneSystem.instance.IsZoneLoaded(item.Position))
				{
					missingSince.Remove(key);
				}
				else if (!missingSince.TryGetValue(key, out value))
				{
					missingSince[key] = Time.time;
				}
				else if (Time.time - value >= 5f)
				{
					(list ?? (list = new List<PortalEntry>())).Add(item);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (PortalEntry item2 in list)
			{
				missingSince.Remove(item2.Key);
				if (Journal.Forget(item2.Key))
				{
					Plugin.Message(Texts.T("gone", Destinations.DisplayName(item2.Name, Texts.T("unnamed"))), (MessageType)1);
				}
			}
		}
	}
	internal static class ListWindow
	{
		private sealed class Row
		{
			public GameObject Go;

			public TMP_Text Name;

			public TMP_Text Distance;

			public Image Icon;

			public Image Star;

			public Image Ignore;

			public Image Rename;

			public GameObject Selected;

			public Button Button;

			public ColorBlock Colors;

			public SpriteState Sprites;

			public bool HoverOff;
		}

		private const float W = 620f;

		private const float H = 776f;

		private const float Side = 30f;

		private const float ListTop = 196f;

		private const float ListHeight = 408f;

		private const float Inner = 6f;

		private const int PageRows = 8;

		private const float CloseDistance = 6f;

		private static TeleportWorld source;

		private static int openFrame;

		private static int closedFrame = -100;

		private static string search = "";

		private static ListTab tab;

		private static List<PortalEntry> rows = new List<PortalEntry>();

		private static int hidden;

		private static int selected = -1;

		private static PortalPos? selectedKey;

		private static bool scrollToSelected;

		private static bool mouseSelects = true;

		private static Vector3 lastMouse;

		private static bool keysReleased;

		private static bool focusSearchWhenFree;

		private static int caretToEnd;

		private static readonly StringBuilder typed = new StringBuilder();

		private static bool renaming;

		private static GameObject root;

		private static TMP_Text title;

		private static TMP_Text from;

		private static TMP_Text footer;

		private static TMP_Text hints;

		private static TMP_Text empty;

		private static GuiInputField searchField;

		private static Button tabAll;

		private static Button tabFavorites;

		private static Button tabIgnored;

		private static Button sortButton;

		private static Button mapButton;

		private static Button closeButton;

		private static RectTransform viewport;

		private static RectTransform content;

		private static ScrollRect scroll;

		private static readonly List<Row> pool = new List<Row>();

		private static float rowHeight = 34f;

		private static float rowPitch = 38f;

		private static Sprite portalIcon;

		private const int WheelRows = 1;

		public static bool IsOpen
		{
			get
			{
				if (Object.op_Implicit((Object)(object)source) && Object.op_Implicit((Object)(object)root))
				{
					if (!root.activeSelf)
					{
						return renaming;
					}
					return true;
				}
				return false;
			}
		}

		public static bool BlocksInput
		{
			get
			{
				if (!IsOpen)
				{
					return Time.frameCount - closedFrame <= 2;
				}
				return true;
			}
		}

		private static bool SearchFocused
		{
			get
			{
				if (Object.op_Implicit((Object)(object)searchField))
				{
					return ((TMP_InputField)searchField).isFocused;
				}
				return false;
			}
		}

		private static bool MapAvailable
		{
			get
			{
				if (!Game.m_noMap)
				{
					return Object.op_Implicit((Object)(object)Minimap.instance);
				}
				return false;
			}
		}

		public static void Open(TeleportWorld portal, string filter = "", bool focusList = false, bool allTab = false)
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)root) || Build())
			{
				source = portal;
				if (allTab)
				{
					tab = ListTab.All;
				}
				openFrame = Time.frameCount;
				renaming = false;
				search = filter ?? "";
				if (Object.op_Implicit((Object)(object)searchField))
				{
					((TMP_InputField)searchField).SetTextWithoutNotify(search);
				}
				selected = 0;
				selectedKey = null;
				content.anchoredPosition = Vector2.zero;
				mouseSelects = !Pad.Active;
				lastMouse = ZInput.pointerPosition;
				keysReleased = false;
				typed.Clear();
				ListenToTyping(on: true);
				root.SetActive(true);
				root.transform.SetAsLastSibling();
				Refresh();
				Render();
				if (focusList)
				{
					mouseSelects = false;
				}
				focusSearchWhenFree = !focusList && !Pad.Active && Object.op_Implicit((Object)(object)searchField);
			}
		}

		public static void Close()
		{
			if (Object.op_Implicit((Object)(object)source) || (Object.op_Implicit((Object)(object)root) && root.activeSelf))
			{
				source = null;
				closedFrame = Time.frameCount;
				renaming = false;
				focusSearchWhenFree = false;
				ListenToTyping(on: false);
				if (Object.op_Implicit((Object)(object)searchField))
				{
					((TMP_InputField)searchField).DeactivateInputField(false);
				}
				if (Object.op_Implicit((Object)(object)root))
				{
					root.SetActive(false);
				}
				Ui.Deselect();
			}
		}

		private static bool Build()
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Expected O, but got Unknown
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Expected O, but got Unknown
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Expected O, but got Unknown
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Expected O, but got Unknown
			//IL_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0395: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0522: Unknown result type (might be due to invalid IL or missing references)
			//IL_0569: Unknown result type (might be due to invalid IL or missing references)
			//IL_0437: Unknown result type (might be due to invalid IL or missing references)
			//IL_043c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0447: Unknown result type (might be due to invalid IL or missing references)
			//IL_0451: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0466: Unknown result type (might be due to invalid IL or missing references)
			//IL_0471: Unknown result type (might be due to invalid IL or missing references)
			//IL_047b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0486: Unknown result type (might be due to invalid IL or missing references)
			//IL_049a: Unknown result type (might be due to invalid IL or missing references)
			//IL_05db: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f3: Expected O, but got Unknown
			//IL_0629: Unknown result type (might be due to invalid IL or missing references)
			//IL_064a: Expected O, but got Unknown
			//IL_0680: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a7: Expected O, but got Unknown
			//IL_06d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_06dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e2: Unknown result type (might be due to invalid IL or missing references)
			Transform canvasRoot = Ui.CanvasRoot;
			if (!Object.op_Implicit((Object)(object)canvasRoot))
			{
				return false;
			}
			portalIcon = Ui.PortalIcon();
			pool.Clear();
			RectTransform val = Ui.Stretch(Ui.Rect("ClientPortals List", canvasRoot));
			root = ((Component)val).gameObject;
			((Graphic)((Component)val).gameObject.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0f);
			RectTransform val2 = Ui.Rect("Panel", (Transform)(object)val);
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(0.5f, 0.5f);
			val2.pivot = val3;
			Vector2 anchorMin = (val2.anchorMax = val3);
			val2.anchorMin = anchorMin;
			val2.sizeDelta = new Vector2(620f, 776f);
			Ui.Panel(val2, mirrorBottom: true);
			title = Ui.Title(Ui.Place(Ui.Rect("Title", (Transform)(object)val2), 30f, 16f, 560f, 46f), 36f);
			from = Ui.Body(Ui.Place(Ui.Rect("From", (Transform)(object)val2), 30f, 62f, 560f, 28f), 19f, Ui.Beige, (TextAlignmentOptions)514);
			searchField = Ui.InputField((Transform)(object)val2);
			if (Object.op_Implicit((Object)(object)searchField))
			{
				Ui.Place((RectTransform)((Component)searchField).transform, 30f, 98f, 560f, 40f);
				((UnityEvent<string>)(object)((TMP_InputField)searchField).onValueChanged).AddListener((UnityAction<string>)OnSearch);
			}
			float num = 182.66667f;
			tabAll = Ui.Tab((Transform)(object)val2, "All", delegate
			{
				SetTab(ListTab.All);
			});
			Ui.Place((RectTransform)((Component)tabAll).transform, 30f, 148f, num, 42f);
			tabFavorites = Ui.Tab((Transform)(object)val2, "Favorites", delegate
			{
				SetTab(ListTab.Favorites);
			});
			Ui.Place((RectTransform)((Component)tabFavorites).transform, 30f + num + 6f, 148f, num, 42f);
			tabIgnored = Ui.Tab((Transform)(object)val2, "Ignored", delegate
			{
				SetTab(ListTab.Ignored);
			});
			Ui.Place((RectTransform)((Component)tabIgnored).transform, 30f + 2f * (num + 6f), 148f, num, 42f);
			RectTransform val5 = Ui.Place(Ui.Rect("List", (Transform)(object)val2), 30f, 196f, 560f, 408f);
			Ui.Inset(val5);
			viewport = Ui.Stretch(Ui.Rect("Viewport", (Transform)(object)val5), 6f, 6f, 22f, 6f);
			((Component)viewport).gameObject.AddComponent<RectMask2D>();
			((Graphic)((Component)viewport).gameObject.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0f);
			content = Ui.Rect("Content", (Transform)(object)viewport);
			content.anchorMin = new Vector2(0f, 1f);
			content.anchorMax = new Vector2(1f, 1f);
			content.pivot = new Vector2(0.5f, 1f);
			content.sizeDelta = Vector2.zero;
			scroll = ((Component)val5).gameObject.AddComponent<ScrollRect>();
			scroll.viewport = viewport;
			scroll.content = content;
			scroll.horizontal = false;
			scroll.movementType = (MovementType)2;
			scroll.scrollSensitivity = 0f;
			Scrollbar val6 = Ui.Scrollbar((Transform)(object)val5);
			if (Object.op_Implicit((Object)(object)val6))
			{
				RectTransform val7 = (RectTransform)((Component)val6).transform;
				val7.anchorMin = new Vector2(1f, 0f);
				val7.anchorMax = new Vector2(1f, 1f);
				val7.pivot = new Vector2(1f, 0.5f);
				val7.offsetMin = new Vector2(-14f, 6f);
				val7.offsetMax = new Vector2(-4f, -6f);
				scroll.verticalScrollbar = val6;
				scroll.verticalScrollbarVisibility = (ScrollbarVisibility)1;
			}
			empty = Ui.Body(Ui.Stretch(Ui.Rect("Empty", (Transform)(object)val5), 30f, 30f, 30f, 30f), 19f, Ui.Dim, (TextAlignmentOptions)514);
			footer = Ui.Fit(Ui.Body(Ui.Place(Ui.Rect("Footer", (Transform)(object)val2), 30f, 608f, 560f, 48f), 16f, Ui.Dim, (TextAlignmentOptions)514), 11f);
			hints = Ui.Body(Ui.Place(Ui.Rect("Hints", (Transform)(object)val2), 30f, 658f, 560f, 30f), 18f, Color.white, (TextAlignmentOptions)514);
			hints.textWrappingMode = (TextWrappingModes)0;
			Ui.Fit(hints, 12f);
			float num2 = 180f;
			float y = 698f;
			sortButton = Ui.Button((Transform)(object)val2, "Sort", ToggleSort);
			Ui.Place((RectTransform)((Component)sortButton).transform, 30f, y, num2, 44f);
			mapButton = Ui.Button((Transform)(object)val2, "MapView", SwitchToMap);
			Ui.Place((RectTransform)((Component)mapButton).transform, 30f + num2 + 10f, y, num2, 44f);
			closeButton = Ui.Button((Transform)(object)val2, "Close", Close);
			Ui.Place((RectTransform)((Component)closeButton).transform, 30f + 2f * (num2 + 10f), y, num2, 44f);
			GameObject val8 = (Object.op_Implicit((Object)(object)InventoryGui.instance) ? InventoryGui.instance.m_recipeElementPrefab : null);
			if (Object.op_Implicit((Object)(object)val8))
			{
				Rect rect = ((RectTransform)val8.transform).rect;
				rowHeight = Mathf.Max(34f, ((Rect)(ref rect)).height);
			}
			rowPitch = rowHeight + 4f;
			root.SetActive(false);
			return true;
		}

		private static Row NewRow(int index)
		{
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0405: Unknown result type (might be due to invalid IL or missing references)
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			//IL_043e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0451: Unknown result type (might be due to invalid IL or missing references)
			//IL_045b: Expected O, but got Unknown
			//IL_047d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0484: Unknown result type (might be due to invalid IL or missing references)
			//IL_0497: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_050c: Unknown result type (might be due to invalid IL or missing references)
			//IL_051f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0529: Expected O, but got Unknown
			//IL_054b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0552: Unknown result type (might be due to invalid IL or missing references)
			//IL_0565: Unknown result type (might be due to invalid IL or missing references)
			//IL_057b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0591: Unknown result type (might be due to invalid IL or missing references)
			//IL_05cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_05da: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f7: Expected O, but got Unknown
			//IL_060a: Unknown result type (might be due to invalid IL or missing references)
			//IL_060f: Unknown result type (might be due to invalid IL or missing references)
			//IL_061b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0620: Unknown result type (might be due to invalid IL or missing references)
			//IL_0637: Unknown result type (might be due to invalid IL or missing references)
			//IL_0641: Expected O, but got Unknown
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Ui.ListRow((Transform)(object)content);
			Row row = new Row
			{
				Go = val
			};
			RectTransform val2;
			if (Object.op_Implicit((Object)(object)val))
			{
				val2 = (RectTransform)val.transform;
				Transform obj = val.transform.Find("icon");
				row.Icon = ((obj != null) ? ((Component)obj).GetComponent<Image>() : null);
				Transform obj2 = val.transform.Find("name");
				row.Name = ((obj2 != null) ? ((Component)obj2).GetComponent<TMP_Text>() : null);
				Transform obj3 = val.transform.Find("selected");
				row.Selected = ((obj3 != null) ? ((Component)obj3).gameObject : null);
				string[] array = new string[2] { "Durability", "QualityLevel" };
				foreach (string text in array)
				{
					Transform val3 = val.transform.Find(text);
					if (Object.op_Implicit((Object)(object)val3))
					{
						((Component)val3).gameObject.SetActive(false);
					}
				}
			}
			else
			{
				val2 = Ui.Rect("Portal", (Transform)(object)content);
				val = (row.Go = ((Component)val2).gameObject);
				((Graphic)val.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.25f);
				val.AddComponent<Button>();
			}
			val2.anchorMin = new Vector2(0f, 1f);
			val2.anchorMax = new Vector2(1f, 1f);
			val2.pivot = new Vector2(0.5f, 1f);
			val2.sizeDelta = new Vector2(0f, rowHeight);
			val2.anchoredPosition = new Vector2(0f, (float)(-index) * rowPitch);
			Vector2 val4 = default(Vector2);
			if (Object.op_Implicit((Object)(object)row.Icon))
			{
				RectTransform rectTransform = ((Graphic)row.Icon).rectTransform;
				((Vector2)(ref val4))..ctor(0f, 0.5f);
				rectTransform.anchorMax = val4;
				rectTransform.anchorMin = val4;
				rectTransform.pivot = new Vector2(0f, 0.5f);
				rectTransform.anchoredPosition = new Vector2(6f, 0f);
				rectTransform.sizeDelta = new Vector2(rowHeight - 6f, rowHeight - 6f);
				((Graphic)row.Icon).color = Color.white;
			}
			if (!Object.op_Implicit((Object)(object)row.Name))
			{
				row.Name = Ui.Body(Ui.Rect("name", (Transform)(object)val2), 19f, Color.white, (TextAlignmentOptions)513);
			}
			RectTransform rectTransform2 = row.Name.rectTransform;
			rectTransform2.anchorMin = Vector2.zero;
			rectTransform2.anchorMax = Vector2.one;
			rectTransform2.offsetMin = new Vector2(rowHeight + 8f, 0f);
			rectTransform2.offsetMax = new Vector2(-220f, 0f);
			row.Name.alignment = (TextAlignmentOptions)4097;
			row.Name.textWrappingMode = (TextWrappingModes)0;
			row.Name.overflowMode = (TextOverflowModes)1;
			RectTransform val5 = Ui.Rect("distance", (Transform)(object)val2);
			val5.anchorMin = new Vector2(1f, 0f);
			val5.anchorMax = new Vector2(1f, 1f);
			val5.pivot = new Vector2(1f, 0.5f);
			val5.offsetMin = new Vector2(-210f, 0f);
			val5.offsetMax = new Vector2(-104f, 0f);
			row.Distance = Ui.Body(val5, 16f, Ui.Dim, (TextAlignmentOptions)4100);
			row.Distance.textWrappingMode = (TextWrappingModes)0;
			RectTransform val6 = Ui.Rect("star", (Transform)(object)val2);
			((Vector2)(ref val4))..ctor(1f, 0.5f);
			val6.anchorMax = val4;
			val6.anchorMin = val4;
			val6.pivot = new Vector2(1f, 0.5f);
			val6.anchoredPosition = new Vector2(-10f, 0f);
			val6.sizeDelta = new Vector2(24f, 24f);
			row.Star = ((Component)val6).gameObject.AddComponent<Image>();
			Button obj4 = ((Component)val6).gameObject.AddComponent<Button>();
			Navigation navigation = default(Navigation);
			((Navigation)(ref navigation)).mode = (Mode)0;
			((Selectable)obj4).navigation = navigation;
			((UnityEvent)obj4.onClick).AddListener((UnityAction)delegate
			{
				ToggleFavorite(index);
			});
			RectTransform val7 = Ui.Rect("ignore", (Transform)(object)val2);
			((Vector2)(ref val4))..ctor(1f, 0.5f);
			val7.anchorMax = val4;
			val7.anchorMin = val4;
			val7.pivot = new Vector2(1f, 0.5f);
			val7.anchoredPosition = new Vector2(-42f, 0f);
			val7.sizeDelta = new Vector2(22f, 22f);
			row.Ignore = ((Component)val7).gameObject.AddComponent<Image>();
			row.Ignore.sprite = Ui.NoSign;
			Button obj5 = ((Component)val7).gameObject.AddComponent<Button>();
			navigation = default(Navigation);
			((Navigation)(ref navigation)).mode = (Mode)0;
			((Selectable)obj5).navigation = navigation;
			((UnityEvent)obj5.onClick).AddListener((UnityAction)delegate
			{
				ToggleIgnored(index);
			});
			RectTransform val8 = Ui.Rect("rename", (Transform)(object)val2);
			((Vector2)(ref val4))..ctor(1f, 0.5f);
			val8.anchorMax = val4;
			val8.anchorMin = val4;
			val8.pivot = new Vector2(1f, 0.5f);
			val8.anchoredPosition = new Vector2(-72f, 0f);
			val8.sizeDelta = new Vector2(24f, 24f);
			row.Rename = ((Component)val8).gameObject.AddComponent<Image>();
			row.Rename.sprite = Ui.Dots;
			Button obj6 = ((Component)val8).gameObject.AddComponent<Button>();
			navigation = default(Navigation);
			((Navigation)(ref navigation)).mode = (Mode)0;
			((Selectable)obj6).navigation = navigation;
			((UnityEvent)obj6.onClick).AddListener((UnityAction)delegate
			{
				Rename(index);
			});
			row.Button = val.GetComponent<Button>();
			row.Colors = ((Selectable)row.Button).colors;
			row.Sprites = ((Selectable)row.Button).spriteState;
			((UnityEvent)row.Button.onClick).AddListener((UnityAction)delegate
			{
				TravelTo(index);
			});
			RowHover rowHover = val.AddComponent<RowHover>();
			rowHover.Index = index;
			rowHover.OnEnter = delegate(int index2)
			{
				if (mouseSelects)
				{
					Select(index2, scrollIntoView: false);
				}
			};
			rowHover.OnMiddleClick = ToggleIgnored;
			return row;
		}

		private static void OnSearch(string text)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			search = text ?? "";
			selected = 0;
			selectedKey = null;
			content.anchoredPosition = Vector2.zero;
			Refresh();
		}

		private static void Refresh()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			rows = PortalWorld.DestinationsFrom(PortalWorld.PositionOf(source), tab, search, out hidden);
			PortalPos? portalPos = selectedKey;
			if (portalPos.HasValue)
			{
				PortalPos key = portalPos.GetValueOrDefault();
				int num = rows.FindIndex((PortalEntry r) => r.Key == key);
				if (num >= 0)
				{
					selected = num;
				}
			}
			selected = ((rows.Count == 0) ? (-1) : Mathf.Clamp(selected, 0, rows.Count - 1));
			selectedKey = ((selected >= 0) ? new PortalPos?(rows[selected].Key) : ((PortalPos?)null));
		}

		private static void Select(int index, bool scrollIntoView)
		{
			selected = Destinations.Step(index, 0, rows.Count);
			selectedKey = ((selected >= 0) ? new PortalPos?(rows[selected].Key) : ((PortalPos?)null));
			scrollToSelected |= scrollIntoView;
		}

		private static void SetTab(ListTab to)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (tab != to)
			{
				tab = to;
				selected = 0;
				selectedKey = null;
				content.anchoredPosition = Vector2.zero;
				Refresh();
			}
		}

		private static void StepTab(int step)
		{
			SetTab((ListTab)((int)(tab + step + 3) % 3));
		}

		private static void ToggleSort()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			Plugin.SortBy.Value = Destinations.Next(Plugin.SortBy.Value);
			selected = 0;
			selectedKey = null;
			content.anchoredPosition = Vector2.zero;
			Refresh();
		}

		private static void ToggleIgnored(int index)
		{
			if (index >= 0 && index < rows.Count)
			{
				Ignore(rows[index]);
				Refresh();
				scrollToSelected = true;
			}
		}

		public static void Ignore(PortalEntry e)
		{
			if (Journal.ToggleIgnored(e))
			{
				Plugin.Message(Destinations.IsUnnamed(e) ? Texts.T("ignored_unnamed") : Texts.T("ignored", Destinations.DisplayName(e.Name, Texts.T("unnamed"))), (MessageType)1);
			}
		}

		private static void Rename(int index)
		{
			if (index >= 0 && index < rows.Count && Object.op_Implicit((Object)(object)TextInput.instance))
			{
				Select(index, scrollIntoView: true);
				if (SearchFocused)
				{
					((TMP_InputField)searchField).DeactivateInputField(false);
				}
				renaming = true;
				root.SetActive(false);
				PairRename.OpenFor(rows[index]);
			}
		}

		private static void ToggleFavorite(int index)
		{
			if (index >= 0 && index < rows.Count)
			{
				Journal.ToggleFavorite(rows[index].Key);
				Refresh();
				scrollToSelected = true;
			}
		}

		private static void TravelTo(int index)
		{
			if (index >= 0 && index < rows.Count && Object.op_Implicit((Object)(object)source))
			{
				PortalEntry target = rows[index];
				TeleportWorld obj = source;
				Close();
				Travel.Go(obj, target);
			}
		}

		private static void SwitchToMap()
		{
			if (MapAvailable && Object.op_Implicit((Object)(object)source))
			{
				TeleportWorld portal = source;
				string filter = search;
				Close();
				Journal.LastViewMap = true;
				MapPicker.Open(portal, filter);
			}
		}

		private static void FocusSearch()
		{
			if (Object.op_Implicit((Object)(object)searchField))
			{
				searchField.ActivateInputField();
				caretToEnd = 4;
			}
		}

		private static void ListenToTyping(bool on)
		{
			Keyboard current = Keyboard.current;
			if (current != null)
			{
				current.onTextInput -= OnTextInput;
				if (on)
				{
					current.onTextInput += OnTextInput;
				}
			}
		}

		private static void OnTextInput(char c)
		{
			if (IsOpen && !renaming && keysReleased && !SearchFocused && !char.IsControl(c))
			{
				typed.Append(c);
			}
		}

		public static void Update()
		{
			//IL_005f: 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)
			if (!Object.op_Implicit((Object)(object)source))
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)root) || !Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead() || ((Character)localPlayer).IsTeleporting() || !Object.op_Implicit((Object)(object)source.m_nview) || !source.m_nview.IsValid() || Vector3.Distance(((Component)localPlayer).transform.position, ((Component)source).transform.position) > 6f)
			{
				Close();
				return;
			}
			if (renaming)
			{
				if (Object.op_Implicit((Object)(object)TextInput.instance) && Object.op_Implicit((Object)(object)TextInput.instance.m_panel) && TextInput.instance.m_panel.gameObject.activeSelf)
				{
					return;
				}
				renaming = false;
				openFrame = Time.frameCount;
				root.SetActive(true);
				scrollToSelected = true;
			}
			Refresh();
			HandleInput();
			if (Object.op_Implicit((Object)(object)source))
			{
				Render();
			}
		}

		private static void HandleInput()
		{
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_034e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			if (!keysReleased && !Ui.AnyKeyHeld)
			{
				keysReleased = true;
			}
			if (Time.frameCount <= openFrame + 1)
			{
				return;
			}
			if (focusSearchWhenFree && keysReleased)
			{
				focusSearchWhenFree = false;
				FocusSearch();
			}
			bool searchFocused = SearchFocused;
			if (caretToEnd > 0 && searchFocused)
			{
				caretToEnd--;
				((TMP_InputField)searchField).stringPosition = ((TMP_InputField)searchField).text.Length;
			}
			if (!searchFocused)
			{
				Ui.Deselect();
			}
			if (typed.Length > 0)
			{
				if (!searchFocused && Object.op_Implicit((Object)(object)searchField) && ((Component)searchField).gameObject.activeInHierarchy)
				{
					((TMP_InputField)searchField).text = search + typed;
					FocusSearch();
				}
				typed.Clear();
			}
			if (ZInput.GetKeyDown((KeyCode)27, true) || Pad.Down("JoyButtonB"))
			{
				if (search.Length == 0 || !Object.op_Implicit((Object)(object)searchField))
				{
					Close();
					return;
				}
				((TMP_InputField)searchField).text = "";
				if (!Pad.Active)
				{
					FocusSearch();
				}
				return;
			}
			bool flag = ZInput.GetKey((KeyCode)304, true) || ZInput.GetKey((KeyCode)303, true);
			if (Pad.Down("JoyMap") || (ZInput.GetKeyDown((KeyCode)9, true) && !flag))
			{
				SwitchToMap();
				return;
			}
			int num = 0;
			bool keyDown = ZInput.GetKeyDown((KeyCode)273, true);
			if (Pad.Down("JoyDPadUp") || Pad.Down("JoyLStickUp") || keyDown)
			{
				num--;
			}
			if (Pad.Down("JoyDPadDown") || Pad.Down("JoyLStickDown") || ZInput.GetKeyDown((KeyCode)274, true))
			{
				num++;
			}
			if (Pad.Down("JoyLTrigger") || ZInput.GetKeyDown((KeyCode)280, true))
			{
				num -= 8;
			}
			if (Pad.Down("JoyRTrigger") || ZInput.GetKeyDown((KeyCode)281, true))
			{
				num += 8;
			}
			if (keyDown && !searchFocused && selected <= 0)
			{
				FocusSearch();
				return;
			}
			if (num != 0)
			{
				mouseSelects = false;
				if (searchFocused)
				{
					((TMP_InputField)searchField).DeactivateInputField(false);
				}
				Select(Destinations.Step(selected, num, rows.Count), scrollIntoView: true);
			}
			if (Pad.Down("JoyLBumper") || Pad.Down("JoyDPadLeft") || (!searchFocused && ZInput.GetKeyDown((KeyCode)276, true)))
			{
				StepTab(-1);
			}
			if (Pad.Down("JoyRBumper") || Pad.Down("JoyDPadRight") || (!searchFocused && ZInput.GetKeyDown((KeyCode)275, true)))
			{
				StepTab(1);
			}
			if (Pad.Down("JoyButtonX"))
			{
				ToggleSort();
			}
			if (Pad.Down("JoyButtonY") || ZInput.GetKeyDown((KeyCode)277, true))
			{
				ToggleFavorite(selected);
			}
			if (Pad.Down("JoyRStick") || (!searchFocused && ZInput.GetKeyDown((KeyCode)127, true)))
			{
				ToggleIgnored(selected);
			}
			if (ZInput.GetKeyDown((KeyCode)283, true))
			{
				Rename(selected);
				return;
			}
			if (Pad.Down("JoyButtonA") || ZInput.GetKeyDown((KeyCode)13, true) || ZInput.GetKeyDown((KeyCode)271, true))
			{
				TravelTo(selected);
				return;
			}
			Wheel();
			Vector3 pointerPosition = ZInput.pointerPosition;
			Vector3 val = pointerPosition - lastMouse;
			if (((Vector3)(ref val)).sqrMagnitude > 4f)
			{
				mouseSelects = true;
			}
			lastMouse = pointerPosition;
		}

		private static void Wheel()
		{
			//IL_0016: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			Mouse current = Mouse.current;
			float num = ((current != null) ? ((InputControl<Vector2>)(object)current.scroll).ReadValue().y : 0f);
			if (num != 0f)
			{
				float num2 = ((Mathf.Abs(num) >= 10f) ? (num / 120f) : num);
				float y = content.sizeDelta.y;
				Rect rect = viewport.rect;
				float num3 = Mathf.Max(0f, y - ((Rect)(ref rect)).height);
				content.anchoredPosition = new Vector2(0f, Mathf.Clamp(content.anchoredPosition.y - num2 * 1f * rowPitch, 0f, num3));
				scroll.velocity = Vector2.zero;
			}
		}

		private static void Render()
		{
			//IL_0612: Unknown result type (might be due to invalid IL or missing references)
			//IL_0604: Unknown result type (might be due to invalid IL or missing references)
			//IL_0617: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0699: Unknown result type (might be due to invalid IL or missing references)
			//IL_069d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0931: Unknown result type (might be due to invalid IL or missing references)
			//IL_0936: Unknown result type (might be due to invalid IL or missing references)
			//IL_0944: Unknown result type (might be due to invalid IL or missing references)
			//IL_0970: Unknown result type (might be due to invalid IL or missing references)
			//IL_097f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0984: Unknown result type (might be due to invalid IL or missing references)
			//IL_0998: Unknown result type (might be due to invalid IL or missing references)
			//IL_09a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_079f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0798: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_07bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0809: Unknown result type (might be due to invalid IL or missing references)
			//IL_0802: Unknown result type (might be due to invalid IL or missing references)
			//IL_07fb: Unknown result type (might be due to invalid IL or missing references)
			bool active = Pad.Active;
			Atlas current = Journal.Current;
			if (current == null)
			{
				return;
			}
			ZDO zDO = source.m_nview.GetZDO();
			Ui.SetHeader(title, Texts.T("title"));
			Set(from, Texts.T("from", Destinations.DisplayName((zDO != null) ? PortalWorld.Tag(zDO) : "", Texts.T("unnamed"))));
			if (Object.op_Implicit((Object)(object)searchField))
			{
				Graphic placeholder = ((TMP_InputField)searchField).placeholder;
				TMP_Text val = (TMP_Text)(object)((placeholder is TMP_Text) ? placeholder : null);
				if (val != null)
				{
					Set(val, Texts.T("search"));
				}
			}
			((Selectable)tabAll).interactable = tab != ListTab.All;
			((Selectable)tabFavorites).interactable = tab != ListTab.Favorites;
			((Selectable)tabIgnored).interactable = tab != ListTab.Ignored;
			Ui.SetLabels((Component[])(object)new Component[3]
			{
				(Component)tabAll,
				(Component)tabFavorites,
				(Component)tabIgnored
			}, new string[3]
			{
				(active ? (Pad.Glyph("JoyLBumper") + " ") : "") + string.Format("{0} ({1})", Texts.T("tab_all"), RowsOf(ListTab.All)),
				string.Format("{0} ({1})", Texts.T("tab_favorites"), RowsOf(ListTab.Favorites)),
				string.Format("{0} ({1})", Texts.T("tab_ignored"), RowsOf(ListTab.Ignored)) + (active ? (" " + Pad.Glyph("JoyRBumper")) : "")
			});
			string text = (active ? (Pad.Glyph("JoyButtonX") + " ") : "");
			string[] array = new string[3]
			{
				text + Texts.T("sort_name"),
				text + Texts.T("sort_nearest"),
				text + Texts.T("sort_farthest")
			};
			Ui.SetLabel((Component)(object)sortButton, array[(int)Plugin.SortBy.Value], array);
			((Component)mapButton).gameObject.SetActive(MapAvailable);
			string text2 = (active ? (Pad.Glyph("JoyMap") + " " + Texts.T("map_view")) : (Texts.T("map_view") + " (Tab)"));
			string text3 = (active ? (Pad.Glyph("JoyButtonB") + " " + Texts.T("close")) : (Texts.T("close") + " (Esc)"));
			Ui.SetLabel((Component)(object)mapButton, text2, new string[1] { text2 });
			Ui.SetLabel((Component)(object)closeButton, text3, new string[1] { text3 });
			string text4 = Texts.T("known", current.KnownCount.ToString());
			if (hidden > 0)
			{
				text4 = text4 + "   ·   " + Texts.T("hidden", hidden.ToString());
			}
			Set(footer, text4 + "\n" + Texts.T("learn_more"));
			Set(hints, active ? (Pad.Hint(Pad.Glyph("JoyDPadUp") + Pad.Glyph("JoyDPadDown"), Texts.T("select")) + "     " + Pad.Hint(Pad.Glyph("JoyButtonA"), Texts.T("travel")) + "     " + Pad.Hint(Pad.Glyph("JoyButtonY"), Texts.T("favorite")) + "     " + Pad.Hint(Pad.Glyph("JoyRStick"), Texts.T("ignore"))) : (SearchFocused ? (Pad.Hint("Enter", Texts.T("travel")) + "     " + Pad.Hint("↑↓", Texts.T("select")) + "     " + Pad.Hint("Ins", Texts.T("favorite")) + "     " + Pad.Hint("F2", Texts.T("rename"))) : (Pad.Hint("Enter", Texts.T("travel")) + "     " + Pad.Hint("←→", Texts.T("tabs")) + "     " + Pad.Hint("Ins", Texts.T("favorite")) + "     " + Pad.Hint("Del", Texts.T("ignore")) + "     " + Pad.Hint("F2", Texts.T("rename")))));
			while (pool.Count < rows.Count)
			{
				pool.Add(NewRow(pool.Count));
			}
			Player localPlayer = Player.m_localPlayer;
			Vector3 val2 = (Object.op_Implicit((Object)(object)localPlayer) ? ((Component)localPlayer).transform.position : Vector3.zero);
			for (int i = 0; i < pool.Count; i++)
			{
				Row row = pool[i];
				bool flag = i < rows.Count;
				if (row.Go.activeSelf != flag)
				{
					row.Go.SetActive(flag);
				}
				if (flag)
				{
					PortalEntry portalEntry = rows[i];
					Set(row.Name, Destinations.DisplayName(portalEntry.Name, Texts.T("unnamed")));
					int num = Mathf.RoundToInt(Vector3.Distance(val2, portalEntry.Position));
					Set(row.Distance, (num >= 1000) ? $"{(float)num / 1000f:0.0} km" : $"{num} m");
					if (Object.op_Implicit((Object)(object)row.Icon) && Object.op_Implicit((Object)(object)portalIcon) && (Object)(object)row.Icon.sprite != (Object)(object)portalIcon)
					{
						row.Icon.sprite = portalIcon;
					}
					bool flag2 = Journal.IsFavorite(portalEntry.Key);
					bool flag3 = i == selected;
					row.Star.sprite = (flag2 ? Ui.Star : Ui.StarOutline);
					((Graphic)row.Star).color = (Color)(flag3 ? Color.white : (flag2 ? Ui.Orange : new Color(Ui.Dim.r, Ui.Dim.g, Ui.Dim.b, 0.7f)));
					((Graphic)row.Distance).color = (flag3 ? Color.white : Ui.Dim);
					bool flag4 = tab == ListTab.Ignored;
					((Component)row.Ignore).gameObject.SetActive(flag3 || flag4);
					((Graphic)row.Ignore).color = (flag4 ? Ui.Orange : (flag3 ? Color.white : Ui.Dim));
					bool flag5 = flag3 && !active;
					if (((Component)row.Rename).gameObject.activeSelf != flag5)
					{
						((Component)row.Rename).gameObject.SetActive(flag5);
					}
					if (Object.op_Implicit((Object)(object)row.Selected) && row.Selected.activeSelf != flag3)
					{
						row.Selected.SetActive(flag3);
					}
					HoverLook(row, !active);
				}
			}
			content.sizeDelta = new Vector2(0f, Mathf.Max(0f, (float)rows.Count * rowPitch - (rowPitch - rowHeight)));
			((Component)empty).gameObject.SetActive(rows.Count == 0);
			if (rows.Count == 0)
			{
				Set(empty, EmptyText());
			}
			if (scrollToSelected)
			{
				scrollToSelected = false;
				Canvas.ForceUpdateCanvases();
				int index = selected;
				float num2 = rowPitch;
				float num3 = rowHeight;
				Rect rect = viewport.rect;
				float num4 = Destinations.ScrollTo(index, num2, num3, ((Rect)(ref rect)).height, content.anchoredPosition.y);
				RectTransform obj = content;
				float y = content.sizeDelta.y;
				rect = viewport.rect;
				obj.anchoredPosition = new Vector2(0f, Mathf.Clamp(num4, 0f, Mathf.Max(0f, y - ((Rect)(ref rect)).height)));
				scroll.velocity = Vector2.zero;
			}
		}

		private static void HoverLook(Row row, bool on)
		{
			//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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)row.Button) && row.HoverOff != !on)
			{
				row.HoverOff = !on;
				ColorBlock colors = row.Colors;
				SpriteState sprites = row.Sprites;
				if (!on)
				{
					((ColorBlock)(ref colors)).highlightedColor = ((ColorBlock)(ref colors)).normalColor;
					((SpriteState)(ref sprites)).highlightedSprite = null;
				}
				((Selectable)row.Button).colors = colors;
				((Selectable)row.Button).spriteState = sprites;
			}
		}

		private static int RowsOf(ListTab t)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			int num;
			if (t != tab)
			{
				return PortalWorld.DestinationsFrom(PortalWorld.PositionOf(source), t, search, out num).Count;
			}
			return rows.Count;
		}

		private static void Set(TMP_Text text, string value)
		{
			if (Object.op_Implicit((Object)(object)text) && text.text != value)
			{
				text.text = value;
			}
		}

		private static string EmptyText()
		{
			if (tab == ListTab.Favorites && search.Length == 0)
			{
				return Texts.T("empty_favorites");
			}
			if (tab == ListTab.Ignored && search.Length == 0)
			{
				return Texts.T("empty_ignored");
			}
			if (search.Length > 0)
			{
				return Texts.T("empty_search");
			}
			if (hidden > 0)
			{
				return Texts.T("empty_hidden");
			}
			return Texts.T("empty_none");
		}
	}
	internal static class MapPicker
	{
		private sealed class Marker
		{
			public RectTransform Rt;

			public Image Fill;

			public Image Ring;

			public Image Icon;

			public PortalEntry Entry;

			public bool Favorite;

			public bool Visible;

			public TMP_Text Name;

			public Vector2 NameSize;
		}

		[HarmonyPatch(typeof(Minimap), "OnMapLeftClick")]
		private static class LeftClick
		{
			private static bool Prefix()
			{
				if (!IsOpen || hovered < 0 || Pad.Active)
				{
					return true;
				}
				TravelToHovered();
				return false;
			}
		}

		[HarmonyPatch(typeof(Minimap), "RemovePinUnderPointer")]
		private static class RightClick
		{
			private static bool Prefix()
			{
				if (!IsOpen || hovered < 0 || Pad.Active)
				{
					return true;
				}
				Journal.ToggleFavorite(markers[hovered].Entry.Key);
				return false;
			}
		}

		[HarmonyPatch(typeof(Minimap), "OnMapMiddleClick")]
		private static class MiddleClick
		{
			private static bool Prefix()
			{
				if (!IsOpen || hovered < 0 || Pad.Active)
				{
					return true;
				}
				ListWindow.Ignore(markers[hovered].Entry);
				return false;
			}
		}

		[HarmonyPatch(typeof(Minimap), "UpdateMap")]
		private static class TakeInput
		{
			private static void Prefix(ref bool takeInput)
			{
				if (IsOpen && Pad.Active)
				{
					takeInput = false;
				}
			}
		}

		[HarmonyPatch(typeof(Minimap), "SetMapMode")]
		private static class MapKey
		{
			private static bool Prefix(MapMode mode)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Invalid comparison between Unknown and I4
				if (!IsOpen || (int)mode == 2)
				{
					return true;
				}
				if (ZInput.GetButtonDown("JoyButtonB") && search.Length > 0 && Object.op_Implicit((Object)(object)searchField))
				{
					((TMP_InputField)searchField).text = "";
					return false;
				}
				if (ZInput.GetButtonDown("Map") || ZInput.GetButtonDown("JoyMap"))
				{
					backToList = true;
				}
				return true;
			}
		}

		private const float BadgeSize = 34f;

		private const float HoverRadius = 26f;

		private const float CloseDistance = 6f;

		private static TeleportWorld source;

		private static int openFrame;

		private static int closedFrame = -100;

		private static int cycleIndex = -1;

		private static bool backToList;

		private static readonly List<Marker> markers = new List<Marker>();

		private static int hovered = -1;

		private static Minimap builtFor;

		private static RectTransform badgeRoot;

		private static RectTransform namesRoot;

		private static RectTransform label;

		private static RectTransform bar;

		private static TMP_Text labelText;

		private static TMP_Text hintText;

		private static TMP_Text keysText;

		private static Button listButton;

		private static Toggle onlyPortalsToggle;

		private static Toggle namesToggle;

		private static TMP_Text nameTemplate;

		private static readonly List<Rect> taken = new List<Rect>();

		private static bool[] savedPinFilter;

		private static bool keysReleased;

		private static bool focusSearchWhenFree;

		private static GuiInputField searchField;

		private static string search = "";

		private static int matches;

		private static float openZoom;

		private static Sprite portalIcon;

		private static readonly List<GameObject> hiddenHints = new List<GameObject>();

		private static UIGamePad publicHotkey;

		private const int FitNearest = 8;

		private const float MaxFitZoom = 0.25f;

		private const float MinSearchHalf = 500f;

		private const float BarWidth = 1000f;

		private const float BarHeight = 150f;

		private const float BarSide = 24f;

		private const float ListButtonWidth = 250f;

		private const float ToggleGap = 8f;

		private const float TogglesApart = 40f;

		private const float TitleGap = 24f;

		private static bool searchWasFocused;

		private static int caretToEnd;

		private static readonly StringBuilder typed = new StringBuilder();

		private static string toggleLabels;

		private const string NamesButton = "JoyLStick";

		private static readonly List<int> nameOrder = new List<int>();

		private const float Padding = 60f;

		public static bool IsOpen => Object.op_Implicit((Object)(object)source);

		public static bool SearchFocused
		{
			get
			{
				if (IsOpen && Object.op_Implicit((Object)(object)searchField))
				{
					return ((TMP_InputField)searchField).isFocused;
				}
				return false;
			}
		}

		public static bool BlocksInput
		{
			get
			{
				if (IsOpen || Time.frameCount - closedFrame <= 2)
				{
					return !Pad.Active;
				}
				return false;
			}
		}

		public static void Open(TeleportWorld portal, string filter = "")
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			Minimap instance = Minimap.instance;
			if (Object.op_Implicit((Object)(object)instance))
			{
				if ((Object)(object)builtFor != (Object)(object)instance || !Object.op_Implicit((Object)(object)badgeRoot))
				{
					Build(instance);
				}
				source = portal;
				openFrame = Time.frameCount;
				cycleIndex = -1;
				backToList = false;
				search = filter ?? "";
				if (Object.op_Implicit((Object)(object)searchField))
				{
					((TMP_InputField)searchField).SetTextWithoutNotify(search);
				}
				instance.SetMapMode((MapMode)2);
				instance.inputDelay = 0.5f;
				instance.m_mapOffset = Vector3.zero;
				ZoomToFit(instance, portal);
				openZoom = instance.LargeZoom;
				if (search.Trim().Length > 0)
				{
					ZoomToMatches(instance);
				}
				Show(on: true);
				SetAsideMapControls(instance, aside: true);
				HidePins(instance, Plugin.OnlyPortals.Value);
				if (Object.op_Implicit((Object)(object)onlyPortalsToggle))
				{
					onlyPortalsToggle.SetIsOnWithoutNotify(Plugin.OnlyPortals.Value);
				}
				if (Object.op_Implicit((Object)(object)namesToggle))
				{
					namesToggle.SetIsOnWithoutNotify(Plugin.ShowNames.Value);
				}
				keysReleased = false;
				focusSearchWhenFree = !Pad.Active && Object.op_Implicit((Object)(object)searchField);
				typed.Clear();
				ListenToTyping(on: true);
			}
		}

		private static void ListenToTyping(bool on)
		{
			Keyboard current = Keyboard.current;
			if (current != null)
			{
				current.onTextInput -= OnTextInput;
				if (on)
				{
					current.onTextInput += OnTextInput;
				}
			}
		}

		private static void OnTextInput(char c)
		{
			if (IsOpen && keysReleased && !SearchFocused && !char.IsControl(c))
			{
				typed.Append(c);
			}
		}

		public static void Close()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Invalid comparison between Unknown and I4
			if (IsOpen)
			{
				source = null;
				closedFrame = Time.frameCount;
				focusSearchWhenFree = false;
				ListenToTyping(on: false);
				Show(on: false);
				SetAsideMapControls(Minimap.instance, aside: false);
				HidePins(Minimap.instance, hide: false);
				if (Object.op_Implicit((Object)(object)Minimap.instance) && (int)Minimap.instance.m_mode == 2)
				{
					Minimap.instance.SetMapMode((MapMode)1);
				}
			}
		}

		private static void SwitchToList()
		{
			TeleportWorld portal = source;
			string filter = search;
			Close();
			Journal.LastViewMap = false;
			ListWindow.Open(portal, filter, focusList: false, allTab: true);
		}

		private static void Show(bool on)
		{
			if (Object.op_Implicit((Object)(object)badgeRoot))
			{
				((Component)badgeRoot).gameObject.SetActive(on);
			}
			if (Object.op_Implicit((Object)(object)namesRoot))
			{
				((Component)namesRoot).gameObject.SetActive(on);
			}
			if (Object.op_Implicit((Object)(object)bar))
			{
				((Component)bar).gameObject.SetActive(on);
			}
			if (Object.op_Implicit((Object)(object)label))
			{
				((Component)label).gameObject.SetActive(false);
			}
			if (!on && Object.op_Implicit((Object)(object)searchField))
			{
				((TMP_InputField)searchField).DeactivateInputField(false);
			}
			hovered = -1;
		}

		private static void Build(Minimap map)
		{
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Expected O, but got Unknown
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a9: Expected O, but got Unknown
			//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ed: Expected O, but got Unknown
			builtFor = map;
			markers.Clear();
			portalIcon = Ui.PortalIcon();
			namesRoot = Ui.Stretch(Ui.Rect("ClientPortals Names", (Transform)(object)map.m_pinRootLarge));
			((Transform)namesRoot).SetAsLastSibling();
			badgeRoot = Ui.Stretch(Ui.Rect("ClientPortals Badges", (Transform)(object)map.m_pinRootLarge));
			((Transform)badgeRoot).SetAsLastSibling();
			nameTemplate = (Object.op_Implicit((Object)(object)map.m_pinNamePrefab) ? map.m_pinNamePrefab.GetComponentInChildren<TMP_Text>(true) : null);
			Transform transform = map.m_largeRoot.transform;
			label = Ui.Rect("ClientPortals Label", transform);
			label.pivot = new Vector2(0.5f, 0f);
			Image obj = ((Component)label).gameObject.AddComponent<Image>();
			obj.sprite = Ui.Sprite("button_small") ?? Ui.Sprite("text_field");
			obj.type = (Type)1;
			((Graphic)obj).color = (Object.op_Implicit((Object)(object)obj.sprite) ? new Color(0.15f, 0.12f, 0.09f, 0.95f) : new Color(0f, 0f, 0f, 0.75f));
			((Graphic)obj).raycastTarget = false;
			labelText = Ui.Body(Ui.Stretch(Ui.Rect("Text", (Transform)(object)label), 12f, 4f, 12f, 4f), 20f, Color.white, (TextAlignmentOptions)514);
			labelText.textWrappingMode = (TextWrappingModes)0;
			labelText.overflowMode = (TextOverflowModes)0;
			HorizontalLayoutGroup obj2 = ((Component)label).gameObject.AddComponent<HorizontalLayoutGroup>();
			((LayoutGroup)obj2).padding = new RectOffset(14, 14, 6, 6);
			bool childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true);
			((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = childControlWidth;
			((Component)label).gameObject.AddComponent<ContentSizeFitter>().horizontalFit = (FitMode)2;
			((Component)label).GetComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			bar = Ui.Rect("ClientPortals Bar", transform);
			RectTransform obj3 = bar;
			RectTransform obj4 = bar;
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0.5f, 1f);
			obj4.anchorMax = val;
			obj3.anchorMin = val;
			bar.pivot = new Vector2(0.5f, 1f);
			bar.anchoredPosition = new Vector2(0f, -70f);
			bar.sizeDelta = new Vector2(1000f, 150f);
			Ui.Panel(bar, mirrorBottom: true);
			hintText = Ui.Body(Ui.Place(Ui.Rect("Hint", (Transform)(object)bar), 24f, 10f, 952f, 40f), 22f, Ui.Orange, (TextAlignmentOptions)4097);
			hintText.textWrappingMode = (TextWrappingModes)0;
			Ui.Fit(hintText, 14f);
			keysText = Ui.Body(Ui.Place(Ui.Rect("Keys", (Transform)(object)bar), 24f, 107f, 952f, 36f), 18f, Color.white, (TextAlignmentOptions)514);
			keysText.textWrappingMode = (TextWrappingModes)0;
			Ui.Fit(keysText, 12f);
			listButton = Ui.Button((Transform)(object)bar, "ListView", SwitchToList);
			Ui.Place((RectTransform)((Component)listButton).transform, 726f, 58f, 250f, 44f);
			searchField = Ui.InputField((Transform)(object)bar);
			if (Object.op_Implicit((Object)(object)searchField))
			{
				Ui.Place((RectTransform)((Component)searchField).transform, 24f, 58f, 686f, 44f);
				((UnityEvent<string>)(object)((TMP_InputField)searchField).onValueChanged).AddListener((UnityAction<string>)OnSearch);
			}
			onlyPortalsToggle = BarToggle(map, "OnlyPortals", delegate(bool on)
			{
				Plugin.OnlyPortals.Value = on;
				if (IsOpen)
				{
					HidePins(Minimap.instance, on);
				}
			});
			namesToggle = BarToggle(map, "PortalNames", delegate(bool on)
			{
				Plugin.ShowNames.Value = on;
			});
			toggleLabels = null;
			Show(on: false);
		}

		private static Marker NewMarker()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = Ui.Rect("Portal", (Transform)(object)badgeRoot);
			Vector2 anchorMin = (val.anchorMax = Vector2.zero);
			val.anchorMin = anchorMin;
			val.pivot = new Vector2(0.5f, 0.5f);
			Marker marker = new Marker
			{
				Rt = val,
				Fill = ((Component)val).gameObject.AddComponent<Image>()
			};
			marker.Fill.sprite = Ui.Badge;
			((Graphic)marker.Fill).raycastTarget = false;
			marker.Ring = ((Component)Ui.Stretch(Ui.Rect("Ring", (Transform)(object)val))).gameObject.AddComponent<Image>();
			((Graphic)marker.Ring).raycastTarget = false;
			marker.Icon = ((Component)Ui.Stretch(Ui.Rect("Icon", (Transform)(object)val), 5f, 5f, 5f, 5f)).gameObject.AddComponent<Image>();
			marker.Icon.sprite = portalIcon;
			marker.Icon.preserveAspect = true;
			((Graphic)marker.Icon).raycastTarget = false;
			if (!Object.op_Implicit((Object)(object)portalIcon))
			{
				((Behaviour)marker.Icon).enabled = false;
			}
			marker.Name = NewName();
			return marker;
		}

		private static TMP_Text NewName()
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			TMP_Text val;
			if (Object.op_Implicit((Object)(object)nameTemplate))
			{
				val = Object.Instantiate<GameObject>(((Component)nameTemplate).gameObject, (Transform)(object)namesRoot, false).GetComponent<TMP_Text>();
				((Object)val).name = "Name";
				Localize[] componentsInChildren = ((Component)val).GetComponentsInChildren<Localize>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
				}
			}
			else
			{
				val = Ui.Body(Ui.Rect("Name", (Transform)(object)namesRoot), 16f, Color.white, (TextAlignmentOptions)258);
			}
			RectTransform rectTransform = val.rectTransform;
			Vector2 anchorMin = (rectTransform.anchorMax = Vector2.zero);
			rectTransform.anchorMin = anchorMin;
			rectTransform.pivot = new Vector2(0.5f, 1f);
			val.alignment = (TextAlignmentOptions)258;
			val.textWrappingMode = (TextWrappingModes)0;
			val.overflowMode = (TextOverflowModes)0;
			((Graphic)val).raycastTarget = false;
			val.text = "";
			((Component)val).gameObject.SetActive(false);
			return val;
		}

		private static Toggle BarToggle(Minimap map, string name, UnityAction<bool> changed)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)map.m_publicPosition))
			{
				return null;
			}
			Toggle component = Ui.Clone(((Component)map.m_publicPosition).gameObject, (Transform)(object)bar, name).GetComponent<Toggle>();
			RectTransform val = (RectTransform)((Component)component).transform;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0f, 1f);
			val.anchorMax = val2;
			val.anchorMin = val2;
			val.pivot = new Vector2(0.5f, 0.5f);
			Graphic graphic = component.graphic;
			Image val3 = (Image)(object)((graphic is Image) ? graphic : null);
			if (val3 != null)
			{
				val3.sprite = Ui.Check;
				((Graphic)val3).color = Ui.Orange;
				val3.preserveAspect = true;
			}
			TMP_Text componentInChildren = ((Component)component).GetComponentInChildren<TMP_Text>(true);
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				RectTransform rectTransform = componentInChildren.rectTransform;
				((Vector2)(ref val2))..ctor(0f, 0.5f);
				rectTransform.anchorMax = val2;
				rectTransform.anchorMin = val2;
				rectTransform.pivot = new Vector2(1f, 0.5f);
				rectTransform.anchoredPosition = new Vector2(-8f, 0f);
				componentInChildren.alignment = (TextAlignmentOptions)4100;
				componentInChildren.textWrappingMode = (TextWrappingModes)0;
				componentInChildren.enableAutoSizing = false;
				componentInChildren.fontSize = 18f;
			}
			((UnityEvent<bool>)(object)component.onValueChanged).AddListener(changed);
			return component;
		}

		private static void LayoutToggles(bool pad)
		{
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			string text = Pad.Glyph("JoyButtonX") + " " + Texts.T("only_portals");
			string text2 = Pad.Glyph("JoyLStick") + " " + Texts.T("portal_names");
			string text3 = (pad ? text : Texts.T("only_portals"));
			string text4 = (pad ? text2 : Texts.T("portal_names"));
			if (toggleLabels == text3 + "\n" + text4)
			{
				return;
			}
			toggleLabels = text3 + "\n" + text4;
			Toggle[] array = (Toggle[])(object)new Toggle[2] { onlyPortalsToggle, namesToggle };
			string[] array2 = new string[2] { text3, text4 };
			string[] array3 = new string[2] { text, text2 };
			float num = 976f;
			for (int num2 = array.Length - 1; num2 >= 0; num2--)
			{
				TMP_Text val = (Object.op_Implicit((Object)(object)array[num2]) ? ((Component)array[num2]).GetComponentInChildren<TMP_Text>(true) : null);
				if (Object.op_Implicit((Object)(object)val))
				{
					val.text = array2[num2];
					float num3 = Mathf.Max(val.GetPreferredValues(array2[num2]).x, val.GetPreferredValues(array3[num2]).x);
					val.rectTransform.sizeDelta = new Vector2(num3, 30f);
					((RectTransform)((Component)array[num2]).transform).anchoredPosition = new Vector2(num - BoxHalf(array[num2]), -30f);
					num -= BoxHalf(array[num2]) + ToggleHalf(array[num2]) + 8f + num3 + 40f;
				}
			}
			RectTransform rectTransform = hintText.rectTransform;
			rectTransform.sizeDelta = new Vector2(Mathf.Max(100f, num + 40f - 24f - 24f), rectTransform.sizeDelta.y);
		}

		private static float ToggleHalf(Toggle toggle)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Rect rect = ((RectTransform)((Component)toggle).transform).rect;
			return ((Rect)(ref rect)).width / 2f;
		}

		private static float BoxHalf(Toggle toggle)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)((Selectable)toggle).targetGraphic))
			{
				return ToggleHalf(toggle);
			}
			Rect rect = ((Selectable)toggle).targetGraphic.rectTransform.rect;
			return Mathf.Max(((Rect)(ref rect)).width / 2f, ToggleHalf(toggle));
		}

		public static void Update()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Invalid comparison between Unknown and I4
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			if (!IsOpen)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			Minimap instance = Minimap.instance;
			if (!Object.op_Implicit((Object)(object)instance) || (int)instance.m_mode != 2)
			{
				TeleportWorld val = source;
				source = null;
				Show(on: false);
				SetAsideMapControls(instance, aside: false);
				HidePins(instance, hide: false);
				if (backToList && Object.op_Implicit((Object)(object)val))
				{
					Journal.LastViewMap = false;
					ListWindow.Open(val, search, focusList: false, allTab: true);
				}
				return;
			}
			if (!Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead() || ((Character)localPlayer).IsTeleporting() || !Object.op_Implicit((Object)(object)source.m_nview) || !source.m_nview.IsValid() || Vector3.Distance(((Component)localPlayer).transform.position, ((Component)source).transform.position) > 6f)
			{
				Close();
				return;
			}
			Layout(instance);
			Render();
			if (!keysReleased && !Ui.AnyKeyHeld)
			{
				keysReleased = true;
			}
			if (Time.frameCount <= openFrame + 1)
			{
				return;
			}
			if (focusSearchWhenFree && keysReleased)
			{
				focusSearchWhenFree = false;
				FocusSearch();
			}
			if (typed.Length > 0)
			{
				if (!SearchFocused && Object.op_Implicit((Object)(object)searchField))
				{
					((TMP_InputField)searchField).text = search + typed;
					FocusSearch();
				}
				typed.Clear();
			}
			if (caretToEnd > 0 && SearchFocused)
			{
				caretToEnd--;
				((TMP_InputField)searchField).stringPosition = ((TMP_InputField)searchField).text.Length;
			}
			if (Pad.Active)
			{
				if (ZInput.GetButton("JoyMapZoomIn"))
				{
					instance.LargeZoom += instance.LargeZoom * Time.deltaTime * 2f;
				}
				if (ZInput.GetButton("JoyMapZoomOut"))
				{
					instance.LargeZoom -= instance.LargeZoom * Time.deltaTime * 2f;
				}
			}
			if (BlocksInput)
			{
				if (ZInput.GetKeyDown((KeyCode)9, true))
				{
					SwitchToList();
					return;
				}
				if (ZInput.GetKeyDown((KeyCode)27, true))
				{
					if (search.Length == 0 || !Object.op_Implicit((Object)(object)searchField))
					{
						Close();
						return;
					}
					((TMP_InputField)searchField).text = "";
					FocusSearch();
					return;
				}
				instance.LargeZoom -= Mathf.Clamp(ZInput.GetMouseScrollWheel(), -0.05f, 0.05f) * instance.LargeZoom * 2f;
			}
			bool flag = ZInput.GetKeyDown((KeyCode)13, true) || ZInput.GetKeyDown((KeyCode)271, true);
			bool num = SearchFocused || (searchWasFocused && flag);
			searchWasFocused = SearchFocused;
			if (num)
			{
				if (flag)
				{
					((TMP_InputField)searchField).DeactivateInputField(false);
				}
				if (flag && search.Trim().Length > 0)
				{
					int hidden;
					List<PortalEntry> list = PortalWorld.DestinationsFrom(PortalWorld.PositionOf(source), ListTab.All, search, out hidden);
					TeleportWorld val2 = source;
					if (list.Count == 1)
					{
						Close();
						Travel.Go(val2, list[0]);
					}
					else if (list.Count > 1)
					{
						string filter = search;
						Close();
						ListWindow.Open(val2, filter, focusList: true, allTab: true);
					}
				}
				return;
			}
			if (Pad.Down("JoyRBumper"))
			{
				Cycle(instance, localPlayer, 1);
			}
			if (Pad.Down("JoyLBumper"))
			{
				Cycle(instance, localPlayer, -1);
			}
			if (Pad.Down("JoyButtonX") && Object.op_Implicit((Object)(object)onlyPortalsToggle))
			{
				onlyPortalsToggle.isOn = !onlyPortalsToggle.isOn;
			}
			if (Pad.Down("JoyLStick") && Object.op_Implicit((Object)(object)namesToggle))
			{
				namesToggle.isOn = !namesToggle.isOn;
			}
			if (hovered >= 0)
			{
				if (Pad.Down("JoyButtonA"))
				{
					TravelToHovered();
				}
				else if (Pad.Down("JoyButtonY"))
				{
					Journal.ToggleFavorite(markers[hovered].Entry.Key);
				}
				else if (Pad.Down("JoyRStick"))
				{
					ListWindow.Ignore(markers[hovered].Entry);
				}
			}
		}

		private static void HidePins(Minimap map, bool hide)
		{
			if (!Object.op_Implicit((Object)(object)map) || map.m_visibleIconTypes == null)
			{
				return;
			}
			if (hide && savedPinFilter == null)
			{
				savedPinFilter = (bool[])map.m_visibleIconTypes.Clone();
				for (int i = 0; i < map.m_visibleIconTypes.Length; i++)
				{
					map.m_visibleIconTypes[i] = false;
				}
			}
			else
			{
				if (hide || savedPinFilter == null)
				{
					return;
				}
				if (savedPinFilter.Length == map.m_visibleIconTypes.Length)
				{
					savedPinFilter.CopyTo(map.m_visibleIconTypes, 0);
				}
				savedPinFilter = null;
			}
			map.m_pinUpdateRequired = true;
		}

		private static void Layout(Minimap map)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = PortalWorld.PositionOf(source);
			int hidden;
			List<PortalEntry> list = PortalWorld.DestinationsFrom(val, ListTab.All, search, out hidden);
			matches = list.Count;
			while (markers.Count < list.Count + 1)
			{
				markers.Add(NewMarker());
			}
			Canvas canvas = ((Graphic)map.m_mapImageLarge).canvas;
			Camera val2 = ((Object.op_Implicit((Object)(object)canvas) && (int)canvas.renderMode != 0) ? canvas.worldCamera : null);
			Vector2 val3 = (Vector2)(Pad.Active ? new Vector2((float)Screen.width / 2f, (float)Screen.height / 2f) : Vector2.op_Implicit(ZInput.pointerPosition));
			float num = (Object.op_Implicit((Object)(object)canvas) ? canvas.scaleFactor : 1f);
			float num2 = 26f * num;
			hovered = -1;
			float num3 = default(float);
			float num4 = default(float);
			for (int i = 0; i < markers.Count; i++)
			{
				Marker marker = markers[i];
				Vector3 val4;
				if (i == 0)
				{
					marker.Entry = null;
					val4 = val;
				}
				else
				{
					if (i > list.Count)
					{
						marker.Visible = false;
						((Component)marker.Rt).gameObject.SetActive(false);
						continue;
					}
					marker.Entry = list[i - 1];
					val4 = marker.Entry.Position;
				}
				marker.Visible = map.IsPointVisible(val4, map.m_mapImageLarge);
				((Component)marker.Rt).gameObject.SetActive(marker.Visible);
				if (!marker.Visible)
				{
					continue;
				}
				map.WorldToMapPoint(val4, ref num3, ref num4);
				marker.Rt.anchoredPosition = map.MapPointToLocalGuiPos(num3, num4, map.m_mapImageLarge);
				marker.Favorite = marker.Entry != null && Journal.IsFavorite(marker.Entry.Key);
				if (marker.Entry != null)
				{
					float num5 = Vector2.Distance(val3, RectTransformUtility.WorldToScreenPoint(val2, ((Transform)marker.Rt).position));
					if (num5 < num2)
					{
						num2 = num5;
						hover